]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.4-aacraid-043001.patch
- removed all Group fields translations (oure rpm now can handle translating
[packages/kernel.git] / linux-2.4.4-aacraid-043001.patch
CommitLineData
b6b47fac
JR
1diff -burN linux-2.4.4/MAINTAINERS linux/MAINTAINERS
2--- linux-2.4.4/MAINTAINERS Wed Apr 25 16:35:25 2001
3+++ linux/MAINTAINERS Mon Apr 30 09:43:33 2001
4@@ -113,6 +113,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@domsch.com
11+L: linux-aacraid-devel@domsch.com
12+L: linux-aacraid-announce@domsch.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.4/arch/i386/defconfig linux/arch/i386/defconfig
20--- linux-2.4.4/arch/i386/defconfig Fri Apr 27 16:41:16 2001
21+++ linux/arch/i386/defconfig Mon Apr 30 09:43:33 2001
22@@ -283,6 +283,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.4/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31--- linux-2.4.4/drivers/scsi/Config.in Sun Mar 4 16:30:18 2001
32+++ linux/drivers/scsi/Config.in Mon Apr 30 09:43:33 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.4/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42--- linux-2.4.4/drivers/scsi/Makefile Mon Mar 26 17:36:30 2001
43+++ linux/drivers/scsi/Makefile Mon Apr 30 09:43:33 2001
44@@ -64,6 +64,7 @@
45 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
46 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx_drv.o
47 endif
48+obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
49 obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o
50 obj-$(CONFIG_SCSI_IPS) += ips.o
51 obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
52@@ -184,3 +185,7 @@
53 sim710_u.h: sim710_d.h
54
55 sim710.o : sim710_d.h
56+
57+aacraid.o:
58+ cd aacraid; make
59+
60diff -burN linux-2.4.4/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
61--- linux-2.4.4/drivers/scsi/aacraid/ChangeLog Wed Dec 31 18:00:00 1969
62+++ linux/drivers/scsi/aacraid/ChangeLog Mon Apr 30 09:46:47 2001
63@@ -0,0 +1,5 @@
64+2001-04-30 Matt Domsch <Matt_Domsch@dell.com>
65+* Started with linux-2.4.3-aacraid-030101.patch
66+* Applied against 2.4.4.
67+* Added scsi_set_pci_device() call in linit.c
68+
69diff -burN linux-2.4.4/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
70--- linux-2.4.4/drivers/scsi/aacraid/Makefile Wed Dec 31 18:00:00 1969
71+++ linux/drivers/scsi/aacraid/Makefile Mon Apr 30 09:43:33 2001
72@@ -0,0 +1,169 @@
73+#
74+# Makefile aacraid Raid Controller
75+#
76+
77+###############################################################################
78+### SOURCE FILES DEFINES
79+###############################################################################
80+
81+CFILES_DRIVER=\
82+ ./aachba.c \
83+ ./aacid.c \
84+ ./commctrl.c \
85+ ./comminit.c \
86+ ./commsup.c \
87+ ./dpcsup.c \
88+ ./linit.c \
89+ ./osddi.c \
90+ ./osfuncs.c \
91+ ./ossup.c \
92+ ./port.c \
93+ ./rx.c \
94+ ./sap1sup.c
95+
96+IFILES_DRIVER=\
97+ ./include/AacGenericTypes.h \
98+ ./include/aac_unix_defs.h \
99+ ./include/adapter.h \
100+ ./include/afacomm.h \
101+ ./include/aifstruc.h \
102+ ./include/build_number.h \
103+ ./include/commdata.h \
104+ ./include/commerr.h \
105+ ./include/commfibcontext.h \
106+ ./include/comprocs.h \
107+ ./include/comproto.h \
108+ ./include/comstruc.h \
109+ ./include/comsup.h \
110+ ./include/fsact.h \
111+ ./include/fsafs.h \
112+ ./include/fsaioctl.h \
113+ ./include/fsaport.h \
114+ ./include/fsatypes.h \
115+ ./include/linit.h \
116+ ./include/monkerapi.h \
117+ ./include/nodetype.h \
118+ ./include/nvramioctl.h \
119+ ./include/osheaders.h \
120+ ./include/ostypes.h \
121+ ./include/pcisup.h \
122+ ./include/perfpack.h \
123+ ./include/port.h \
124+ ./include/protocol.h \
125+ ./include/revision.h \
126+ ./include/rxcommon.h \
127+ ./include/rx.h \
128+ ./include/sap1common.h \
129+ ./include/sap1.h \
130+ ./include/version.h
131+
132+ALL_SOURCE=\
133+ ${CFILES_DRIVER} \
134+ ${IFILES_DRIVER}
135+
136+###############################################################################
137+### OBJECT FILES DEFINES
138+###############################################################################
139+
140+
141+OFILES_DRIVER=\
142+ linit.o \
143+ osfuncs.o \
144+ osddi.o \
145+ aachba.o \
146+ commctrl.o \
147+ comminit.o \
148+ commsup.o \
149+ dpcsup.o \
150+ ossup.o \
151+ port.o \
152+ rx.o \
153+ sap1sup.o
154+
155+TARGET_OFILES= ${OFILES_DRIVER} aacid.o
156+
157+###############################################################################
158+### GENERAL DEFINES
159+###############################################################################
160+
161+# Remember that we're doing a chdir one level lower, so we need an extra ../
162+INCS= \
163+ -I./include \
164+ -I../../../include -I..
165+
166+WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
167+
168+
169+COMMON_FLAGS=\
170+ -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
171+ ${INCS} \
172+ ${WARNINGS}
173+
174+AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
175+
176+###############################################################################
177+### DO GENERAL STUFF
178+###############################################################################
179+
180+.SUFFIXES:
181+.SUFFIXES: .c .o .h .a
182+
183+all: source ${TARGET_OFILES} aacraid.o
184+
185+source: ${ALL_SOURCE}
186+
187+clean:
188+ rm *.o
189+
190+###############################################################################
191+### DRIVER LINKS
192+###############################################################################
193+
194+aacraid.o: source ${TARGET_OFILES}
195+ ld -r -o $@ $(TARGET_OFILES)
196+ cp -r aacraid.o ../
197+
198+###############################################################################
199+### SIMPLE COMPILES
200+###############################################################################
201+
202+linit.o: ./linit.c
203+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
204+
205+aachba.o: ./aachba.c
206+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
207+
208+osddi.o: ./osddi.c
209+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
210+
211+osfuncs.o: ./osfuncs.c
212+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
213+
214+commctrl.o: ./commctrl.c
215+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
216+
217+comminit.o: ./comminit.c
218+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
219+
220+commsup.o: ./commsup.c
221+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
222+
223+dpcsup.o: ./dpcsup.c
224+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
225+
226+aacid.o: ./aacid.c
227+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
228+
229+port.o: ./port.c
230+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
231+
232+ossup.o: ./ossup.c
233+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
234+
235+rx.o: ./rx.c
236+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
237+
238+sap1sup.o: ./sap1sup.c
239+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
240+
241+
242diff -burN linux-2.4.4/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
243--- linux-2.4.4/drivers/scsi/aacraid/README Wed Dec 31 18:00:00 1969
244+++ linux/drivers/scsi/aacraid/README Mon Apr 30 09:43:33 2001
245@@ -0,0 +1,46 @@
246+ AACRAID Driver for Linux
247+
248+Introduction
249+-------------------------
250+The aacraid driver adds support for Adaptec (http://www.adaptec.com)
251+OEM based RAID controllers.
252+
253+It is important to note the amount of test time the 2.4.x driver
254+received. Though not a great deal has changed between 2.2 and 2.4
255+for this version, it has not recevied a great deal of test time.
256+
257+A new driver version is in the works and that version will be
258+submitted to the standard distribution kernel. The previous
259+2.2 version was submitted but rejected due to the large
260+amount of code reduncdancy and NTisms. This driver was
261+initially ported from NT to Solaris and then to Linux.
262+
263+The new version is being written on Unix for Unix and
264+should be much easier to read and a great deal cleaner.
265+
266+Supported Cards/Chipsets
267+-------------------------
268+ Dell Computer Corporation PERC 2 Quad Channel
269+ Dell Computer Corporation PERC 2/Si
270+ Dell Computer Corporation PERC 3/Si
271+ Dell Computer Corporation PERC 3/Di
272+ HP NetRAID-4M
273+
274+Not Supported Devices
275+-------------------------
276+ Any and All Adaptec branded raid controllers.
277+
278+People
279+-------------------------
280+ Adaptec Unix OEM Product Group
281+
282+Mailing List
283+-------------------------
284+please see http://domsch.com/linux for information
285+on mailing lists. There is both a development and
286+an announcment list. Due to the overwhelming amount
287+of mail I receive about this driver, I can not
288+answer questions individually and requests should
289+be directed to the list server. Thanks.
290+
291+Modified by Brian Boerner February 2001
292diff -burN linux-2.4.4/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
293--- linux-2.4.4/drivers/scsi/aacraid/aachba.c Wed Dec 31 18:00:00 1969
294+++ linux/drivers/scsi/aacraid/aachba.c Mon Apr 30 09:43:34 2001
295@@ -0,0 +1,1874 @@
296+/*++
297+ * Adaptec aacraid device driver for Linux.
298+ *
299+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
300+ *
301+ * This program is free software; you can redistribute it and/or modify
302+ * it under the terms of the GNU General Public License as published by
303+ * the Free Software Foundation; either version 2, or (at your option)
304+ * any later version.
305+ *
306+ * This program is distributed in the hope that it will be useful,
307+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
308+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
309+ * GNU General Public License for more details.
310+ *
311+ * You should have received a copy of the GNU General Public License
312+ * along with this program; see the file COPYING. If not, write to
313+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
314+ *
315+ * Module Name:
316+ * aachba.c
317+ *
318+ * Abstract: driver...
319+ *
320+--*/
321+
322+static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
323+
324+/*------------------------------------------------------------------------------
325+ * I N C L U D E S
326+ *----------------------------------------------------------------------------*/
327+#include "osheaders.h"
328+#include "AacGenericTypes.h"
329+#include "aac_unix_defs.h"
330+#include "comstruc.h"
331+#include "monkerapi.h"
332+#include "protocol.h"
333+#include "fsafs.h"
334+#include "fsact.h"
335+#include "fsaioctl.h"
336+
337+#include "sap1common.h"
338+#include "fsaport.h"
339+#include "pcisup.h"
340+#include "sap1.h"
341+#include "nodetype.h"
342+#include "comsup.h"
343+#include "afacomm.h"
344+#include "adapter.h"
345+
346+/*------------------------------------------------------------------------------
347+ * D E F I N E S
348+ *----------------------------------------------------------------------------*/
349+/* SCSI Commands */
350+#define SS_TEST 0x00 /* Test unit ready */
351+#define SS_REZERO 0x01 /* Rezero unit */
352+#define SS_REQSEN 0x03 /* Request Sense */
353+#define SS_REASGN 0x07 /* Reassign blocks */
354+#define SS_READ 0x08 /* Read 6 */
355+#define SS_WRITE 0x0A /* Write 6 */
356+#define SS_INQUIR 0x12 /* inquiry */
357+#define SS_ST_SP 0x1B /* Start/Stop unit */
358+#define SS_LOCK 0x1E /* prevent/allow medium removal */
359+#define SS_RESERV 0x16 /* Reserve */
360+#define SS_RELES 0x17 /* Release */
361+#define SS_MODESEN 0x1A /* Mode Sense 6 */
362+#define SS_RDCAP 0x25 /* Read Capacity */
363+#define SM_READ 0x28 /* Read 10 */
364+#define SM_WRITE 0x2A /* Write 10 */
365+#define SS_SEEK 0x2B /* Seek */
366+
367+/* values for inqd_pdt: Peripheral device type in plain English */
368+#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
369+#define INQD_PDT_PROC 0x03 /* Processor device */
370+#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
371+#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
372+#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
373+#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
374+
375+#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
376+#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
377+
378+#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
379+#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
380+#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
381+
382+#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
383+
384+#define MAX_DRIVER_SG_SEGMENT_COUNT 17
385+
386+// ------------------------------------------------------
387+// Sense keys
388+//
389+#define SENKEY_NO_SENSE 0x00 //
390+#define SENKEY_UNDEFINED 0x01 //
391+#define SENKEY_NOT_READY 0x02 //
392+#define SENKEY_MEDIUM_ERR 0x03 //
393+#define SENKEY_HW_ERR 0x04 //
394+#define SENKEY_ILLEGAL 0x05 //
395+#define SENKEY_ATTENTION 0x06 //
396+#define SENKEY_PROTECTED 0x07 //
397+#define SENKEY_BLANK 0x08 //
398+#define SENKEY_V_UNIQUE 0x09 //
399+#define SENKEY_CPY_ABORT 0x0A //
400+#define SENKEY_ABORT 0x0B //
401+#define SENKEY_EQUAL 0x0C //
402+#define SENKEY_VOL_OVERFLOW 0x0D //
403+#define SENKEY_MISCOMP 0x0E //
404+#define SENKEY_RESERVED 0x0F //
405+
406+// ------------------------------------------------------
407+// Sense codes
408+//
409+#define SENCODE_NO_SENSE 0x00
410+#define SENCODE_END_OF_DATA 0x00
411+#define SENCODE_BECOMING_READY 0x04
412+#define SENCODE_INIT_CMD_REQUIRED 0x04
413+#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
414+#define SENCODE_INVALID_COMMAND 0x20
415+#define SENCODE_LBA_OUT_OF_RANGE 0x21
416+#define SENCODE_INVALID_CDB_FIELD 0x24
417+#define SENCODE_LUN_NOT_SUPPORTED 0x25
418+#define SENCODE_INVALID_PARAM_FIELD 0x26
419+#define SENCODE_PARAM_NOT_SUPPORTED 0x26
420+#define SENCODE_PARAM_VALUE_INVALID 0x26
421+#define SENCODE_RESET_OCCURRED 0x29
422+#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
423+#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
424+#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
425+#define SENCODE_DIAGNOSTIC_FAILURE 0x40
426+#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
427+#define SENCODE_INVALID_MESSAGE_ERROR 0x49
428+#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
429+#define SENCODE_OVERLAPPED_COMMAND 0x4E
430+
431+// ------------------------------------------------------
432+// Additional sense codes
433+//
434+#define ASENCODE_NO_SENSE 0x00
435+#define ASENCODE_END_OF_DATA 0x05
436+#define ASENCODE_BECOMING_READY 0x01
437+#define ASENCODE_INIT_CMD_REQUIRED 0x02
438+#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
439+#define ASENCODE_INVALID_COMMAND 0x00
440+#define ASENCODE_LBA_OUT_OF_RANGE 0x00
441+#define ASENCODE_INVALID_CDB_FIELD 0x00
442+#define ASENCODE_LUN_NOT_SUPPORTED 0x00
443+#define ASENCODE_INVALID_PARAM_FIELD 0x00
444+#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
445+#define ASENCODE_PARAM_VALUE_INVALID 0x02
446+#define ASENCODE_RESET_OCCURRED 0x00
447+#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
448+#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
449+#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
450+#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
451+#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
452+#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
453+#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
454+#define ASENCODE_OVERLAPPED_COMMAND 0x00
455+
456+#define BYTE0( x ) ( unsigned char )( x )
457+#define BYTE1( x ) ( unsigned char )( x >> 8 )
458+#define BYTE2( x ) ( unsigned char )( x >> 16 )
459+#define BYTE3( x ) ( unsigned char )( x >> 24 )
460+
461+/*------------------------------------------------------------------------------
462+ * S T R U C T S / T Y P E D E F S
463+ *----------------------------------------------------------------------------*/
464+/* SCSI inquiry data */
465+struct inquiry_data {
466+ unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
467+ unchar inqd_dtq; /* RMB | Device Type Qualifier */
468+ unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
469+ unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
470+ unchar inqd_len; /* Additional length (n-4) */
471+ unchar inqd_pad1[2]; /* Reserved - must be zero */
472+ unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
473+ unchar inqd_vid[8]; /* Vendor ID */
474+ unchar inqd_pid[16]; /* Product ID */
475+ unchar inqd_prl[4]; /* Product Revision Level */
476+};
477+
478+struct sense_data {
479+ unchar error_code; // 70h (current errors), 71h(deferred errors)
480+ unchar valid:1; // A valid bit of one indicates that the information
481+ // field contains valid information as defined in the
482+ // SCSI-2 Standard.
483+
484+ unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
485+ // commands
486+
487+ unchar sense_key:4; // Sense Key
488+ unchar reserved:1;
489+ unchar ILI:1; // Incorrect Length Indicator
490+ unchar EOM:1; // End Of Medium - reserved for random access devices
491+ unchar filemark:1; // Filemark - reserved for random access devices
492+
493+ unchar information[4]; // for direct-access devices, contains the unsigned
494+ // logical block address or residue associated with
495+ // the sense key
496+ unchar add_sense_len; // number of additional sense bytes to follow this field
497+ unchar cmnd_info[4]; // not used
498+ unchar ASC; // Additional Sense Code
499+ unchar ASCQ; // Additional Sense Code Qualifier
500+ unchar FRUC; // Field Replaceable Unit Code - not used
501+
502+ unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
503+ // was in error
504+ unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
505+ // the bit_ptr field has valid value
506+ unchar reserved2:2;
507+ unchar CD:1; // command data bit: 1- illegal parameter in CDB.
508+ // 0- illegal parameter in data.
509+ unchar SKSV:1;
510+
511+ unchar field_ptr[2]; // byte of the CDB or parameter data in error
512+};
513+
514+/*------------------------------------------------------------------------------
515+ * G L O B A L S
516+ *----------------------------------------------------------------------------*/
517+/*------------------------------------------------------------------------------
518+ * M O D U L E G L O B A L S
519+ *----------------------------------------------------------------------------*/
520+static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
521+static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
522+
523+/*------------------------------------------------------------------------------
524+ * F U N C T I O N P R O T O T Y P E S
525+ *----------------------------------------------------------------------------*/
526+AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
527+AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
528+BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
529+BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
530+ PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
531+
532+void AacHba_CompleteScsi(
533+ Scsi_Cmnd *scsi_cmnd_ptr );
534+
535+void AacHba_CompleteScsiNoLock(
536+ Scsi_Cmnd *scsi_cmnd_ptr );
537+
538+static void AacHba_ReadCallback(
539+ void *Context,
540+ PFIB_CONTEXT FibContext,
541+ int FibStatus );
542+
543+static void AacHba_WriteCallback(
544+ void *Context,
545+ PFIB_CONTEXT FibContext,
546+ int FibStatus );
547+
548+int AacHba_DoScsiRead(
549+ Scsi_Cmnd *scsi_cmnd_ptr,
550+ int ContainerId,
551+ int wait );
552+
553+int AacHba_DoScsiWrite(
554+ Scsi_Cmnd *scsi_cmnd_ptr,
555+ int ContainerId,
556+ int wait );
557+
558+int AacHba_QueryDisk(
559+ PVOID AdapterArg, // CommonExtensionPtr
560+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
561+
562+int AacHba_ForceDeleteDisk(
563+ PVOID AdapterArg, // CommonExtensionPtr
564+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
565+
566+int AacHba_DeleteDisk(
567+ PVOID AdapterArg,
568+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
569+
570+void AacHba_DetachAdapter(
571+ IN PVOID AdapterArg );
572+
573+BOOLEAN AacCommDetachAdapter(
574+ IN PAFA_COMM_ADAPTER Adapter );
575+
576+void AacHba_SetSenseData(
577+ char * sense_buf,
578+ unchar sense_key,
579+ unchar sense_code,
580+ unchar a_sense_code,
581+ unchar incorrect_length,
582+ unchar bit_pointer,
583+ unsigned field_pointer,
584+ unsigned long residue );
585+
586+static void get_sd_devname(
587+ long disknum,
588+ char * buffer);
589+
590+// Keep these here for the time being - #REVIEW#
591+int
592+AfaCommAdapterDeviceControl (
593+ IN PVOID AdapterArg,
594+ IN PAFA_IOCTL_CMD IoctlCmdPtr
595+ );
596+
597+AAC_STATUS
598+AfaCommRegisterNewClassDriver(
599+ IN PAFA_COMM_ADAPTER Adapter,
600+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
601+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
602+ );
603+
604+void
605+SetInqDataStr (int, void *, int);
606+/*------------------------------------------------------------------------------
607+ * F U N C T I O N S
608+ *----------------------------------------------------------------------------*/
609+
610+/*------------------------------------------------------------------------------
611+ AacHba_ClassDriverInit()
612+
613+ Setup 'core' class driver to answer ioctl's
614+ *----------------------------------------------------------------------------*/
615+int AacHba_ClassDriverInit(
616+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
617+/*----------------------------------------------------------------------------*/
618+{
619+ AFA_NEW_CLASS_DRIVER NewClassDriver;
620+ AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
621+ PAFA_COMM_ADAPTER Adapter;
622+
623+ Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
624+
625+ RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
626+
627+ // ClassDriverExtension is the first argument passed to class driver functions below
628+ NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
629+
630+ NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
631+ NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
632+ NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
633+ NewClassDriver.HandleAif = AacHba_HandleAif;
634+ AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
635+
636+ return(0);
637+}
638+
639+
640+/*------------------------------------------------------------------------------
641+ AacHba_ProbeContainers()
642+
643+ Make a list of all containers in the system.
644+------------------------------------------------------------------------------*/
645+int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
646+{
647+ fsadev_t *fsa_dev_ptr;
648+ int Index, Status;
649+ PMNTINFO DiskInfo;
650+ PMNTINFORESPONSE DiskInfoResponse;
651+ PFIB_CONTEXT FibContext;
652+ AFA_COMM_ADAPTER *Adapter;
653+ unsigned instance;
654+ char *bufp;
655+ int size;
656+
657+
658+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
659+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
660+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
661+
662+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
663+ {
664+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
665+ return( STATUS_UNSUCCESSFUL );
666+ }
667+
668+ for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
669+ {
670+ Adapter->CommFuncs.InitializeFib( FibContext );
671+
672+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
673+
674+ DiskInfo->Command = VM_NameServe;
675+ DiskInfo->MntCount = Index;
676+ DiskInfo->MntType = FT_FILESYS;
677+
678+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
679+ FibContext,
680+ sizeof(MNTINFO),
681+ FsaNormal,
682+ TRUE,
683+ NULL,
684+ TRUE,
685+ NULL,
686+ NULL );
687+ if ( Status )
688+ {
689+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
690+ break;
691+ }
692+
693+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
694+
695+
696+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
697+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
698+ {
699+
700+
701+ fsa_dev_ptr->ContainerValid[Index] = TRUE;
702+ fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
703+ fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
704+
705+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
706+ fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
707+ }
708+
709+ Adapter->CommFuncs.CompleteFib( FibContext );
710+
711+ // If there are no more containers, then stop asking.
712+ if ((Index + 1) >= DiskInfoResponse->MntRespCount)
713+ break;
714+ } // end for()
715+
716+ Adapter->CommFuncs.FreeFib( FibContext );
717+
718+ g_fsa_dev_array[instance] = fsa_dev_ptr;
719+ return( Status );
720+}
721+
722+
723+/*------------------------------------------------------------------------------
724+ AacHba_ProbeContainer()
725+
726+ Probe a single container.
727+ *----------------------------------------------------------------------------*/
728+int AacHba_ProbeContainer(
729+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
730+ int ContainerId )
731+/*----------------------------------------------------------------------------*/
732+{
733+ fsadev_t *fsa_dev_ptr;
734+ int Status;
735+ PMNTINFO DiskInfo;
736+ PMNTINFORESPONSE DiskInfoResponse;
737+ PFIB_CONTEXT FibContext;
738+ AFA_COMM_ADAPTER *Adapter;
739+ unsigned instance;
740+
741+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
742+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
743+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
744+
745+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
746+ {
747+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
748+ return( STATUS_UNSUCCESSFUL );
749+ }
750+
751+ Adapter->CommFuncs.InitializeFib( FibContext );
752+
753+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
754+
755+ DiskInfo->Command = VM_NameServe;
756+ DiskInfo->MntCount = ContainerId;
757+ DiskInfo->MntType = FT_FILESYS;
758+
759+ Status = Adapter->CommFuncs.SendFib (ContainerCommand,
760+ FibContext,
761+ sizeof(MNTINFO),
762+ FsaNormal,
763+ TRUE,
764+ NULL,
765+ TRUE,
766+ NULL,
767+ NULL );
768+ if ( Status )
769+ {
770+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
771+ Adapter->CommFuncs.CompleteFib( FibContext );
772+ Adapter->CommFuncs.FreeFib( FibContext );
773+ return( Status );
774+ }
775+
776+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
777+
778+
779+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
780+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
781+ {
782+
783+ fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
784+ fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
785+ fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
786+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
787+ fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
788+ }
789+
790+ Adapter->CommFuncs.CompleteFib( FibContext );
791+ Adapter->CommFuncs.FreeFib( FibContext );
792+
793+ return( Status );
794+}
795+
796+
797+/*------------------------------------------------------------------------------
798+ AacHba_CompleteScsi()
799+
800+ Call SCSI completion routine after acquiring io_request_lock
801+
802+ Preconditions:
803+ Postconditions:
804+ *----------------------------------------------------------------------------*/
805+void AacHba_CompleteScsi(
806+ Scsi_Cmnd *scsi_cmnd_ptr )
807+{
808+ unsigned long cpu_flags;
809+
810+ spin_lock_irqsave( &io_request_lock, cpu_flags );
811+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
812+ spin_unlock_irqrestore( &io_request_lock, cpu_flags );
813+}
814+
815+
816+/*------------------------------------------------------------------------------
817+ AacHba_CompleteScsiNoLock()
818+
819+ Call SCSI completion routine
820+
821+ Preconditions:
822+ Postconditions:
823+ *----------------------------------------------------------------------------*/
824+void AacHba_CompleteScsiNoLock(
825+ Scsi_Cmnd *scsi_cmnd_ptr )
826+{
827+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
828+}
829+
830+/*------------------------------------------------------------------------------
831+ AacHba_DoScsiCmd()
832+
833+ Process SCSI command
834+
835+ Preconditions:
836+ Postconditions:
837+ Returns 0 on success, -1 on failure
838+ *----------------------------------------------------------------------------*/
839+int AacHba_DoScsiCmd(
840+ Scsi_Cmnd *scsi_cmnd_ptr,
841+ int wait )
842+{
843+ int ContainerId = 0;
844+ fsadev_t *fsa_dev_ptr;
845+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
846+ int MiniPortIndex;
847+
848+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
849+ MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
850+
851+ fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
852+
853+ // If the bus, target or lun is out of range, return fail
854+ // Test does not apply to ID 16, the pseudo id for the controller itself.
855+ if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
856+ {
857+ if( ( scsi_cmnd_ptr->channel > 0 ) ||
858+ ( scsi_cmnd_ptr->target > 15 ) ||
859+ ( scsi_cmnd_ptr->lun > 7 ) )
860+ {
861+ cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
862+ scsi_cmnd_ptr->channel,
863+ scsi_cmnd_ptr->target,
864+ scsi_cmnd_ptr->lun );
865+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
866+
867+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
868+
869+ return ( -1 );
870+ }
871+
872+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
873+
874+
875+ // If the target container doesn't exist, it may have been newly created
876+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
877+ {
878+ switch( scsi_cmnd_ptr->cmnd[0] )
879+ {
880+ case SS_INQUIR:
881+ case SS_RDCAP:
882+ case SS_TEST:
883+ spin_unlock_irq( &io_request_lock );
884+ AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
885+ spin_lock_irq( &io_request_lock );
886+ default:
887+ break;
888+ }
889+ }
890+
891+ // If the target container still doesn't exist, return failure
892+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
893+ {
894+
895+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
896+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
897+
898+ return ( -1 );
899+ }
900+ }
901+ else // the command is for the controller itself
902+ if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
903+ ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
904+ {
905+ cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
906+ scsi_cmnd_ptr->cmnd[0] );
907+
908+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
909+
910+ AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
911+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
912+ 0, 0, 0, 0 );
913+
914+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
915+
916+ return ( -1 );
917+ }
918+
919+ // Handle commands here that don't really require going out to the adapter
920+ switch ( scsi_cmnd_ptr->cmnd[0] )
921+ {
922+ case SS_INQUIR:
923+ {
924+ struct inquiry_data *inq_data_ptr;
925+
926+ cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
927+ inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
928+ bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
929+
930+ inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
931+
932+ inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
933+ // that the medium is removable
934+ inq_data_ptr->inqd_rdf = 2; // A response data format value of
935+ // two indicates that the data shall
936+ // be in the format specified in SCSI-2
937+ inq_data_ptr->inqd_len = 31;
938+
939+ // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
940+ SetInqDataStr( MiniPortIndex,
941+ (void *)(inq_data_ptr->inqd_vid),
942+ fsa_dev_ptr->ContainerType[ContainerId]);
943+
944+ if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
945+ inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
946+ else
947+ inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
948+
949+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
950+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
951+
952+ return ( 0 );
953+ }
954+
955+ case SS_RDCAP:
956+ {
957+ int capacity;
958+ char *cp;
959+
960+ cmn_err( CE_DEBUG, "READ CAPACITY command" );
961+ capacity = fsa_dev_ptr->ContainerSize[ContainerId];
962+ cp = scsi_cmnd_ptr->request_buffer;
963+ cp[0] = ( capacity >> 24 ) & 0xff;
964+ cp[1] = ( capacity >> 16 ) & 0xff;
965+ cp[2] = ( capacity >> 8 ) & 0xff;
966+ cp[3] = ( capacity >> 0 ) & 0xff;
967+ cp[4] = 0;
968+ cp[5] = 0;
969+ cp[6] = 2;
970+ cp[7] = 0;
971+
972+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
973+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
974+
975+ return ( 0 );
976+ }
977+
978+ case SS_MODESEN:
979+ {
980+ char *mode_buf;
981+
982+ cmn_err( CE_DEBUG, "MODE SENSE command" );
983+ mode_buf = scsi_cmnd_ptr->request_buffer;
984+ mode_buf[0] = 0; // Mode data length (MSB)
985+ mode_buf[1] = 6; // Mode data length (LSB)
986+ mode_buf[2] = 0; // Medium type - default
987+ mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
988+ mode_buf[4] = 0; // reserved
989+ mode_buf[5] = 0; // reserved
990+ mode_buf[6] = 0; // Block descriptor length (MSB)
991+ mode_buf[7] = 0; // Block descriptor length (LSB)
992+
993+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
994+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
995+
996+ return ( 0 );
997+ }
998+
999+
1000+ // These commands are all No-Ops
1001+ case SS_TEST:
1002+ cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1003+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1004+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1005+ return ( 0 );
1006+
1007+ case SS_REQSEN:
1008+ cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1009+
1010+ memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1011+ sizeof( struct sense_data ) );
1012+ bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1013+
1014+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1015+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1016+ return ( 0 );
1017+
1018+ case SS_LOCK:
1019+ cmn_err(CE_DEBUG, "LOCK command");
1020+
1021+ if( scsi_cmnd_ptr->cmnd[4] )
1022+ fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1023+ else
1024+ fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1025+
1026+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1027+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1028+ return ( 0 );
1029+
1030+ case SS_RESERV:
1031+ cmn_err( CE_DEBUG, "RESERVE command" );
1032+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1033+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1034+ return ( 0 );
1035+
1036+ case SS_RELES:
1037+ cmn_err( CE_DEBUG, "RELEASE command" );
1038+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1039+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1040+ return ( 0 );
1041+
1042+ case SS_REZERO:
1043+ cmn_err( CE_DEBUG, "REZERO command" );
1044+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1045+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1046+ return ( 0 );
1047+
1048+ case SS_REASGN:
1049+ cmn_err( CE_DEBUG, "REASSIGN command" );
1050+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1051+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1052+ return ( 0 );
1053+
1054+ case SS_SEEK:
1055+ cmn_err( CE_DEBUG, "SEEK command" );
1056+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1057+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1058+ return ( 0 );
1059+
1060+ case SS_ST_SP:
1061+ cmn_err( CE_DEBUG, "START/STOP command" );
1062+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1063+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1064+ return ( 0 );
1065+ }
1066+
1067+ switch ( scsi_cmnd_ptr->cmnd[0] )
1068+ {
1069+ case SS_READ:
1070+ case SM_READ:
1071+ // Hack to keep track of ordinal number of the device that corresponds
1072+ // to a container. Needed to convert containers to /dev/sd device names
1073+ fsa_dev_ptr->ContainerDevNo[ContainerId] =
1074+ DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1075+
1076+ return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1077+ break;
1078+
1079+ case SS_WRITE:
1080+ case SM_WRITE:
1081+
1082+ return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1083+ break;
1084+ }
1085+ //
1086+ // Unhandled commands
1087+ //
1088+ cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1089+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1090+
1091+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1092+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1093+ 0, 0, 0, 0 );
1094+
1095+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1096+ return ( -1 );
1097+}
1098+
1099+
1100+/*------------------------------------------------------------------------------
1101+ AacHba_DoScsiRead()
1102+
1103+ Handles SCSI READ requests
1104+
1105+ Preconditions:
1106+ Postconditions:
1107+ Returns 0 on success, -1 on failure
1108+ *----------------------------------------------------------------------------*/
1109+int AacHba_DoScsiRead(
1110+ Scsi_Cmnd *scsi_cmnd_ptr,
1111+ int ContainerId,
1112+ int wait )
1113+/*----------------------------------------------------------------------------*/
1114+{
1115+ u_long lba;
1116+ u_long count;
1117+ u_long byte_count;
1118+ int Status;
1119+
1120+ PBLOCKREAD BlockReadDisk;
1121+ PBLOCKREADRESPONSE BlockReadResponse;
1122+ uint16_t FibSize;
1123+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1124+ AFA_COMM_ADAPTER *Adapter;
1125+ PFIB_CONTEXT cmd_fibcontext;
1126+
1127+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1128+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1129+
1130+ // Get block address and transfer length
1131+ if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1132+ {
1133+ cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1134+
1135+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1136+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1137+ scsi_cmnd_ptr->cmnd[3];
1138+ count = scsi_cmnd_ptr->cmnd[4];
1139+
1140+ if ( count == 0 )
1141+ count = 256;
1142+ }
1143+ else
1144+ {
1145+ cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1146+
1147+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1148+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1149+
1150+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1151+ }
1152+ cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1153+
1154+ //-------------------------------------------------------------------------
1155+ // Alocate and initialize a Fib
1156+ // Setup BlockRead command
1157+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1158+ {
1159+ cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1160+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1161+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1162+ return ( -1 );
1163+ }
1164+
1165+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1166+
1167+ BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1168+ BlockReadDisk->Command = VM_CtBlockRead;
1169+ BlockReadDisk->ContainerId = ContainerId;
1170+ BlockReadDisk->BlockNumber = lba;
1171+ BlockReadDisk->ByteCount = count * 512;
1172+ BlockReadDisk->SgMap.SgCount = 1;
1173+
1174+ if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1175+ {
1176+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1177+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1178+
1179+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1180+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1181+ 0, 0, 7, 0 );
1182+
1183+ goto err_return;
1184+ }
1185+
1186+ //-------------------------------------------------------------------------
1187+ // Build Scatter/Gather list
1188+ //
1189+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1190+ {
1191+ struct scatterlist *scatterlist_ptr;
1192+ int segment;
1193+
1194+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1195+
1196+ byte_count = 0;
1197+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1198+ {
1199+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1200+ ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1201+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1202+ scatterlist_ptr[segment].length;
1203+
1204+#ifdef DEBUG_SGBUFFER
1205+ memset( scatterlist_ptr[segment].address, 0xa5,
1206+ scatterlist_ptr[segment].length );
1207+#endif
1208+
1209+ byte_count += scatterlist_ptr[segment].length;
1210+
1211+ if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1212+ {
1213+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1214+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1215+
1216+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1217+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1218+ 0, 0, 7, 0 );
1219+
1220+ goto err_return;
1221+ }
1222+ /*
1223+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1224+ segment,
1225+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1226+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1227+ */
1228+ }
1229+ BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1230+
1231+ if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1232+ {
1233+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1234+ MAX_DRIVER_SG_SEGMENT_COUNT );
1235+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1236+ goto err_return;
1237+ }
1238+ }
1239+ else // one piece of contiguous phys mem
1240+ {
1241+ BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1242+ ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1243+ BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1244+
1245+ byte_count = scsi_cmnd_ptr->request_bufflen;
1246+
1247+ if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1248+ {
1249+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1250+ cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1251+ cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1252+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1253+
1254+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1255+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1256+ 0, 0, 7, 0 );
1257+
1258+ goto err_return;
1259+ }
1260+ }
1261+
1262+ if( byte_count != BlockReadDisk->ByteCount )
1263+ cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1264+
1265+ //-------------------------------------------------------------------------
1266+ // Now send the Fib to the adapter
1267+ //
1268+ FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1269+
1270+ if( wait )
1271+ {
1272+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1273+ cmd_fibcontext,
1274+ FibSize,
1275+ FsaNormal,
1276+ TRUE,
1277+ NULL,
1278+ TRUE,
1279+ NULL,
1280+ NULL);
1281+
1282+ BlockReadResponse = ( PBLOCKREADRESPONSE )
1283+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1284+
1285+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1286+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1287+
1288+ if( BlockReadResponse->Status != ST_OK )
1289+ {
1290+ cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1291+ BlockReadResponse->Status );
1292+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1293+
1294+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1295+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1296+ 0, 0, 0, 0 );
1297+
1298+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1299+ return ( -1 );
1300+ }
1301+ else
1302+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1303+
1304+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1305+ return ( 0 );
1306+ }
1307+ else
1308+ {
1309+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1310+ cmd_fibcontext,
1311+ FibSize,
1312+ FsaNormal,
1313+ FALSE,
1314+ NULL,
1315+ TRUE,
1316+ ( PFIB_CALLBACK )AacHba_ReadCallback,
1317+ ( void *)scsi_cmnd_ptr );
1318+ // don't call done func here
1319+ return ( 0 );
1320+ }
1321+
1322+err_return:
1323+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1324+
1325+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1326+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1327+
1328+ return ( -1 );
1329+}
1330+
1331+
1332+/*------------------------------------------------------------------------------
1333+ AacHba_DoScsiWrite()
1334+
1335+ Handles SCSI WRITE requests
1336+
1337+ Preconditions:
1338+ Postconditions:
1339+ Returns 0 on success, -1 on failure
1340+ *----------------------------------------------------------------------------*/
1341+int AacHba_DoScsiWrite(
1342+ Scsi_Cmnd *scsi_cmnd_ptr,
1343+ int ContainerId,
1344+ int wait )
1345+/*----------------------------------------------------------------------------*/
1346+{
1347+ u_long lba;
1348+ u_long count;
1349+ u_long byte_count;
1350+ int Status;
1351+
1352+ PBLOCKWRITE BlockWriteDisk;
1353+ PBLOCKWRITERESPONSE BlockWriteResponse;
1354+ uint16_t FibSize;
1355+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1356+ AFA_COMM_ADAPTER *Adapter;
1357+ PFIB_CONTEXT cmd_fibcontext;
1358+
1359+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1360+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1361+
1362+ // Get block address and transfer length
1363+ if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1364+ {
1365+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1366+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1367+ scsi_cmnd_ptr->cmnd[3];
1368+ count = scsi_cmnd_ptr->cmnd[4];
1369+
1370+ if ( count == 0 )
1371+ count = 256;
1372+ }
1373+ else
1374+ {
1375+ cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1376+
1377+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1378+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1379+
1380+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1381+
1382+ }
1383+ cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1384+
1385+ //-------------------------------------------------------------------------
1386+ // Alocate and initialize a Fib
1387+ // Setup BlockWrite command
1388+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1389+ {
1390+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1391+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1392+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1393+ return ( -1 );
1394+ }
1395+
1396+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1397+
1398+ BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1399+ BlockWriteDisk->Command = VM_CtBlockWrite;
1400+ BlockWriteDisk->ContainerId = ContainerId;
1401+ BlockWriteDisk->BlockNumber = lba;
1402+ BlockWriteDisk->ByteCount = count * 512;
1403+ BlockWriteDisk->SgMap.SgCount = 1;
1404+
1405+
1406+ if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1407+ {
1408+ struct scatterlist *scatterlist_ptr;
1409+ int segment;
1410+ scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1411+
1412+ cmn_err( CE_WARN, "\n");
1413+ cmn_err( CE_WARN, "AacHba_`DoScsiWrite: WRITE request is larger than 64K");
1414+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1415+/* cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1416+/* cmn_err( CE_WARN, "Dump SG Element Size..."); */
1417+/* for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) */
1418+/* { */
1419+/* cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1420+/* } */
1421+/* cmn_err (CE_WARN, "\n"); */
1422+
1423+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1424+
1425+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1426+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1427+ 0, 0, 7, 0 );
1428+
1429+ goto err_return;
1430+ }
1431+
1432+ //-------------------------------------------------------------------------
1433+ // Build Scatter/Gather list
1434+ //
1435+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1436+ {
1437+ struct scatterlist *scatterlist_ptr;
1438+ int segment;
1439+
1440+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1441+
1442+ byte_count = 0;
1443+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1444+ {
1445+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1446+ ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1447+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1448+ scatterlist_ptr[segment].length;
1449+
1450+ byte_count += scatterlist_ptr[segment].length;
1451+
1452+ if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1453+ {
1454+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1455+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1456+
1457+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1458+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1459+ 0, 0, 7, 0 );
1460+
1461+ goto err_return;
1462+ }
1463+
1464+ /*
1465+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1466+ segment,
1467+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1468+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1469+ */
1470+ }
1471+ BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1472+
1473+ if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1474+ {
1475+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1476+ MAX_DRIVER_SG_SEGMENT_COUNT );
1477+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1478+ goto err_return;
1479+ }
1480+ }
1481+ else // one piece of contiguous phys mem
1482+ {
1483+ BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1484+ ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1485+ BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1486+
1487+ byte_count = scsi_cmnd_ptr->request_bufflen;
1488+
1489+ if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1490+ {
1491+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1492+
1493+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1494+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1495+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1496+ 0, 0, 7, 0 );
1497+
1498+ goto err_return;
1499+ }
1500+ }
1501+
1502+ if( byte_count != BlockWriteDisk->ByteCount )
1503+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1504+
1505+ //-------------------------------------------------------------------------
1506+ // Now send the Fib to the adapter
1507+ //
1508+ FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1509+
1510+ if( wait )
1511+ {
1512+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1513+ cmd_fibcontext,
1514+ FibSize,
1515+ FsaNormal,
1516+ TRUE,
1517+ NULL,
1518+ TRUE,
1519+ NULL,
1520+ NULL );
1521+
1522+ BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1523+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1524+
1525+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1526+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1527+
1528+ if( BlockWriteResponse->Status != ST_OK )
1529+ {
1530+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1531+ BlockWriteResponse->Status );
1532+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1533+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1534+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1535+ 0, 0, 0, 0 );
1536+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1537+ return ( -1 );
1538+ }
1539+ else
1540+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1541+
1542+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1543+ return ( 0 );
1544+ }
1545+ else
1546+ {
1547+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1548+ cmd_fibcontext,
1549+ FibSize,
1550+ FsaNormal,
1551+ FALSE,
1552+ NULL,
1553+ TRUE,
1554+ ( PFIB_CALLBACK )AacHba_WriteCallback,
1555+ ( void * )scsi_cmnd_ptr );
1556+
1557+ // don't call done func here - it should be called by the WriteCallback
1558+ return ( 0 );
1559+ }
1560+
1561+err_return:
1562+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1563+
1564+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1565+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1566+
1567+ return ( -1 );
1568+}
1569+
1570+
1571+/*------------------------------------------------------------------------------
1572+ AacHba_ReadCallback()
1573+ *----------------------------------------------------------------------------*/
1574+void AacHba_ReadCallback(
1575+ VOID *Context,
1576+ PFIB_CONTEXT FibContext,
1577+ int FibStatus )
1578+/*----------------------------------------------------------------------------*/
1579+{
1580+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1581+ AFA_COMM_ADAPTER *Adapter;
1582+ BLOCKREADRESPONSE *BlockReadResponse;
1583+ Scsi_Cmnd * scsi_cmnd_ptr;
1584+ u_long lba;
1585+ int ContainerId;
1586+
1587+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1588+
1589+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1590+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1591+
1592+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1593+
1594+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1595+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1596+ scsi_cmnd_ptr->cmnd[3];
1597+ cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1598+
1599+ if( FibContext == 0 )
1600+ {
1601+ cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1602+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1603+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1604+ return;
1605+ }
1606+
1607+ BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1608+
1609+ if ( BlockReadResponse->Status == ST_OK )
1610+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1611+ else
1612+ {
1613+ cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1614+ BlockReadResponse->Status );
1615+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1616+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1617+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1618+ 0, 0, 0, 0 );
1619+ }
1620+
1621+#ifdef DEBUG_SGBUFFER
1622+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1623+ {
1624+ struct scatterlist *scatterlist_ptr;
1625+ int i, segment, count;
1626+ char *ptr;
1627+
1628+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1629+
1630+ for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1631+ {
1632+ count = 0;
1633+ ptr = scatterlist_ptr[segment].address;
1634+ for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1635+ {
1636+ if( *( ptr++ ) == 0xa5 )
1637+ count++;
1638+ }
1639+ if( count == scatterlist_ptr[segment].length )
1640+ cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1641+
1642+ }
1643+ }
1644+#endif
1645+
1646+ Adapter->CommFuncs.CompleteFib( FibContext );
1647+ Adapter->CommFuncs.FreeFib( FibContext );
1648+
1649+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1650+}
1651+
1652+/*------------------------------------------------------------------------------
1653+ AacHba_WriteCallback()
1654+ *----------------------------------------------------------------------------*/
1655+void AacHba_WriteCallback(
1656+ VOID *Context,
1657+ PFIB_CONTEXT FibContext,
1658+ int FibStatus )
1659+/*----------------------------------------------------------------------------*/
1660+{
1661+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1662+ AFA_COMM_ADAPTER *Adapter;
1663+ BLOCKWRITERESPONSE *BlockWriteResponse;
1664+ Scsi_Cmnd *scsi_cmnd_ptr;
1665+ u_long lba;
1666+ int ContainerId;
1667+
1668+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1669+
1670+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1671+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1672+
1673+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1674+
1675+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1676+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1677+ scsi_cmnd_ptr->cmnd[3];
1678+ cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1679+ if( FibContext == 0 )
1680+ {
1681+ cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1682+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1683+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1684+ return;
1685+ }
1686+
1687+ BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1688+ if (BlockWriteResponse->Status == ST_OK)
1689+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1690+ else
1691+ {
1692+ cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1693+ BlockWriteResponse->Status );
1694+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1695+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1696+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1697+ 0, 0, 0, 0 );
1698+ }
1699+
1700+ Adapter->CommFuncs.CompleteFib( FibContext );
1701+ Adapter->CommFuncs.FreeFib( FibContext );
1702+
1703+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1704+}
1705+
1706+
1707+/*------------------------------------------------------------------------------
1708+ AacHba_Ioctl()
1709+
1710+ Handle IOCTL requests
1711+
1712+ Preconditions:
1713+ Postconditions:
1714+ *----------------------------------------------------------------------------*/
1715+int AacHba_Ioctl(
1716+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1717+ int cmd,
1718+ void * arg )
1719+/*----------------------------------------------------------------------------*/
1720+{
1721+ Sa_ADAPTER_EXTENSION *AdapterExtension;
1722+ AFA_IOCTL_CMD IoctlCmd;
1723+ int status;
1724+
1725+ AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1726+
1727+ cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1728+ switch( cmd )
1729+ {
1730+ case FSACTL_SENDFIB:
1731+ cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1732+ break;
1733+
1734+ case FSACTL_AIF_THREAD:
1735+ cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1736+ break;
1737+
1738+ case FSACTL_NULL_IO_TEST:
1739+ cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1740+ break;
1741+
1742+ case FSACTL_SIM_IO_TEST:
1743+ cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1744+ break;
1745+
1746+ case FSACTL_GET_FIBTIMES:
1747+ cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1748+ break;
1749+
1750+ case FSACTL_ZERO_FIBTIMES:
1751+ cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1752+ break;
1753+
1754+ case FSACTL_GET_VAR:
1755+ cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1756+ break;
1757+
1758+ case FSACTL_SET_VAR:
1759+ cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1760+ break;
1761+
1762+ case FSACTL_OPEN_ADAPTER_CONFIG:
1763+ cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1764+ break;
1765+
1766+ case FSACTL_CLOSE_ADAPTER_CONFIG:
1767+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1768+ break;
1769+
1770+ case FSACTL_QUERY_ADAPTER_CONFIG:
1771+ cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1772+ break;
1773+
1774+ case FSACTL_OPEN_GET_ADAPTER_FIB:
1775+ cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1776+ break;
1777+
1778+ case FSACTL_GET_NEXT_ADAPTER_FIB:
1779+ cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1780+ break;
1781+
1782+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
1783+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1784+ break;
1785+
1786+ case FSACTL_MINIPORT_REV_CHECK:
1787+ cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1788+ break;
1789+
1790+ case FSACTL_OPENCLS_COMM_PERF_DATA:
1791+ cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1792+ break;
1793+
1794+ case FSACTL_GET_COMM_PERF_DATA:
1795+ cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1796+ break;
1797+
1798+ case FSACTL_QUERY_DISK:
1799+ cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1800+ break;
1801+
1802+ case FSACTL_DELETE_DISK:
1803+ cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1804+ break;
1805+
1806+ default:
1807+ cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1808+ }
1809+
1810+ IoctlCmd.cmd = cmd;
1811+ IoctlCmd.arg = ( intptr_t )arg;
1812+ IoctlCmd.flag = 0;
1813+ IoctlCmd.cred_p = 0;
1814+ IoctlCmd.rval_p = 0;
1815+
1816+ status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1817+ cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1818+ return( status );
1819+}
1820+
1821+
1822+/*------------------------------------------------------------------------------
1823+ AacHba_AdapterDeviceControl()
1824+
1825+ Preconditions:
1826+ Postconditions:
1827+ Returns TRUE if ioctl handled, FALSE otherwise
1828+ *ReturnStatus set to completion status
1829+ *----------------------------------------------------------------------------*/
1830+BOOLEAN AacHba_AdapterDeviceControl (
1831+ PVOID AdapterArg, // CommonExtensionPtr
1832+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
1833+ OUT int * ReturnStatus )
1834+/*----------------------------------------------------------------------------*/
1835+{
1836+ BOOLEAN Handled = TRUE; // start out handling it.
1837+ int Status = EFAULT;
1838+
1839+ switch( IoctlCmdPtr->cmd )
1840+ {
1841+ case FSACTL_QUERY_DISK:
1842+ Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1843+ break;
1844+
1845+ case FSACTL_DELETE_DISK:
1846+ Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1847+ break;
1848+
1849+ case FSACTL_FORCE_DELETE_DISK:
1850+ Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1851+ break;
1852+
1853+ case 2131:
1854+ if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1855+ Status = -EFAULT;
1856+ break;
1857+
1858+ default:
1859+ Handled = FALSE;
1860+ break;
1861+ }
1862+
1863+ *ReturnStatus = Status;
1864+
1865+ return( Handled );
1866+}
1867+
1868+
1869+/*------------------------------------------------------------------------------
1870+ AacHba_QueryDisk()
1871+
1872+ Postconditions:
1873+ Return values
1874+ 0 = OK
1875+ -EFAULT = Bad address
1876+ -EINVAL = Bad container number
1877+ *----------------------------------------------------------------------------*/
1878+int AacHba_QueryDisk(
1879+ PVOID AdapterArg, // CommonExtensionPtr
1880+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
1881+/*----------------------------------------------------------------------------*/
1882+{
1883+ UNIX_QUERY_DISK QueryDisk;
1884+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1885+ fsadev_t *fsa_dev_ptr;
1886+
1887+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1888+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1889+
1890+ if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1891+ return( -EFAULT );
1892+
1893+ if (QueryDisk.ContainerNumber == -1)
1894+ QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1895+ else
1896+ if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1897+ {
1898+ if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1899+ return( -EINVAL );
1900+
1901+ QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1902+ QueryDisk.Bus = 0;
1903+ QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1904+ QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1905+ }
1906+ else
1907+ return( -EINVAL );
1908+
1909+ QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1910+ QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1911+ QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1912+
1913+ if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1914+ QueryDisk.UnMapped = TRUE;
1915+ else
1916+ QueryDisk.UnMapped = FALSE;
1917+
1918+ get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1919+ QueryDisk.diskDeviceName );
1920+
1921+ if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1922+ return( -EFAULT );
1923+
1924+ return( 0 );
1925+}
1926+
1927+
1928+/*------------------------------------------------------------------------------
1929+ get_sd_devname()
1930+ *----------------------------------------------------------------------------*/
1931+static void get_sd_devname(
1932+ long disknum,
1933+ char * buffer)
1934+/*----------------------------------------------------------------------------*/
1935+{
1936+ if( disknum < 0 )
1937+ {
1938+ sprintf(buffer, "%s", "");
1939+ return;
1940+ }
1941+
1942+ if( disknum < 26 )
1943+ sprintf(buffer, "sd%c", 'a' + disknum);
1944+ else {
1945+ unsigned int min1;
1946+ unsigned int min2;
1947+ /*
1948+ * For larger numbers of disks, we need to go to a new
1949+ * naming scheme.
1950+ */
1951+ min1 = disknum / 26;
1952+ min2 = disknum % 26;
1953+ sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1954+ }
1955+}
1956+
1957+
1958+/*------------------------------------------------------------------------------
1959+ AacHba_ForceDeleteDisk()
1960+
1961+ Postconditions:
1962+ Return values
1963+ 0 = OK
1964+ -EFAULT = Bad address
1965+ -EINVAL = Bad container number
1966+ *----------------------------------------------------------------------------*/
1967+int AacHba_ForceDeleteDisk(
1968+ PVOID AdapterArg, // CommonExtensionPtr
1969+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
1970+/*----------------------------------------------------------------------------*/
1971+{
1972+ DELETE_DISK DeleteDisk;
1973+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1974+ fsadev_t *fsa_dev_ptr;
1975+
1976+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1977+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1978+
1979+ if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
1980+ return( -EFAULT );
1981+
1982+ if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1983+ return( -EINVAL );
1984+
1985+ // Mark this container as being deleted.
1986+ fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
1987+
1988+ // Mark the container as no longer valid
1989+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1990+
1991+ return( 0 );
1992+}
1993+
1994+
1995+/*------------------------------------------------------------------------------
1996+ AacHba_DeleteDisk()
1997+
1998+ Postconditions:
1999+ Return values
2000+ 0 = OK
2001+ -EFAULT = Bad address
2002+ -EINVAL = Bad container number
2003+ -EBUSY = Device locked
2004+ *----------------------------------------------------------------------------*/
2005+int AacHba_DeleteDisk(
2006+ PVOID AdapterArg,
2007+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
2008+/*----------------------------------------------------------------------------*/
2009+{
2010+ DELETE_DISK DeleteDisk;
2011+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2012+ fsadev_t *fsa_dev_ptr;
2013+
2014+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2015+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2016+
2017+ if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2018+ return( -EFAULT );
2019+
2020+ if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2021+ return( -EINVAL );
2022+
2023+ // If the container is locked, it can not be deleted by the API.
2024+ if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2025+ return( -EBUSY );
2026+ else
2027+ {
2028+ // Mark the container as no longer being valid.
2029+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2030+ fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2031+ return(0);
2032+ }
2033+}
2034+
2035+
2036+/*------------------------------------------------------------------------------
2037+ AacHba_OpenAdapter()
2038+ *----------------------------------------------------------------------------*/
2039+AAC_STATUS AacHba_OpenAdapter(
2040+ IN PVOID AdapterArg )
2041+/*----------------------------------------------------------------------------*/
2042+{
2043+ return( STATUS_SUCCESS );
2044+}
2045+
2046+
2047+/*------------------------------------------------------------------------------
2048+ AacHba_CloseAdapter()
2049+ *----------------------------------------------------------------------------*/
2050+AAC_STATUS AacHba_CloseAdapter(
2051+ IN PVOID AdapterArg )
2052+/*----------------------------------------------------------------------------*/
2053+{
2054+ return( STATUS_SUCCESS );
2055+}
2056+
2057+
2058+/*------------------------------------------------------------------------------
2059+ AacHba_DetachAdapter()
2060+ *----------------------------------------------------------------------------*/
2061+void AacHba_DetachAdapter(
2062+ IN PVOID AdapterArg )
2063+/*----------------------------------------------------------------------------*/
2064+{
2065+ AacCommDetachAdapter( AdapterArg );
2066+}
2067+
2068+
2069+/*------------------------------------------------------------------------------
2070+ AacHba_AbortScsiCommand()
2071+ *----------------------------------------------------------------------------*/
2072+void AacHba_AbortScsiCommand(
2073+ Scsi_Cmnd *scsi_cmnd_ptr )
2074+/*----------------------------------------------------------------------------*/
2075+{
2076+ u_short interrupt_status;
2077+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2078+
2079+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2080+ interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2081+ DoorbellReg_p );
2082+ cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2083+
2084+ if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2085+ cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2086+ }
2087+
2088+ if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2089+ cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2090+ }
2091+
2092+ if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2093+ cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2094+ }
2095+
2096+ if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2097+ cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2098+ }
2099+
2100+}
2101+
2102+
2103+/*------------------------------------------------------------------------------
2104+ AacHba_HandleAif()
2105+ *----------------------------------------------------------------------------*/
2106+BOOLEAN AacHba_HandleAif(
2107+ IN PVOID AdapterArg,
2108+ IN PFIB_CONTEXT FibContext )
2109+/*----------------------------------------------------------------------------*/
2110+{
2111+ return( FALSE );
2112+}
2113+
2114+
2115+/*------------------------------------------------------------------------------
2116+ AacHba_SetSenseData()
2117+ Fill in the sense data.
2118+ Preconditions:
2119+ Postconditions:
2120+ *----------------------------------------------------------------------------*/
2121+void AacHba_SetSenseData(
2122+ char * sense_buf,
2123+ unchar sense_key,
2124+ unchar sense_code,
2125+ unchar a_sense_code,
2126+ unchar incorrect_length,
2127+ unchar bit_pointer,
2128+ unsigned field_pointer,
2129+ unsigned long residue )
2130+/*----------------------------------------------------------------------------*/
2131+{
2132+ sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2133+ sense_buf[1] = 0; // Segment number, always zero
2134+
2135+ if( incorrect_length )
2136+ {
2137+ sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2138+ sense_buf[3] = BYTE3(residue);
2139+ sense_buf[4] = BYTE2(residue);
2140+ sense_buf[5] = BYTE1(residue);
2141+ sense_buf[6] = BYTE0(residue);
2142+ }
2143+ else
2144+ sense_buf[2] = sense_key; // Sense key
2145+
2146+ if( sense_key == SENKEY_ILLEGAL )
2147+ sense_buf[7] = 10; // Additional sense length
2148+ else
2149+ sense_buf[7] = 6; // Additional sense length
2150+
2151+ sense_buf[12] = sense_code; // Additional sense code
2152+ sense_buf[13] = a_sense_code; // Additional sense code qualifier
2153+ if( sense_key == SENKEY_ILLEGAL )
2154+ {
2155+ sense_buf[15] = 0;
2156+
2157+ if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2158+ sense_buf[15] = 0x80; // Std sense key specific field
2159+ // Illegal parameter is in the parameter block
2160+
2161+ if( sense_code == SENCODE_INVALID_CDB_FIELD )
2162+ sense_buf[15] = 0xc0; // Std sense key specific field
2163+ // Illegal parameter is in the CDB block
2164+ sense_buf[15] |= bit_pointer;
2165+ sense_buf[16] = field_pointer >> 8; // MSB
2166+ sense_buf[17] = field_pointer; // LSB
2167+ }
2168+}
2169+
2170diff -burN linux-2.4.4/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2171--- linux-2.4.4/drivers/scsi/aacraid/aacid.c Wed Dec 31 18:00:00 1969
2172+++ linux/drivers/scsi/aacraid/aacid.c Mon Apr 30 09:43:34 2001
2173@@ -0,0 +1,153 @@
2174+/*++
2175+ * Adaptec aacraid device driver for Linux.
2176+ *
2177+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2178+ *
2179+ * This program is free software; you can redistribute it and/or modify
2180+ * it under the terms of the GNU General Public License as published by
2181+ * the Free Software Foundation; either version 2, or (at your option)
2182+ * any later version.
2183+ *
2184+ * This program is distributed in the hope that it will be useful,
2185+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2186+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2187+ * GNU General Public License for more details.
2188+ *
2189+ * You should have received a copy of the GNU General Public License
2190+ * along with this program; see the file COPYING. If not, write to
2191+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2192+ *
2193+ * Module Name:
2194+ * aac.c
2195+ *
2196+ * Abstract: Data structures for controller specific info.
2197+ *
2198+--*/
2199+
2200+static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2201+
2202+#include "osheaders.h"
2203+
2204+#include "AacGenericTypes.h"
2205+
2206+#include "aac_unix_defs.h"
2207+
2208+#include "fsatypes.h"
2209+#include "comstruc.h"
2210+#include "fsaport.h"
2211+#include "pcisup.h"
2212+
2213+#include "version.h"
2214+
2215+
2216+/* Function Prototypes */
2217+void InqStrCopy(char *a, char *b); /* ossup.c */
2218+
2219+/* Device name used to register and unregister
2220+ the device in linit.c */
2221+char devicestr[]="aac";
2222+
2223+char *container_types[] = {
2224+ "None",
2225+ "Volume",
2226+ "Mirror",
2227+ "Stripe",
2228+ "RAID5",
2229+ "SSRW",
2230+ "SSRO",
2231+ "Morph",
2232+ "Legacy",
2233+ "RAID4",
2234+ "RAID10",
2235+ "RAID00",
2236+ "V-MIRRORS",
2237+ "PSEUDO R4",
2238+ "RAID50",
2239+ "Unknown"
2240+};
2241+
2242+/* Local Structure to set SCSI inquiry data strings */
2243+typedef struct _INQSTR {
2244+ char vid[8]; /* Vendor ID */
2245+ char pid[16]; /* Product ID */
2246+ char prl[4]; /* Product Revision Level */
2247+} INQSTR, *INQSTRP;
2248+
2249+FSA_MINIPORT MiniPorts[];
2250+
2251+/* Function: SetInqDataStr
2252+ *
2253+ * Arguments: [1] pointer to void [1] int
2254+ *
2255+ * Purpose: Sets SCSI inquiry data strings for vendor, product
2256+ * and revision level. Allows strings to be set in platform dependant
2257+ * files instead of in OS dependant driver source.
2258+ */
2259+void
2260+SetInqDataStr (
2261+ int MiniPortIndex,
2262+ void *dataPtr,
2263+ int tindex)
2264+{
2265+ INQSTRP InqStrPtr;
2266+ char *findit;
2267+ FSA_MINIPORT *mp;
2268+
2269+ mp = &MiniPorts[MiniPortIndex];
2270+
2271+ InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2272+
2273+ InqStrCopy (mp->Vendor, InqStrPtr->vid);
2274+ InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2275+
2276+ findit = InqStrPtr->pid;
2277+
2278+ for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2279+ findit++;
2280+
2281+ if (tindex < (sizeof(container_types)/sizeof(char *))){
2282+ InqStrCopy (container_types[tindex], findit);
2283+ }
2284+ InqStrCopy ("0001", InqStrPtr->prl);
2285+}
2286+
2287+int
2288+SaInitDevice(
2289+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2290+ IN ULONG AdapterNumber,
2291+ IN ULONG PciBus,
2292+ IN ULONG PciSlot
2293+);
2294+
2295+int
2296+RxInitDevice(
2297+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2298+ IN ULONG AdapterNumber,
2299+ IN ULONG PciBus,
2300+ IN ULONG PciSlot
2301+);
2302+
2303+
2304+/*
2305+ * Because of the way Linux names scsi devices, the order in this table has
2306+ * become important. Check for on-board Raid first, add-in cards second.
2307+ */
2308+
2309+FSA_MINIPORT MiniPorts[] = {
2310+ { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2311+ { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2312+ { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2313+ { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2314+ { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2315+ { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2316+ { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2317+ { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel */
2318+ { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2319+};
2320+
2321+
2322+#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2323+
2324+int NumMiniPorts = NUM_MINIPORTS;
2325+
2326+char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2327diff -burN linux-2.4.4/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2328--- linux-2.4.4/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2329+++ linux/drivers/scsi/aacraid/commctrl.c Mon Apr 30 09:43:34 2001
2330@@ -0,0 +1,1098 @@
2331+/*++
2332+ * Adaptec aacraid device driver for Linux.
2333+ *
2334+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2335+ *
2336+ * This program is free software; you can redistribute it and/or modify
2337+ * it under the terms of the GNU General Public License as published by
2338+ * the Free Software Foundation; either version 2, or (at your option)
2339+ * any later version.
2340+ *
2341+ * This program is distributed in the hope that it will be useful,
2342+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2343+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2344+ * GNU General Public License for more details.
2345+ *
2346+ * You should have received a copy of the GNU General Public License
2347+ * along with this program; see the file COPYING. If not, write to
2348+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2349+ *
2350+ * Module Name:
2351+ * commctrl.c
2352+ *
2353+ * Abstract: Contains all routines for control of the AFA comm layer
2354+ *
2355+--*/
2356+
2357+static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2358+
2359+#include "comprocs.h"
2360+#include "osheaders.h"
2361+#include "ostypes.h"
2362+
2363+
2364+
2365+
2366+
2367+typedef BOOLEAN BOOL;
2368+#define inline /* _inline */
2369+
2370+#include <revision.h>
2371+AAC_STATUS
2372+FsaCtlCheckRevision(
2373+ IN PAFA_COMM_ADAPTER Adapter,
2374+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2375+ )
2376+/*++
2377+
2378+Routine Description:
2379+
2380+ This routine validates the revision of the caller with the current revision
2381+ of the filesystem.
2382+
2383+Arguments:
2384+
2385+ Adapter - Supplies which adapter is being processed.
2386+
2387+ Irp - Supplies the Irp being processed.
2388+
2389+ IrpContext - Supplies the IrpContext.
2390+
2391+Return Value:
2392+
2393+ AAC_STATUS
2394+
2395+--*/
2396+
2397+{
2398+ RevCheck APIRevCheck;
2399+ RevCheckResp APIRevCheckResp;
2400+ RevComponent APICallingComponent;
2401+ ULONG APIBuildNumber;
2402+
2403+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2404+ return (EFAULT);
2405+ }
2406+
2407+ APICallingComponent = APIRevCheck.callingComponent;
2408+ APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2409+
2410+ APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2411+
2412+ APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2413+ APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2414+
2415+ if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2416+ return (EFAULT);
2417+ }
2418+
2419+ return (0);
2420+}
2421+
2422+
2423+int
2424+AfaCommAdapterDeviceControl(
2425+ IN PVOID AdapterArg,
2426+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2427+ )
2428+{
2429+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2430+ int Status = ENOTTY;
2431+// PIO_STACK_LOCATION IrpSp;
2432+ PAFA_CLASS_DRIVER ClassDriver;
2433+
2434+ //
2435+ // First loop through all of the class drivers to give them a chance to handle
2436+ // the Device control first.
2437+ //
2438+
2439+ ClassDriver = Adapter->ClassDriverList;
2440+
2441+ while (ClassDriver) {
2442+
2443+ if (ClassDriver->DeviceControl) {
2444+
2445+ if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2446+
2447+ return (Status);
2448+
2449+ }
2450+ }
2451+
2452+ ClassDriver = ClassDriver->Next;
2453+ }
2454+
2455+ switch (IoctlCmdPtr->cmd) {
2456+
2457+
2458+ case FSACTL_SENDFIB:
2459+
2460+ Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2461+ break;
2462+
2463+ case FSACTL_AIF_THREAD:
2464+
2465+ Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2466+ break;
2467+
2468+
2469+ case FSACTL_OPEN_GET_ADAPTER_FIB:
2470+
2471+ Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2472+ break;
2473+
2474+ case FSACTL_GET_NEXT_ADAPTER_FIB:
2475+
2476+ Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2477+ break;
2478+
2479+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
2480+
2481+ Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2482+ break;
2483+
2484+ case FSACTL_MINIPORT_REV_CHECK:
2485+
2486+ Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2487+ break;
2488+
2489+
2490+ default:
2491+
2492+ Status = ENOTTY;
2493+ break;
2494+
2495+ }
2496+
2497+
2498+ return (Status);
2499+}
2500+
2501+AAC_STATUS
2502+AfaCommRegisterNewClassDriver(
2503+ IN PAFA_COMM_ADAPTER Adapter,
2504+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2505+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2506+ )
2507+/*++
2508+
2509+Routine Description:
2510+
2511+ This routine registers a new class driver for the comm layer.
2512+
2513+ It will return a pointer to the communication functions for the class driver
2514+ to use.
2515+
2516+Arguments:
2517+
2518+ Adapter - Supplies which adapter is being processed.
2519+
2520+ Irp - Supplies the Irp being processed.
2521+
2522+Return Value:
2523+
2524+ STATUS_SUCCESS - Everything OK.
2525+
2526+--*/
2527+{
2528+ AAC_STATUS Status;
2529+ PAFA_CLASS_DRIVER ClassDriver;
2530+
2531+
2532+ ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2533+
2534+ if (ClassDriver == NULL) {
2535+
2536+ Status = STATUS_INSUFFICIENT_RESOURCES;
2537+
2538+ return Status;
2539+ }
2540+
2541+ //
2542+ // If the class driver has sent in user Vars, then copy them into the global
2543+ // area.
2544+ //
2545+
2546+ if (NewClassDriver->NumUserVars) {
2547+
2548+ PFSA_USER_VAR NewUserVars;
2549+
2550+ NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2551+ NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2552+
2553+ //
2554+ // First copy the existing into the new area.
2555+ //
2556+
2557+ RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2558+
2559+ //
2560+ // Next copy the new vars passed in from class driver.
2561+ //
2562+
2563+ RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2564+ NewClassDriver->UserVars,
2565+ NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2566+
2567+ //
2568+ // Free up the old user vars.
2569+ //
2570+
2571+ OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2572+
2573+ //
2574+ // Point the global to the new area.
2575+ //
2576+
2577+ FsaCommData.UserVars = NewUserVars;
2578+
2579+ //
2580+ // Update the total count.
2581+ //
2582+
2583+ FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2584+
2585+ }
2586+
2587+ ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2588+ ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2589+ ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2590+ ClassDriver->HandleAif = NewClassDriver->HandleAif;
2591+ ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2592+
2593+ ClassDriver->Next = Adapter->ClassDriverList;
2594+ Adapter->ClassDriverList = ClassDriver;
2595+
2596+ //
2597+ // Now return the information needed by the class driver to communicate to us.
2598+ //
2599+
2600+ NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2601+ NewClassDriverResponse->CommPortExtension = Adapter;
2602+ NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2603+ NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2604+ NewClassDriverResponse->Dip = Adapter->Dip;
2605+
2606+ return (STATUS_SUCCESS);
2607+
2608+
2609+}
2610+
2611+int
2612+AfaCommCtlSendFib(
2613+ IN PAFA_COMM_ADAPTER Adapter,
2614+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2615+)
2616+/*++
2617+
2618+Routine Description:
2619+
2620+ This routine sends a fib to the adapter on behalf of a user level
2621+ program.
2622+
2623+Arguments:
2624+
2625+ Adapter - Supplies which adapter is being processed.
2626+
2627+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2628+
2629+Return Value:
2630+
2631+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2632+
2633+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2634+
2635+ STATUS_SUCCESS - Everything OK.
2636+
2637+--*/
2638+{
2639+ PFIB KFib;
2640+// PMDL DmaMdl = NULL;
2641+ PCOMM_FIB_CONTEXT FibContext;
2642+ PSGMAP_CONTEXT SgMapContext;
2643+ SGMAP_CONTEXT _SgMapContext;
2644+ QUEUE_TYPES WhichQueue;
2645+ PVOID UsersAddress;
2646+ AAC_STATUS Status;
2647+
2648+ FibContext = AllocateFib( Adapter );
2649+
2650+ KFib = FibContext->Fib;
2651+
2652+ //
2653+ // First copy in the header so that we can check the size field.
2654+ //
2655+
2656+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2657+ FreeFib( FibContext );
2658+ Status = EFAULT;
2659+ return (Status);
2660+ }
2661+
2662+ //
2663+ // Since we copy based on the fib header size, make sure that we
2664+ // will not overrun the buffer when we copy the memory. Return
2665+ // an error if we would.
2666+ //
2667+
2668+ if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2669+ FreeFib( FibContext );
2670+ Status = EINVAL;
2671+ return Status;
2672+
2673+ }
2674+
2675+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2676+ FreeFib( FibContext );
2677+ Status = EFAULT;
2678+ return (Status);
2679+ }
2680+
2681+ WhichQueue = AdapNormCmdQueue;
2682+
2683+
2684+ if (KFib->Header.Command == TakeABreakPt) {
2685+
2686+ InterruptAdapter(Adapter);
2687+
2688+ //
2689+ // Since we didn't really send a fib, zero out the state to allow
2690+ // cleanup code not to assert.
2691+ //
2692+
2693+ KFib->Header.XferState = 0;
2694+
2695+
2696+ } else {
2697+
2698+ if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2699+ TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2700+ FsaCommPrint("User SendFib failed!.\n");
2701+
2702+
2703+ FreeFib( FibContext );
2704+ return (ENXIO);
2705+ }
2706+
2707+ if (CompleteFib(FibContext) != FSA_SUCCESS) {
2708+ FsaCommPrint("User Complete FIB failed.\n");
2709+
2710+ FreeFib( FibContext );
2711+ return (ENXIO);
2712+ }
2713+
2714+
2715+ }
2716+
2717+
2718+ //
2719+ // Make sure that the size returned by the adapter (which includes
2720+ // the header) is less than or equal to the size of a fib, so we
2721+ // don't corrupt application data. Then copy that size to the user
2722+ // buffer. (Don't try to add the header information again, since it
2723+ // was already included by the adapter.)
2724+ //
2725+ ASSERT(KFib->Header.Size <= sizeof(FIB));
2726+
2727+ if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2728+ FreeFib( FibContext );
2729+ Status = EFAULT;
2730+ return (Status);
2731+ }
2732+
2733+ FreeFib( FibContext );
2734+
2735+ return (0);
2736+
2737+}
2738+
2739+int
2740+AfaCommCtlAifThread(
2741+ IN PAFA_COMM_ADAPTER Adapter,
2742+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2743+)
2744+/*++
2745+
2746+Routine Description:
2747+
2748+ This routine will act as the AIF thread for this adapter.
2749+
2750+Arguments:
2751+
2752+ Adapter - Supplies which adapter is being processed.
2753+
2754+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2755+
2756+Return Value:
2757+
2758+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2759+
2760+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2761+
2762+ STATUS_SUCCESS - Everything OK.
2763+
2764+--*/
2765+{
2766+ return (NormCommandThread(Adapter));
2767+}
2768+
2769+
2770+
2771+#ifdef GATHER_FIB_TIMES
2772+AAC_STATUS
2773+AfaCommGetFibTimes(
2774+ IN PAFA_COMM_ADAPTER Adapter,
2775+ IN PIRP Irp
2776+ )
2777+/*++
2778+
2779+Routine Description:
2780+
2781+ This routine returns the gathered fibtimes to the user.
2782+
2783+Arguments:
2784+
2785+ Adapter - Supplies which adapter is being processed.
2786+
2787+ Irp - Supplies the Irp being processed.
2788+
2789+Return Value:
2790+
2791+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2792+
2793+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2794+
2795+ STATUS_SUCCESS - Everything OK.
2796+
2797+--*/
2798+{
2799+ PALL_FIB_TIMES AllFibTimes;
2800+ PLARGE_INTEGER FreqPtr;
2801+ PIO_STACK_LOCATION IrpSp;
2802+
2803+ //
2804+ // Get a pointer to the current Irp stack location
2805+ //
2806+
2807+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2808+
2809+ FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2810+
2811+ *FreqPtr = Adapter->FibTimesFrequency;
2812+
2813+ AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2814+
2815+ RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2816+
2817+ Irp->IoStatus.Information = 0;
2818+
2819+ return (STATUS_SUCCESS);
2820+
2821+}
2822+
2823+AAC_STATUS
2824+AfaCommZeroFibTimes(
2825+ IN PAFA_COMM_ADAPTER Adapter,
2826+ IN PIRP Irp
2827+ )
2828+/*++
2829+
2830+Routine Description:
2831+
2832+ This routine zero's the FibTimes structure within the adapter structure.
2833+
2834+Arguments:
2835+
2836+ Adapter - Supplies which adapter is being processed.
2837+
2838+ Irp - Supplies the Irp being processed.
2839+
2840+Return Value:
2841+
2842+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2843+
2844+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2845+
2846+ STATUS_SUCCESS - Everything OK.
2847+
2848+--*/
2849+{
2850+ PFIB_TIMES FibTimesPtr;
2851+ int i;
2852+ PIO_STACK_LOCATION IrpSp;
2853+
2854+ //
2855+ // Get a pointer to the current Irp stack location
2856+ //
2857+
2858+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2859+
2860+ //
2861+ // Initialize the Fib timing data structures
2862+ //
2863+ RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2864+
2865+ for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2866+
2867+ FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2868+
2869+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2870+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2871+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2872+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2873+ }
2874+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2875+
2876+ FibTimesPtr = &Adapter->FibTimes->Read[i];
2877+
2878+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2879+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2880+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2881+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2882+ }
2883+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2884+
2885+ FibTimesPtr = &Adapter->FibTimes->Write[i];
2886+
2887+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2888+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2889+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2890+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2891+ }
2892+
2893+ FibTimesPtr = &Adapter->FibTimes->Other;
2894+
2895+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2896+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2897+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2898+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2899+
2900+ Irp->IoStatus.Information = 0;
2901+
2902+ return (STATUS_SUCCESS);
2903+
2904+}
2905+#endif // GATHER_FIB_TIMES
2906+
2907+#ifndef unix_aif
2908+int
2909+FsaCtlOpenGetAdapterFib(
2910+ IN PAFA_COMM_ADAPTER Adapter,
2911+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2912+ )
2913+/*++
2914+
2915+Routine Description:
2916+
2917+ This routine will get the next Fib, if available, from the AdapterFibContext
2918+ passed in from the user.
2919+
2920+Arguments:
2921+
2922+ Adapter - Supplies which adapter is being processed.
2923+
2924+ Irp - Supplies the Irp being processed.
2925+
2926+Return Value:
2927+
2928+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2929+
2930+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2931+
2932+ STATUS_SUCCESS - Everything OK.
2933+
2934+--*/
2935+{
2936+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2937+// HANDLE Event;
2938+// PKEVENT eventObject = (PKEVENT) NULL;
2939+ int Status;
2940+
2941+ //
2942+ // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2943+ //
2944+
2945+ AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2946+
2947+ if (AdapterFibContext == NULL) {
2948+
2949+ Status = ENOMEM;
2950+
2951+ } else {
2952+
2953+ AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2954+ AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2955+
2956+
2957+ //
2958+ // Initialize the conditional variable use to wait for the next AIF.
2959+ //
2960+
2961+ OsCv_init( &AdapterFibContext->UserEvent);
2962+
2963+ //
2964+ // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
2965+ //
2966+
2967+ AdapterFibContext->WaitingForFib = FALSE;
2968+
2969+ //
2970+ // Initialize the FibList and set the count of fibs on the list to 0.
2971+ //
2972+
2973+ AdapterFibContext->FibCount = 0;
2974+ InitializeListHead(&AdapterFibContext->FibList);
2975+
2976+ //
2977+ // Overload FileObject with a time stamp.
2978+ //
2979+ AdapterFibContext->FileObject = (void *)OsGetSeconds();
2980+
2981+ //
2982+ // Now add this context onto the adapter's AdapterFibContext list.
2983+ //
2984+
2985+ OsCvLockAcquire(Adapter->AdapterFibMutex);
2986+
2987+ InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
2988+
2989+ OsCvLockRelease(Adapter->AdapterFibMutex);
2990+
2991+ if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
2992+ IoctlCmdPtr->flag )) {
2993+
2994+ Status = EFAULT;
2995+
2996+ } else {
2997+
2998+ Status = 0;
2999+
3000+ }
3001+
3002+ }
3003+
3004+ return (Status);
3005+}
3006+
3007+int
3008+FsaCtlGetNextAdapterFib(
3009+ IN PAFA_COMM_ADAPTER Adapter,
3010+ IN PAFA_IOCTL_CMD IoctlCmdPtr
3011+ )
3012+/*++
3013+
3014+Routine Description:
3015+
3016+ This routine will get the next Fib, if available, from the AdapterFibContext
3017+ passed in from the user.
3018+
3019+Arguments:
3020+
3021+ Adapter - Supplies which adapter is being processed.
3022+
3023+ Irp - Supplies the Irp being processed.
3024+
3025+Return Value:
3026+
3027+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3028+
3029+ STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3030+
3031+ STATUS_SUCCESS - Everything OK.
3032+
3033+--*/
3034+{
3035+ GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3036+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3037+ PFIB Fib;
3038+ int Status;
3039+ PLIST_ENTRY Entry;
3040+ int found;
3041+
3042+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3043+ sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3044+ return (EFAULT);
3045+ }
3046+
3047+ //
3048+ // Extract the AdapterFibContext from the Input parameters.
3049+ //
3050+
3051+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3052+
3053+ //
3054+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3055+ //
3056+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3057+ // this is a valid address
3058+
3059+ found = 0;
3060+ Entry = Adapter->AdapterFibContextList.Flink;
3061+
3062+ while ( Entry != &Adapter->AdapterFibContextList ) {
3063+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3064+ if ( AdapterFibContext == aifcp ) { // We found a winner
3065+ found = 1;
3066+ break;
3067+ }
3068+ Entry = Entry->Flink;
3069+ }
3070+
3071+ if ( found == 0 ) {
3072+ return ( EINVAL );;
3073+ }
3074+
3075+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3076+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3077+
3078+ return ( EINVAL );
3079+
3080+ }
3081+
3082+ Status = STATUS_SUCCESS;
3083+
3084+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3085+
3086+ //
3087+ // If there are no fibs to send back, then either wait or return EAGAIN
3088+ //
3089+return_fib:
3090+
3091+ if (!IsListEmpty(&AdapterFibContext->FibList)) {
3092+
3093+ PLIST_ENTRY Entry;
3094+
3095+ //
3096+ // Pull the next fib from the FibList
3097+ //
3098+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3099+
3100+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3101+
3102+ AdapterFibContext->FibCount--;
3103+
3104+ if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3105+
3106+ OsCvLockRelease( Adapter->AdapterFibMutex );
3107+ OsFreeMemory( Fib, sizeof(Fib) );
3108+ return (EFAULT);
3109+
3110+ }
3111+
3112+ //
3113+ // Free the space occupied by this copy of the fib.
3114+ //
3115+
3116+ OsFreeMemory(Fib, sizeof(FIB));
3117+
3118+ Status = 0;
3119+
3120+ //
3121+ // Overload FileObject with a time stamp
3122+ //
3123+ AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3124+
3125+ } else {
3126+
3127+ if (AdapterFibIoctl.Wait) {
3128+
3129+ if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3130+
3131+ Status = EINTR;
3132+
3133+ } else {
3134+
3135+ goto return_fib;
3136+
3137+ }
3138+ } else {
3139+
3140+ Status = EAGAIN;
3141+
3142+ }
3143+
3144+ }
3145+ OsCvLockRelease( Adapter->AdapterFibMutex );
3146+
3147+ return (Status);
3148+}
3149+
3150+int
3151+FsaCtlCloseGetAdapterFib(
3152+ IN PAFA_COMM_ADAPTER Adapter,
3153+ IN PAFA_IOCTL_CMD IoctlCmdPtr
3154+ )
3155+/*++
3156+
3157+Routine Description:
3158+
3159+ This routine will close down the AdapterFibContext passed in from the user.
3160+
3161+Arguments:
3162+
3163+ Adapter - Supplies which adapter is being processed.
3164+
3165+ Irp - Supplies the Irp being processed.
3166+
3167+Return Value:
3168+
3169+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3170+
3171+ STATUS_SUCCESS - Everything OK.
3172+
3173+--*/
3174+{
3175+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3176+ AAC_STATUS Status;
3177+
3178+ PLIST_ENTRY Entry;
3179+ int found;
3180+
3181+ //
3182+ // Extract the AdapterFibContext from the Input parameters
3183+ //
3184+
3185+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3186+
3187+ if (AdapterFibContext == 0) {
3188+ cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3189+ return(EINVAL);
3190+ }
3191+
3192+ //
3193+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3194+ //
3195+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3196+ // this is a valid address
3197+
3198+ found = 0;
3199+ Entry = Adapter->AdapterFibContextList.Flink;
3200+
3201+ while ( Entry != &Adapter->AdapterFibContextList ) {
3202+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3203+ if ( AdapterFibContext == aifcp ) { // We found a winner
3204+ found = 1;
3205+ break;
3206+ }
3207+ Entry = Entry->Flink;
3208+ }
3209+
3210+ if ( found == 0 ) {
3211+ return ( 0 ); // Already Gone
3212+ }
3213+
3214+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3215+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3216+
3217+ return (EINVAL);
3218+
3219+ }
3220+
3221+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3222+
3223+ Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3224+
3225+ OsCvLockRelease(Adapter->AdapterFibMutex);
3226+
3227+ return (Status);
3228+}
3229+
3230+int
3231+FsaCloseAdapterFibContext(
3232+ IN PAFA_COMM_ADAPTER Adapter,
3233+ IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3234+ )
3235+{
3236+ int Status;
3237+ PFIB Fib;
3238+
3239+ //
3240+ // First free any FIBs that have not been consumed yet.
3241+ //
3242+
3243+ while (!IsListEmpty(&AdapterFibContext->FibList)) {
3244+
3245+ PLIST_ENTRY Entry;
3246+
3247+ //
3248+ // Pull the next fib from the FibList
3249+ //
3250+
3251+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3252+
3253+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3254+
3255+ AdapterFibContext->FibCount--;
3256+
3257+ //
3258+ // Free the space occupied by this copy of the fib.
3259+ //
3260+
3261+ OsFreeMemory(Fib, sizeof(FIB));
3262+ }
3263+
3264+ //
3265+ // Remove the Context from the AdapterFibContext List
3266+ //
3267+
3268+ RemoveEntryList(&AdapterFibContext->NextContext);
3269+
3270+ OsCv_destroy( &AdapterFibContext->UserEvent );
3271+
3272+ //
3273+ // Invalidate context
3274+ //
3275+
3276+ AdapterFibContext->NodeTypeCode = 0;
3277+
3278+ //
3279+ // Free the space occupied by the Context
3280+ //
3281+
3282+ OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3283+
3284+ Status = STATUS_SUCCESS;
3285+
3286+ return Status;
3287+}
3288+#endif
3289+
3290+AAC_STATUS
3291+AfaCommOpenAdapter(
3292+ IN PVOID Arg
3293+ )
3294+/*++
3295+
3296+Routine Description:
3297+
3298+ The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3299+ for the adapter.
3300+
3301+ The main purpose of this routine is to set up any data structures that may be needed
3302+ to handle any requests made on this DeviceObject.
3303+
3304+Arguments:
3305+
3306+ Adapter - Pointer to which adapter miniport was opened.
3307+
3308+
3309+Return Value:
3310+
3311+ STATUS_SUCCESS
3312+
3313+--*/
3314+
3315+{
3316+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3317+ AAC_STATUS Status = STATUS_SUCCESS;
3318+ PAFA_CLASS_DRIVER ClassDriver;
3319+
3320+ ClassDriver = Adapter->ClassDriverList;
3321+
3322+ while (ClassDriver) {
3323+
3324+ if (ClassDriver->OpenAdapter) {
3325+
3326+ Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3327+
3328+ if (Status != STATUS_SUCCESS)
3329+ break;
3330+ }
3331+
3332+ ClassDriver = ClassDriver->Next;
3333+ }
3334+
3335+ return ( Status );
3336+}
3337+
3338+AAC_STATUS
3339+AfaCommCloseAdapter(
3340+ IN PVOID Arg
3341+ )
3342+/*++
3343+
3344+Routine Description:
3345+
3346+ This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3347+ for the adapter.
3348+
3349+ The main purpose of this routine is to cleanup any data structures that have been set up
3350+ while this FileObject has been opened.
3351+
3352+ This routine loops through all of the AdapterFibContext structures to determine if any need
3353+ to be deleted for this FileObject.
3354+
3355+Arguments:
3356+
3357+ Adapter - Pointer to adapter miniport
3358+
3359+ Irp - Pointer to Irp that caused this close
3360+
3361+Return Value:
3362+
3363+ Status value returned from File system driver AdapterClose
3364+
3365+--*/
3366+{
3367+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3368+ PLIST_ENTRY Entry, NextEntry;
3369+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3370+ AAC_STATUS Status = STATUS_SUCCESS;
3371+ PAFA_CLASS_DRIVER ClassDriver;
3372+
3373+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3374+
3375+ Entry = Adapter->AdapterFibContextList.Flink;
3376+
3377+ //
3378+ // Loop through all of the AdapterFibContext, looking for any that
3379+ // were created with the FileObject that is being closed.
3380+ //
3381+ while (Entry != &Adapter->AdapterFibContextList) {
3382+
3383+ //
3384+ // Extract the AdapterFibContext
3385+ //
3386+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3387+
3388+ //
3389+ // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3390+ //
3391+ NextEntry = Entry->Flink;
3392+
3393+ Entry = NextEntry;
3394+
3395+ }
3396+
3397+#ifdef unix_config_file
3398+ //
3399+ // If this FileObject had the adapter open for configuration, then release it.
3400+ //
3401+ if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3402+
3403+ Adapter->AdapterConfigFileObject = NULL;
3404+
3405+ }
3406+#endif
3407+
3408+ OsCvLockRelease(Adapter->AdapterFibMutex);
3409+
3410+ ClassDriver = Adapter->ClassDriverList;
3411+
3412+ while (ClassDriver) {
3413+
3414+ if (ClassDriver->CloseAdapter) {
3415+
3416+ Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3417+
3418+ if (Status != STATUS_SUCCESS)
3419+ break;
3420+ }
3421+
3422+ ClassDriver = ClassDriver->Next;
3423+ }
3424+
3425+ return ( Status );
3426+
3427+}
3428+
3429diff -burN linux-2.4.4/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3430--- linux-2.4.4/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3431+++ linux/drivers/scsi/aacraid/comminit.c Mon Apr 30 09:43:34 2001
3432@@ -0,0 +1,986 @@
3433+/*++
3434+ * Adaptec aacraid device driver for Linux.
3435+ *
3436+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3437+ *
3438+ * This program is free software; you can redistribute it and/or modify
3439+ * it under the terms of the GNU General Public License as published by
3440+ * the Free Software Foundation; either version 2, or (at your option)
3441+ * any later version.
3442+ *
3443+ * This program is distributed in the hope that it will be useful,
3444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3446+ * GNU General Public License for more details.
3447+ *
3448+ * You should have received a copy of the GNU General Public License
3449+ * along with this program; see the file COPYING. If not, write to
3450+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3451+ *
3452+ * Module Name:
3453+ * comminit.c
3454+ *
3455+ * Abstract: This supports the initialization of the host adapter commuication interface.
3456+ * This is a platform dependent module for the pci cyclone board.
3457+ *
3458+ --*/
3459+
3460+static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3461+
3462+#include "comprocs.h"
3463+
3464+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3465+
3466+VOID
3467+AfaCommBugcheckHandler(
3468+ IN PVOID Buffer,
3469+ IN ULONG Length
3470+ );
3471+
3472+VOID
3473+ThrottlePeriodEndDpcRtn(
3474+ IN PKDPC Dpc,
3475+ IN PVOID DeferredContext,
3476+ IN PVOID SystemArgument1,
3477+ IN PVOID SystemArgument2);
3478+
3479+FSA_COMM_DATA FsaCommData;
3480+
3481+AAC_STATUS
3482+HardInterruptModeration1Changed(
3483+ IN PVOID AdapterContext,
3484+ IN ULONG NewValue
3485+ )
3486+{
3487+ PAFA_COMM_ADAPTER Adapter = AdapterContext;
3488+
3489+ //
3490+ // If we are using interrupt moderation, then disable the interrupt
3491+ // until we need to use it.
3492+ //
3493+ if (FsaCommData.HardInterruptModeration1)
3494+ DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3495+ else
3496+ EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3497+
3498+ return (STATUS_SUCCESS);
3499+}
3500+
3501+AAC_STATUS
3502+FsaFibTimeoutChanged(
3503+ IN PVOID AdapterContext,
3504+ IN ULONG NewValue
3505+ )
3506+{
3507+ //
3508+ // scale the new timeout from seconds to 100 nsec units
3509+ //
3510+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3511+
3512+ return (STATUS_SUCCESS);
3513+}
3514+
3515+#ifdef GATHER_FIB_TIMES
3516+extern int GatherFibTimes;
3517+#endif
3518+
3519+FSA_USER_VAR FsaCommUserVars[] = {
3520+#ifdef FIB_CHECKSUMS
3521+ { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3522+#endif
3523+#ifdef GATHER_FIB_TIMES
3524+ { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3525+#endif
3526+ { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3527+ { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3528+ { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3529+ { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3530+ { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3531+ { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3532+ { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3533+ { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3534+ { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3535+ { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3536+};
3537+
3538+#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3539+
3540+\f
3541+AAC_STATUS
3542+AacCommDriverEntry(
3543+ )
3544+
3545+/*++
3546+
3547+Routine Description:
3548+
3549+ This is the initialization routine for the FileArray Comm layer device driver.
3550+
3551+Arguments:
3552+
3553+ DriverObject - Pointer to driver object created by the system.
3554+
3555+Return Value:
3556+
3557+ AAC_STATUS - The function value is the final status from the initialization
3558+ operation.
3559+
3560+--*/
3561+
3562+{
3563+ AAC_STATUS Status;
3564+ PVOID BugCheckBuffer;
3565+
3566+ RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3567+
3568+
3569+ //
3570+ // Load the global timeout value for the adapter timeout
3571+ // Also init the global that enables or disables adapter timeouts
3572+ //
3573+
3574+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3575+
3576+ FsaCommData.FibTimeoutSeconds = 180;
3577+
3578+ FsaCommData.EnableAdapterTimeouts = TRUE;
3579+
3580+// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3581+
3582+#ifdef unix_fib_timeout
3583+ FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3584+#endif
3585+
3586+ FsaCommData.EnableInterruptModeration = FALSE;
3587+
3588+ //
3589+ // Preload UserVars with all variables from the comm layer. The class layers will
3590+ // include theirs when they register.
3591+ //
3592+
3593+ FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3594+ FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3595+
3596+ RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3597+
3598+
3599+#ifdef AACDISK
3600+ //
3601+ // Call the disk driver to initialize itself.
3602+ //
3603+
3604+ AacDiskDriverEntry();
3605+
3606+#endif
3607+
3608+
3609+
3610+ return (STATUS_SUCCESS);
3611+}
3612+
3613+
3614+VOID
3615+DetachNTQueue(
3616+ IN PAFA_COMM_ADAPTER Adapter,
3617+ IN OUT PCOMM_QUE Queue,
3618+ IN QUEUE_TYPES WhichQueue
3619+ )
3620+/*++
3621+
3622+Routine Description:
3623+
3624+ This routine will release all of the resources used by a given queue.
3625+
3626+Arguments:
3627+
3628+ Adapter - Which adapter the queue belongs to
3629+ Queue - Pointer to the queue itself
3630+ WhichQueue - Identifies which of the host queues this is.
3631+
3632+Return Value:
3633+
3634+ NONE.
3635+
3636+--*/
3637+{
3638+ switch (WhichQueue) {
3639+
3640+ case HostNormCmdQueue:
3641+
3642+ Os_remove_softintr( Queue->ConsumerRoutine );
3643+ OsSpinLockDestroy( Queue->QueueLock );
3644+ OsCv_destroy( &Queue->CommandReady );
3645+
3646+ break;
3647+
3648+ case HostHighCmdQueue:
3649+
3650+ Os_remove_softintr( Queue->ConsumerRoutine );
3651+ OsSpinLockDestroy( Queue->QueueLock );
3652+ OsCv_destroy( &Queue->CommandReady );
3653+
3654+ break;
3655+
3656+ case HostNormRespQueue:
3657+
3658+ Os_remove_softintr( Queue->ConsumerRoutine );
3659+ OsSpinLockDestroy( Queue->QueueLock );
3660+ break;
3661+
3662+ case HostHighRespQueue:
3663+
3664+ Os_remove_softintr( Queue->ConsumerRoutine );
3665+ OsSpinLockDestroy( Queue->QueueLock );
3666+ break;
3667+
3668+ case AdapNormCmdQueue:
3669+ case AdapHighCmdQueue:
3670+ case AdapNormRespQueue:
3671+ case AdapHighRespQueue:
3672+ OsCv_destroy( &Queue->QueueFull );
3673+ break;
3674+ }
3675+}
3676+
3677+VOID
3678+InitializeNTQueue(
3679+ IN PAFA_COMM_ADAPTER Adapter,
3680+ IN OUT PCOMM_QUE Queue,
3681+ IN QUEUE_TYPES WhichQueue
3682+ )
3683+/*++
3684+
3685+Routine Description:
3686+
3687+ Will initialize all entries in the queue that is NT specific.
3688+
3689+Arguments:
3690+
3691+Return Value:
3692+
3693+ Nothing there is nothing to allocate so nothing should fail
3694+
3695+--*/
3696+{
3697+
3698+ Queue->NumOutstandingIos = 0;
3699+
3700+ //
3701+ // Store a pointer to the adapter structure.
3702+ //
3703+
3704+ Queue->Adapter = Adapter;
3705+
3706+ InitializeListHead( &Queue->OutstandingIoQueue );
3707+
3708+ switch (WhichQueue) {
3709+
3710+ case HostNormCmdQueue:
3711+
3712+ OsCv_init( &Queue->CommandReady);
3713+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3714+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3715+ NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3716+ (caddr_t)Queue ) != DDI_SUCCESS) {
3717+
3718+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3719+ }
3720+
3721+ InitializeListHead(&Queue->CommandQueue);
3722+
3723+ break;
3724+
3725+ case HostHighCmdQueue:
3726+
3727+ OsCv_init( &Queue->CommandReady);
3728+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3729+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3730+ NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3731+ (caddr_t) Queue ) != DDI_SUCCESS) {
3732+
3733+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3734+ }
3735+
3736+ InitializeListHead(&Queue->CommandQueue);
3737+ break;
3738+
3739+ case HostNormRespQueue:
3740+
3741+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3742+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3743+ NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3744+ (caddr_t) Queue ) != DDI_SUCCESS) {
3745+
3746+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3747+ }
3748+ break;
3749+
3750+ case HostHighRespQueue:
3751+
3752+
3753+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3754+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3755+ NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3756+ (caddr_t) Queue ) != DDI_SUCCESS) {
3757+
3758+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3759+ }
3760+ break;
3761+
3762+ case AdapNormCmdQueue:
3763+ case AdapHighCmdQueue:
3764+ case AdapNormRespQueue:
3765+ case AdapHighRespQueue:
3766+
3767+ OsCv_init( &Queue->QueueFull);
3768+ break;
3769+ }
3770+}
3771+
3772+BOOLEAN
3773+StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3774+/*++
3775+
3776+Routine Description:
3777+
3778+ Create and start the command receiver threads.
3779+
3780+Arguments:
3781+
3782+
3783+Return Value:
3784+
3785+ Nothing
3786+
3787+--*/
3788+
3789+{
3790+ return(TRUE);
3791+}
3792+
3793+
3794+
3795+/*++
3796+
3797+Routine Description:
3798+
3799+ This routine gets called to detach all resources that have been allocated for
3800+ this adapter.
3801+
3802+Arguments:
3803+
3804+ Adapter - Pointer to the adapter structure to detach.
3805+
3806+Return Value:
3807+
3808+ TRUE - All resources have been properly released.
3809+ FALSE - An error occured while trying to release resources.
3810+--*/
3811+BOOLEAN
3812+AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3813+{
3814+ PAFA_CLASS_DRIVER ClassDriver;
3815+ //
3816+ // First remove this adapter from the list of adapters.
3817+ //
3818+
3819+ if (FsaCommData.AdapterList == Adapter) {
3820+
3821+ FsaCommData.AdapterList = Adapter->NextAdapter;
3822+
3823+ } else {
3824+
3825+ PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3826+
3827+ CurrentAdapter = FsaCommData.AdapterList;
3828+ NextAdapter = CurrentAdapter->NextAdapter;
3829+
3830+ while (NextAdapter) {
3831+
3832+ if (NextAdapter == Adapter) {
3833+
3834+ CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3835+ break;
3836+
3837+ }
3838+
3839+ CurrentAdapter = NextAdapter;
3840+ NextAdapter = CurrentAdapter->NextAdapter;
3841+ }
3842+ }
3843+
3844+ //
3845+ // First send a shutdown to the adapter.
3846+ //
3847+
3848+ AfaCommShutdown( Adapter );
3849+
3850+ //
3851+ // Destroy the FibContextZone for this adapter. This will free up all
3852+ // of the fib space used by this adapter.
3853+ //
3854+
3855+ FsaFreeFibContextZone( Adapter );
3856+
3857+ //
3858+ // Destroy the mutex used for synch'ing adapter fibs.
3859+ //
3860+
3861+ OsCvLockDestroy( Adapter->AdapterFibMutex );
3862+
3863+ //
3864+ // Detach all of the host queues.
3865+ //
3866+
3867+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3868+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3869+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3870+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3871+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3872+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3873+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3874+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3875+
3876+ //
3877+ // Destroy the mutex used to protect the FibContextZone
3878+ //
3879+
3880+ OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3881+
3882+ //
3883+ // Call the miniport to free the space allocated for the shared comm queues
3884+ // between the host and the adapter.
3885+ //
3886+
3887+ FsaFreeAdapterCommArea( Adapter );
3888+
3889+ //
3890+ // Free the memory used by the comm region for this adapter
3891+ //
3892+
3893+ OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3894+
3895+ //
3896+ // Free the memory used by the adapter structure.
3897+ //
3898+ ClassDriver = Adapter->ClassDriverList;
3899+ Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3900+ OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3901+
3902+ OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3903+
3904+ return (TRUE);
3905+}
3906+
3907+PVOID
3908+AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3909+{
3910+ PVOID BugCheckBuffer;
3911+ PAFA_COMM_ADAPTER Adapter;
3912+ MAPFIB_CONTEXT MapFibContext;
3913+ LARGE_INTEGER Time;
3914+ char ErrorBuffer[60];
3915+
3916+ Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3917+
3918+ if (Adapter == NULL)
3919+ return (NULL);
3920+
3921+ RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3922+
3923+
3924+ //
3925+ // Save the current adapter number and increment the total number.
3926+ //
3927+
3928+ Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3929+
3930+
3931+ //
3932+ // Fill in the pointer back to the device specific structures.
3933+ // The device specific driver has also passed a pointer for us to
3934+ // fill in with the Adapter object that we have created.
3935+ //
3936+
3937+ Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3938+ Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3939+ Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3940+ Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3941+ Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3942+
3943+ Adapter->Dip = NewAdapter->Dip;
3944+
3945+ //
3946+ // Fill in Our address into the function dispatch table
3947+ //
3948+
3949+ NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3950+ NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3951+ NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3952+ NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3953+
3954+ //
3955+ // Ok now init the communication subsystem
3956+ //
3957+
3958+ Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3959+ if (Adapter->CommRegion == NULL) {
3960+ cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3961+ return (NULL);
3962+ }
3963+ RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3964+
3965+ //
3966+ // Get a pointer to the iblock_cookie
3967+ //
3968+
3969+ ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
3970+
3971+ if (!CommInit(Adapter)) {
3972+ FsaCommPrint("Failed to init the commuication subsystem.\n");
3973+ return(NULL);
3974+ }
3975+
3976+
3977+ //
3978+ // Initialize the list of AdapterFibContext's.
3979+ //
3980+
3981+ InitializeListHead(&Adapter->AdapterFibContextList);
3982+
3983+ //
3984+ // Initialize the fast mutex used for synchronization of the adapter fibs
3985+ //
3986+
3987+ Adapter->AdapterFibMutex = OsCvLockAlloc();
3988+ OsCvLockInit(Adapter->AdapterFibMutex, NULL);
3989+
3990+ //
3991+ // Allocate and start the FSA command threads. These threads will handle
3992+ // command requests from the adapter. They will wait on an event then pull
3993+ // all CDBs off the thread's queue. Each CDB will be given to a worker thread
3994+ // upto a defined limit. When that limit is reached wait a event will be waited
3995+ // on till a worker thread is finished.
3996+ //
3997+
3998+ if (!StartFsaCommandThreads(Adapter)) {
3999+ FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4000+ return (NULL);
4001+ }
4002+
4003+#ifdef unix_crash_dump
4004+ //
4005+ // Allocate and map a fib for use by the synch path, which is used for crash
4006+ // dumps.
4007+ //
4008+ // Allocate an entire page so that alignment is correct.
4009+ //
4010+
4011+ Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4012+ MapFibContext.Fib = Adapter->SyncFib;
4013+ MapFibContext.Size = sizeof(FIB);
4014+ MapFib( Adapter, &MapFibContext );
4015+ Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4016+#endif
4017+
4018+ Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4019+
4020+ Adapter->CommFuncs.AllocateFib = AllocateFib;
4021+
4022+ Adapter->CommFuncs.FreeFib = FreeFib;
4023+ Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4024+ Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4025+
4026+ Adapter->CommFuncs.InitializeFib = InitializeFib;
4027+ Adapter->CommFuncs.GetFibData = FsaGetFibData;
4028+ Adapter->CommFuncs.SendFib = SendFib;
4029+ Adapter->CommFuncs.CompleteFib = CompleteFib;
4030+ Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4031+
4032+ Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4033+
4034+ Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4035+ Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4036+
4037+ //
4038+ // Add this adapter in to our Adapter List.
4039+ //
4040+
4041+ Adapter->NextAdapter = FsaCommData.AdapterList;
4042+ FsaCommData.AdapterList = Adapter;
4043+
4044+ NewAdapter->Adapter = Adapter;
4045+
4046+// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4047+
4048+ return (Adapter);
4049+}
4050+
4051+AAC_STATUS
4052+CommInitialize(
4053+ PAFA_COMM_ADAPTER Adapter
4054+ )
4055+{
4056+ //
4057+ // Now allocate and initialize the zone structures used as our pool
4058+ // of FIB context records. The size of the zone is based on the
4059+ // system memory size. We also initialize the mutex used to protect
4060+ // the zone.
4061+ //
4062+ Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4063+ OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4064+
4065+ Adapter->FibContextZoneExtendSize = 64;
4066+
4067+ return (STATUS_SUCCESS);
4068+}
4069+
4070+
4071+
4072+/*++
4073+
4074+Routine Description:
4075+
4076+ Initializes the data structures that are required for the FSA commuication
4077+ interface to operate.
4078+
4079+Arguments:
4080+
4081+ None - all global or allocated data.
4082+
4083+Return Value:
4084+
4085+ TRUE - if we were able to init the commuication interface.
4086+ FALSE - If there were errors initing. This is a fatal error.
4087+--*/
4088+BOOLEAN
4089+CommInit(PAFA_COMM_ADAPTER Adapter)
4090+{
4091+
4092+ ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4093+ ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4094+ PQUEUE_INDEX Headers;
4095+ PQUEUE_ENTRY Queues;
4096+ ULONG TotalSize;
4097+ PCOMM_REGION CommRegion = Adapter->CommRegion;
4098+
4099+ CommInitialize( Adapter );
4100+
4101+ 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",
4102+ sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4103+ //
4104+ //
4105+ // Allocate the physically contigous space for the commuication queue
4106+ // headers.
4107+ //
4108+
4109+ TotalSize = SizeOfHeaders + SizeOfQueues;
4110+
4111+ if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4112+ return (FALSE);
4113+
4114+ Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4115+
4116+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4117+ NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4118+ (caddr_t)CommRegion ) != DDI_SUCCESS) {
4119+
4120+ cmn_err(CE_CONT, "Os_addr_intr failed\n");
4121+ }
4122+
4123+
4124+ // Adapter to Host normal priority Command queue
4125+
4126+
4127+ CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4128+ CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4129+ *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4130+ *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4131+
4132+ CommRegion->HostNormCmdQue.SavedIrql = 0;
4133+ CommRegion->HostNormCmdQue.BaseAddress = Queues;
4134+ CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4135+
4136+ CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4137+ if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4138+ return (FALSE);
4139+ }
4140+ InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4141+
4142+
4143+ Queues += HOST_NORM_CMD_ENTRIES;
4144+
4145+ // Adapter to Host high priority command queue
4146+
4147+ CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4148+ CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4149+ *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4150+ *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4151+
4152+ CommRegion->HostHighCmdQue.SavedIrql = 0;
4153+ CommRegion->HostHighCmdQue.BaseAddress = Queues;
4154+ CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4155+// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4156+ CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4157+ if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4158+ return (FALSE);
4159+ }
4160+ InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4161+
4162+ Queues += HOST_HIGH_CMD_ENTRIES;
4163+
4164+ // Host to adapter normal priority command queue
4165+
4166+ CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4167+ CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4168+ *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4169+ *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4170+
4171+ CommRegion->AdapNormCmdQue.SavedIrql = 0;
4172+ CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4173+ CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4174+ InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4175+
4176+ Queues += ADAP_NORM_CMD_ENTRIES;
4177+
4178+ // host to adapter high priority command queue
4179+
4180+ CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4181+ CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4182+ *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4183+ *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4184+
4185+ CommRegion->AdapHighCmdQue.SavedIrql = 0;
4186+ CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4187+ CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4188+ InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4189+
4190+ Queues += ADAP_HIGH_CMD_ENTRIES;
4191+
4192+ // adapter to host normal priority response queue
4193+
4194+ CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4195+ CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4196+ *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4197+ *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4198+
4199+ CommRegion->HostNormRespQue.SavedIrql = 0;
4200+ CommRegion->HostNormRespQue.BaseAddress = Queues;
4201+ CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4202+// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4203+ CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4204+ if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4205+ return (FALSE);
4206+ }
4207+ InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4208+
4209+ Queues += HOST_NORM_RESP_ENTRIES;
4210+
4211+ // adapter to host high priority response queue
4212+
4213+ CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4214+ CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4215+ *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4216+ *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4217+
4218+ CommRegion->HostHighRespQue.SavedIrql = 0;
4219+ CommRegion->HostHighRespQue.BaseAddress = Queues;
4220+ CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4221+// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4222+ CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4223+ if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4224+ return (FALSE);
4225+ }
4226+ InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4227+
4228+ Queues += HOST_HIGH_RESP_ENTRIES;
4229+
4230+ // host to adapter normal priority response queue
4231+
4232+ CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4233+ CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4234+ *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4235+ *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4236+
4237+ CommRegion->AdapNormRespQue.SavedIrql = 0;
4238+ CommRegion->AdapNormRespQue.BaseAddress = Queues;
4239+ CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4240+ InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4241+
4242+ Queues += ADAP_NORM_RESP_ENTRIES;
4243+
4244+ // host to adapter high priority response queue
4245+
4246+ CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4247+ CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4248+ *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4249+ *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4250+
4251+ CommRegion->AdapHighRespQue.SavedIrql = 0;
4252+ CommRegion->AdapHighRespQue.BaseAddress = Queues;
4253+ CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4254+ InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4255+
4256+ CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4257+ CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4258+ CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4259+ CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4260+
4261+ return(TRUE);
4262+}
4263+
4264+AAC_STATUS
4265+AfaCommShutdown(
4266+ PAFA_COMM_ADAPTER Adapter
4267+ )
4268+/*++
4269+
4270+Routine Description:
4271+
4272+ This routine will send a shutdown request to each adapter.
4273+
4274+Arguments:
4275+
4276+ Adapter - which adapter to send the shutdown to.
4277+
4278+Return Value:
4279+
4280+ NT Status success.
4281+
4282+--*/
4283+
4284+{
4285+ PFIB_CONTEXT FibContext;
4286+ PCLOSECOMMAND CloseCommand;
4287+ AAC_STATUS Status;
4288+
4289+ FibContext = AllocateFib( Adapter );
4290+
4291+ InitializeFib( FibContext );
4292+
4293+ CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4294+
4295+ CloseCommand->Command = VM_CloseAll;
4296+ CloseCommand->ContainerId = 0xffffffff;
4297+
4298+ Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4299+
4300+ if (Status != STATUS_SUCCESS) {
4301+
4302+ FreeFib( FibContext );
4303+
4304+ goto ret;
4305+
4306+ }
4307+
4308+ CompleteFib( FibContext );
4309+
4310+ FreeFib( FibContext );
4311+
4312+
4313+ Status = STATUS_SUCCESS;
4314+
4315+ret:
4316+
4317+ return (Status);
4318+
4319+}
4320+
4321+VOID
4322+AfaCommBugcheckHandler(
4323+ IN PVOID Buffer,
4324+ IN ULONG Length
4325+ )
4326+/*++
4327+
4328+Routine Description:
4329+
4330+ This routine will shutdown the adapter if there is a bugcheck and
4331+ copy the shutdown data from the adapter response into the buffer
4332+ so it will show up in the host dump file.
4333+p
4334+Arguments:
4335+
4336+ Buffer - This buffer will be written to the host dump by nt for us.
4337+
4338+ Length - The size of the buffer.
4339+
4340+Return Value:
4341+
4342+ N/A
4343+
4344+--*/
4345+{
4346+ PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4347+
4348+ while (Adapter) {
4349+
4350+ NotifyAdapter(Adapter, HostShutdown);
4351+
4352+ Adapter = Adapter->NextAdapter;
4353+
4354+ }
4355+
4356+}
4357+
4358+VOID
4359+FsaCommLogEvent(
4360+ PFIB_CONTEXT FibContext,
4361+ PDEVICE_OBJECT DeviceObject,
4362+ AAC_STATUS FsaStatus,
4363+ AAC_STATUS AacStatus,
4364+ ULONG LocationCode,
4365+ USHORT Category,
4366+ PUCHAR String,
4367+ BOOLEAN DumpFib
4368+)
4369+{
4370+}
4371+
4372+AfaCommProbeDisks(
4373+ PAFA_COMM_ADAPTER Adapter
4374+ )
4375+{
4376+ PMNTINFO DiskInfo;
4377+ PMNTINFORESPONSE DiskInfoResponse;
4378+ AAC_STATUS Status;
4379+ PCOMM_FIB_CONTEXT FibContext;
4380+
4381+ FibContext = AllocateFib( Adapter );
4382+
4383+ InitializeFib( FibContext );
4384+
4385+ DiskInfo = (PMNTINFO) FibContext->Fib->data;
4386+ DiskInfo->Command = VM_NameServe;
4387+ DiskInfo->MntCount = 0;
4388+ DiskInfo->MntType = FT_FILESYS;
4389+
4390+ Status = SendFib(ContainerCommand,
4391+ FibContext,
4392+ sizeof(MNTINFO),
4393+ FsaNormal,
4394+ TRUE,
4395+ NULL,
4396+ TRUE,
4397+ NULL,
4398+ NULL);
4399+
4400+ DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4401+
4402+ if (DiskInfoResponse->MntRespCount) {
4403+
4404+ cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4405+ DiskInfoResponse->MntTable[0].Capacity);
4406+
4407+ } else {
4408+
4409+ cmn_err(CE_CONT, "no containers found on adapter\n");
4410+
4411+ }
4412+
4413+ CompleteFib( FibContext );
4414+
4415+ FreeFib( FibContext );
4416+}
4417+
4418+
4419diff -burN linux-2.4.4/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4420--- linux-2.4.4/drivers/scsi/aacraid/commsup.c Wed Dec 31 18:00:00 1969
4421+++ linux/drivers/scsi/aacraid/commsup.c Mon Apr 30 09:43:34 2001
4422@@ -0,0 +1,2180 @@
4423+/*++
4424+ * Adaptec aacraid device driver for Linux.
4425+ *
4426+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4427+ *
4428+ * This program is free software; you can redistribute it and/or modify
4429+ * it under the terms of the GNU General Public License as published by
4430+ * the Free Software Foundation; either version 2, or (at your option)
4431+ * any later version.
4432+ *
4433+ * This program is distributed in the hope that it will be useful,
4434+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4435+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4436+ * GNU General Public License for more details.
4437+ *
4438+ * You should have received a copy of the GNU General Public License
4439+ * along with this program; see the file COPYING. If not, write to
4440+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4441+ *
4442+ * Module Name:
4443+ * commsup.c
4444+ *
4445+ * Abstract: Contain all routines that are required for FSA host/adapter
4446+ * commuication.
4447+ *
4448+ *
4449+ --*/
4450+
4451+static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4452+
4453+#include "comprocs.h"
4454+
4455+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4456+
4457+int CommPrinting;
4458+
4459+void
4460+ThrottleExceptionHandler(
4461+ IN PCOMM_REGION CommRegion,
4462+ AAC_STATUS Status
4463+ );
4464+
4465+void ThrottlePeriodEndDpcRtn(
4466+ IN PKDPC Dpc,
4467+ IN PVOID DeferredContext,
4468+ IN PVOID SystemArgument1,
4469+ IN PVOID SystemArgument2
4470+ );
4471+
4472+
4473+/*++
4474+
4475+Routine Description:
4476+
4477+ This routine will free all resources used by a given FibContextSegment.
4478+
4479+Arguments:
4480+
4481+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4482+ ZoneSegment - The segment to release resources from.
4483+
4484+Return Value:
4485+
4486+ TRUE - All resources were properly freed.
4487+ FALSE - An Error occured while freeing resources.
4488+
4489+--*/
4490+BOOLEAN
4491+FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4492+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4493+{
4494+ PCOMM_FIB_CONTEXT FibContext;
4495+ int i;
4496+
4497+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4498+
4499+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4500+ i < ZoneSegment->ExtendSize; i++, FibContext++) {
4501+
4502+ OsCvLockDestroy( FibContext->FsaEventMutex );
4503+ OsCv_destroy( &FibContext->FsaEvent );
4504+
4505+ }
4506+
4507+ UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4508+
4509+ OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4510+
4511+ OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4512+
4513+ return (TRUE);
4514+}
4515+
4516+BOOLEAN
4517+FsaFreeFibContextZone(
4518+ PAFA_COMM_ADAPTER Adapter
4519+ )
4520+/*++
4521+
4522+Routine Description:
4523+
4524+ This routine will walk through the FibContextSegmentList and free up all
4525+ resources used by the FibContextZone.
4526+
4527+Arguments:
4528+
4529+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4530+
4531+Return Value:
4532+
4533+ TRUE - All resources were properly freed.
4534+ FALSE - An Error occured while freeing resources.
4535+
4536+--*/
4537+
4538+{
4539+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4540+
4541+ ZoneSegment = Adapter->FibContextSegmentList;
4542+
4543+ while (ZoneSegment) {
4544+
4545+ NextZoneSegment = ZoneSegment->Next;
4546+
4547+ FsaFreeFibContextSegment( Adapter, ZoneSegment );
4548+
4549+ ZoneSegment = NextZoneSegment;
4550+ }
4551+
4552+ return (TRUE);
4553+}
4554+
4555+
4556+
4557+BOOLEAN
4558+FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4559+{
4560+ int ExtendSize;
4561+ KIRQL SavedIrql;
4562+ ULONG ZoneSegmentAllocSize, FibAllocSize;
4563+ PVOID FibContextSegment;
4564+ PCOMM_FIB_CONTEXT FibContext;
4565+ PFIB Fib;
4566+ PVOID FibPhysicalAddress;
4567+ int i;
4568+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4569+
4570+ //
4571+ // Allocate space to describe this zone segment.
4572+ //
4573+
4574+ cmn_err (CE_DEBUG, "Entered FsaExtendFibConextZone");
4575+ ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4576+
4577+ ExtendSize = Adapter->FibContextZoneExtendSize;
4578+ ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4579+
4580+ FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4581+
4582+ if (FibContextSegment == NULL) {
4583+ return (FALSE);
4584+ }
4585+
4586+ RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4587+
4588+ ZoneSegment->FibContextSegment = FibContextSegment;
4589+ ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4590+ ZoneSegment->ExtendSize = ExtendSize;
4591+
4592+ FibAllocSize = ExtendSize * sizeof(FIB);
4593+
4594+
4595+ ZoneSegment->MapFibContext.Size = FibAllocSize;
4596+
4597+ AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4598+
4599+ Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4600+ FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4601+
4602+ RtlZeroMemory( Fib, FibAllocSize );
4603+
4604+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4605+
4606+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4607+ i < ExtendSize; i++, FibContext++) {
4608+
4609+ FibContext->Adapter = Adapter;
4610+
4611+ FibContext->Fib = Fib;
4612+ FibContext->FibData = (PVOID) FibContext->Fib->data;
4613+
4614+ OsCv_init( &FibContext->FsaEvent);
4615+ FibContext->FsaEventMutex = OsCvLockAlloc();
4616+ OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4617+
4618+ Fib->Header.XferState = 0xffffffff;
4619+ Fib->Header.SenderSize = sizeof(FIB);
4620+
4621+ FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4622+
4623+ Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4624+ FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4625+ }
4626+
4627+ //
4628+ // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4629+ // initialized, we just need to extend it.
4630+ //
4631+
4632+ if (Adapter->FibContextZone.TotalSegmentSize) {
4633+
4634+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4635+
4636+ ExExtendZone( &Adapter->FibContextZone,
4637+ FibContextSegment,
4638+ ZoneSegmentAllocSize );
4639+
4640+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4641+
4642+ } else {
4643+
4644+ if (ExInitializeZone( &Adapter->FibContextZone,
4645+ sizeof(COMM_FIB_CONTEXT),
4646+ FibContextSegment,
4647+ ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4648+ FsaBugCheck(0,0,0);
4649+
4650+ }
4651+
4652+ //
4653+ // Add this segment to the adapter's list of segments
4654+ //
4655+
4656+ ZoneSegment->Next = Adapter->FibContextSegmentList;
4657+ Adapter->FibContextSegmentList = ZoneSegment;
4658+
4659+ return (TRUE);
4660+}
4661+
4662+
4663+
4664+/*++
4665+
4666+Routine Description:
4667+
4668+ This routine creates a new COMM_FIB_CONTEXT record
4669+
4670+Arguments:
4671+
4672+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4673+
4674+Return Value:
4675+
4676+ PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4677+
4678+--*/
4679+PFIB_CONTEXT
4680+AllocateFib (IN PVOID AdapterArg)
4681+{
4682+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4683+ KIRQL SavedIrql;
4684+ PCOMM_FIB_CONTEXT FibContext;
4685+ int FullZoneLoopCounter = 0;
4686+
4687+
4688+ //
4689+ // Acquire the zone spin lock, and check to see if the zone is full.
4690+ // If it is, then release the spin lock and allocate more fibs for the
4691+ // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4692+ // the new fibs onto the zone.
4693+ //
4694+
4695+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4696+
4697+ while (ExIsFullZone( &Adapter->FibContextZone )) {
4698+
4699+ if (++FullZoneLoopCounter > 10)
4700+ FsaBugCheck(0,0,0);
4701+
4702+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4703+
4704+ // bmb debug
4705+ cmn_err (CE_DEBUG, "Extending FibContextZone");
4706+ if (FsaExtendFibContextZone(Adapter) == FALSE) {
4707+ return (NULL);
4708+ }
4709+
4710+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4711+
4712+ }
4713+
4714+ //
4715+ // At this point we now know that the zone has at least one more
4716+ // IRP context record available. So allocate from the zone and
4717+ // then release the mutex.
4718+ //
4719+
4720+ FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4721+
4722+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4723+
4724+ //
4725+ // Set the proper node type code and node byte size
4726+ //
4727+
4728+ FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4729+ FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4730+
4731+ //
4732+ // Null out fields that depend on being zero at the start of each I/O
4733+ //
4734+
4735+ FibContext->Fib->Header.XferState = 0;
4736+ FibContext->FibCallback = NULL;
4737+ FibContext->FibCallbackContext = NULL;
4738+
4739+
4740+ //
4741+ // return and tell the caller
4742+ //
4743+
4744+ return ((PFIB_CONTEXT) FibContext);
4745+}
4746+
4747+
4748+/*++
4749+
4750+Routine Description:
4751+
4752+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4753+ from the Fsafs in memory data structures. It should only be called
4754+ by FsaCompleteRequest.
4755+
4756+Arguments:
4757+
4758+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4759+
4760+Return Value:
4761+
4762+ None
4763+
4764+--*/
4765+VOID
4766+FreeFib (IN PFIB_CONTEXT Context)
4767+{
4768+ KIRQL SavedIrql;
4769+ PCOMM_FIB_CONTEXT FibContext = Context;
4770+
4771+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4772+
4773+ OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4774+
4775+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4776+
4777+ FsaCommData.TimedOutFibs++;
4778+
4779+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4780+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4781+
4782+ } else {
4783+
4784+ ASSERT(FibContext->Fib->Header.XferState == 0);
4785+
4786+ if (FibContext->Fib->Header.XferState != 0) {
4787+ cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4788+ FibContext, FibContext->Fib->Header.XferState);
4789+ }
4790+
4791+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4792+
4793+ }
4794+
4795+ OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4796+
4797+ //
4798+ // return and tell the caller
4799+ //
4800+
4801+ return;
4802+}
4803+
4804+
4805+/*++
4806+
4807+Routine Description:
4808+
4809+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4810+ from the Fsafs in memory data structures. It should only be called
4811+ from the dpc routines to from dpc to free an FibContext from an async or
4812+ no response io
4813+
4814+Arguments:
4815+
4816+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4817+
4818+Return Value:
4819+
4820+ None
4821+
4822+--*/
4823+VOID
4824+FreeFibFromDpc (IN PFIB_CONTEXT Context)
4825+{
4826+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4827+
4828+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4829+
4830+ OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4831+
4832+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4833+
4834+ FsaCommData.TimedOutFibs++;
4835+
4836+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4837+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4838+
4839+ } else {
4840+
4841+ ASSERT(FibContext->Fib->Header.XferState == 0);
4842+
4843+ if (FibContext->Fib->Header.XferState != 0) {
4844+ cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4845+ FibContext, FibContext->Fib->Header.XferState);
4846+ }
4847+
4848+
4849+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4850+
4851+ }
4852+
4853+ OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4854+
4855+ //
4856+ // return and tell the caller
4857+ //
4858+
4859+ return;
4860+}
4861+
4862+
4863+/*++
4864+
4865+Routine Description:
4866+
4867+ Will initialize a FIB of the requested size.
4868+
4869+Arguments:
4870+
4871+ Fib is a pointer to a location which will receive the address of the allocated
4872+ FIB.
4873+
4874+ Size is the size of the Fib to allocate.
4875+
4876+Return Value:
4877+
4878+ NT_SUCCESS if a Fib was returned to the caller.
4879+ NT_ERROR if event was an invalid event.
4880+
4881+--*/
4882+AAC_STATUS
4883+InitializeFib (IN PFIB_CONTEXT Context)
4884+{
4885+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4886+ PFIB Fib = FibContext->Fib;
4887+
4888+ Fib->Header.StructType = TFib;
4889+ Fib->Header.Size = sizeof(FIB);
4890+// if (Fib->Header.XferState & AllocatedFromPool)
4891+// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4892+// else
4893+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4894+ Fib->Header.SenderFibAddress = 0;
4895+ Fib->Header.ReceiverFibAddress = 0;
4896+ Fib->Header.SenderSize = sizeof(FIB);
4897+
4898+ return(STATUS_SUCCESS);
4899+}
4900+
4901+
4902+/*++
4903+
4904+Routine Description:
4905+
4906+ Will allocate and initialize a FIB of the requested size and return a
4907+ pointer to the structure. The size allocated may be larger than the size
4908+ requested due to allocation performace optimizations.
4909+
4910+Arguments:
4911+
4912+ Fib is a pointer to a location which will receive the address of the allocated
4913+ FIB.
4914+
4915+ Size is the size of the Fib to allocate.
4916+
4917+ JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4918+ imbedded structure the FS always allocates. So just initiaize it and return.
4919+
4920+Return Value:
4921+
4922+ NT_SUCCESS if a Fib was returned to the caller.
4923+ NT_ERROR if event was an invalid event.
4924+
4925+--*/
4926+AAC_STATUS
4927+AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4928+{}
4929+
4930+
4931+/*++
4932+
4933+Routine Description:
4934+
4935+ Will deallocate and return to the free pool the FIB pointed to by the
4936+ caller. Upon return accessing locations pointed to by the FIB parameter
4937+ could cause system access faults.
4938+
4939+Arguments:
4940+
4941+ Fib is a pointer to the FIB that caller wishes to deallocate.
4942+
4943+Return Value:
4944+
4945+ NT_SUCCESS if a Fib was returned to the caller.
4946+ NT_ERROR if event was an invalid event.
4947+
4948+--*/
4949+AAC_STATUS
4950+DeallocateFib (PFIB_CONTEXT Context)
4951+{
4952+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4953+ PFIB Fib = FibContext->Fib;
4954+
4955+ if ( Fib->Header.StructType != TFib ) {
4956+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4957+ return(STATUS_UNSUCCESSFUL);
4958+ }
4959+
4960+
4961+ Fib->Header.XferState = 0;
4962+
4963+ return(STATUS_SUCCESS);
4964+
4965+}
4966+
4967+
4968+AAC_STATUS
4969+GetResponse(
4970+ IN PCOMM_QUE ResponseQueue,
4971+ OUT PFIB Fib
4972+ )
4973+/*++
4974+
4975+Routine Description:
4976+
4977+ Gets a QE off the requested response queue and gets the response FIB into
4978+ host memory. The FIB may already be in host memory depending on the bus
4979+ interface, or may require the host to DMA it over from the adapter. The routine
4980+ will return the FIB to the caller.
4981+
4982+Arguments:
4983+
4984+ ResponseQueue - Is the queue the caller wishes to have the response gotten from.
4985+ Fib - Is the Fib which was the response from the adapter
4986+
4987+Return Value:
4988+
4989+ NT_SUCCESS if a Fib was returned to the caller.
4990+ NT_ERROR if there was no Fib to return to the caller.
4991+ bkpfix - add in all the other possible errors ect
4992+
4993+--*/
4994+{
4995+return(STATUS_UNSUCCESSFUL);
4996+}
4997+
4998+//
4999+// Commuication primitives define and support the queuing method we use to
5000+// support host to adapter commuication. All queue accesses happen through
5001+// these routines and are the only routines which have a knowledge of the
5002+// how these queues are implemented.
5003+//
5004+
5005+
5006+/*++
5007+
5008+Routine Description:
5009+
5010+ With a priority the routine returns a queue entry if the queue has free entries. If the queue
5011+ is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5012+ returned.
5013+
5014+Arguments:
5015+
5016+ Priority is an enumerated type which determines which priority level
5017+ command queue the QE is going to be queued on.
5018+
5019+ Entry is a pointer to the address of where to return the address of
5020+ the queue entry from the requested command queue.
5021+
5022+ Index is a pointer to the address of where to store the index of the new
5023+ queue entry returned.
5024+
5025+ DontInterrupt - We set this true if the queue state is such that we don't
5026+ need to interrupt the adapter for this queue entry.
5027+
5028+Return Value:
5029+
5030+ TRUE - If a queue entry is returned
5031+ FALSE - If there are no free queue entries on the requested command queue.
5032+
5033+--*/
5034+BOOLEAN
5035+GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5036+ OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5037+ OUT ULONG *DontInterrupt)
5038+{
5039+ ULONG QueueOffset;
5040+ BOOLEAN status;
5041+ PCOMM_REGION CommRegion;
5042+
5043+ CommRegion = Adapter->CommRegion;
5044+
5045+ //
5046+ // All of the queues wrap when they reach the end, so we check to see if they
5047+ // have reached the end and if they have we just set the index back to zero.
5048+ // This is a wrap. You could or off the high bits in all updates but this is
5049+ // a bit faster I think.
5050+ //
5051+
5052+ if (WhichQueue == AdapHighCmdQueue) {
5053+ *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5054+
5055+ if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5056+ *DontInterrupt = TRUE;
5057+
5058+ if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5059+ *Index = 0;
5060+
5061+ if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5062+ status = FALSE;
5063+ cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5064+ CommRegion->AdapHighCmdQue.NumOutstandingIos);
5065+ } else {
5066+ QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5067+ *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5068+
5069+ status = TRUE;
5070+ }
5071+ } else if (WhichQueue == AdapNormCmdQueue) {
5072+
5073+ *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5074+
5075+ if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5076+ *DontInterrupt = TRUE;
5077+
5078+ //
5079+ // If we are at the end of the QUEUE then wrap back to
5080+ // the beginning.
5081+ //
5082+
5083+ if (*Index >= ADAP_NORM_CMD_ENTRIES)
5084+ *Index = 0; // Wrap to front of the Producer Queue.
5085+
5086+ //
5087+ // The IEEE spec says that it the producer is one behind the consumer then
5088+ // the queue is full.
5089+ //
5090+
5091+ ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5092+
5093+ if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5094+ cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5095+ CommRegion->AdapNormCmdQue.NumOutstandingIos);
5096+ status = FALSE;
5097+ } else {
5098+ //
5099+ // The success case just falls through and returns the a valid queue entry.
5100+ //
5101+
5102+#ifdef commdebug
5103+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5104+ FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5105+ *Index, QueueOffset, Entry, *Entry);
5106+#endif
5107+ *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5108+
5109+ status = TRUE;
5110+ }
5111+ } else if (WhichQueue == AdapHighRespQueue) {
5112+
5113+ *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5114+
5115+ if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5116+ *DontInterrupt = TRUE;
5117+
5118+ if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5119+ *Index = 0;
5120+
5121+ if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5122+ status = FALSE;
5123+ cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5124+ CommRegion->AdapHighRespQue.NumOutstandingIos);
5125+ } else {
5126+ *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5127+ status = TRUE;
5128+ }
5129+ } else if (WhichQueue == AdapNormRespQueue) {
5130+
5131+ *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5132+
5133+ if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5134+ *DontInterrupt = TRUE;
5135+
5136+ //
5137+ // If we are at the end of the QUEUE then wrap back to
5138+ // the beginning.
5139+ //
5140+
5141+ if (*Index >= ADAP_NORM_RESP_ENTRIES)
5142+ *Index = 0; // Wrap to front of the Producer Queue.
5143+
5144+ //
5145+ // The IEEE spec says that it the producer is one behind the consumer then
5146+ // the queue is full.
5147+ //
5148+
5149+ if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5150+ status = FALSE;
5151+ cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5152+ CommRegion->AdapNormRespQue.NumOutstandingIos);
5153+ } else {
5154+ //
5155+ // The success case just falls through and returns the a valid queue entry.
5156+ //
5157+
5158+ *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5159+
5160+#ifdef commdebug
5161+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5162+ FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5163+#endif
5164+ status = TRUE;
5165+ }
5166+ } else {
5167+ cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5168+ }
5169+
5170+
5171+ return (status);
5172+}
5173+
5174+
5175+
5176+#ifdef API_THROTTLE
5177+
5178+void ThrottleCheck(
5179+ IN PAFA_COMM_ADAPTER Adapter,
5180+ IN PFIB Fib
5181+ )
5182+/*++
5183+
5184+Routine Description:
5185+
5186+ This routine implements data I/O throttling. Throttling occurs when
5187+ a CLI FIB is detected. To ensure the CLI responds quickly (the user
5188+ is waiting for the response), this mechanism restricts the queue
5189+ depth of data IOs at the adapter for a period of time (called the
5190+ Throttle Period, default 5 seconds).
5191+
5192+ The mechanism uses a counted semaphore to place threads into a wait
5193+ state should there be too many data I/Os outstanding.
5194+
5195+ At the start of a throttle period (indicated by the first CLI FIB)
5196+ a timer is started. When the timer expires, new requests can go to
5197+ the adapter freely. Throttled requests gradually drain to the
5198+ adapter as each outstanding throttle I/O completes.
5199+
5200+ To avoid hurting regular I/O performance, we use a flag in the FIB
5201+ header to mark FIBs involved in throttling. This means we only need
5202+ take the extra spinlock in the response DPC routine for FIBs who
5203+ were subject to throttling. If no throttling is occurring, the cost
5204+ to the regular code paths is a handful of instructions.
5205+
5206+Arguments:
5207+
5208+ Adapter - Pointer to per-adapter context. This is used to locate the
5209+ throttle information for this adapter.
5210+
5211+ Fib - Pointer to the header for the fib being sent.
5212+
5213+Return Value:
5214+
5215+ None.
5216+
5217+--*/
5218+{
5219+ PCOMM_REGION CommRegion = Adapter->CommRegion;
5220+ AAC_STATUS Status;
5221+
5222+ //
5223+ // This routine is called under protection of the queue spinlock.
5224+ // As such we are allowed to check and change the counts for the
5225+ // throttle.
5226+ // Check the FIB. If its not a data operation, send it on without
5227+ // throttle check. If it is a data operation, check for throttle.
5228+ //
5229+
5230+ CommRegion->TotalFibs++; // Keep statistics
5231+
5232+ if ((Fib->Header.XferState & ApiFib) != 0) {
5233+
5234+ CommRegion->ApiFibs++; // Keep statistics
5235+
5236+ //
5237+ // Its an API fib. If the throttle is not already active,
5238+ // make it so. This will prevent new data Fibs being sent
5239+ // if they exceed the throttle check.
5240+ //
5241+
5242+ if (!CommRegion->ThrottleActive) {
5243+ BOOLEAN InQue;
5244+
5245+ CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5246+
5247+ //
5248+ // Schedule a timer for the throttle active period. When
5249+ // it expires, we'll be called back at routine ThrottleDpcRoutine
5250+ // above. This will signify the throttle active period ended
5251+ // and any waiting threads will be signalled to restart.
5252+ //
5253+
5254+ FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5255+ CommRegion->ThrottleTimerSets++;
5256+ InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5257+ CommRegion->ThrottleTimeout,
5258+ &CommRegion->ThrottleDpc);
5259+ ASSERT(InQue == FALSE);
5260+ }
5261+
5262+ return;
5263+ }
5264+
5265+ //
5266+ // Its a non-API fib, so subject to throttle checks.
5267+ // The following are exempt from throttling:
5268+ // o FIBs marked as "throttle exempt" by upper layers.
5269+ // o I/Os issued from a raised IRQL. We can't suspend
5270+ // a thread when at raised IRQL so throttling is exempt.
5271+ //
5272+
5273+ if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5274+
5275+ CommRegion->NonPassiveFibs++;
5276+ FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5277+ return;
5278+
5279+ }
5280+
5281+ if (CommRegion->ThrottleActive) {
5282+
5283+ //
5284+ // Throttle is active.
5285+ // Check if the FIB is a read or write. If so, and its to the
5286+ // file system information area, let it through without throttling.
5287+ //
5288+
5289+ if (Fib->Header.Command == ContainerCommand) {
5290+ PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5291+
5292+ //
5293+ // *** Note *** We are using read and write command formats
5294+ // interchangably here. This is ok for this purpose as the
5295+ // command is in the same place for both. Read and write command
5296+ // formats are different at higher offsets though.
5297+ //
5298+
5299+ if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5300+ (BlockDisk->Command == VM_CtBlockWrite)) &&
5301+ (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5302+
5303+ CommRegion->FSInfoFibs++; // Keep statistics
5304+ return;
5305+
5306+ }
5307+
5308+ }
5309+
5310+ //
5311+ // Throttle the FIB.
5312+ // Mark it as throttle active so that it can signal a waiter
5313+ // when it completes.
5314+
5315+ CommRegion->ThrottledFibs++;
5316+ Fib->Header.Flags |= ThrottledFib;
5317+
5318+ //
5319+ // Release the spinlock so we can wait the thread if necessary.
5320+ // Since we specify a timeout, check the caller is at passive level.
5321+ //
5322+
5323+ OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5324+
5325+ FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5326+
5327+ Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5328+ Executive, // Don't allow user APCs to wake us
5329+ KernelMode, // Wait in kernel mode
5330+ FALSE, // Not alertable
5331+ &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5332+
5333+ //
5334+ // Check the signal status. If we've timed out, clear the throttle
5335+ // flag on the FIB to avoid us signalling the semaphore on completion.
5336+ // We never acquired the semaphore.
5337+ //
5338+ if (Status == STATUS_TIMEOUT) {
5339+
5340+ CommRegion->ThrottleTimedoutFibs++;
5341+ FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5342+ Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5343+
5344+ } else {
5345+
5346+ ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5347+
5348+ }
5349+
5350+ //
5351+ // We've been woken up and can now send the FIB to the adapter.
5352+ // Acquire the spinlock again so we can get a queue entry. This
5353+ // returns to GetQueueEntry.
5354+ //
5355+
5356+ FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5357+ KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5358+ CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5359+ return;
5360+
5361+ }
5362+}
5363+
5364+#endif //#ifdef API_THROTTLE
5365+
5366+int GetQueueEntryTimeouts = 0;
5367+
5368+
5369+/*++
5370+
5371+Routine Description:
5372+
5373+ Gets the next free QE off the requested priorty adapter command queue and
5374+ associates the Fib with the QE. The QE represented by index is ready to
5375+ insert on the queue when this routine returns success.
5376+
5377+Arguments:
5378+
5379+ Index is the returned value which represents the QE which is ready to
5380+ insert on the adapter's command queue.
5381+
5382+ Priority is an enumerated type which determines which priority level
5383+ command queue the QE is going to be queued on.
5384+
5385+ Fib is a pointer to the FIB the caller wishes to have associated with the
5386+ QE.
5387+
5388+ Wait is a boolean which determines if the routine will wait if there are
5389+ no free QEs on the requested priority command queue.
5390+
5391+ FibContext is where the driver stores all system resources required to execute the
5392+ command requested from the calling thread. This includes mapping resources for
5393+ the FIB and the 'users' buffer.
5394+
5395+ DontInterrupt - We set this true if the queue state is such that we don't
5396+ need to interrupt the adapter for this queue entry.
5397+
5398+Return Value:
5399+
5400+ NT_SUCCESS if a Fib was returned to the caller.
5401+ NT_ERROR if event was an invalid event.
5402+
5403+--*/
5404+AAC_STATUS
5405+GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5406+ IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5407+ IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5408+{
5409+ PQUEUE_ENTRY QueueEntry = NULL;
5410+ BOOLEAN MapAddress = FALSE;
5411+ int timeouts = 0;
5412+ AAC_STATUS Status;
5413+ PCOMM_REGION CommRegion;
5414+
5415+ CommRegion = Adapter->CommRegion;
5416+
5417+ //
5418+ // Get the spinlock for the queue we are putting a command on
5419+ //
5420+
5421+ if (WhichQueue == AdapHighCmdQueue)
5422+ OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5423+ else if (WhichQueue == AdapNormCmdQueue)
5424+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5425+ else if (WhichQueue == AdapHighRespQueue)
5426+ OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5427+ else if (WhichQueue == AdapNormRespQueue)
5428+ OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5429+ else {
5430+ FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5431+ return(FSA_INVALID_QUEUE);
5432+ }
5433+
5434+ //
5435+ // Get the pointers to a queue entry on the queue the caller wishes to queue
5436+ // a command request on. If there are no entries then wait if that is what the
5437+ // caller requested.
5438+ //
5439+
5440+ if (WhichQueue == AdapHighCmdQueue) {
5441+ // if no entries wait for some if caller wants to
5442+ while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5443+ cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5444+ }
5445+
5446+ //
5447+ // Setup queue entry with a command, status and Fib mapped
5448+ //
5449+
5450+ QueueEntry->Size = Fib->Header.Size;
5451+ MapAddress = TRUE;
5452+
5453+ } else if (WhichQueue == AdapNormCmdQueue) {
5454+ // if no entries wait for some if caller wants to
5455+ while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5456+ cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5457+ }
5458+
5459+ //
5460+ // Setup queue entry with command, status and Fib mapped
5461+ //
5462+
5463+ QueueEntry->Size = Fib->Header.Size;
5464+ MapAddress = TRUE;
5465+
5466+ } else if (WhichQueue == AdapHighRespQueue) {
5467+
5468+ while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5469+ }
5470+
5471+ //
5472+ // Setup queue entry with command, status and Fib mapped
5473+ //
5474+
5475+ QueueEntry->Size = Fib->Header.Size;
5476+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5477+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5478+ MapAddress = FALSE;
5479+
5480+ } else if (WhichQueue == AdapNormRespQueue) {
5481+ while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5482+ }
5483+
5484+ //
5485+ // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5486+ //
5487+
5488+ QueueEntry->Size = Fib->Header.Size;
5489+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5490+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5491+ MapAddress = FALSE;
5492+ }
5493+
5494+ //
5495+ // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5496+ //
5497+
5498+ if (MapAddress) {
5499+ QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5500+ }
5501+
5502+ //
5503+ // Return
5504+ //
5505+#ifdef commdebug
5506+ FsaCommPrint("Queue Entry contents:.\n");
5507+ FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5508+ FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5509+ FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5510+ FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5511+#endif
5512+
5513+ return(FSA_SUCCESS);
5514+}
5515+
5516+
5517+/*++
5518+
5519+Routine Description:
5520+
5521+ Gets the next free QE off the requested priorty adapter command queue and
5522+ associates the Fib with the QE. The QE represented by index is ready to
5523+ insert on the queue when this routine returns success.
5524+
5525+Arguments:
5526+
5527+ Index is the returned value which represents the QE which is ready to
5528+ insert on the adapter's command queue.
5529+
5530+ WhichQueue tells us which queue the caller wishes to have the entry put.
5531+
5532+Return Value:
5533+
5534+ NT_SUCCESS if a Fib was returned to the caller.
5535+ NT_ERROR if event was an invalid event.
5536+
5537+--*/
5538+AAC_STATUS
5539+InsertQueueEntry(
5540+ IN PAFA_COMM_ADAPTER Adapter,
5541+ IN QUEUE_INDEX Index,
5542+ IN QUEUE_TYPES WhichQueue,
5543+ IN ULONG DontInterrupt
5544+ )
5545+{
5546+ PCOMM_REGION CommRegion;
5547+
5548+ CommRegion = Adapter->CommRegion;
5549+
5550+ //
5551+ // We have already verified the queue in getentry, but we still have to make
5552+ // sure we don't wrap here too.
5553+ //
5554+
5555+ if (WhichQueue == AdapHighCmdQueue) {
5556+
5557+ *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5558+
5559+ OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5560+
5561+ if (!DontInterrupt)
5562+ NotifyAdapter(Adapter, AdapHighCmdQue);
5563+
5564+ } else if (WhichQueue == AdapNormCmdQueue) {
5565+
5566+#ifdef commdebug
5567+ FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5568+#endif
5569+ *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5570+
5571+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5572+
5573+ if (!DontInterrupt)
5574+ NotifyAdapter(Adapter, AdapNormCmdQue);
5575+
5576+ } else if (WhichQueue == AdapHighRespQueue) {
5577+
5578+ *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5579+
5580+ OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5581+
5582+ if (!DontInterrupt)
5583+ NotifyAdapter(Adapter, AdapHighRespQue);
5584+
5585+ } else if (WhichQueue == AdapNormRespQueue) {
5586+
5587+ *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5588+
5589+ OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5590+
5591+ if (!DontInterrupt)
5592+ NotifyAdapter(Adapter, AdapNormRespQue);
5593+
5594+ } else {
5595+ FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5596+ return(FSA_INVALID_QUEUE_PRIORITY);
5597+ }
5598+
5599+ return(FSA_SUCCESS);
5600+}
5601+
5602+extern int GatherFibTimes;
5603+
5604+BOOLEAN
5605+SendSynchFib(
5606+ PVOID Arg,
5607+ FIB_COMMAND Command,
5608+ PVOID Data,
5609+ USHORT Size,
5610+ PVOID Response,
5611+ USHORT *ResponseSize
5612+ )
5613+/*++
5614+
5615+Routine Description:
5616+
5617+ This routine will send a synchronous FIB to the adapter and wait for its
5618+ completion.
5619+
5620+Arguments:
5621+
5622+ DeviceExtension - Pointer to adapter extension structure.
5623+
5624+
5625+Return Value:
5626+
5627+ BOOLEAN
5628+
5629+--*/
5630+{
5631+ PAFA_COMM_ADAPTER Adapter = Arg;
5632+ FIB *Fib;
5633+ ULONG returnStatus;
5634+
5635+ Fib = Adapter->SyncFib;
5636+
5637+ Fib->Header.StructType = TFib;
5638+ Fib->Header.Size = sizeof(FIB);
5639+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5640+ Fib->Header.ReceiverFibAddress = 0;
5641+ Fib->Header.SenderSize = sizeof(FIB);
5642+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5643+ Fib->Header.Command = Command;
5644+
5645+ //
5646+ // Copy the Data portion into the Fib.
5647+ //
5648+
5649+ RtlCopyMemory( Fib->data, Data, Size );
5650+
5651+
5652+ Fib->Header.XferState |= (SentFromHost | NormalPriority);
5653+
5654+ //
5655+ // Set the size of the Fib we want to send to the adapter
5656+ //
5657+
5658+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5659+
5660+ if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5661+ Adapter->SyncFibPhysicalAddress )) {
5662+
5663+ return (FALSE);
5664+
5665+ }
5666+
5667+ //
5668+ // Copy the response back to the caller's buffer.
5669+ //
5670+
5671+ RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5672+
5673+ *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5674+
5675+ //
5676+ // Indicate success
5677+ //
5678+
5679+ return (TRUE);
5680+}
5681+
5682+//
5683+// Define the highest level of host to adapter communication routines. These
5684+// routines will support host to adapter FS commuication. These routines have
5685+// no knowledge of the commuication method used. This level sends and receives
5686+// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5687+//
5688+
5689+
5690+
5691+/*++
5692+
5693+Routine Description:
5694+
5695+ Sends the requested FIB to the adapter and optionally will wait for a
5696+ response FIB. If the caller does not wish to wait for a response than
5697+ an event to wait on must be supplied. This event will be set when a
5698+ response FIB is received from the adapter.
5699+
5700+Arguments:
5701+
5702+ Fib is a pointer to the FIB the caller wishes to send to the adapter.
5703+
5704+ Size - Size of the data portion of the Fib.
5705+
5706+ Priority is an enumerated type which determines which priority level
5707+ the caller wishes to send this command at.
5708+
5709+ Wait is a boolean which determines if the routine will wait for the
5710+ completion Fib to be returned(TRUE), or return when the Fib has been
5711+ successfully received by the adapter(FALSE).
5712+
5713+ WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5714+ FIB has been returned by the adapter.
5715+
5716+ ReturnFib is an optional pointer to a FIB that if present the response FIB will
5717+ copied to.
5718+
5719+Return Value:
5720+
5721+ NT_SUCCESS if a Fib was returned to the caller.
5722+ NT_ERROR if event was an invalid event.
5723+
5724+ --*/
5725+AAC_STATUS
5726+SendFib (IN FIB_COMMAND Command,
5727+ IN PFIB_CONTEXT Context,
5728+ IN ULONG Size,
5729+ IN COMM_PRIORITIES Priority,
5730+ IN BOOLEAN Wait,
5731+ IN PVOID WaitOn,
5732+ IN BOOLEAN ResponseExpected,
5733+ IN PFIB_CALLBACK FibCallback,
5734+ IN PVOID FibCallbackContext)
5735+{
5736+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5737+ QUEUE_INDEX Index;
5738+ QUEUE_TYPES WhichQueue;
5739+ LARGE_INTEGER Timeout;
5740+ AAC_STATUS Status;
5741+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5742+ ULONG DontInterrupt = FALSE;
5743+ PFIB Fib = FibContext->Fib;
5744+ IN PCOMM_QUE OurQueue;
5745+
5746+ Timeout = FsaCommData.AdapterTimeout;
5747+
5748+ if (!(Fib->Header.XferState & HostOwned)) {
5749+ FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5750+ FsaCommLogEvent(FibContext,
5751+ FsaCommData.DeviceObject,
5752+ FSAFS_FIB_INVALID,
5753+ STATUS_UNSUCCESSFUL,
5754+ BugCheckFileId | __LINE__,
5755+ FACILITY_FSAFS_ERROR_CODE,
5756+ NULL,
5757+ TRUE);
5758+
5759+ return(STATUS_UNSUCCESSFUL);
5760+
5761+ }
5762+
5763+ //
5764+ // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5765+ // are if the caller requests to wait and does not request a response and if the
5766+ // caller does not want a response and the Fib is not allocated from pool. If a response
5767+ // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5768+ // comes back from the adapter. No further processing will be done besides deleting the
5769+ // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5770+ // and the host can log that fact.
5771+
5772+ if (Wait && !ResponseExpected) {
5773+
5774+ FsaCommLogEvent(FibContext,
5775+ FsaCommData.DeviceObject,
5776+ FSAFS_FIB_INVALID,
5777+ STATUS_UNSUCCESSFUL,
5778+ BugCheckFileId | __LINE__,
5779+ FACILITY_FSAFS_ERROR_CODE,
5780+ NULL,
5781+ TRUE);
5782+
5783+ return(STATUS_UNSUCCESSFUL);
5784+
5785+ } else if (!Wait && ResponseExpected) {
5786+ Fib->Header.XferState |= (Async | ResponseExpected);
5787+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5788+ } else if (!Wait && !ResponseExpected) {
5789+ Fib->Header.XferState |= NoResponseExpected;
5790+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5791+ } else if (Wait && ResponseExpected) {
5792+ Fib->Header.XferState |= ResponseExpected;
5793+ FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5794+ }
5795+
5796+ Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5797+
5798+ //
5799+ // Set FIB state to indicate where it came from and if we want a response from the
5800+ // adapter. Also load the command from the caller.
5801+ //
5802+
5803+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5804+ Fib->Header.Command = Command;
5805+ Fib->Header.XferState |= SentFromHost;
5806+ FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5807+
5808+ //
5809+ // Set the size of the Fib we want to send to the adapter
5810+ //
5811+
5812+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5813+ if (Fib->Header.Size > Fib->Header.SenderSize) {
5814+ return(STATUS_BUFFER_OVERFLOW);
5815+ }
5816+
5817+ //
5818+ // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5819+ //
5820+
5821+ if (Priority == FsaHigh) {
5822+ Fib->Header.XferState |= HighPriority;
5823+ WhichQueue = AdapHighCmdQueue;
5824+ OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5825+ } else {
5826+ Fib->Header.XferState |= NormalPriority;
5827+ WhichQueue = AdapNormCmdQueue;
5828+ OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5829+ }
5830+
5831+ if (Wait) {
5832+ OsCvLockAcquire( FibContext->FsaEventMutex );
5833+ }
5834+
5835+ if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5836+ return(STATUS_UNSUCCESSFUL);
5837+
5838+ // bmb debug
5839+
5840+ cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5841+ cmn_err (CE_DEBUG,"Fib contents:.\n");
5842+ cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5843+ cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5844+
5845+ //
5846+ // Fill in the Callback and CallbackContext if we are not going to wait.
5847+ //
5848+
5849+ if (!Wait) {
5850+
5851+ FibContext->FibCallback = FibCallback;
5852+ FibContext->FibCallbackContext = FibCallbackContext;
5853+
5854+ }
5855+
5856+ FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5857+
5858+ InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5859+ OurQueue->NumOutstandingIos++;
5860+
5861+ FibContext->FibComplete = 0;
5862+
5863+
5864+
5865+ if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5866+ return(STATUS_UNSUCCESSFUL);
5867+
5868+ //
5869+ // If the caller wanted us to wait for response wait now.
5870+ // If Timeouts are enabled than set the timeout otherwise wait forever.
5871+ //
5872+
5873+ if (Wait) {
5874+ while (FibContext->FibComplete == 0) {
5875+ OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5876+ }
5877+
5878+ OsCvLockRelease( FibContext->FsaEventMutex );
5879+
5880+ if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5881+ return(STATUS_IO_TIMEOUT);
5882+ } else {
5883+ return(STATUS_SUCCESS);
5884+ }
5885+ }
5886+
5887+ //
5888+ // If the user does not want a response than return success otherwise return pending
5889+ //
5890+
5891+ ASSERT( FibCallback );
5892+
5893+ if (ResponseExpected)
5894+ return(STATUS_PENDING);
5895+ else
5896+ return(STATUS_SUCCESS);
5897+}
5898+
5899+BOOLEAN
5900+GetConsumerEntry(
5901+ IN PAFA_COMM_ADAPTER Adapter,
5902+ PCOMM_QUE OurQueue,
5903+ OUT PQUEUE_ENTRY *Entry
5904+ )
5905+/*++
5906+
5907+Routine Description:
5908+
5909+ Will return a pointer to the entry on the top of the queue requested that we are a consumer
5910+ of, and return the address of the queue entry. It does not change the state of the queue.
5911+
5912+Arguments:
5913+
5914+ OurQueue - is the queue the queue entry should be removed from.
5915+
5916+ Entry - is a pointer where the address of the queue entry should be returned.
5917+
5918+Return Value:
5919+
5920+ TRUE if there was a queue entry on the response queue for the host to consume.
5921+ FALSE if there were no queue entries to consume.
5922+
5923+--*/
5924+
5925+{
5926+ QUEUE_INDEX Index;
5927+ BOOLEAN status;
5928+
5929+ if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5930+ status = FALSE;
5931+ } else {
5932+
5933+ //
5934+ // The consumer index must be wrapped if we have reached the end of
5935+ // the queue.
5936+ // Else we just use the entry pointed to by the header index
5937+ //
5938+
5939+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5940+ Index = 0;
5941+ else
5942+ Index = *OurQueue->Headers.ConsumerIndex;
5943+
5944+ *Entry = OurQueue->BaseAddress + Index;
5945+
5946+#ifdef commdebug
5947+ FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5948+#endif
5949+ status = TRUE;
5950+ }
5951+
5952+ return(status);
5953+}
5954+
5955+BOOLEAN
5956+ConsumerEntryAvailable(
5957+ IN PAFA_COMM_ADAPTER Adapter,
5958+ PCOMM_QUE OurQueue
5959+ )
5960+{
5961+ return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
5962+}
5963+
5964+VOID
5965+FreeConsumerEntry(
5966+ IN PAFA_COMM_ADAPTER Adapter,
5967+ PCOMM_QUE OurQueue,
5968+ QUEUE_TYPES WhichQueue
5969+ )
5970+/*++
5971+
5972+Routine Description:
5973+
5974+ Frees up the current top of the queue we are a consumer of. If the queue was full
5975+ notify the producer that the queue is no longer full.
5976+
5977+Arguments:
5978+
5979+ OurQueue - is the queue we will free the current consumer entry on.
5980+
5981+Return Value:
5982+
5983+ TRUE if there was a queue entry on the response queue for the host to consume.
5984+ FALSE if there were no queue entries to consume.
5985+
5986+--*/
5987+
5988+{
5989+ BOOLEAN WasFull = FALSE;
5990+ HOST_2_ADAP_EVENT Notify;
5991+
5992+ if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
5993+ WasFull = TRUE;
5994+
5995+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5996+ *OurQueue->Headers.ConsumerIndex = 1;
5997+ else
5998+ *OurQueue->Headers.ConsumerIndex += 1;
5999+
6000+ if (WasFull) {
6001+ switch (WhichQueue) {
6002+
6003+ case HostNormCmdQueue:
6004+ Notify = HostNormCmdNotFull;
6005+ break;
6006+ case HostHighCmdQueue:
6007+ Notify = HostHighCmdNotFull;
6008+ break;
6009+
6010+ case HostNormRespQueue:
6011+ Notify = HostNormRespNotFull;
6012+ break;
6013+
6014+ case HostHighRespQueue:
6015+ Notify = HostHighRespNotFull;
6016+ break;
6017+
6018+ }
6019+ NotifyAdapter(Adapter, Notify);
6020+ }
6021+
6022+}
6023+
6024+AAC_STATUS
6025+CompleteAdapterFib(
6026+ IN PFIB_CONTEXT Context,
6027+ IN USHORT Size
6028+ )
6029+/*++
6030+
6031+Routine Description:
6032+
6033+ Will do all necessary work to complete a FIB that was sent from the adapter.
6034+
6035+Arguments:
6036+
6037+ Fib is a pointer to the FIB that caller wishes to complete processing on.
6038+
6039+ Size - Size of the completion Packet(Opitional). If not present than the current
6040+ largest size in the Fib will be used
6041+
6042+ Adapter - Pointer to which adapter sent this FIB
6043+
6044+Return Value:
6045+
6046+ NT_SUCCESS if a Fib was returned to the caller.
6047+ NT_ERROR if event was an invalid event.
6048+
6049+--*/
6050+{
6051+ PCOMM_FIB_CONTEXT FibContext = Context;
6052+ PFIB Fib = FibContext->Fib;
6053+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6054+ ULONG DontInterrupt = FALSE;
6055+
6056+ if (Fib->Header.XferState == 0)
6057+ return(STATUS_SUCCESS);
6058+
6059+ //
6060+ // If we plan to do anything check the structure type first.
6061+ //
6062+
6063+ if ( Fib->Header.StructType != TFib ) {
6064+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6065+ return(STATUS_UNSUCCESSFUL);
6066+ }
6067+
6068+ //
6069+ // This block handles the case where the adapter had sent us a command and we
6070+ // have finished processing the command. We call completeFib when we are done
6071+ // processing the command and want to send a response back to the adapter. This
6072+ // will send the completed cdb to the adapter.
6073+ //
6074+
6075+ if (Fib->Header.XferState & SentFromAdapter) {
6076+ Fib->Header.XferState |= HostProcessed;
6077+ if (Fib->Header.XferState & HighPriority) {
6078+ QUEUE_INDEX Index;
6079+
6080+ if (Size) {
6081+ Size += sizeof(FIB_HEADER);
6082+ if (Size > Fib->Header.SenderSize)
6083+ return(STATUS_BUFFER_OVERFLOW);
6084+ Fib->Header.Size = Size;
6085+ }
6086+
6087+ if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6088+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6089+ return(FSA_FATAL);
6090+ }
6091+ if (InsertQueueEntry(Adapter,
6092+ Index,
6093+ AdapHighRespQueue,
6094+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6095+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6096+ }
6097+ } else if (Fib->Header.XferState & NormalPriority) {
6098+ QUEUE_INDEX Index;
6099+
6100+ if (Size) {
6101+ Size += sizeof(FIB_HEADER);
6102+ if (Size > Fib->Header.SenderSize)
6103+ return(STATUS_BUFFER_OVERFLOW);
6104+ Fib->Header.Size = Size;
6105+ }
6106+
6107+ if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6108+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6109+ return(FSA_FATAL);
6110+ }
6111+ if (InsertQueueEntry(Adapter,
6112+ Index,
6113+ AdapNormRespQueue,
6114+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6115+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6116+ }
6117+ }
6118+ } else {
6119+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6120+ FsaBugCheck(0,0,0);
6121+ }
6122+ return(STATUS_SUCCESS);
6123+}
6124+
6125+AAC_STATUS
6126+CompleteFib(
6127+ IN PFIB_CONTEXT Context
6128+ )
6129+/*++
6130+
6131+Routine Description:
6132+
6133+ Will do all necessary work to complete a FIB. If the caller wishes to
6134+ reuse the FIB after post processing has been completed Reinitialize
6135+ should be called set to TRUE, otherwise the FIB will be returned to the
6136+ free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6137+ reinitialzied and is ready for reuse on return from this routine.
6138+
6139+Arguments:
6140+
6141+ Fib is a pointer to the FIB that caller wishes to complete processing on.
6142+
6143+ Size - Size of the completion Packet(Opitional). If not present than the current
6144+ largest size in the Fib will be used
6145+
6146+ Reinitialize is a boolean which determines if the routine will ready the
6147+ completed FIB for reuse(TRUE) or not(FALSE).
6148+
6149+Return Value:
6150+
6151+ NT_SUCCESS if a Fib was returned to the caller.
6152+ NT_ERROR if event was an invalid event.
6153+
6154+--*/
6155+{
6156+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6157+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6158+ PFIB Fib = FibContext->Fib;
6159+
6160+ //
6161+ // Check for a fib which has already been completed
6162+ //
6163+
6164+// ASSERT(Fib->Header.XferState & AdapterProcessed);
6165+ if (Fib->Header.XferState == 0)
6166+ return(STATUS_SUCCESS);
6167+
6168+ //
6169+ // If we plan to do anything check the structure type first.
6170+ //
6171+
6172+ if ( Fib->Header.StructType != TFib ) {
6173+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6174+ return(STATUS_UNSUCCESSFUL);
6175+ }
6176+
6177+#if 0
6178+//#if FSA_ADAPTER_METER
6179+ //
6180+ // Meter the completion
6181+ //
6182+ fsaMeterEnd( // meter the end of an operation
6183+ &(Adapter->FibMeter), // .. the meter
6184+ IrpContext->FibMeterType, // .. type of operation
6185+ &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6186+ FibGetMeterSize(Fib, // .. number of bytes in operation
6187+ IrpContext->FibMeterType,
6188+ IrpContext->FibSubCommand));
6189+#endif // FSA_ADAPTER_METER
6190+
6191+ //
6192+ // This block completes a cdb which orginated on the host and we just need
6193+ // to deallocate the cdb or reinit it. At this point the command is complete
6194+ // that we had sent to the adapter and this cdb could be reused.
6195+ //
6196+
6197+ if ( (Fib->Header.XferState & SentFromHost) &&
6198+ (Fib->Header.XferState & AdapterProcessed)) {
6199+
6200+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6201+
6202+ return( DeallocateFib(FibContext) );
6203+
6204+ //
6205+ // This handles the case when the host has aborted the I/O to the
6206+ // adapter because the adapter is not responding
6207+ //
6208+
6209+ } else if (Fib->Header.XferState & SentFromHost) {
6210+
6211+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6212+
6213+
6214+ return( DeallocateFib(FibContext) );
6215+
6216+ } else if (Fib->Header.XferState & HostOwned) {
6217+
6218+ return(DeallocateFib(FibContext));
6219+
6220+ } else {
6221+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6222+ FsaBugCheck(0,0,0);
6223+ }
6224+ return(STATUS_SUCCESS);
6225+}
6226+
6227+VOID
6228+HandleDriverAif(
6229+ IN PAFA_COMM_ADAPTER Adapter,
6230+ IN PCOMM_FIB_CONTEXT FibContext
6231+ )
6232+/*++
6233+
6234+Routine Description:
6235+
6236+ This routine handles a driver notify fib from the adapter and dispatches it to
6237+ the appropriate routine for handling.
6238+
6239+Arguments:
6240+
6241+ Adapter - Which adapter this fib is from
6242+ FibContext - Pointer to FibContext from adapter.
6243+
6244+Return Value:
6245+
6246+ Nothing.
6247+
6248+--*/
6249+{
6250+ PFIB Fib = FibContext->Fib;
6251+ PAFA_CLASS_DRIVER ClassDriver;
6252+ BOOLEAN Handled = FALSE;
6253+
6254+
6255+ //
6256+ // First loop through all of the class drivers to give them a chance to handle
6257+ // the Fib.
6258+ //
6259+
6260+ ClassDriver = Adapter->ClassDriverList;
6261+
6262+ while (ClassDriver) {
6263+
6264+ if (ClassDriver->HandleAif) {
6265+
6266+ if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6267+
6268+ Handled = TRUE;
6269+ break;
6270+
6271+ }
6272+ }
6273+
6274+ ClassDriver = ClassDriver->Next;
6275+ }
6276+
6277+ if (!Handled) {
6278+
6279+ //
6280+ // Set the status of this FIB to be Invalid parameter.
6281+ //
6282+
6283+// *(FSASTATUS *)Fib->data = ST_INVAL;
6284+ *(FSASTATUS *)Fib->data = ST_OK;
6285+
6286+
6287+ CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6288+
6289+ }
6290+}
6291+
6292+int
6293+NormCommandThread(
6294+ IN PAFA_COMM_ADAPTER Adapter
6295+ )
6296+/*++
6297+
6298+Routine Description:
6299+
6300+ Waits on the commandready event in it's queue. When the event gets set it will
6301+ pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6302+ When the queue is empty it will wait for more FIBs.
6303+
6304+Arguments:
6305+
6306+ Context is used. All data os global
6307+
6308+Return Value:
6309+ Nothing.
6310+
6311+--*/
6312+{
6313+ PFIB Fib, NewFib;
6314+ COMM_FIB_CONTEXT FibContext; // for error logging
6315+ KIRQL SavedIrql;
6316+ PCOMM_REGION CommRegion = Adapter->CommRegion;
6317+ PLIST_ENTRY Entry;
6318+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6319+
6320+ //
6321+ // We can only have one thread per adapter for AIF's.
6322+ //
6323+
6324+ if (Adapter->AifThreadStarted) {
6325+ return (EINVAL);
6326+ }
6327+
6328+// cmn_err(CE_DEBUG, "AIF thread started");
6329+
6330+ //
6331+ // Let the DPC know it has a place to send the AIF's to.
6332+ //
6333+
6334+ Adapter->AifThreadStarted = TRUE;
6335+
6336+ RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6337+
6338+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6339+
6340+ while (TRUE) {
6341+
6342+ //
6343+ // NOTE : the QueueLock is held at the top of each loop.
6344+ //
6345+
6346+ ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6347+
6348+ while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6349+ PLIST_ENTRY Entry;
6350+ PAIFCOMMANDTOHOST AifCommandToHost;
6351+
6352+ Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6353+
6354+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6355+
6356+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6357+
6358+ //
6359+ // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6360+ // can't do anything at this point since we don't have anything defined for this thread to
6361+ // do.
6362+ //
6363+
6364+ // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6365+
6366+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6367+
6368+
6369+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6370+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6371+ FibContext.Fib = Fib;
6372+ FibContext.FibData = Fib->data;
6373+ FibContext.Adapter = Adapter;
6374+
6375+
6376+ //
6377+ // We only handle AifRequest fibs from the adapter.
6378+ //
6379+
6380+ ASSERT(Fib->Header.Command == AifRequest);
6381+
6382+
6383+ AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6384+
6385+ if (AifCommandToHost->command == AifCmdDriverNotify) {
6386+
6387+
6388+
6389+ HandleDriverAif( Adapter, &FibContext );
6390+
6391+ } else {
6392+ AAC_UINT32 time_now, time_last;
6393+ time_now = (AAC_UINT32)OsGetSeconds();
6394+
6395+
6396+ OsCvLockAcquire(Adapter->AdapterFibMutex);
6397+
6398+ Entry = Adapter->AdapterFibContextList.Flink;
6399+
6400+ //
6401+ // For each Context that is on the AdapterFibContextList, make a copy of the
6402+ // fib, and then set the event to wake up the thread that is waiting for it.
6403+ //
6404+
6405+ while (Entry != &Adapter->AdapterFibContextList) {
6406+
6407+ //
6408+ // Extract the AdapterFibContext
6409+ //
6410+
6411+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6412+
6413+ //
6414+ // Check if the queue is getting backlogged
6415+ //
6416+ if ( AdapterFibContext->FibCount > 20 ) {
6417+ time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6418+
6419+ //
6420+ // has it been > 2 minutes since the last read off the queue?
6421+ //
6422+ if ((time_now - time_last) > 120) {
6423+ Entry = Entry->Flink;
6424+ // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6425+ // time_now - time_last,
6426+ // AdapterFibContext->FibCount);
6427+ FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6428+ continue;
6429+ }
6430+ }
6431+
6432+// Warning: sleep possible while holding spinlock
6433+ NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6434+
6435+ if (NewFib) {
6436+
6437+ //
6438+ // Make the copy of the FIB
6439+ //
6440+
6441+ RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6442+
6443+ //
6444+ // Put the FIB onto the AdapterFibContext's FibList
6445+ //
6446+
6447+ InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6448+ AdapterFibContext->FibCount++;
6449+
6450+ //
6451+ // Set the event to wake up the thread that will waiting.
6452+ //
6453+
6454+ OsCv_signal(&AdapterFibContext->UserEvent);
6455+
6456+ } else {
6457+
6458+
6459+ }
6460+
6461+ Entry = Entry->Flink;
6462+ }
6463+
6464+ //
6465+ // Set the status of this FIB
6466+ //
6467+
6468+ *(FSASTATUS *)Fib->data = ST_OK;
6469+
6470+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6471+
6472+ OsCvLockRelease(Adapter->AdapterFibMutex);
6473+
6474+ }
6475+
6476+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6477+
6478+ }
6479+
6480+ //
6481+ // There are no more AIF's, call cv_wait_sig to wait for more
6482+ // to process.
6483+ //
6484+
6485+ // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6486+
6487+ if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6488+ CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6489+
6490+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6491+
6492+ Adapter->AifThreadStarted = FALSE;
6493+
6494+ // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6495+
6496+ return (EINTR);
6497+
6498+ }
6499+
6500+ // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6501+
6502+ }
6503+}
6504+
6505+
6506+PVOID
6507+FsaGetFibData(
6508+ IN PFIB_CONTEXT Context
6509+ )
6510+{
6511+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6512+
6513+ return ((PVOID)FibContext->Fib->data);
6514+}
6515+
6516+
6517+#ifdef API_THROTTLE
6518+
6519+void ThrottlePeriodEndDpcRtn(
6520+ IN PKDPC Dpc,
6521+ IN PVOID DeferredContext,
6522+ IN PVOID SystemArgument1,
6523+ IN PVOID SystemArgument2
6524+ )
6525+/*++
6526+
6527+Routine Description:
6528+
6529+ This routine is called as a DPC when a throttle period expires. It
6530+ restarts all threads suspended due to the throttling flow control.
6531+
6532+ The throttling counted semaphore is signalled for all waiting threads
6533+ and the indicator of throttling active is cleared.
6534+
6535+Arguments:
6536+
6537+ Dpc - Pointer to Dpc structure. Not used.
6538+ DefferedContext - Pointer to per-adapter context. This is used to locate the
6539+ throttle information for this adapter.
6540+ SystemArgument1 - Not used
6541+ SystemArgument2 - Not used
6542+
6543+Return Value:
6544+
6545+ None.
6546+
6547+--*/
6548+{
6549+ PCOMM_REGION CommRegion;
6550+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6551+
6552+ CommRegion = Adapter->CommRegion;
6553+
6554+ //
6555+ // Acquire the spinlock protecting the throttle status.
6556+ //
6557+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6558+
6559+ FsaCommPrint("ThrottlePeriodEndDpc\n");
6560+
6561+ //
6562+ // Check that the timer has fired as many times as it was set !
6563+ //
6564+
6565+ CommRegion->ThrottleTimerFires++;
6566+ ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6567+
6568+ //
6569+ // The throttle period is now over. Restart all threads waiting
6570+ // on the throttle being released.
6571+ // Clear the throttle active indicator. This will allow new FIBs
6572+ // to be sent to the adapter once we release the spinlock on exiting
6573+ // the DPC. This means all restarted threads will be runnable
6574+ // threads by then.
6575+ //
6576+
6577+ ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6578+ CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6579+
6580+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6581+}
6582+
6583+#endif // #ifdef API_THROTTLE
6584+
6585+/*
6586+ * Overrides for Emacs so that we almost follow Linus's tabbing style.
6587+ * Emacs will notice this stuff at the end of the file and automatically
6588+ * adjust the settings for this buffer only. This must remain at the end
6589+ * of the file.
6590+ * ---------------------------------------------------------------------------
6591+ * Local variables:
6592+ * c-indent-level: 4
6593+ * c-brace-imaginary-offset: 0
6594+ * c-brace-offset: -4
6595+ * c-argdecl-indent: 4
6596+ * c-label-offset: -4
6597+ * c-continued-statement-offset: 4
6598+ * c-continued-brace-offset: 0
6599+ * indent-tabs-mode: nil
6600+ * tab-width: 8
6601+ * End:
6602+ */
6603diff -burN linux-2.4.4/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6604--- linux-2.4.4/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 18:00:00 1969
6605+++ linux/drivers/scsi/aacraid/dpcsup.c Mon Apr 30 09:43:34 2001
6606@@ -0,0 +1,443 @@
6607+/*++
6608+ * Adaptec aacraid device driver for Linux.
6609+ *
6610+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6611+ *
6612+ * This program is free software; you can redistribute it and/or modify
6613+ * it under the terms of the GNU General Public License as published by
6614+ * the Free Software Foundation; either version 2, or (at your option)
6615+ * any later version.
6616+ *
6617+ * This program is distributed in the hope that it will be useful,
6618+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6619+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6620+ * GNU General Public License for more details.
6621+ *
6622+ * You should have received a copy of the GNU General Public License
6623+ * along with this program; see the file COPYING. If not, write to
6624+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6625+ *
6626+ * Module Name:
6627+ * dpcsup.c
6628+ *
6629+ * Abstract: All DPC processing routines for the cyclone board occur here.
6630+ *
6631+ *
6632+ --*/
6633+
6634+static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6635+
6636+#include "comprocs.h"
6637+
6638+
6639+//
6640+// The Bug check file id for this module
6641+//
6642+
6643+#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6644+
6645+#define Dbg (DEBUG_TRACE_DPCSUP)
6646+
6647+u_int
6648+CommonNotFullDpc(
6649+ IN PCOMM_REGION CommRegion
6650+ )
6651+/*++
6652+
6653+Routine Description:
6654+
6655+ This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6656+ no longer full. The Isr will pass the queue that we will set the not full event.
6657+
6658+Arguments:
6659+
6660+ Dpc - Pointer to this routine.
6661+
6662+ Dummy - is a pointer to the comm region which is global so we don't need it anyway
6663+
6664+ Queue is a pointer to the queue structure we will operate on.
6665+
6666+ MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6667+ stuff in here.
6668+
6669+Return Value:
6670+ Nothing.
6671+
6672+--*/
6673+{
6674+
6675+#ifdef unix_queue_full
6676+ KeSetEvent(&Queue->QueueFull, 0, FALSE);
6677+#endif
6678+
6679+}
6680+
6681+int GatherFibTimes = 0;
6682+
6683+// XXX - hack this in until I figure out which header file should contain it. <smb>
6684+extern ULONG
6685+FibGetMeterSize(
6686+ PFIB pFib,
6687+ ULONG MeterType,
6688+ char SubCommand
6689+ );
6690+
6691+
6692+/*++
6693+
6694+Routine Description:
6695+
6696+ This DPC routine will be queued when the adapter interrupts us to let us know there
6697+ is a response on our normal priority queue. We will pull off all QE there are and wake
6698+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6699+ on it.
6700+
6701+Arguments:
6702+
6703+ Dpc - Pointer to this routine.
6704+
6705+ OurQueue is a pointer to the queue structure we will operate on.
6706+
6707+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6708+ stuff in here.
6709+
6710+Return Value:
6711+ Nothing.
6712+
6713+--*/
6714+u_int
6715+HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6716+{
6717+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6718+ PQUEUE_ENTRY QueueEntry;
6719+ PFIB Fib;
6720+ PCOMM_FIB_CONTEXT FibContext;
6721+ int Consumed = 0;
6722+ KIRQL OldIrql;
6723+
6724+ LARGE_INTEGER ResponseAllocSize;
6725+
6726+#ifdef commdebug
6727+ FsaCommPrint("entering the host normal reponse dpc routine.\n");
6728+#endif
6729+
6730+ OsSpinLockAcquire( OurQueue->QueueLock );
6731+
6732+ //
6733+ // Keep pulling response QEs off the response queue and waking
6734+ // up the waiters until there are no more QEs. We then return
6735+ // back to the system. If no response was requesed we just
6736+ // deallocate the Fib here and continue.
6737+ //
6738+
6739+ loop:
6740+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6741+
6742+ int IsFastResponse;
6743+
6744+ IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6745+ Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6746+
6747+ FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6748+
6749+ FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6750+
6751+ ASSERT(FibContext->Fib == Fib);
6752+
6753+ //
6754+ // Remove this FibContext from the Outstanding I/O queue.
6755+ // But only if it has not already been timed out.
6756+ //
6757+ // If the fib has been timed out already, then just continue.
6758+ // The caller has already been notified that the fib timed out.
6759+ //
6760+
6761+ if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6762+
6763+ RemoveEntryList( &FibContext->QueueEntry );
6764+ Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6765+
6766+ } else {
6767+
6768+ FsaCommLogEvent(FibContext,
6769+ FsaCommData.DeviceObject,
6770+ FSAFS_TIMED_OUT_FIB_COMPLETED,
6771+ STATUS_UNSUCCESSFUL,
6772+ BugCheckFileId | __LINE__,
6773+ FACILITY_FSAFS_ERROR_CODE,
6774+ NULL,
6775+ TRUE);
6776+
6777+ continue;
6778+
6779+ }
6780+
6781+ OsSpinLockRelease( OurQueue->QueueLock );
6782+
6783+ if (IsFastResponse) {
6784+
6785+ //
6786+ // doctor the fib
6787+ //
6788+
6789+ *(FSASTATUS *)Fib->data = ST_OK;
6790+
6791+ Fib->Header.XferState |= AdapterProcessed;
6792+
6793+ }
6794+
6795+ ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6796+
6797+ FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6798+
6799+ ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6800+
6801+
6802+ if (Fib->Header.Command == NuFileSystem) {
6803+
6804+ FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6805+
6806+ if (*pStatus & 0xffff0000) {
6807+
6808+ ULONG Hint = *pStatus;
6809+
6810+ *pStatus = ST_OK;
6811+
6812+/*
6813+ DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6814+ IrpContext->NonPaged->FileId.fid_driveno,
6815+ IrpContext->NonPaged->FileId.fid_f1,
6816+ IrpContext->NonPaged->FileId.fid_f2,
6817+ IrpContext->NonPaged->FileId.fid_hint,
6818+ Hint);
6819+*/
6820+
6821+ }
6822+
6823+ }
6824+
6825+ if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6826+
6827+ ASSERT(FibContext->FibCallback);
6828+
6829+ if (Fib->Header.XferState & NoResponseExpected)
6830+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6831+ else
6832+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6833+
6834+ //
6835+ // NOTE: we can not touch the FibContext after this call, because it may have been
6836+ // deallocated.
6837+ //
6838+
6839+ FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6840+
6841+ } else {
6842+
6843+ OsCvLockAcquire( FibContext->FsaEventMutex);
6844+
6845+ FibContext->FibComplete = 1;
6846+
6847+ OsCv_signal( &FibContext->FsaEvent );
6848+
6849+ OsCvLockRelease( FibContext->FsaEventMutex );
6850+
6851+ FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6852+
6853+ }
6854+
6855+
6856+ Consumed++;
6857+
6858+ OsSpinLockAcquire( OurQueue->QueueLock );
6859+
6860+ }
6861+
6862+ if (Consumed > FsaCommData.PeakFibsConsumed)
6863+ FsaCommData.PeakFibsConsumed = Consumed;
6864+
6865+ if (Consumed == 0)
6866+ FsaCommData.ZeroFibsConsumed++;
6867+
6868+ if (FsaCommData.HardInterruptModeration) {
6869+
6870+ //
6871+ // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6872+ // been put on the queue. This removes the race condition that exists between the
6873+ // last time we checked the queue, and when we re-enabled the interrupt.
6874+ //
6875+ // If there is something on the queue, then go handle it.
6876+ //
6877+
6878+ EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6879+
6880+ if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6881+
6882+ DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6883+
6884+ goto loop;
6885+
6886+ }
6887+ }
6888+
6889+#ifdef commdebug
6890+ FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6891+#endif
6892+
6893+ OsSpinLockRelease( OurQueue->QueueLock );
6894+
6895+}
6896+
6897+/*++
6898+
6899+Routine Description:
6900+
6901+ This DPC routine wiol be queued when the adapter interrupts us to let us know there
6902+ is a response on our high priority queue. We will pull off all QE there are and wake
6903+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6904+ on it.
6905+
6906+Arguments:
6907+
6908+ Dpc - Pointer to this routine.
6909+
6910+ OurQueue is a pointer to the queue structure we will operate on.
6911+
6912+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6913+ stuff in here.
6914+
6915+Return Value:
6916+ Nothing.
6917+
6918+--*/
6919+u_int
6920+HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6921+{}
6922+
6923+
6924+/*++
6925+
6926+Routine Description:
6927+
6928+ This DPC routine will be queued when the adapter interrupts us to let us know there
6929+ is a command on our high priority queue. We will pull off all QE there are and wake
6930+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6931+ on it.
6932+
6933+Arguments:
6934+
6935+ Dpc - Pointer to this routine.
6936+
6937+ OurQueue is a pointer to the queue structure we will operate on.
6938+
6939+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6940+ stuff in here.
6941+
6942+Return Value:
6943+ Nothing.
6944+
6945+--*/
6946+u_int
6947+HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6948+{}
6949+
6950+
6951+/*++
6952+
6953+Routine Description:
6954+
6955+ This DPC routine will be queued when the adapter interrupts us to let us know there
6956+ is a command on our normal priority queue. We will pull off all QE there are and wake
6957+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6958+ on it.
6959+
6960+Arguments:
6961+
6962+ Dpc - Pointer to this routine.
6963+
6964+ OurQueue is a pointer to the queue structure we will operate on.
6965+
6966+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6967+ stuff in here.
6968+
6969+Return Value:
6970+ Nothing.
6971+
6972+--*/
6973+u_int
6974+HostCommandNormDpc (IN PCOMM_QUE OurQueue)
6975+{
6976+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6977+ PQUEUE_ENTRY QueueEntry;
6978+
6979+ OsSpinLockAcquire( OurQueue->QueueLock );
6980+
6981+ //
6982+ // Keep pulling response QEs off the response queue and waking
6983+ // up the waiters until there are no more QEs. We then return
6984+ // back to the system.
6985+ //
6986+
6987+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6988+
6989+ PFIB Fib;
6990+
6991+ Fib = (PFIB)QueueEntry->FibAddress;
6992+
6993+
6994+ if (Adapter->AifThreadStarted) {
6995+
6996+
6997+// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
6998+
6999+
7000+ InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7001+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7002+ OsCv_signal(&OurQueue->CommandReady);
7003+
7004+
7005+
7006+ } else {
7007+
7008+
7009+
7010+ COMM_FIB_CONTEXT FibContext;
7011+
7012+
7013+
7014+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7015+
7016+
7017+
7018+ OsSpinLockRelease( OurQueue->QueueLock );
7019+
7020+
7021+
7022+// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7023+
7024+
7025+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7026+
7027+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7028+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7029+ FibContext.Fib = Fib;
7030+ FibContext.FibData = Fib->data;
7031+ FibContext.Adapter = Adapter;
7032+
7033+ //
7034+ // Set the status of this FIB
7035+ //
7036+
7037+ *(FSASTATUS *)Fib->data = ST_OK;
7038+
7039+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7040+
7041+
7042+
7043+ OsSpinLockAcquire( OurQueue->QueueLock );
7044+ }
7045+ }
7046+
7047+ OsSpinLockRelease( OurQueue->QueueLock );
7048+
7049+}
7050diff -burN linux-2.4.4/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7051--- linux-2.4.4/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 18:00:00 1969
7052+++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Mon Apr 30 09:43:34 2001
7053@@ -0,0 +1,57 @@
7054+/*++
7055+ * Adaptec aacraid device driver for Linux.
7056+ *
7057+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7058+ *
7059+ * This program is free software; you can redistribute it and/or modify
7060+ * it under the terms of the GNU General Public License as published by
7061+ * the Free Software Foundation; either version 2, or (at your option)
7062+ * any later version.
7063+ *
7064+ * This program is distributed in the hope that it will be useful,
7065+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7066+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7067+ * GNU General Public License for more details.
7068+ *
7069+ * You should have received a copy of the GNU General Public License
7070+ * along with this program; see the file COPYING. If not, write to
7071+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7072+ *
7073+ * Module Name:
7074+ *
7075+ * AacGenericTypes.h
7076+ *
7077+ * Abstract:
7078+ *
7079+ * The module defines the generic data types that all of the other header files
7080+ * depend upon.
7081+ --*/
7082+
7083+#ifndef _AAC_GENERIC_TYPES
7084+#define _AAC_GENERIC_TYPES
7085+
7086+static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7087+
7088+typedef char AAC_INT8, *PAAC_INT8;
7089+typedef short AAC_INT16, *PAAC_INT16;
7090+typedef int AAC_INT32, *PAAC_INT32;
7091+typedef long long AAC_INT64, *PAAC_INT64;
7092+
7093+typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7094+typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7095+typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7096+typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7097+
7098+typedef void AAC_VOID, *PAAC_VOID;
7099+
7100+//
7101+// this compiler uses 32 bit enum data types
7102+//
7103+
7104+#define AAC_32BIT_ENUMS 1
7105+#define FAILURE 1
7106+#define INTR_UNCLAIMED 1
7107+#define INTR_CLAIMED 0
7108+
7109+#endif // _AAC_GENERIC_TYPES
7110+
7111diff -burN linux-2.4.4/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7112--- linux-2.4.4/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 18:00:00 1969
7113+++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Mon Apr 30 09:43:34 2001
7114@@ -0,0 +1,300 @@
7115+/*++
7116+ * Adaptec aacraid device driver for Linux.
7117+ *
7118+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7119+ *
7120+ * This program is free software; you can redistribute it and/or modify
7121+ * it under the terms of the GNU General Public License as published by
7122+ * the Free Software Foundation; either version 2, or (at your option)
7123+ * any later version.
7124+ *
7125+ * This program is distributed in the hope that it will be useful,
7126+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7127+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7128+ * GNU General Public License for more details.
7129+ *
7130+ * You should have received a copy of the GNU General Public License
7131+ * along with this program; see the file COPYING. If not, write to
7132+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7133+ *
7134+ * Module Name:
7135+ *
7136+ * aac_unix_defs.h
7137+ *
7138+ * Abstract:
7139+ *
7140+ * Macro definition and typedefs
7141+ *
7142+ --*/
7143+
7144+#ifndef _AAC_UNIX_DEFS
7145+#define _AAC_UNIX_DEFS
7146+
7147+static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7148+
7149+#define AAC_MAX_ADAPTERS 64
7150+
7151+#ifndef TRUE
7152+#define TRUE 1
7153+#define FALSE 0
7154+#endif
7155+
7156+#define PAGE_SIZE 4096
7157+
7158+typedef void VOID;
7159+typedef VOID *PVOID;
7160+
7161+typedef char CHAR, *PCHAR;
7162+typedef unsigned char UCHAR, *PUCHAR;
7163+typedef short SHORT, *PSHORT;
7164+typedef short CSHORT, *PCSHORT;
7165+typedef unsigned short USHORT, *PUSHORT;
7166+typedef unsigned long ULONG, *PULONG;
7167+typedef long LONG, *PLONG;
7168+
7169+typedef unsigned long BOOLEAN;
7170+
7171+typedef unsigned long AAC_STATUS, *PNT_STATUS;
7172+
7173+typedef struct {
7174+ unsigned long LowPart;
7175+ unsigned long HighPart;
7176+} LARGE_INTEGER;
7177+
7178+typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7179+
7180+
7181+typedef struct _AFA_IOCTL_CMD {
7182+ int cmd;
7183+ intptr_t arg;
7184+ int flag;
7185+ cred_t *cred_p;
7186+ int *rval_p;
7187+} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7188+
7189+
7190+//
7191+// Singly linked list structure. Can be used as either a list head, or
7192+// as link words.
7193+//
7194+
7195+typedef struct _SINGLE_LIST_ENTRY {
7196+ struct _SINGLE_LIST_ENTRY *Next;
7197+} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7198+
7199+
7200+//
7201+// Calculate the address of the base of the structure given its type, and an
7202+// address of a field within the structure.
7203+//
7204+
7205+#define CONTAINING_RECORD(address, type, field) ((type *)( \
7206+ (PCHAR)(address) - \
7207+ (PCHAR)(&((type *)0)->field)))
7208+
7209+typedef PVOID PMDL;
7210+typedef PVOID PDEVICE_OBJECT;
7211+typedef PVOID PADAPTER_OBJECT;
7212+typedef ULONG KIRQL;
7213+typedef PVOID HANDLE;
7214+typedef PVOID KDPC, *PKDPC;
7215+typedef PVOID PFILE_OBJECT;
7216+typedef PVOID PIRP;
7217+typedef PVOID PDRIVER_OBJECT;
7218+typedef ULONG KTIMER;
7219+
7220+
7221+#define STATUS_SUCCESS 0x00000000
7222+#define STATUS_PENDING 0x40000001
7223+#define STATUS_IO_TIMEOUT 0xc0000001
7224+#define STATUS_UNSUCCESSFUL 0xc0000002
7225+#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7226+#define STATUS_BUFFER_OVERFLOW 0xc0000003
7227+
7228+
7229+#define OUT
7230+
7231+
7232+
7233+typedef u_int
7234+(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7235+
7236+//
7237+// Zone Allocation
7238+//
7239+
7240+typedef struct _ZONE_SEGMENT_HEADER {
7241+ SINGLE_LIST_ENTRY SegmentList;
7242+ PVOID Reserved;
7243+} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7244+
7245+typedef struct _ZONE_HEADER {
7246+ SINGLE_LIST_ENTRY FreeList;
7247+ SINGLE_LIST_ENTRY SegmentList;
7248+ ULONG BlockSize;
7249+ ULONG TotalSegmentSize;
7250+} ZONE_HEADER, *PZONE_HEADER;
7251+
7252+
7253+//++
7254+//
7255+// PVOID
7256+// ExAllocateFromZone(
7257+// IN PZONE_HEADER Zone
7258+// )
7259+//
7260+// Routine Description:
7261+//
7262+// This routine removes an entry from the zone and returns a pointer to it.
7263+//
7264+// Arguments:
7265+//
7266+// Zone - Pointer to the zone header controlling the storage from which the
7267+// entry is to be allocated.
7268+//
7269+// Return Value:
7270+//
7271+// The function value is a pointer to the storage allocated from the zone.
7272+//
7273+//--
7274+
7275+#define ExAllocateFromZone(Zone) \
7276+ (PVOID)((Zone)->FreeList.Next); \
7277+ if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7278+
7279+//++
7280+//
7281+// PVOID
7282+// ExFreeToZone(
7283+// IN PZONE_HEADER Zone,
7284+// IN PVOID Block
7285+// )
7286+//
7287+// Routine Description:
7288+//
7289+// This routine places the specified block of storage back onto the free
7290+// list in the specified zone.
7291+//
7292+// Arguments:
7293+//
7294+// Zone - Pointer to the zone header controlling the storage to which the
7295+// entry is to be inserted.
7296+//
7297+// Block - Pointer to the block of storage to be freed back to the zone.
7298+//
7299+// Return Value:
7300+//
7301+// Pointer to previous block of storage that was at the head of the free
7302+// list. NULL implies the zone went from no available free blocks to
7303+// at least one free block.
7304+//
7305+//--
7306+
7307+#define ExFreeToZone(Zone,Block) \
7308+ ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7309+ (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7310+ ((PSINGLE_LIST_ENTRY)(Block))->Next \
7311+ )
7312+
7313+//++
7314+//
7315+// BOOLEAN
7316+// ExIsFullZone(
7317+// IN PZONE_HEADER Zone
7318+// )
7319+//
7320+// Routine Description:
7321+//
7322+// This routine determines if the specified zone is full or not. A zone
7323+// is considered full if the free list is empty.
7324+//
7325+// Arguments:
7326+//
7327+// Zone - Pointer to the zone header to be tested.
7328+//
7329+// Return Value:
7330+//
7331+// TRUE if the zone is full and FALSE otherwise.
7332+//
7333+//--
7334+
7335+#define ExIsFullZone(Zone) \
7336+ ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7337+
7338+
7339+#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7340+#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7341+
7342+//
7343+// Doubly-linked list manipulation routines. Implemented as macros
7344+// but logically these are procedures.
7345+//
7346+
7347+//
7348+// VOID
7349+// InitializeListHead(
7350+// PLIST_ENTRY ListHead
7351+// );
7352+//
7353+
7354+#define InitializeListHead(ListHead) (\
7355+ (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7356+
7357+//
7358+// BOOLEAN
7359+// IsListEmpty(
7360+// PLIST_ENTRY ListHead
7361+// );
7362+//
7363+
7364+#define IsListEmpty(ListHead) \
7365+ ((ListHead)->Flink == (ListHead))
7366+
7367+//
7368+// PLIST_ENTRY
7369+// RemoveHeadList(
7370+// PLIST_ENTRY ListHead
7371+// );
7372+//
7373+
7374+#define RemoveHeadList(ListHead) \
7375+ (ListHead)->Flink;\
7376+ {RemoveEntryList((ListHead)->Flink)}
7377+
7378+
7379+//
7380+// VOID
7381+// RemoveEntryList(
7382+// PLIST_ENTRY Entry
7383+// );
7384+//
7385+
7386+#define RemoveEntryList(Entry) {\
7387+ PLIST_ENTRY _EX_Blink;\
7388+ PLIST_ENTRY _EX_Flink;\
7389+ _EX_Flink = (Entry)->Flink;\
7390+ _EX_Blink = (Entry)->Blink;\
7391+ _EX_Blink->Flink = _EX_Flink;\
7392+ _EX_Flink->Blink = _EX_Blink;\
7393+ }
7394+
7395+//
7396+// VOID
7397+// InsertTailList(
7398+// PLIST_ENTRY ListHead,
7399+// PLIST_ENTRY Entry
7400+// );
7401+//
7402+
7403+#define InsertTailList(ListHead,Entry) {\
7404+ PLIST_ENTRY _EX_Blink;\
7405+ PLIST_ENTRY _EX_ListHead;\
7406+ _EX_ListHead = (ListHead);\
7407+ _EX_Blink = _EX_ListHead->Blink;\
7408+ (Entry)->Flink = _EX_ListHead;\
7409+ (Entry)->Blink = _EX_Blink;\
7410+ _EX_Blink->Flink = (Entry);\
7411+ _EX_ListHead->Blink = (Entry);\
7412+ }
7413+
7414+#endif /* AAC_UNIX_DEFS */
7415diff -burN linux-2.4.4/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7416--- linux-2.4.4/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 18:00:00 1969
7417+++ linux/drivers/scsi/aacraid/include/adapter.h Mon Apr 30 09:43:34 2001
7418@@ -0,0 +1,164 @@
7419+/*++
7420+ * Adaptec aacraid device driver for Linux.
7421+ *
7422+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7423+ *
7424+ * This program is free software; you can redistribute it and/or modify
7425+ * it under the terms of the GNU General Public License as published by
7426+ * the Free Software Foundation; either version 2, or (at your option)
7427+ * any later version.
7428+ *
7429+ * This program is distributed in the hope that it will be useful,
7430+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7431+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7432+ * GNU General Public License for more details.
7433+ *
7434+ * You should have received a copy of the GNU General Public License
7435+ * along with this program; see the file COPYING. If not, write to
7436+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7437+ *
7438+ * Module Name:
7439+ *
7440+ * Adapter.h
7441+ *
7442+ * Abstract:
7443+ * The module contains the definitions for a comm layer view of the adapter.
7444+ *
7445+ *
7446+ *
7447+ --*/
7448+
7449+#ifndef _ADAPTER_
7450+#define _ADAPTER_
7451+
7452+static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7453+
7454+typedef struct _GET_ADAPTER_FIB_CONTEXT {
7455+
7456+ NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7457+ NODE_BYTE_SIZE NodeByteSize;
7458+ PFILE_OBJECT FileObject; // used for cleanup
7459+ LIST_ENTRY NextContext; // used to link context's into a linked list
7460+ OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7461+ BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7462+ ULONG FibCount; // total number of FIBs on FibList
7463+ LIST_ENTRY FibList;
7464+} GET_ADAPTER_FIB_CONTEXT;
7465+typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7466+
7467+
7468+typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7469+
7470+ struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7471+ ULONG FibContextSegmentSize;
7472+ PVOID FibContextSegment;
7473+ ULONG ExtendSize;
7474+ MAPFIB_CONTEXT MapFibContext;
7475+
7476+} FIB_CONTEXT_ZONE_SEGMENT;
7477+typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7478+
7479+typedef struct _AFA_COMM_ADAPTER {
7480+
7481+ struct _AFA_COMM_ADAPTER *NextAdapter;
7482+
7483+ //
7484+ // The following fields are used to allocate FIB context structures
7485+ // using the zone allocator, and other fixed sized structures from a
7486+ // small cache. The mutex protects access to the zone/lists
7487+ //
7488+
7489+ ZONE_HEADER FibContextZone;
7490+ OS_SPINLOCK *FibContextZoneSpinLock;
7491+ int FibContextZoneExtendSize;
7492+
7493+ PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7494+
7495+ PVOID FibContextTimedOutList;
7496+
7497+ PFIB SyncFib;
7498+ ULONG SyncFibPhysicalAddress;
7499+
7500+ PCOMM_REGION CommRegion;
7501+
7502+ OS_SPINLOCK_COOKIE SpinLockCookie;
7503+
7504+ //
7505+ // The user API will use an IOCTL to register itself to receive FIBs
7506+ // from the adapter. The following list is used to keep track of all
7507+ // the threads that have requested these FIBs. The mutex is used to
7508+ // synchronize access to all data associated with the adapter fibs.
7509+ //
7510+ LIST_ENTRY AdapterFibContextList;
7511+ OS_CVLOCK *AdapterFibMutex;
7512+
7513+ //
7514+ // The following holds which FileObject is allow to send configuration
7515+ // commands to the adapter that would modify the configuration.
7516+ //
7517+ // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7518+ // ioctls.
7519+ //
7520+ PFILE_OBJECT AdapterConfigFileObject;
7521+
7522+ //
7523+ // The following is really here because of the simulator
7524+ //
7525+ BOOLEAN InterruptsBelowDpc;
7526+
7527+ //
7528+ // The following is the device specific extension.
7529+ //
7530+ PVOID AdapterExtension;
7531+ PFSAPORT_FUNCS AdapterFuncs;
7532+ void *Dip;
7533+
7534+ //
7535+ // The following are user variables that are specific to the mini port.
7536+ //
7537+ PFSA_USER_VAR AdapterUserVars;
7538+ ULONG AdapterUserVarsSize;
7539+
7540+ //
7541+ // The following is the number of the individual adapter..i.e. \Device\Afa0
7542+ //
7543+ LONG AdapterNumber;
7544+
7545+ AFACOMM_FUNCS CommFuncs;
7546+
7547+ PAFA_CLASS_DRIVER ClassDriverList;
7548+
7549+ BOOLEAN AifThreadStarted;
7550+
7551+} AFA_COMM_ADAPTER;
7552+
7553+typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7554+
7555+
7556+#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7557+ Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7558+
7559+#define FsaFreeAdapterCommArea(Adapter) \
7560+ Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7561+
7562+
7563+#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7564+ Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7565+
7566+#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7567+ Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7568+
7569+#define InterruptAdapter(Adapter) \
7570+ Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7571+
7572+#define NotifyAdapter(Adapter, AdapterEvent) \
7573+ Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7574+
7575+#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7576+ Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7577+
7578+#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7579+ Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7580+
7581+
7582+#endif // _ADAPTER_
7583diff -burN linux-2.4.4/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7584--- linux-2.4.4/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 18:00:00 1969
7585+++ linux/drivers/scsi/aacraid/include/afacomm.h Mon Apr 30 09:43:34 2001
7586@@ -0,0 +1,191 @@
7587+/*++
7588+ * Adaptec aacraid device driver for Linux.
7589+ *
7590+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7591+ *
7592+ * This program is free software; you can redistribute it and/or modify
7593+ * it under the terms of the GNU General Public License as published by
7594+ * the Free Software Foundation; either version 2, or (at your option)
7595+ * any later version.
7596+ *
7597+ * This program is distributed in the hope that it will be useful,
7598+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7599+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7600+ * GNU General Public License for more details.
7601+ *
7602+ * You should have received a copy of the GNU General Public License
7603+ * along with this program; see the file COPYING. If not, write to
7604+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7605+ *
7606+ * Module Name:
7607+ * AfaComm.h
7608+ *
7609+ * Abstract:
7610+ * This module defines all of the external interfaces to the AFA comm layer.
7611+ *
7612+ *
7613+ *
7614+ --*/
7615+#ifndef _AFACOMM_
7616+#define _AFACOMM_
7617+
7618+static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7619+
7620+#include "fsaport.h"
7621+
7622+typedef void *PFIB_CONTEXT;
7623+
7624+typedef VOID
7625+(*PFIB_CALLBACK)(
7626+ PVOID FibCallbackContext,
7627+ PFIB_CONTEXT FibContext,
7628+ AAC_STATUS Status
7629+ );
7630+
7631+
7632+typedef PFIB_CONTEXT
7633+(*PAFA_COMM_ALLOCATE_FIB) (
7634+ IN PVOID AdapterExtension
7635+ );
7636+
7637+typedef VOID
7638+(*PAFA_COMM_FREE_FIB) (
7639+ IN PFIB_CONTEXT FibContext
7640+ );
7641+
7642+
7643+typedef AAC_STATUS
7644+(*PAFA_COMM_DEALLOCATE_FIB) (
7645+ IN PFIB_CONTEXT FibContext
7646+ );
7647+
7648+
7649+typedef VOID
7650+(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7651+ IN PFIB_CONTEXT FibContext
7652+ );
7653+
7654+typedef AAC_STATUS
7655+(*PAFA_COMM_INITIALIZE_FIB) (
7656+ IN PFIB_CONTEXT FibContext
7657+ );
7658+
7659+typedef PVOID
7660+(*PAFA_COMM_GET_FIB_DATA) (
7661+ IN PFIB_CONTEXT FibContext
7662+ );
7663+
7664+typedef AAC_STATUS
7665+(*PAFA_COMM_SEND_FIB) (
7666+ IN FIB_COMMAND Command,
7667+ IN PFIB_CONTEXT FibContext,
7668+ IN ULONG Size,
7669+ IN COMM_PRIORITIES Priority,
7670+ IN BOOLEAN Wait,
7671+ IN PVOID WaitOn,
7672+ IN BOOLEAN ResponseExpected,
7673+ IN PFIB_CALLBACK FibCallback,
7674+ IN PVOID FibCallbackContext
7675+ );
7676+
7677+typedef AAC_STATUS
7678+(*PAFA_COMM_COMPLETE_FIB) (
7679+ IN PFIB_CONTEXT FibContext
7680+ );
7681+
7682+typedef AAC_STATUS
7683+(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7684+ IN PFIB_CONTEXT FibContext,
7685+ IN USHORT Size
7686+ );
7687+
7688+typedef BOOLEAN
7689+(*PAFA_COMM_SEND_SYNCH_FIB) (
7690+ PVOID AdapterExtension,
7691+ FIB_COMMAND Command,
7692+ PVOID Data,
7693+ USHORT Size,
7694+ PVOID Response,
7695+ USHORT *ResponseSize
7696+ );
7697+
7698+
7699+typedef struct _AFACOMM_FUNCS {
7700+ ULONG SizeOfAfaCommFuncs;
7701+ PAFA_COMM_ALLOCATE_FIB AllocateFib;
7702+ PAFA_COMM_FREE_FIB FreeFib;
7703+ PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7704+ PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7705+ PAFA_COMM_INITIALIZE_FIB InitializeFib;
7706+ PAFA_COMM_GET_FIB_DATA GetFibData;
7707+ PAFA_COMM_SEND_FIB SendFib;
7708+ PAFA_COMM_COMPLETE_FIB CompleteFib;
7709+ PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7710+ PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7711+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7712+ PFSA_BUILD_SGMAP BuildSgMap;
7713+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7714+} AFACOMM_FUNCS;
7715+typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7716+
7717+
7718+typedef AAC_STATUS
7719+(*PAFA_CLASS_OPEN_ADAPTER) (
7720+ IN PVOID Adapter
7721+ );
7722+
7723+
7724+typedef AAC_STATUS
7725+(*PAFA_CLASS_CLOSE_ADAPTER) (
7726+ IN PVOID Adapter
7727+ );
7728+
7729+
7730+typedef BOOLEAN
7731+(*PAFA_CLASS_DEV_CONTROL) (
7732+ IN PVOID Adapter,
7733+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
7734+ OUT int * Status
7735+ );
7736+
7737+typedef BOOLEAN
7738+(*PAFA_CLASS_HANDLE_AIF) (
7739+ IN PVOID Adapter,
7740+ IN PFIB_CONTEXT FibContext
7741+ );
7742+
7743+
7744+typedef struct _AFA_NEW_CLASS_DRIVER {
7745+ PVOID ClassDriverExtension;
7746+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7747+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7748+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7749+ PAFA_CLASS_HANDLE_AIF HandleAif;
7750+ PFSA_USER_VAR UserVars;
7751+ ULONG NumUserVars;
7752+} AFA_NEW_CLASS_DRIVER;
7753+typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7754+
7755+
7756+typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7757+ PAFACOMM_FUNCS CommFuncs;
7758+ PVOID CommPortExtension;
7759+ PVOID MiniPortExtension;
7760+ OS_SPINLOCK_COOKIE SpinLockCookie;
7761+ void *Dip;
7762+} AFA_NEW_CLASS_DRIVER_RESPONSE;
7763+typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7764+
7765+
7766+typedef struct _AFA_CLASS_DRIVER {
7767+ struct _AFA_CLASS_DRIVER *Next;
7768+ PVOID ClassDriverExtension;
7769+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7770+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7771+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7772+ PAFA_CLASS_HANDLE_AIF HandleAif;
7773+} AFA_CLASS_DRIVER;
7774+typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7775+
7776+
7777+#endif // _AFACOMM_
7778diff -burN linux-2.4.4/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7779--- linux-2.4.4/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7780+++ linux/drivers/scsi/aacraid/include/aifstruc.h Mon Apr 30 09:43:34 2001
7781@@ -0,0 +1,319 @@
7782+/*++
7783+ * Adaptec aacraid device driver for Linux.
7784+ *
7785+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7786+ *
7787+ * This program is free software; you can redistribute it and/or modify
7788+ * it under the terms of the GNU General Public License as published by
7789+ * the Free Software Foundation; either version 2, or (at your option)
7790+ * any later version.
7791+ *
7792+ * This program is distributed in the hope that it will be useful,
7793+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7794+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7795+ * GNU General Public License for more details.
7796+ *
7797+ * You should have received a copy of the GNU General Public License
7798+ * along with this program; see the file COPYING. If not, write to
7799+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7800+ *
7801+ * Module Name:
7802+ * Aifstruc.h
7803+ *
7804+ * Abstract:
7805+ * Define all shared data types relating to
7806+ * the set of features utilizing Adapter
7807+ * Initiated Fibs.
7808+ *
7809+ *
7810+ *
7811+ --*/
7812+#ifndef _AIFSTRUC_H
7813+#define _AIFSTRUC_H
7814+
7815+static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7816+
7817+#include <protocol.h>
7818+
7819+//
7820+// Progress report structure definitions
7821+//
7822+typedef enum {
7823+ AifJobStsSuccess = 1,
7824+ AifJobStsFinished,
7825+ AifJobStsAborted,
7826+ AifJobStsFailed,
7827+ AifJobStsLastReportMarker = 100, // All before mean last report
7828+ AifJobStsSuspended,
7829+ AifJobStsRunning
7830+} _E_AifJobStatus;
7831+
7832+#ifdef AAC_32BIT_ENUMS
7833+typedef _E_AifJobStatus AifJobStatus;
7834+#else
7835+typedef AAC_UINT32 AifJobStatus;
7836+#endif
7837+
7838+
7839+typedef enum {
7840+ AifJobScsiMin = 1, // Minimum value for Scsi operation
7841+ AifJobScsiZero, // SCSI device clear operation
7842+ AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7843+ AifJobScsiExercise, // SCSI device Exercise operation
7844+ AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7845+ // Add new SCSI task types above this line
7846+ AifJobScsiMax = 99, // Max Scsi value
7847+ AifJobCtrMin, // Min Ctr op value
7848+ AifJobCtrZero, // Container clear operation
7849+ AifJobCtrCopy, // Container copy operation
7850+ AifJobCtrCreateMirror, // Container Create Mirror operation
7851+ AifJobCtrMergeMirror, // Container Merge Mirror operation
7852+ AifJobCtrScrubMirror, // Container Scrub Mirror operation
7853+ AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7854+ AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7855+ AifJobCtrMorph, // Container morph operation
7856+ AifJobCtrPartCopy, // Container Partition copy operation
7857+ AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7858+ AifJobCtrCrazyCache, // crazy cache
7859+ // Add new container task types above this line
7860+ AifJobCtrMax = 199, // Max Ctr type operation
7861+ AifJobFsMin, // Min Fs type operation
7862+ AifJobFsCreate, // File System Create operation
7863+ AifJobFsVerify, // File System Verify operation
7864+ AifJobFsExtend, // File System Extend operation
7865+ // Add new file system task types above this line
7866+ AifJobFsMax = 299, // Max Fs type operation
7867+ // Add new API task types here
7868+ AifJobApiFormatNTFS, // Format a drive to NTFS
7869+ AifJobApiFormatFAT, // Format a drive to FAT
7870+ AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7871+ AifJobApiFormatFAT32, // Format a drive to FAT32
7872+ AifJobApiMax = 399, // Max API type operation
7873+ AifJobCtlContinuousCtrVerify, // Controller operation
7874+ AifJobCtlMax = 499 // Max Controller type operation
7875+
7876+} _E_AifJobType;
7877+
7878+#ifdef AAC_32BIT_ENUMS
7879+typedef _E_AifJobType AifJobType;
7880+#else
7881+typedef AAC_UINT32 AifJobType;
7882+#endif
7883+
7884+union SrcContainer {
7885+ AAC_UINT32 from;
7886+ AAC_UINT32 master;
7887+ AAC_UINT32 container;
7888+};
7889+
7890+union DstContainer {
7891+ AAC_UINT32 to;
7892+ AAC_UINT32 slave;
7893+ AAC_UINT32 container;
7894+};
7895+
7896+
7897+struct AifContainers {
7898+ union SrcContainer src;
7899+ union DstContainer dst;
7900+};
7901+
7902+union AifJobClient {
7903+
7904+ struct AifContainers container; // For Container nd file system progress ops;
7905+ AAC_INT32 scsi_dh; // For SCSI progress ops
7906+};
7907+
7908+struct AifJobDesc {
7909+ AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7910+ AifJobType type; // Operation that is being performed
7911+ union AifJobClient client; // Details
7912+};
7913+
7914+struct AifJobProgressReport {
7915+ struct AifJobDesc jd;
7916+ AifJobStatus status;
7917+ AAC_UINT32 finalTick;
7918+ AAC_UINT32 currentTick;
7919+ AAC_UINT32 jobSpecificData1;
7920+ AAC_UINT32 jobSpecificData2;
7921+};
7922+
7923+//
7924+// Notification of events structure definition starts here
7925+//
7926+typedef enum {
7927+ // General application notifies start here
7928+ AifEnGeneric = 1, // Generic notification
7929+ AifEnTaskComplete, // Task has completed
7930+ AifEnConfigChange, // Adapter configuration change occurred
7931+ AifEnContainerChange, // Adapter specific container configuration change
7932+ AifEnDeviceFailure, // SCSI device failed
7933+ AifEnMirrorFailover, // Mirror failover started
7934+ AifEnContainerEvent, // Significant container event
7935+ AifEnFileSystemChange, // File system changed
7936+ AifEnConfigPause, // Container pause event
7937+ AifEnConfigResume, // Container resume event
7938+ AifEnFailoverChange, // Failover space assignment changed
7939+ AifEnRAID5RebuildDone, // RAID5 rebuild finished
7940+ AifEnEnclosureManagement, // Enclosure management event
7941+ AifEnBatteryEvent, // Significant NV battery event
7942+ AifEnAddContainer, // A new container was created.
7943+ AifEnDeleteContainer, // A container was deleted.
7944+ AifEnSMARTEvent, // SMART Event
7945+ AifEnBatteryNeedsRecond, // The battery needs reconditioning
7946+ AifEnClusterEvent, // Some cluster event
7947+ AifEnDiskSetEvent, // A disk set event occured.
7948+ // Add general application notifies above this comment
7949+ AifDriverNotifyStart=199, // Notifies for host driver go here
7950+ // Host driver notifications start here
7951+ AifDenMorphComplete, // A morph operation completed
7952+ AifDenVolumeExtendComplete // A volume expand operation completed
7953+ // Add host driver notifications above this comment
7954+} _E_AifEventNotifyType;
7955+
7956+#ifdef AAC_32BIT_ENUMS
7957+typedef _E_AifEventNotifyType AifEventNotifyType;
7958+#else
7959+typedef AAC_UINT32 AifEventNotifyType;
7960+#endif
7961+
7962+struct AifEnsGeneric {
7963+ AAC_INT8 text[132]; // Generic text
7964+};
7965+
7966+struct AifEnsDeviceFailure {
7967+ AAC_INT32 deviceHandle; // SCSI device handle
7968+};
7969+
7970+struct AifEnsMirrorFailover {
7971+ AAC_UINT32 container; // Container with failed element
7972+ AAC_UINT32 failedSlice; // Old slice which failed
7973+ AAC_UINT32 creatingSlice; // New slice used for auto-create
7974+};
7975+
7976+struct AifEnsContainerChange {
7977+ AAC_UINT32 container[2]; // container that changed, -1 if no container
7978+};
7979+
7980+struct AifEnsContainerEvent {
7981+ AAC_UINT32 container; // container number
7982+ AAC_UINT32 eventType; // event type
7983+};
7984+
7985+struct AifEnsEnclosureEvent {
7986+ AAC_UINT32 empID; // enclosure management processor number
7987+ AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
7988+ AAC_UINT32 eventType; // event type
7989+};
7990+
7991+
7992+struct AifEnsBatteryEvent {
7993+ NVBATT_TRANSITION transition_type; // e.g. from low to ok
7994+ NVBATTSTATUS current_state; // current battery state
7995+ NVBATTSTATUS prior_state; // previous battery state
7996+};
7997+
7998+struct AifEnsDiskSetEvent {
7999+ AAC_UINT32 eventType;
8000+ AAC_UINT32 DsNum[2];
8001+ AAC_UINT32 CreatorId[2];
8002+};
8003+
8004+
8005+
8006+typedef enum _CLUSTER_AIF_EVENT {
8007+ CLUSTER_NULL_EVENT = 0,
8008+ CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
8009+ // (partner's agent may be up)
8010+ CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8011+ // (partner has rebooted)
8012+} _E_CLUSTER_AIF_EVENT;
8013+
8014+#ifdef AAC_32BIT_ENUMS
8015+typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
8016+#else
8017+typedef AAC_UINT32 CLUSTER_AIF_EVENT;
8018+#endif
8019+
8020+struct AifEnsClusterEvent {
8021+ CLUSTER_AIF_EVENT eventType;
8022+};
8023+
8024+struct AifEventNotify {
8025+ AifEventNotifyType type;
8026+ union {
8027+ struct AifEnsGeneric EG;
8028+ struct AifEnsDeviceFailure EDF;
8029+ struct AifEnsMirrorFailover EMF;
8030+ struct AifEnsContainerChange ECC;
8031+ struct AifEnsContainerEvent ECE;
8032+ struct AifEnsEnclosureEvent EEE;
8033+ struct AifEnsBatteryEvent EBE;
8034+ struct AifEnsDiskSetEvent EDS;
8035+#ifdef BRIDGE
8036+ struct AifEnsSMARTEvent ES;
8037+#endif
8038+ struct AifEnsClusterEvent ECLE;
8039+ } data;
8040+};
8041+
8042+//
8043+// Generic API structure
8044+//
8045+#define AIF_API_REPORT_MAX_SIZE 64
8046+typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8047+
8048+
8049+
8050+//
8051+// For FIB communication, we need all of the following things
8052+// to send back to the user.
8053+//
8054+typedef enum {
8055+ AifCmdEventNotify = 1, // Notify of event
8056+ AifCmdJobProgress, // Progress report
8057+ AifCmdAPIReport, // Report from other user of API
8058+ AifCmdDriverNotify, // Notify host driver of event
8059+ AifReqJobList = 100, // Gets back complete job list
8060+ AifReqJobsForCtr, // Gets back jobs for specific container
8061+ AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8062+ AifReqJobReport, // Gets back a specific job report or list of them
8063+ AifReqTerminateJob, // Terminates job
8064+ AifReqSuspendJob, // Suspends a job
8065+ AifReqResumeJob, // Resumes a job
8066+ AifReqSendAPIReport, // API generic report requests
8067+ AifReqAPIJobStart, // Start a job from the API
8068+ AifReqAPIJobUpdate, // Update a job report from the API
8069+ AifReqAPIJobFinish // Finish a job from the API
8070+} _E_AIFCOMMAND;
8071+
8072+#ifdef AAC_32BIT_ENUMS
8073+typedef _E_AIFCOMMAND AIFCOMMAND;
8074+#else
8075+typedef AAC_UINT32 AIFCOMMAND;
8076+#endif
8077+
8078+
8079+
8080+//
8081+// Adapter Initiated FIB command structures. Start with the adapter
8082+// initiated FIBs that really come from the adapter, and get responded
8083+// to by the host.
8084+//
8085+typedef struct _AIFCOMMANDTOHOST {
8086+ AIFCOMMAND command; // Tell host what type of notify this is
8087+ AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8088+ union {
8089+ // First define data going to the adapter
8090+ struct AifEventNotify EN; // Event notify structure
8091+ struct AifJobProgressReport PR[1]; // Progress report
8092+ AifApiReport AR;
8093+ } data;
8094+} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8095+
8096+
8097+#endif // _AIFSTRUC_H
8098+
8099+
8100+
8101diff -burN linux-2.4.4/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8102--- linux-2.4.4/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 18:00:00 1969
8103+++ linux/drivers/scsi/aacraid/include/build_number.h Mon Apr 30 09:43:34 2001
8104@@ -0,0 +1,39 @@
8105+/*++
8106+ * Adaptec aacraid device driver for Linux.
8107+ *
8108+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8109+ *
8110+ * This program is free software; you can redistribute it and/or modify
8111+ * it under the terms of the GNU General Public License as published by
8112+ * the Free Software Foundation; either version 2, or (at your option)
8113+ * any later version.
8114+ *
8115+ * This program is distributed in the hope that it will be useful,
8116+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8117+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8118+ * GNU General Public License for more details.
8119+ *
8120+ * You should have received a copy of the GNU General Public License
8121+ * along with this program; see the file COPYING. If not, write to
8122+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8123+ *
8124+ * Module Name:
8125+ * build_number.h
8126+ *
8127+ * Abstract:
8128+ * DThis module contains the single location where the build number
8129+ * is kept.
8130+ *
8131+ *
8132+ *
8133+ --*/
8134+#ifndef _BUILD_NUMBER_H
8135+#define _BUILD_NUMBER_H
8136+
8137+static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8138+
8139+#define REV_BUILD_NUMBER 3911
8140+
8141+
8142+#endif // _BUILD_NUMBER_H
8143+
8144diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8145--- linux-2.4.4/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8146+++ linux/drivers/scsi/aacraid/include/commdata.h Mon Apr 30 09:43:34 2001
8147@@ -0,0 +1,112 @@
8148+/*++
8149+ * Adaptec aacraid device driver for Linux.
8150+ *
8151+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8152+ *
8153+ * This program is free software; you can redistribute it and/or modify
8154+ * it under the terms of the GNU General Public License as published by
8155+ * the Free Software Foundation; either version 2, or (at your option)
8156+ * any later version.
8157+ *
8158+ * This program is distributed in the hope that it will be useful,
8159+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8160+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8161+ * GNU General Public License for more details.
8162+ *
8163+ * You should have received a copy of the GNU General Public License
8164+ * along with this program; see the file COPYING. If not, write to
8165+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8166+ *
8167+ * Module Name:
8168+ * commdata.h
8169+ *
8170+ * Abstract: Define the communication layer of the adapter
8171+ *
8172+ *
8173+ *
8174+ --*/
8175+#ifndef _COMMDATA_
8176+#define _COMMDATA_
8177+
8178+static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8179+
8180+typedef struct _FSA_COMM_DATA {
8181+
8182+ //
8183+ // A pointer to the Driver and Device object we were initialized with
8184+ //
8185+
8186+ PDRIVER_OBJECT DriverObject;
8187+ PDEVICE_OBJECT DeviceObject;
8188+
8189+ //
8190+ // A list of all adapters we have configured.
8191+ //
8192+
8193+ PAFA_COMM_ADAPTER AdapterList;
8194+ ULONG TotalAdapters;
8195+
8196+ //
8197+ // Adapter timeout support. This is the default timeout to wait for the
8198+ // adapter to respond(setup in initfs.c), and a boolean to indicate if
8199+ // we should timeout requests to the adapter or not.
8200+ //
8201+
8202+ LARGE_INTEGER QueueFreeTimeout;
8203+ LARGE_INTEGER AdapterTimeout;
8204+ BOOLEAN EnableAdapterTimeouts;
8205+
8206+ ULONG FibTimeoutIncrement;
8207+
8208+ ULONG FibsSent;
8209+ ULONG FibRecved;
8210+ ULONG NoResponseSent;
8211+ ULONG NoResponseRecved;
8212+ ULONG AsyncSent;
8213+ ULONG AsyncRecved;
8214+ ULONG NormalSent;
8215+ ULONG NormalRecved;
8216+
8217+ ULONG TimedOutFibs;
8218+
8219+ KDPC TimeoutDPC;
8220+ KTIMER TimeoutTimer;
8221+
8222+ //
8223+ // If this value is set to 1 then interrupt moderation will occur
8224+ // in the base commuication support.
8225+ //
8226+
8227+ ULONG EnableInterruptModeration;
8228+
8229+ int HardInterruptModeration;
8230+ int HardInterruptModeration1;
8231+ int PeakFibsConsumed;
8232+ int ZeroFibsConsumed;
8233+ int EnableFibTimeoutBreak;
8234+ ULONG FibTimeoutSeconds;
8235+
8236+ //
8237+ // The following holds all of the available user settable variables.
8238+ // This includes all for the comm layer as well as any from the class
8239+ // drivers as well.
8240+ //
8241+
8242+ FSA_USER_VAR *UserVars;
8243+ ULONG NumUserVars;
8244+
8245+
8246+ ULONG MeterFlag;
8247+
8248+#ifdef FIB_CHECKSUMS
8249+ int do_fib_checksums;
8250+#endif
8251+
8252+} FSA_COMM_DATA;
8253+typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8254+
8255+extern FSA_COMM_DATA FsaCommData;
8256+
8257+
8258+#endif // _COMMDATA_
8259+
8260diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8261--- linux-2.4.4/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 18:00:00 1969
8262+++ linux/drivers/scsi/aacraid/include/commerr.h Mon Apr 30 09:43:34 2001
8263@@ -0,0 +1,125 @@
8264+/*++
8265+ * Adaptec aacraid device driver for Linux.
8266+ *
8267+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8268+ *
8269+ * This program is free software; you can redistribute it and/or modify
8270+ * it under the terms of the GNU General Public License as published by
8271+ * the Free Software Foundation; either version 2, or (at your option)
8272+ * any later version.
8273+ *
8274+ * This program is distributed in the hope that it will be useful,
8275+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8276+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8277+ * GNU General Public License for more details.
8278+ *
8279+ * You should have received a copy of the GNU General Public License
8280+ * along with this program; see the file COPYING. If not, write to
8281+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8282+ *
8283+ * Module Name:
8284+ * commerr.h
8285+ *
8286+ * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8287+ *
8288+ *
8289+ *
8290+ --*/
8291+
8292+#ifndef _FSAERR_
8293+#define _FSAERR_
8294+
8295+static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8296+
8297+//
8298+// Note: comments in the .mc file must use both ";" and "//".
8299+//
8300+// Status values are 32 bit values layed out as follows:
8301+//
8302+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8303+// 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
8304+// +---+-+-------------------------+-------------------------------+
8305+// |Sev|C| Facility | Code |
8306+// +---+-+-------------------------+-------------------------------+
8307+//
8308+// where
8309+//
8310+// Sev - is the severity code
8311+//
8312+// 00 - Success
8313+// 01 - Informational
8314+// 10 - Warning
8315+// 11 - Error
8316+//
8317+// C - is the Customer code flag
8318+//
8319+// Facility - is the facility code
8320+//
8321+// Code - is the facility's status code
8322+//
8323+
8324+
8325+//
8326+// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8327+// called with a device, the name of the device will be inserted into
8328+// the message at %1. Otherwise, the place of %1 will be left empty.
8329+// In either case, the insertion strings from the driver's error log
8330+// entry starts at %2. In other words, the first insertion string goes
8331+// to %2, the second to %3 and so on.
8332+//
8333+
8334+//
8335+// Values are 32 bit values layed out as follows:
8336+//
8337+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8338+// 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
8339+// +---+-+-+-----------------------+-------------------------------+
8340+// |Sev|C|R| Facility | Code |
8341+// +---+-+-+-----------------------+-------------------------------+
8342+//
8343+// where
8344+//
8345+// Sev - is the severity code
8346+//
8347+// 00 - Success
8348+// 01 - Informational
8349+// 10 - Warning
8350+// 11 - Error
8351+//
8352+// C - is the Customer code flag
8353+//
8354+// R - is a reserved bit
8355+//
8356+// Facility - is the facility code
8357+//
8358+// Code - is the facility's status code
8359+//
8360+//
8361+// Define the facility codes
8362+//
8363+
8364+
8365+#define FACILITY_FSAFS_ERROR_CODE 0x7
8366+
8367+
8368+
8369+//
8370+// MessageId: FSAFS_FIB_INVALID
8371+//
8372+// MessageText:
8373+//
8374+// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8375+//
8376+#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8377+
8378+
8379+//
8380+// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8381+//
8382+// MessageText:
8383+//
8384+// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8385+//
8386+#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8387+
8388+#endif _FSAERR_
8389diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8390--- linux-2.4.4/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 18:00:00 1969
8391+++ linux/drivers/scsi/aacraid/include/commfibcontext.h Mon Apr 30 09:43:34 2001
8392@@ -0,0 +1,98 @@
8393+/*++
8394+ * Adaptec aacraid device driver for Linux.
8395+ *
8396+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8397+ *
8398+ * This program is free software; you can redistribute it and/or modify
8399+ * it under the terms of the GNU General Public License as published by
8400+ * the Free Software Foundation; either version 2, or (at your option)
8401+ * any later version.
8402+ *
8403+ * This program is distributed in the hope that it will be useful,
8404+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8405+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8406+ * GNU General Public License for more details.
8407+ *
8408+ * You should have received a copy of the GNU General Public License
8409+ * along with this program; see the file COPYING. If not, write to
8410+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8411+ *
8412+ * Module Name:
8413+ * commfibcontext.h
8414+ *
8415+ * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8416+ *
8417+ *
8418+ *
8419+ --*/
8420+#ifndef _COMM_FIB_CONTEXT_
8421+#define _COMM_FIB_CONTEXT_
8422+
8423+static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8424+
8425+typedef struct _COMM_FIB_CONTEXT {
8426+
8427+ PVOID Next; // this is used by the zone allocation
8428+
8429+ //
8430+ // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8431+ //
8432+ // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8433+ // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8434+ // ITS SIZE.
8435+ //
8436+
8437+ NODE_TYPE_CODE NodeTypeCode;
8438+ NODE_BYTE_SIZE NodeByteSize;
8439+
8440+ //
8441+ // The Adapter that this I/O is destined for.
8442+ //
8443+
8444+ PAFA_COMM_ADAPTER Adapter;
8445+
8446+ PHYSICAL_ADDRESS LogicalFibAddress;
8447+
8448+ //
8449+ // This is the event the sendfib routine will wait on if the
8450+ // caller did not pass one and this is synch io.
8451+ //
8452+
8453+ OS_CV_T FsaEvent;
8454+ OS_CVLOCK *FsaEventMutex;
8455+
8456+ ULONG FibComplete; // gets set to 1 when fib is complete
8457+
8458+ PFIB_CALLBACK FibCallback;
8459+ PVOID FibCallbackContext;
8460+
8461+ ULONG Flags;
8462+
8463+
8464+#ifdef GATHER_FIB_TIMES
8465+ LARGE_INTEGER FibTimeStamp;
8466+ PFIB_TIMES FibTimesPtr;
8467+#endif
8468+
8469+ //
8470+ // The following is used to put this fib context onto the Outstanding I/O queue.
8471+ //
8472+
8473+ LIST_ENTRY QueueEntry;
8474+
8475+ //
8476+ // The following is used to timeout a fib to the adapter.
8477+ //
8478+
8479+ LARGE_INTEGER TimeoutValue;
8480+
8481+ PVOID FibData;
8482+
8483+ PFIB Fib;
8484+
8485+} COMM_FIB_CONTEXT;
8486+typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8487+
8488+#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8489+
8490+#endif /* _COMM_FIB_CONTEXT_ */
8491diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8492--- linux-2.4.4/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8493+++ linux/drivers/scsi/aacraid/include/comprocs.h Mon Apr 30 09:43:34 2001
8494@@ -0,0 +1,93 @@
8495+/*++
8496+ * Adaptec aacraid device driver for Linux.
8497+ *
8498+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8499+ *
8500+ * This program is free software; you can redistribute it and/or modify
8501+ * it under the terms of the GNU General Public License as published by
8502+ * the Free Software Foundation; either version 2, or (at your option)
8503+ * any later version.
8504+ *
8505+ * This program is distributed in the hope that it will be useful,
8506+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8507+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8508+ * GNU General Public License for more details.
8509+ *
8510+ * You should have received a copy of the GNU General Public License
8511+ * along with this program; see the file COPYING. If not, write to
8512+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8513+ *
8514+ * Module Name:
8515+ * comprocs.h
8516+ *
8517+ * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8518+ *
8519+ *
8520+ *
8521+ --*/
8522+#ifndef _COMPROCS_
8523+#define _COMPROCS_
8524+
8525+static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8526+
8527+#include "osheaders.h"
8528+
8529+#include "AacGenericTypes.h"
8530+
8531+#include "aac_unix_defs.h"
8532+
8533+#include "nodetype.h"
8534+
8535+// #define GATHER_FIB_TIMES
8536+
8537+#include "fsatypes.h"
8538+
8539+#include "perfpack.h"
8540+
8541+#include "comstruc.h"
8542+
8543+//#include "unix_protocol.h"
8544+
8545+#include "fsact.h"
8546+
8547+#include "protocol.h"
8548+
8549+#include "fsaioctl.h"
8550+
8551+#undef GATHER_FIB_TIMES
8552+
8553+#include "aifstruc.h"
8554+
8555+#include "fsaport.h"
8556+#include "comsup.h"
8557+#include "afacomm.h"
8558+#include "adapter.h"
8559+
8560+#include "commfibcontext.h"
8561+#include "comproto.h"
8562+#include "commdata.h"
8563+#include "commerr.h"
8564+
8565+
8566+
8567+
8568+//
8569+// The following macro is used when sending and receiving FIBs. It is only used for
8570+// debugging.
8571+
8572+#if DBG
8573+#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8574+#else
8575+#define FIB_COUNTER_INCREMENT(Counter)
8576+#endif
8577+
8578+
8579+
8580+int
8581+AfaCommAdapterDeviceControl (
8582+ IN PVOID AdapterArg,
8583+ IN PAFA_IOCTL_CMD IoctlCmdPtr
8584+ );
8585+
8586+
8587+#endif // _COMPROCS_
8588diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8589--- linux-2.4.4/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8590+++ linux/drivers/scsi/aacraid/include/comproto.h Mon Apr 30 09:43:34 2001
8591@@ -0,0 +1,170 @@
8592+/*++
8593+ * Adaptec aacraid device driver for Linux.
8594+ *
8595+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8596+ *
8597+ * This program is free software; you can redistribute it and/or modify
8598+ * it under the terms of the GNU General Public License as published by
8599+ * the Free Software Foundation; either version 2, or (at your option)
8600+ * any later version.
8601+ *
8602+ * This program is distributed in the hope that it will be useful,
8603+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8604+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8605+ * GNU General Public License for more details.
8606+ *
8607+ * You should have received a copy of the GNU General Public License
8608+ * along with this program; see the file COPYING. If not, write to
8609+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8610+ *
8611+ * Module Name:
8612+ * comproto.h
8613+ *
8614+ * Abstract: Global routines for the commuication interface that are device
8615+ * independant.
8616+ *
8617+ *
8618+ *
8619+ --*/
8620+#ifndef _COMM_PROTO
8621+#define _COMM_PROTO
8622+
8623+static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8624+
8625+//
8626+// define the routines we need so we can commuicate with the
8627+// fsa adapter
8628+//
8629+
8630+//
8631+// The following 4 dpc routines will support commuication from the adapter to the
8632+// host. There is one DPC routine to deal with each type of queue that supports
8633+// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8634+// These routines will simply pull off the QE and set an event. In the case of a
8635+// adapter to host command they will also put the FIB on a queue to be processed by
8636+// a FS thread running at passive level.
8637+//
8638+
8639+// Handle queue not full notification to the file system thread waiting for a queue entry
8640+
8641+u_int
8642+CommonNotFullDpc(
8643+ IN PCOMM_REGION CommRegion
8644+ );
8645+
8646+// Adapter to host normal priority responses
8647+
8648+u_int
8649+HostResponseNormalDpc(
8650+ IN PCOMM_QUE OurQueue
8651+ );
8652+
8653+// Adapter to host high priority responses
8654+u_int
8655+HostResponseHighDpc(
8656+ IN PCOMM_QUE OurQueue
8657+ );
8658+
8659+// Adapter to host high priority commands
8660+u_int
8661+HostCommandHighDpc(
8662+ IN PCOMM_QUE OurQueue
8663+ );
8664+
8665+
8666+// Adapter to host normal priority commands
8667+u_int
8668+HostCommandNormDpc(
8669+ IN PCOMM_QUE OurQueue
8670+ );
8671+
8672+
8673+
8674+BOOLEAN
8675+SendSynchFib(
8676+ PVOID Arg,
8677+ FIB_COMMAND Command,
8678+ PVOID Data,
8679+ USHORT Size,
8680+ PVOID Response,
8681+ USHORT *ResponseSize
8682+ );
8683+
8684+PFIB_CONTEXT
8685+AllocateFib (
8686+ IN PVOID Adapter
8687+ );
8688+
8689+VOID
8690+FreeFib (
8691+ IN PFIB_CONTEXT FibContext
8692+ );
8693+
8694+VOID
8695+FreeFibFromDpc(
8696+ IN PFIB_CONTEXT FibContext
8697+ );
8698+
8699+AAC_STATUS
8700+DeallocateFib(
8701+ IN PFIB_CONTEXT FibContext
8702+ );
8703+
8704+
8705+
8706+AAC_STATUS
8707+SendFib(
8708+ IN FIB_COMMAND Command,
8709+ IN PFIB_CONTEXT FibContext,
8710+ IN ULONG Size,
8711+ IN COMM_PRIORITIES Priority,
8712+ IN BOOLEAN Wait,
8713+ IN PVOID WaitOn,
8714+ IN BOOLEAN ResponseExpected,
8715+ IN PFIB_CALLBACK FibCallback,
8716+ IN PVOID FibCallbackContext
8717+ );
8718+
8719+AAC_STATUS
8720+CompleteFib(
8721+ IN PFIB_CONTEXT FibContext
8722+ );
8723+
8724+AAC_STATUS
8725+CompleteAdapterFib(
8726+ IN PFIB_CONTEXT FibContext,
8727+ IN USHORT Size
8728+ );
8729+
8730+AAC_STATUS
8731+InitializeFib(
8732+ IN PFIB_CONTEXT FibContext
8733+ );
8734+
8735+
8736+PVOID
8737+FsaGetFibData(
8738+ IN PFIB_CONTEXT FibContext
8739+ );
8740+
8741+
8742+
8743+AAC_STATUS
8744+AfaCommOpenAdapter (
8745+ IN PVOID AdapterArg
8746+ );
8747+
8748+AAC_STATUS
8749+AfaCommCloseAdapter (
8750+ IN PVOID AdapterArg
8751+ );
8752+
8753+
8754+VOID
8755+AfaCommInterruptHost(
8756+ PVOID Adapter,
8757+ ADAPTER_EVENT AdapterEvent
8758+ );
8759+
8760+
8761+#endif // _COMM_PROTO
8762diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8763--- linux-2.4.4/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8764+++ linux/drivers/scsi/aacraid/include/comstruc.h Mon Apr 30 09:43:34 2001
8765@@ -0,0 +1,435 @@
8766+/*++
8767+ * Adaptec aacraid device driver for Linux.
8768+ *
8769+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8770+ *
8771+ * This program is free software; you can redistribute it and/or modify
8772+ * it under the terms of the GNU General Public License as published by
8773+ * the Free Software Foundation; either version 2, or (at your option)
8774+ * any later version.
8775+ *
8776+ * This program is distributed in the hope that it will be useful,
8777+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8778+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8779+ * GNU General Public License for more details.
8780+ *
8781+ * You should have received a copy of the GNU General Public License
8782+ * along with this program; see the file COPYING. If not, write to
8783+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8784+ *
8785+ * Module Name:
8786+ * comstruc.h
8787+ *
8788+ * Abstract: This module defines the data structures that make up the communication
8789+ * region for the FSA filesystem. This region is how the host based code
8790+ * communicates both control and data to the adapter based code.
8791+ *
8792+ *
8793+ *
8794+ --*/
8795+#ifndef _COMM_STRUCT
8796+#define _COMM_STRUCT
8797+
8798+static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8799+
8800+//
8801+// Define all the constants needed for the communication interface
8802+//
8803+
8804+// Define how many queue entries each queue will have and the total number of
8805+// entries for the entire communication interface. Also define how many queues
8806+// we support.
8807+
8808+#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8809+#define HOST_HIGH_CMD_ENTRIES 4
8810+#define HOST_NORM_CMD_ENTRIES 8
8811+#define ADAP_HIGH_CMD_ENTRIES 4
8812+#define ADAP_NORM_CMD_ENTRIES 512
8813+#define HOST_HIGH_RESP_ENTRIES 4
8814+#define HOST_NORM_RESP_ENTRIES 512
8815+#define ADAP_HIGH_RESP_ENTRIES 4
8816+#define ADAP_NORM_RESP_ENTRIES 8
8817+
8818+#define TOTAL_QUEUE_ENTRIES \
8819+ (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8820+ HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8821+
8822+
8823+
8824+
8825+// Set the queues on a 16 byte alignment
8826+#define QUEUE_ALIGNMENT 16
8827+
8828+
8829+//
8830+// The queue headers define the Communication Region queues. These
8831+// are physically contiguous and accessible by both the adapter and the
8832+// host. Even though all queue headers are in the same contiguous block they will be
8833+// represented as individual units in the data structures.
8834+//
8835+
8836+typedef AAC_UINT32 QUEUE_INDEX;
8837+
8838+typedef QUEUE_INDEX *PQUEUE_INDEX;
8839+
8840+typedef struct _QUEUE_ENTRY {
8841+
8842+ AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8843+ AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8844+
8845+} QUEUE_ENTRY;
8846+
8847+typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8848+
8849+
8850+
8851+// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8852+// adjacently and in that order.
8853+//
8854+typedef struct _QUEUE_HEADERS {
8855+
8856+ PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8857+ PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8858+ PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8859+
8860+} QUEUE_HEADERS;
8861+typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8862+
8863+//
8864+// Define all the events which the adapter would like to notify
8865+// the host of.
8866+//
8867+typedef enum _ADAPTER_EVENT {
8868+ HostNormCmdQue = 1, // Change in host normal priority command queue
8869+ HostHighCmdQue, // Change in host high priority command queue
8870+ HostNormRespQue, // Change in host normal priority response queue
8871+ HostHighRespQue, // Change in host high priority response queue
8872+ AdapNormRespNotFull,
8873+ AdapHighRespNotFull,
8874+ AdapNormCmdNotFull,
8875+ AdapHighCmdNotFull,
8876+ SynchCommandComplete,
8877+ AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8878+
8879+} _E_ADAPTER_EVENT;
8880+
8881+#ifdef AAC_32BIT_ENUMS
8882+typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8883+#else
8884+typedef AAC_UINT32 ADAPTER_EVENT;
8885+#endif
8886+
8887+//
8888+// Define all the events the host wishes to notify the
8889+// adapter of.
8890+//
8891+typedef enum _HOST_2_ADAP_EVENT {
8892+ AdapNormCmdQue = 1,
8893+ AdapHighCmdQue,
8894+ AdapNormRespQue,
8895+ AdapHighRespQue,
8896+ HostShutdown,
8897+ HostPowerFail,
8898+ FatalCommError,
8899+ HostNormRespNotFull,
8900+ HostHighRespNotFull,
8901+ HostNormCmdNotFull,
8902+ HostHighCmdNotFull,
8903+ FastIo,
8904+ AdapPrintfDone
8905+} _E_HOST_2_ADAP_EVENT;
8906+
8907+#ifdef AAC_32BIT_ENUMS
8908+typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8909+#else
8910+typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8911+#endif
8912+
8913+//
8914+// Define all the queues that the adapter and host use to communicate
8915+//
8916+
8917+typedef enum _QUEUE_TYPES {
8918+ HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8919+ HostHighCmdQueue, // Adapter to host high priority command traffic
8920+ AdapNormRespQueue, // Host to adapter normal priority response traffic
8921+ AdapHighRespQueue, // Host to adapter high priority response traffic
8922+ AdapNormCmdQueue, // Host to adapter normal priority command traffic
8923+ AdapHighCmdQueue, // Host to adapter high priority command traffic
8924+ HostNormRespQueue, // Adapter to host normal priority response traffic
8925+ HostHighRespQueue // Adapter to host high priority response traffic
8926+} _E_QUEUE_TYPES;
8927+
8928+#ifdef AAC_32BIT_ENUMS
8929+typedef _E_QUEUE_TYPES QUEUE_TYPES;
8930+#else
8931+typedef AAC_UINT32 QUEUE_TYPES;
8932+#endif
8933+
8934+
8935+//
8936+// Assign type values to the FSA communication data structures
8937+//
8938+
8939+typedef enum _STRUCT_TYPES {
8940+ TFib = 1,
8941+ TQe,
8942+ TCtPerf
8943+} _E_STRUCT_TYPES;
8944+
8945+#ifdef AAC_32BIT_ENUMS
8946+typedef _E_STRUCT_TYPES STRUCT_TYPES;
8947+#else
8948+typedef AAC_UINT32 STRUCT_TYPES;
8949+#endif
8950+
8951+//
8952+// Define the priority levels the FSA communication routines support.
8953+//
8954+
8955+typedef enum _COMM_PRIORITIES {
8956+ FsaNormal = 1,
8957+ FsaHigh
8958+} _E_COMM_PRIORITIES;
8959+
8960+#ifdef AAC_32BIT_ENUMS
8961+typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
8962+#else
8963+typedef AAC_UINT32 COMM_PRIORITIES;
8964+#endif
8965+
8966+
8967+
8968+//
8969+// Define the LIST_ENTRY structure. This structure is used on the NT side to link
8970+// the FIBs together in a linked list. Since this structure gets compiled on the adapter
8971+// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
8972+// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
8973+// is already defined.
8974+#if !defined(_NTDEF_) && !defined(_WINNT_)
8975+typedef struct _LIST_ENTRY {
8976+ struct _LIST_ENTRY *Flink;
8977+ struct _LIST_ENTRY *Blink;
8978+} LIST_ENTRY;
8979+typedef LIST_ENTRY *PLIST_ENTRY;
8980+#endif
8981+
8982+
8983+//
8984+// Define the FIB. The FIB is the where all the requested data and
8985+// command information are put to the application on the FSA adapter.
8986+//
8987+
8988+typedef struct _FIB_HEADER {
8989+ AAC_UINT32 XferState; // Current transfer state for this CCB
8990+ AAC_UINT16 Command; // Routing information for the destination
8991+ AAC_UINT8 StructType; // Type FIB
8992+ AAC_UINT8 Flags; // Flags for FIB
8993+ AAC_UINT16 Size; // Size of this FIB in bytes
8994+ AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
8995+ AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
8996+ AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
8997+ AAC_UINT32 SenderData; // Place holder for the sender to store data
8998+#ifndef __midl
8999+ union {
9000+ struct {
9001+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9002+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9003+ } _s;
9004+ LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
9005+ } _u;
9006+#else // The MIDL compiler does not support unions without a discriminant.
9007+ struct { // Since nothing during the midl compile actually looks into this
9008+ struct { // structure, this shoudl be ok.
9009+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9010+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9011+ } _s;
9012+ } _u;
9013+#endif
9014+} FIB_HEADER;
9015+
9016+
9017+#define FibLinks _u._FibLinks
9018+
9019+
9020+#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9021+
9022+
9023+typedef struct _FIB {
9024+
9025+#ifdef BRIDGE //rma
9026+ DLQUE link;
9027+#endif
9028+ FIB_HEADER Header;
9029+
9030+ AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
9031+
9032+} FIB;
9033+typedef FIB *PFIB;
9034+
9035+
9036+
9037+//
9038+// FIB commands
9039+//
9040+
9041+typedef enum _FIB_COMMANDS {
9042+ TestCommandResponse = 1,
9043+ TestAdapterCommand = 2,
9044+
9045+ // Lowlevel and comm commands
9046+
9047+ LastTestCommand = 100,
9048+ ReinitHostNormCommandQueue = 101,
9049+ ReinitHostHighCommandQueue = 102,
9050+ ReinitHostHighRespQueue = 103,
9051+ ReinitHostNormRespQueue = 104,
9052+ ReinitAdapNormCommandQueue = 105,
9053+ ReinitAdapHighCommandQueue = 107,
9054+ ReinitAdapHighRespQueue = 108,
9055+ ReinitAdapNormRespQueue = 109,
9056+ InterfaceShutdown = 110,
9057+ DmaCommandFib = 120,
9058+ StartProfile = 121,
9059+ TermProfile = 122,
9060+ SpeedTest = 123,
9061+ TakeABreakPt = 124,
9062+ RequestPerfData = 125,
9063+ SetInterruptDefTimer= 126,
9064+ SetInterruptDefCount= 127,
9065+ GetInterruptDefStatus= 128,
9066+ LastCommCommand = 129,
9067+
9068+ // Filesystem commands
9069+
9070+ NuFileSystem = 300,
9071+ UFS = 301,
9072+ HostFileSystem = 302,
9073+ LastFileSystemCommand = 303,
9074+
9075+ // Container Commands
9076+
9077+ ContainerCommand = 500,
9078+ ContainerCommand64 = 501,
9079+
9080+ // Cluster Commands
9081+
9082+ ClusterCommand = 550,
9083+
9084+ // Scsi Port commands (scsi passthrough)
9085+
9086+ ScsiPortCommand = 600,
9087+
9088+ // misc house keeping and generic adapter initiated commands
9089+
9090+ AifRequest = 700,
9091+ CheckRevision = 701,
9092+ FsaHostShutdown = 702,
9093+ RequestAdapterInfo = 703,
9094+ IsAdapterPaused = 704,
9095+ SendHostTime = 705,
9096+ LastMiscCommand = 706
9097+
9098+} _E_FIB_COMMANDS;
9099+
9100+
9101+
9102+typedef AAC_UINT16 FIB_COMMAND;
9103+
9104+//
9105+// Commands that will target the failover level on the FSA adapter
9106+//
9107+
9108+typedef enum _FIB_XFER_STATE {
9109+ HostOwned = (1<<0),
9110+ AdapterOwned = (1<<1),
9111+ FibInitialized = (1<<2),
9112+ FibEmpty = (1<<3),
9113+ AllocatedFromPool = (1<<4),
9114+ SentFromHost = (1<<5),
9115+ SentFromAdapter = (1<<6),
9116+ ResponseExpected = (1<<7),
9117+ NoResponseExpected = (1<<8),
9118+ AdapterProcessed = (1<<9),
9119+ HostProcessed = (1<<10),
9120+ HighPriority = (1<<11),
9121+ NormalPriority = (1<<12),
9122+ Async = (1<<13),
9123+ AsyncIo = (1<<13), // rpbfix: remove with new regime
9124+ PageFileIo = (1<<14), // rpbfix: remove with new regime
9125+ ShutdownRequest = (1<<15),
9126+ LazyWrite = (1<<16), // rpbfix: remove with new regime
9127+ AdapterMicroFib = (1<<17),
9128+ BIOSFibPath = (1<<18),
9129+ FastResponseCapable = (1<<19),
9130+ ApiFib = (1<<20) // Its an API Fib.
9131+
9132+} _E_FIB_XFER_STATE;
9133+
9134+
9135+typedef enum _FSA_ERRORS {
9136+ FSA_NORMAL = 0,
9137+ FSA_SUCCESS = 0,
9138+ FSA_PENDING = 0x01,
9139+ FSA_FATAL = 0x02,
9140+ FSA_INVALID_QUEUE = 0x03,
9141+ FSA_NOENTRIES = 0x04,
9142+ FSA_SENDFAILED = 0x05,
9143+ FSA_INVALID_QUEUE_PRIORITY = 0x06,
9144+ FSA_FIB_ALLOCATION_FAILED = 0x07,
9145+ FSA_FIB_DEALLOCATION_FAILED = 0x08
9146+
9147+} _E_FSA_ERRORS;
9148+
9149+
9150+//
9151+// The following defines needs to be updated any time there is an incompatible change made
9152+// to the ADAPTER_INIT_STRUCT structure.
9153+//
9154+#define ADAPTER_INIT_STRUCT_REVISION 3
9155+
9156+typedef struct _ADAPTER_INIT_STRUCT {
9157+ AAC_UINT32 InitStructRevision;
9158+ AAC_UINT32 MiniPortRevision;
9159+ AAC_UINT32 FilesystemRevision;
9160+ PAAC_VOID CommHeaderAddress;
9161+ PAAC_VOID FastIoCommAreaAddress;
9162+ PAAC_VOID AdapterFibsPhysicalAddress;
9163+ PAAC_VOID AdapterFibsVirtualAddress;
9164+ AAC_UINT32 AdapterFibsSize;
9165+ AAC_UINT32 AdapterFibAlign;
9166+ PAAC_VOID PrintfBufferAddress;
9167+ AAC_UINT32 PrintfBufferSize;
9168+ AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9169+ AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9170+} ADAPTER_INIT_STRUCT;
9171+typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9172+
9173+#ifdef AAC_32BIT_ENUMS
9174+typedef _E_FSA_ERRORS FSA_ERRORS;
9175+#else
9176+typedef AAC_UINT32 FSA_ERRORS;
9177+#endif
9178+
9179+typedef enum _LOG_LEVEL {
9180+ LOG_INIT = 10,
9181+ LOG_INFORMATIONAL = 20,
9182+ LOG_WARNING = 30,
9183+ LOG_LOW_ERROR = 40,
9184+ LOG_MEDIUM_ERROR = 50,
9185+ LOG_HIGH_ERROR = 60,
9186+ LOG_PANIC = 70,
9187+ LOG_DEBUG = 80,
9188+ LOG_WINDBG_PRINT = 90
9189+} _E_LOG_LEVEL;
9190+
9191+#ifdef AAC_32BIT_ENUMS
9192+typedef _E_LOG_LEVEL LOG_LEVEL;
9193+#else
9194+typedef AAC_UINT32 LOG_LEVEL;
9195+#endif
9196+
9197+
9198+#endif //_COMM_STRUCT
9199+
9200+
9201diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9202--- linux-2.4.4/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 18:00:00 1969
9203+++ linux/drivers/scsi/aacraid/include/comsup.h Mon Apr 30 09:43:34 2001
9204@@ -0,0 +1,132 @@
9205+/*++
9206+ * Adaptec aacraid device driver for Linux.
9207+ *
9208+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9209+ *
9210+ * This program is free software; you can redistribute it and/or modify
9211+ * it under the terms of the GNU General Public License as published by
9212+ * the Free Software Foundation; either version 2, or (at your option)
9213+ * any later version.
9214+ *
9215+ * This program is distributed in the hope that it will be useful,
9216+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9217+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9218+ * GNU General Public License for more details.
9219+ *
9220+ * You should have received a copy of the GNU General Public License
9221+ * along with this program; see the file COPYING. If not, write to
9222+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9223+ *
9224+ * Module Name:
9225+ * comsup.h
9226+ *
9227+ * Abstract: This module defines the data structures that make up the
9228+ * commuication region for the FSA filesystem. This region is
9229+ * how the host based code commuicates both control and data
9230+ * to the adapter based code.
9231+ *
9232+ *
9233+ *
9234+ --*/
9235+#ifndef _COMM_SUP_DEF
9236+#define _COMM_SUP_DEF
9237+
9238+static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9239+
9240+//
9241+// The adapter interface specs all queues to be located in the same physically
9242+// contigous block. The host structure that defines the commuication queues will
9243+// assume they are each a seperate physically contigous memory region that will
9244+// support them all being one big contigous block.
9245+// There is a command and response queue for each level and direction of
9246+// commuication. These regions are accessed by both the host and adapter.
9247+//
9248+typedef struct _COMM_QUE {
9249+
9250+ PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9251+
9252+ PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9253+ QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9254+ ULONG QueueEntries; // Number of queue entries on this queue
9255+ OS_CV_T QueueFull; // Event to wait on if the queue is full
9256+ OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9257+ // This is only valid for adapter to host command queues.
9258+ OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9259+ KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9260+ ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9261+ // Only queues which the host will be the consumer will this field be valid
9262+ LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9263+ // only valid for command queues which receive entries from the adapter.
9264+ LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9265+ ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9266+
9267+ PVOID Adapter; // Back pointer to adapter structure
9268+
9269+} COMM_QUE;
9270+typedef COMM_QUE *PCOMM_QUE;
9271+
9272+
9273+typedef struct _COMM_REGION {
9274+
9275+ COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9276+ COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9277+
9278+ COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9279+ COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9280+
9281+ COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9282+ COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9283+
9284+ COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9285+ COMM_QUE AdapHighRespQue; // A response for high priority host responses
9286+
9287+ //
9288+ // The 2 threads below are the threads which handle command traffic from the
9289+ // the adapter. There is one for normal priority and one for high priority queues.
9290+ // These threads will wait on the commandready event for it's queue.
9291+ //
9292+
9293+ HANDLE NormCommandThread;
9294+ HANDLE HighCommandThread;
9295+
9296+ //
9297+ // This dpc routine will handle the setting the of not full event when the adapter
9298+ // lets us know the queue is not longer full via interrupt
9299+ //
9300+
9301+ KDPC QueueNotFullDpc;
9302+
9303+#ifdef API_THROTTLE
9304+ //
9305+ // Support for data I/O throttling to improve CLI performance
9306+ // while the system is under load.
9307+ // This is the throttling mechanism built into the COMM layer.
9308+ // Look in commsup.c, dpcsup.c and comminit.c for use.
9309+ //
9310+
9311+ int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9312+ int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9313+ LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9314+ LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9315+ BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9316+ KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9317+ KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9318+ KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9319+
9320+ unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9321+ unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9322+ unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9323+
9324+ unsigned int ThrottledFibs;
9325+ unsigned int ThrottleTimedoutFibs;
9326+ unsigned int ApiFibs;
9327+ unsigned int NonPassiveFibs;
9328+ unsigned int TotalFibs;
9329+ unsigned int FSInfoFibs;
9330+
9331+#endif // #ifdef API_THROTTLE
9332+
9333+} COMM_REGION;
9334+typedef COMM_REGION *PCOMM_REGION;
9335+
9336+#endif // _COMM_SUP
9337diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9338--- linux-2.4.4/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 18:00:00 1969
9339+++ linux/drivers/scsi/aacraid/include/fsact.h Mon Apr 30 09:43:34 2001
9340@@ -0,0 +1,165 @@
9341+/*++
9342+ * Adaptec aacraid device driver for Linux.
9343+ *
9344+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9345+ *
9346+ * This program is free software; you can redistribute it and/or modify
9347+ * it under the terms of the GNU General Public License as published by
9348+ * the Free Software Foundation; either version 2, or (at your option)
9349+ * any later version.
9350+ *
9351+ * This program is distributed in the hope that it will be useful,
9352+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9353+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9354+ * GNU General Public License for more details.
9355+ *
9356+ * You should have received a copy of the GNU General Public License
9357+ * along with this program; see the file COPYING. If not, write to
9358+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9359+ *
9360+ * Module Name:
9361+ * fsact.h
9362+ *
9363+ * Abstract: Common container structures that are required to be
9364+ * known on both the host and adapter.
9365+ *
9366+ *
9367+ --*/
9368+#ifndef _FSACT_H_
9369+#define _FSACT_H_
9370+
9371+static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9372+
9373+//#include <comstruc.h>
9374+//#include <fsatypes.h>
9375+#include <protocol.h> // definitions for FSASTATUS
9376+
9377+
9378+/*
9379+ * Object-Server / Volume-Manager Dispatch Classes
9380+ */
9381+typedef enum _VM_COMMANDS {
9382+ VM_Null = 0,
9383+ VM_NameServe,
9384+ VM_ContainerConfig,
9385+ VM_Ioctl,
9386+ VM_FilesystemIoctl,
9387+ VM_CloseAll,
9388+ VM_CtBlockRead, // see protocol.h for BlockRead command layout
9389+ VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9390+ VM_SliceBlockRead, // raw access to configured "storage objects"
9391+ VM_SliceBlockWrite,
9392+ VM_DriveBlockRead, // raw access to physical devices
9393+ VM_DriveBlockWrite,
9394+ VM_EnclosureMgt, // enclosure management
9395+ VM_Unused, // used to be diskset management
9396+ VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9397+ VM_CtPerf, // performance test
9398+ VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9399+ VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9400+ VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9401+ MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9402+} _E_VMCOMMAND;
9403+
9404+#ifdef AAC_32BIT_ENUMS
9405+typedef _E_VMCOMMAND VMCOMMAND;
9406+#else
9407+typedef AAC_UINT32 VMCOMMAND;
9408+#endif
9409+
9410+
9411+
9412+//
9413+// Descriptive information (eg, vital stats)
9414+// that a content manager might report. The
9415+// FileArray filesystem component is one example
9416+// of a content manager. Raw mode might be
9417+// another.
9418+//
9419+
9420+struct FileSysInfo {
9421+/*
9422+ a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9423+ b) FSA usage (implemented by ObjType and ContentState fields)
9424+ c) Block size
9425+ d) Frag size
9426+ e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9427+ f) I-node density - (computed from other fields)
9428+*/
9429+ AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9430+ AAC_UINT32 fsBlockSize;
9431+ AAC_UINT32 fsFragSize;
9432+ AAC_UINT32 fsMaxExtendSize;
9433+ AAC_UINT32 fsSpaceUnits;
9434+ AAC_UINT32 fsMaxNumFiles;
9435+ AAC_UINT32 fsNumFreeFiles;
9436+ AAC_UINT32 fsInodeDensity;
9437+}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9438+
9439+union ContentManagerInfo {
9440+ struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9441+};
9442+
9443+//
9444+// Query for "mountable" objects, ie, objects that are typically
9445+// associated with a drive letter on the client (host) side.
9446+//
9447+
9448+typedef struct _MNTOBJ {
9449+
9450+ AAC_UINT32 ObjectId;
9451+ FSASTRING FileSystemName; // if applicable
9452+ ContainerCreationInfo CreateInfo; // if applicable
9453+ AAC_UINT32 Capacity;
9454+ FSAVOLTYPE VolType; // substrate structure
9455+ FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9456+ AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9457+
9458+ union ContentManagerInfo
9459+ ObjExtension; // Info specific to content manager (eg, filesystem)
9460+
9461+ AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9462+
9463+} MNTOBJ;
9464+
9465+
9466+#define FSCS_READONLY 0x0002 // possible result of broken mirror
9467+
9468+
9469+
9470+typedef struct _MNTINFO {
9471+
9472+ VMCOMMAND Command;
9473+ FTYPE MntType;
9474+ AAC_UINT32 MntCount;
9475+
9476+} MNTINFO;
9477+typedef MNTINFO *PMNTINFO;
9478+
9479+typedef struct _MNTINFORESPONSE {
9480+
9481+ FSASTATUS Status;
9482+ FTYPE MntType; // should be same as that requested
9483+ AAC_UINT32 MntRespCount;
9484+ MNTOBJ MntTable[1];
9485+
9486+} MNTINFORESPONSE;
9487+typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9488+
9489+
9490+//
9491+// The following command is sent to shut down each container.
9492+//
9493+
9494+typedef struct _CLOSECOMMAND {
9495+
9496+ VMCOMMAND Command;
9497+ AAC_UINT32 ContainerId;
9498+
9499+} CLOSECOMMAND;
9500+typedef CLOSECOMMAND *PCLOSECOMMAND;
9501+
9502+
9503+#endif /* _FSACT_H_ */
9504+
9505+
9506diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9507--- linux-2.4.4/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 18:00:00 1969
9508+++ linux/drivers/scsi/aacraid/include/fsafs.h Mon Apr 30 09:43:34 2001
9509@@ -0,0 +1,78 @@
9510+/*++
9511+ * Adaptec aacraid device driver for Linux.
9512+ *
9513+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9514+ *
9515+ * This program is free software; you can redistribute it and/or modify
9516+ * it under the terms of the GNU General Public License as published by
9517+ * the Free Software Foundation; either version 2, or (at your option)
9518+ * any later version.
9519+ *
9520+ * This program is distributed in the hope that it will be useful,
9521+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9522+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9523+ * GNU General Public License for more details.
9524+ *
9525+ * You should have received a copy of the GNU General Public License
9526+ * along with this program; see the file COPYING. If not, write to
9527+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9528+ *
9529+ * Module Name:
9530+ * fsafs.h
9531+ *
9532+ * Abstract: Common file system structures that are required to be
9533+ * known on both the host and adapter
9534+ *
9535+ *
9536+ *
9537+ --*/
9538+
9539+#ifndef _FSAFS_H_
9540+#define _FSAFS_H_ 1
9541+
9542+static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9543+
9544+#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9545+
9546+/*
9547+ * Maximum number of filesystems.
9548+ */
9549+#define NFILESYS 24
9550+
9551+/*
9552+ * File identifier.
9553+ * These are unique and self validating within a filesystem
9554+ * on a single machine and can persist across reboots.
9555+ * The hint field may be volatile and is not guaranteed to persist
9556+ * across reboots but is used to speed up the FID to file object translation
9557+ * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9558+ * the file object (assuming a filesystem context, i.e. driveno).
9559+ */
9560+typedef struct {
9561+ AAC_UINT32 hint; // last used hint for fast reclaim
9562+ AAC_UINT32 f1; // opaque
9563+ AAC_UINT32 f2; // opaque
9564+ } fileid_t; /* intra-filesystem file ID type */
9565+
9566+
9567+/*
9568+ * Generic file handle
9569+ */
9570+struct fhandle {
9571+ fsid_t fh_fsid; /* File system id of mount point */
9572+ fileid_t fh_fid; /* File sys specific file id */
9573+};
9574+typedef struct fhandle fhandle_t;
9575+
9576+#define FIDSIZE sizeof(fhandle_t)
9577+
9578+typedef struct {
9579+ union {
9580+ AAC_INT8 fid_data[FIDSIZE];
9581+ struct fhandle fsafid;
9582+ } fidu;
9583+} FSAFID; /* FSA File ID type */
9584+
9585+
9586+#endif /* _FSAFS_H_ */
9587+
9588diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9589--- linux-2.4.4/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9590+++ linux/drivers/scsi/aacraid/include/fsaioctl.h Mon Apr 30 09:43:34 2001
9591@@ -0,0 +1,159 @@
9592+/*++
9593+ * Adaptec aacraid device driver for Linux.
9594+ *
9595+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9596+ *
9597+ * This program is free software; you can redistribute it and/or modify
9598+ * it under the terms of the GNU General Public License as published by
9599+ * the Free Software Foundation; either version 2, or (at your option)
9600+ * any later version.
9601+ *
9602+ * This program is distributed in the hope that it will be useful,
9603+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9604+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9605+ * GNU General Public License for more details.
9606+ *
9607+ * You should have received a copy of the GNU General Public License
9608+ * along with this program; see the file COPYING. If not, write to
9609+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9610+ *
9611+ * Module Name:
9612+ * fsaioctl.h
9613+ *
9614+ * Abstract: Defines the interface structures between user mode applications
9615+ * and the fsa driver. This structures are used in
9616+ * DeviceIoControl() calls.
9617+ *
9618+ *
9619+ *
9620+ --*/
9621+#ifndef _FSAIOCTL_H_
9622+#define _FSAIOCTL_H_
9623+
9624+static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9625+
9626+#ifndef IOTRACEUSER
9627+
9628+#ifndef CTL_CODE
9629+
9630+
9631+#define FILE_DEVICE_CONTROLLER 0x00000004
9632+
9633+//
9634+// Macro definition for defining IOCTL and FSCTL function control codes. Note
9635+// that function codes 0-2047 are reserved for Microsoft Corporation, and
9636+// 2048-4095 are reserved for customers.
9637+//
9638+
9639+#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9640+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9641+)
9642+
9643+//
9644+// Define the method codes for how buffers are passed for I/O and FS controls
9645+//
9646+
9647+#define METHOD_BUFFERED 0
9648+
9649+
9650+#define METHOD_NEITHER 3
9651+
9652+//
9653+// Define the access check value for any access
9654+//
9655+//
9656+// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9657+// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9658+// constants *MUST* always be in sync.
9659+//
9660+#define FILE_ANY_ACCESS 0
9661+
9662+
9663+
9664+#endif
9665+
9666+
9667+
9668+typedef struct _UNIX_QUERY_DISK {
9669+ AAC_INT32 ContainerNumber;
9670+ AAC_INT32 Bus;
9671+ AAC_INT32 Target;
9672+ AAC_INT32 Lun;
9673+ AAC_BOOLEAN Valid;
9674+ AAC_BOOLEAN Locked;
9675+ AAC_BOOLEAN Deleted;
9676+ AAC_INT32 Instance;
9677+ AAC_INT8 diskDeviceName[10];
9678+ AAC_BOOLEAN UnMapped;
9679+} UNIX_QUERY_DISK;
9680+typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9681+
9682+
9683+typedef struct _DELETE_DISK {
9684+ AAC_UINT32 NtDiskNumber;
9685+ AAC_UINT32 ContainerNumber;
9686+} DELETE_DISK;
9687+typedef DELETE_DISK *PDELETE_DISK;
9688+
9689+
9690+#endif /*IOTRACEUSER*/
9691+
9692+#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9693+#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9694+
9695+
9696+#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9697+
9698+
9699+#define FSACTL_GET_VAR 0x93
9700+#define FSACTL_SET_VAR 0xa3
9701+#define FSACTL_GET_FIBTIMES 0xb3
9702+#define FSACTL_ZERO_FIBTIMES 0xc3
9703+
9704+
9705+#define FSACTL_DELETE_DISK 0x163
9706+#define FSACTL_QUERY_DISK 0x173
9707+
9708+
9709+// AfaComm perfmon ioctls
9710+#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9711+
9712+
9713+#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9714+
9715+
9716+typedef struct _GET_ADAPTER_FIB_IOCTL {
9717+ char *AdapterFibContext;
9718+ int Wait;
9719+ char *AifFib;
9720+} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9721+
9722+//
9723+// filesystem ioctls
9724+//
9725+#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9726+
9727+#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9728+
9729+#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9730+
9731+#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9732+
9733+#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9734+
9735+
9736+#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9737+
9738+
9739+#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9740+
9741+
9742+#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9743+
9744+
9745+#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9746+
9747+
9748+#endif // _FSAIOCTL_H_
9749+
9750+
9751diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9752--- linux-2.4.4/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 18:00:00 1969
9753+++ linux/drivers/scsi/aacraid/include/fsaport.h Mon Apr 30 09:43:34 2001
9754@@ -0,0 +1,223 @@
9755+/*++
9756+ * Adaptec aacraid device driver for Linux.
9757+ *
9758+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9759+ *
9760+ * This program is free software; you can redistribute it and/or modify
9761+ * it under the terms of the GNU General Public License as published by
9762+ * the Free Software Foundation; either version 2, or (at your option)
9763+ * any later version.
9764+ *
9765+ * This program is distributed in the hope that it will be useful,
9766+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9767+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9768+ * GNU General Public License for more details.
9769+ *
9770+ * You should have received a copy of the GNU General Public License
9771+ * along with this program; see the file COPYING. If not, write to
9772+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9773+ *
9774+ * Module Name:
9775+ * fsaport.h
9776+ *
9777+ * Abstract: This module defines all of the globally used procedures in the FSA
9778+ * file system.
9779+ *
9780+ *
9781+ *
9782+ --*/
9783+#ifndef _FSAPORT_
9784+#define _FSAPORT_
9785+
9786+static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9787+
9788+//
9789+// The scatter/gather map context is the information we
9790+// we need to keep the map and transfer data to and from the
9791+// adapter.
9792+//
9793+
9794+typedef struct _SGMAP_CONTEXT {
9795+
9796+ caddr_t BaseAddress;
9797+ PVOID MapRegBase;
9798+ ULONG NumberMapRegs;
9799+ PSGMAP SgMapPtr;
9800+ ULONG ByteCount; // Used to check the Mdl length.
9801+ BOOLEAN WriteToDevice;
9802+
9803+ struct buf *bp;
9804+
9805+
9806+} SGMAP_CONTEXT;
9807+typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9808+
9809+typedef struct _MAPFIB_CONTEXT {
9810+ PMDL Mdl;
9811+ PVOID MapRegBase;
9812+ ULONG NumberMapRegs;
9813+ PVOID FibVirtualAddress;
9814+ ULONG Size;
9815+ PVOID FibPhysicalAddress;
9816+
9817+
9818+} MAPFIB_CONTEXT;
9819+typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9820+
9821+typedef BOOLEAN
9822+(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9823+ PVOID AdapterExtension,
9824+ IN OUT PVOID *BaseAddress,
9825+ IN ULONG Size,
9826+ IN ULONG Alignment
9827+ );
9828+
9829+typedef BOOLEAN
9830+(*PFSA_FREE_ADAPTER_COMM_AREA)(
9831+ PVOID AdapterExtension
9832+ );
9833+
9834+typedef VOID
9835+(*PFSA_FREE_DMA_RESOURCES)(
9836+ IN PVOID AdapterExtension,
9837+ IN PSGMAP_CONTEXT SgMapContext
9838+ );
9839+
9840+typedef BOOLEAN
9841+(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9842+ IN PVOID AdapterExtension,
9843+ IN PMAPFIB_CONTEXT MapFibContext
9844+ );
9845+
9846+typedef BOOLEAN
9847+(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9848+ IN PVOID AdapterExtension,
9849+ IN PMAPFIB_CONTEXT MapFibContext
9850+ );
9851+
9852+typedef VOID
9853+(*PFSA_INTERRUPT_ADAPTER)(
9854+ IN PVOID AdapterExtension
9855+ );
9856+
9857+typedef VOID
9858+(*PFSA_NOTIFY_ADAPTER)(
9859+ IN PVOID AdapterExtension,
9860+ IN HOST_2_ADAP_EVENT AdapterEvent
9861+ );
9862+
9863+typedef VOID
9864+(*PFSA_RESET_DEVICE)(
9865+ PVOID AdapterExtension
9866+ );
9867+
9868+typedef AAC_STATUS
9869+(*PFSA_BUILD_SGMAP)(
9870+ IN PVOID AdapterExtension,
9871+ IN PSGMAP_CONTEXT SgMapContext
9872+ );
9873+
9874+typedef PVOID
9875+(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9876+ IN PVOID AdapterExtension,
9877+ IN PVOID AdapterAddress
9878+ );
9879+
9880+typedef VOID
9881+(*PFSA_INTERRUPT_HOST)(
9882+ PVOID Adapter,
9883+ ADAPTER_EVENT AdapterEvent
9884+ );
9885+
9886+typedef VOID
9887+(*PFSA_ENABLE_INTERRUPT)(
9888+ PVOID Adapter,
9889+ ADAPTER_EVENT AdapterEvent,
9890+ BOOLEAN AtDeviceIrq
9891+ );
9892+
9893+
9894+typedef VOID
9895+(*PFSA_DISABLE_INTERRUPT)(
9896+ PVOID Adapter,
9897+ ADAPTER_EVENT AdapterEvent,
9898+ BOOLEAN AtDeviceIrq
9899+ );
9900+
9901+typedef AAC_STATUS
9902+(*PFSA_OPEN_ADAPTER) (
9903+ IN PVOID Adapter
9904+ );
9905+
9906+typedef int
9907+(*PFSA_DEVICE_CONTROL) (
9908+ IN PVOID Adapter,
9909+ IN PAFA_IOCTL_CMD IoctlCmdPtr
9910+ );
9911+
9912+typedef AAC_STATUS
9913+(*PFSA_CLOSE_ADAPTER) (
9914+ IN PVOID Adapter
9915+ );
9916+
9917+typedef BOOLEAN
9918+(*PFSA_SEND_SYNCH_FIB) (
9919+ IN PVOID Adapter,
9920+ IN ULONG FibPhysicalAddress
9921+ );
9922+
9923+typedef struct _FSAPORT_FUNCS {
9924+ ULONG SizeOfFsaPortFuncs;
9925+
9926+ PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9927+ PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9928+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9929+ PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9930+ PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9931+ PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9932+ PFSA_NOTIFY_ADAPTER NotifyAdapter;
9933+ PFSA_ENABLE_INTERRUPT EnableInterrupt;
9934+ PFSA_DISABLE_INTERRUPT DisableInterrupt;
9935+ PFSA_RESET_DEVICE ResetDevice;
9936+ PFSA_BUILD_SGMAP BuildSgMap;
9937+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9938+
9939+ PFSA_INTERRUPT_HOST InterruptHost;
9940+ PFSA_OPEN_ADAPTER OpenAdapter;
9941+ PFSA_DEVICE_CONTROL DeviceControl;
9942+ PFSA_CLOSE_ADAPTER CloseAdapter;
9943+
9944+ PFSA_SEND_SYNCH_FIB SendSynchFib;
9945+
9946+} FSAPORT_FUNCS;
9947+typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9948+
9949+typedef AAC_STATUS
9950+(*PFSA_SETVAR_CALLBACK) (
9951+ IN PVOID Adapter,
9952+ IN ULONG NewValue
9953+ );
9954+
9955+typedef struct _FSA_USER_VAR {
9956+ char Name[32];
9957+ ULONG *Address;
9958+ PFSA_SETVAR_CALLBACK SetVarCallback;
9959+} FSA_USER_VAR;
9960+
9961+typedef FSA_USER_VAR *PFSA_USER_VAR;
9962+
9963+typedef struct _FSA_NEW_ADAPTER {
9964+ PVOID AdapterExtension;
9965+ PFSAPORT_FUNCS AdapterFuncs;
9966+ PVOID Adapter;
9967+ BOOLEAN AdapterInterruptsBelowDpc;
9968+ PFSA_USER_VAR AdapterUserVars;
9969+ ULONG AdapterUserVarsSize;
9970+ void *Dip;
9971+} FSA_NEW_ADAPTER;
9972+typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
9973+
9974+#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9975+#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9976+
9977+#endif
9978diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
9979--- linux-2.4.4/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
9980+++ linux/drivers/scsi/aacraid/include/fsatypes.h Mon Apr 30 09:43:34 2001
9981@@ -0,0 +1,214 @@
9982+/*++
9983+ * Adaptec aacraid device driver for Linux.
9984+ *
9985+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9986+ *
9987+ * This program is free software; you can redistribute it and/or modify
9988+ * it under the terms of the GNU General Public License as published by
9989+ * the Free Software Foundation; either version 2, or (at your option)
9990+ * any later version.
9991+ *
9992+ * This program is distributed in the hope that it will be useful,
9993+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9994+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9995+ * GNU General Public License for more details.
9996+ *
9997+ * You should have received a copy of the GNU General Public License
9998+ * along with this program; see the file COPYING. If not, write to
9999+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10000+ *
10001+ * Module Name:
10002+ * fsatypes.h
10003+ *
10004+ * Abstract: Define all shared data types here, ie, those
10005+ * types shared among several components, such
10006+ * as host (driver + apps), adapter, and BIOS.
10007+ *
10008+ *
10009+ --*/
10010+#ifndef _FSATYPES_H
10011+#define _FSATYPES_H
10012+
10013+static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10014+
10015+typedef AAC_UINT32 AAC_BOOLEAN;
10016+
10017+//
10018+// Define a 64-bit address structure for use on
10019+// a 32-bit processor architecture.
10020+//
10021+typedef struct {
10022+ AAC_UINT32 lo32;
10023+ AAC_UINT32 hi32;
10024+} AAC_UINT64S, *PAAC_UINT64S;
10025+
10026+
10027+
10028+//
10029+// Container Types
10030+//
10031+typedef struct {
10032+ AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
10033+ // know what it looks like. Note, BIOS sees this
10034+ // definition and it must be coded in such a way
10035+ // that it appears to be 64 bits. ints are 16 bits
10036+ // in BIOS land; fortunately, longs are 32 bits.
10037+} SerialNumberT;
10038+
10039+
10040+
10041+//
10042+// ***********************
10043+// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10044+// ***********************
10045+// drivers for CT_NONE to CT_PASSTHRU
10046+//
10047+typedef enum _FSAVOLTYPE {
10048+ CT_NONE = 0,
10049+ CT_VOLUME,
10050+ CT_MIRROR,
10051+ CT_STRIPE,
10052+ CT_RAID5,
10053+ CT_SSRW,
10054+ CT_SSRO,
10055+ CT_MORPH,
10056+ CT_PASSTHRU,
10057+ CT_RAID4,
10058+ CT_RAID10, // stripe of mirror
10059+ CT_RAID00, // stripe of stripe
10060+ CT_VOLUME_OF_MIRRORS, // volume of mirror
10061+ CT_PSEUDO_RAID3, // really raid4
10062+
10063+ CT_LAST_VOLUME_TYPE
10064+
10065+} _E_FSAVOLTYPE;
10066+
10067+#ifdef AAC_32BIT_ENUMS
10068+typedef _E_FSAVOLTYPE FSAVOLTYPE;
10069+#else
10070+typedef AAC_UINT32 FSAVOLTYPE;
10071+#endif
10072+
10073+
10074+//
10075+// Types of objects addressable in some fashion by the client.
10076+// This is a superset of those objects handled just by the filesystem
10077+// and includes "raw" objects that an administrator would use to
10078+// configure containers and filesystems.
10079+//
10080+typedef enum _FTYPE {
10081+ FT_REG = 1, // regular file
10082+ FT_DIR, // directory
10083+ FT_BLK, // "block" device - reserved
10084+ FT_CHR, // "character special" device - reserved
10085+ FT_LNK, // symbolic link
10086+ FT_SOCK, // socket
10087+ FT_FIFO, // fifo
10088+ FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10089+ FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10090+ FT_SLICE, // virtual disk - raw volume - slice
10091+ FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10092+ FT_VOLUME, // Container - Volume Set
10093+ FT_STRIPE, // Container - Stripe Set
10094+ FT_MIRROR, // Container - Mirror Set
10095+ FT_RAID5, // Container - Raid 5 Set
10096+ FT_DATABASE // Storage object with "foreign" content manager
10097+} _E_FTYPE;
10098+
10099+#ifdef AAC_32BIT_ENUMS
10100+typedef _E_FTYPE FTYPE;
10101+#else
10102+typedef AAC_UINT32 FTYPE;
10103+#endif
10104+
10105+
10106+
10107+//
10108+// Host side memory scatter gather list
10109+// Used by the adapter for read, write, and readdirplus operations
10110+//
10111+typedef PAAC_UINT8 HOSTADDRESS;
10112+
10113+typedef struct _SGENTRY {
10114+ HOSTADDRESS SgAddress; /* 32-bit Base address. */
10115+ AAC_UINT32 SgByteCount; /* Length. */
10116+} SGENTRY;
10117+typedef SGENTRY *PSGENTRY;
10118+
10119+
10120+
10121+//
10122+// SGMAP
10123+//
10124+// This is the SGMAP structure for all commands that use
10125+// 32-bit addressing.
10126+//
10127+// Note that the upper 16 bits of SgCount are used as flags.
10128+// Only the lower 16 bits of SgCount are actually used as the
10129+// SG element count.
10130+//
10131+typedef struct _SGMAP {
10132+ AAC_UINT32 SgCount;
10133+ SGENTRY SgEntry[1];
10134+} SGMAP;
10135+typedef SGMAP *PSGMAP;
10136+
10137+
10138+
10139+//
10140+// SGMAP64
10141+//
10142+// This is the SGMAP structure for 64-bit container commands.
10143+//
10144+typedef struct _SGMAP64 {
10145+ AAC_UINT8 SgCount;
10146+ AAC_UINT8 SgSectorsPerPage;
10147+ AAC_UINT16 SgByteOffset; // For the first page
10148+ AAC_UINT64S SgEntry[1]; // Must be last entry
10149+} SGMAP64;
10150+typedef SGMAP64 *PSGMAP64;
10151+
10152+
10153+
10154+
10155+//
10156+// attempt at common time structure across host and adapter
10157+//
10158+typedef struct __TIME_T {
10159+
10160+ AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10161+ AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10162+
10163+} TIME_T;
10164+typedef TIME_T *PTIME_T;
10165+
10166+#ifndef _TIME_T
10167+#define timespec __TIME_T
10168+#define ts_sec tv_sec
10169+#define ts_nsec tv_usec
10170+#endif
10171+
10172+
10173+
10174+
10175+typedef struct _ContainerCreationInfo
10176+{
10177+
10178+ AAC_UINT8 ViaBuildNumber; // e.g., 588
10179+ AAC_UINT8 MicroSecond; // e.g., 588
10180+ AAC_UINT8 Via; // e.g., 1 = FSU,
10181+ // 2 = API,
10182+ AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10183+ AAC_UINT32 Date; //
10184+ // unsigned Month :4; // 1 - 12
10185+ // unsigned Day :6; // 1 - 32
10186+ // unsigned Hour :6; // 0 - 23
10187+ // unsigned Minute :6; // 0 - 60
10188+ // unsigned Second :6; // 0 - 60
10189+ SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10190+} ContainerCreationInfo;
10191+
10192+
10193+#endif // _FSATYPES_H
10194+
10195+
10196diff -burN linux-2.4.4/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10197--- linux-2.4.4/drivers/scsi/aacraid/include/linit.h Wed Dec 31 18:00:00 1969
10198+++ linux/drivers/scsi/aacraid/include/linit.h Mon Apr 30 09:43:34 2001
10199@@ -0,0 +1,107 @@
10200+/*++
10201+ * Adaptec aacraid device driver for Linux.
10202+ *
10203+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10204+ *
10205+ * This program is free software; you can redistribute it and/or modify
10206+ * it under the terms of the GNU General Public License as published by
10207+ * the Free Software Foundation; either version 2, or (at your option)
10208+ * any later version.
10209+ *
10210+ * This program is distributed in the hope that it will be useful,
10211+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10212+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10213+ * GNU General Public License for more details.
10214+ *
10215+ * You should have received a copy of the GNU General Public License
10216+ * along with this program; see the file COPYING. If not, write to
10217+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10218+ *
10219+ * Module Name:
10220+ * linit.h
10221+ *
10222+ * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10223+ *
10224+ --*/
10225+/*------------------------------------------------------------------------------
10226+ * I N C L U D E S
10227+ *----------------------------------------------------------------------------*/
10228+
10229+#ifndef _LINIT_H_
10230+#define _LINIT_H_
10231+
10232+static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10233+
10234+#include <linux/config.h>
10235+
10236+/*------------------------------------------------------------------------------
10237+ * D E F I N E S
10238+ *----------------------------------------------------------------------------*/
10239+/* Define the AAC SCSI Host Template structure. */
10240+#define AAC_HOST_TEMPLATE_ENTRY \
10241+ { name: "AAC", /* Driver Name */ \
10242+ proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10243+ detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10244+ release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10245+ info: AAC_DriverInfo, /* Driver Info Function */ \
10246+ ioctl: AAC_Ioctl, /* ioctl Interface */ \
10247+ command: AAC_Command, /* unqueued command */ \
10248+ queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10249+ abort: AAC_AbortCommand, /* Abort Command Function */ \
10250+ reset: AAC_ResetCommand, /* Reset Command Function */ \
10251+ bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10252+ can_queue: 1, /* Default initial value */ \
10253+ this_id: 0, /* Default initial value */ \
10254+ sg_tablesize: 0, /* Default initial value */ \
10255+ max_sectors: 128, /* max xfer size of 64k */ \
10256+ cmd_per_lun: 0, /* Default initial value */ \
10257+ present: 0, /* Default initial value */ \
10258+ unchecked_isa_dma: 0, /* Default Initial Value */ \
10259+ use_new_eh_code: 0, /* Default initial value */ \
10260+ eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10261+ eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10262+ eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10263+ eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10264+ eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10265+ use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10266+ }
10267+
10268+
10269+/*------------------------------------------------------------------------------
10270+ * T Y P E D E F S / S T R U C T S
10271+ *----------------------------------------------------------------------------*/
10272+typedef struct AAC_BIOS_DiskParameters
10273+{
10274+ int heads;
10275+ int sectors;
10276+ int cylinders;
10277+} AAC_BIOS_DiskParameters_T;
10278+
10279+
10280+/*------------------------------------------------------------------------------
10281+ * P R O G R A M G L O B A L S
10282+ *----------------------------------------------------------------------------*/
10283+
10284+const char *AAC_DriverInfo( struct Scsi_Host * );
10285+
10286+
10287+/*------------------------------------------------------------------------------
10288+ * F U N C T I O N P R O T O T Y P E S
10289+ *----------------------------------------------------------------------------*/
10290+/* Define prototypes for the AAC Driver Interface Functions. */
10291+int AAC_DetectHostAdapter( Scsi_Host_Template * );
10292+int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10293+int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10294+int AAC_Command( Scsi_Cmnd * );
10295+int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10296+int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10297+int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10298+int AAC_Ioctl( Scsi_Device *, int, void * );
10299+
10300+
10301+void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10302+
10303+
10304+int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10305+
10306+#endif /* _LINIT_H_ */
10307diff -burN linux-2.4.4/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10308--- linux-2.4.4/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 18:00:00 1969
10309+++ linux/drivers/scsi/aacraid/include/monkerapi.h Mon Apr 30 09:43:34 2001
10310@@ -0,0 +1,98 @@
10311+/*++
10312+ * Adaptec aacraid device driver for Linux.
10313+ *
10314+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10315+ *
10316+ * This program is free software; you can redistribute it and/or modify
10317+ * it under the terms of the GNU General Public License as published by
10318+ * the Free Software Foundation; either version 2, or (at your option)
10319+ * any later version.
10320+ *
10321+ * This program is distributed in the hope that it will be useful,
10322+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10323+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10324+ * GNU General Public License for more details.
10325+ *
10326+ * You should have received a copy of the GNU General Public License
10327+ * along with this program; see the file COPYING. If not, write to
10328+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10329+ *
10330+ * Module Name:
10331+ * monkerapi.h
10332+ *
10333+ * Abstract: This module contains the definitions used by the Host Adapter
10334+ * Communications interface.
10335+ * This is the interface used for by host programs and the Adapter
10336+ * to communicate via synchronous commands via a shared set of registers
10337+ * on a platform (typically doorbells and mailboxes).
10338+ *
10339+ --*/
10340+//**********************************************************************
10341+//
10342+// Monitor / Kernel API
10343+//
10344+// 03/24/1998 Bob Peret Initial creation
10345+//
10346+//**********************************************************************
10347+
10348+#ifndef MONKER_H
10349+#define MONKER_H
10350+
10351+static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10352+
10353+#define BREAKPOINT_REQUEST 0x00000004
10354+#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10355+
10356+
10357+#define SEND_SYNCHRONOUS_FIB 0x0000000c
10358+
10359+
10360+
10361+//
10362+// Adapter Status Register
10363+//
10364+// Phase Staus mailbox is 32bits:
10365+// <31:16> = Phase Status
10366+// <15:0> = Phase
10367+//
10368+// The adapter reports is present state through the phase. Only
10369+// a single phase should be ever be set. Each phase can have multiple
10370+// phase status bits to provide more detailed information about the
10371+// state of the board. Care should be taken to ensure that any phase status
10372+// bits that are set when changing the phase are also valid for the new phase
10373+// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10374+// for properly maintining the phase status mailbox when it is running.
10375+
10376+//
10377+// MONKER_API Phases
10378+//
10379+// Phases are bit oriented. It is NOT valid
10380+// to have multiple bits set
10381+//
10382+
10383+
10384+#define SELF_TEST_FAILED 0x00000004
10385+
10386+
10387+#define KERNEL_UP_AND_RUNNING 0x00000080
10388+#define KERNEL_PANIC 0x00000100
10389+
10390+
10391+
10392+//
10393+// Doorbell bit defines
10394+//
10395+
10396+
10397+#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10398+
10399+
10400+#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10401+#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10402+#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10403+#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10404+#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10405+
10406+
10407+#endif // MONKER_H
10408+
10409diff -burN linux-2.4.4/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10410--- linux-2.4.4/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10411+++ linux/drivers/scsi/aacraid/include/nodetype.h Mon Apr 30 09:43:34 2001
10412@@ -0,0 +1,67 @@
10413+/*++
10414+ * Adaptec aacraid device driver for Linux.
10415+ *
10416+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10417+ *
10418+ * This program is free software; you can redistribute it and/or modify
10419+ * it under the terms of the GNU General Public License as published by
10420+ * the Free Software Foundation; either version 2, or (at your option)
10421+ * any later version.
10422+ *
10423+ * This program is distributed in the hope that it will be useful,
10424+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10425+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10426+ * GNU General Public License for more details.
10427+ *
10428+ * You should have received a copy of the GNU General Public License
10429+ * along with this program; see the file COPYING. If not, write to
10430+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10431+ *
10432+ * Module Name:
10433+ * nodetype.h
10434+ *
10435+ * Abstract: This module defines all of the node type codes used in this development
10436+ * shell. Every major data structure in the file system is assigned a node
10437+ * type code that is. This code is the first CSHORT in the structure and is
10438+ * followed by a CSHORT containing the size, in bytes, of the structure.
10439+ *
10440+ --*/
10441+#ifndef _NODETYPE_
10442+#define _NODETYPE_
10443+
10444+static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10445+
10446+typedef CSHORT NODE_TYPE_CODE;
10447+
10448+
10449+#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10450+#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10451+
10452+
10453+typedef CSHORT NODE_BYTE_SIZE;
10454+
10455+
10456+//
10457+// The following definitions are used to generate meaningful blue bugcheck
10458+// screens. On a bugcheck the file system can output 4 ulongs of useful
10459+// information. The first ulong will have encoded in it a source file id
10460+// (in the high word) and the line number of the bugcheck (in the low word).
10461+// The other values can be whatever the caller of the bugcheck routine deems
10462+// necessary.
10463+//
10464+// Each individual file that calls bugcheck needs to have defined at the
10465+// start of the file a constant called BugCheckFileId with one of the
10466+// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10467+// the system.
10468+//
10469+
10470+
10471+#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10472+#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10473+
10474+
10475+#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); }
10476+
10477+
10478+#endif // _NODETYPE_
10479+
10480diff -burN linux-2.4.4/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10481--- linux-2.4.4/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 18:00:00 1969
10482+++ linux/drivers/scsi/aacraid/include/nvramioctl.h Mon Apr 30 09:43:34 2001
10483@@ -0,0 +1,112 @@
10484+/*++
10485+ * Adaptec aacraid device driver for Linux.
10486+ *
10487+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10488+ *
10489+ * This program is free software; you can redistribute it and/or modify
10490+ * it under the terms of the GNU General Public License as published by
10491+ * the Free Software Foundation; either version 2, or (at your option)
10492+ * any later version.
10493+ *
10494+ * This program is distributed in the hope that it will be useful,
10495+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10496+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10497+ * GNU General Public License for more details.
10498+ *
10499+ * You should have received a copy of the GNU General Public License
10500+ * along with this program; see the file COPYING. If not, write to
10501+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10502+ *
10503+ * Module Name:
10504+ * nvramioctl.h
10505+ *
10506+ * Abstract: This file defines the data structures related to querying
10507+ * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10508+ *
10509+ --*/
10510+#ifndef _NVRAMIOCTL_H_
10511+#define _NVRAMIOCTL_H_ 1
10512+
10513+static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10514+
10515+/*
10516+ * NVRAM/Write Cache subsystem states
10517+ */
10518+typedef enum _NVSTATUS {
10519+ NVSTATUS_DISABLED = 0, // present, clean, not being used
10520+ NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10521+ NVSTATUS_ERROR, // present, dirty, contains dirty data
10522+ // for bad/missing device
10523+ NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10524+ // for bad/missing device
10525+ NVSTATUS_UNKNOWN // present?????
10526+} _E_NVSTATUS;
10527+
10528+#ifdef AAC_32BIT_ENUMS
10529+typedef _E_NVSTATUS NVSTATUS;
10530+#else
10531+typedef AAC_UINT32 NVSTATUS;
10532+#endif
10533+
10534+/*
10535+ * NVRAM/Write Cache subsystem battery component states
10536+ *
10537+ */
10538+//NB: this enum should be identical to battery_status in nvram.h
10539+// or else collapsed into one enum someday
10540+typedef enum _NVBATTSTATUS {
10541+ NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10542+ NVBATTSTATUS_LOW, // battery is low on power
10543+ NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10544+ NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10545+} _E_NVBATTSTATUS;
10546+
10547+#ifdef AAC_32BIT_ENUMS
10548+typedef _E_NVBATTSTATUS NVBATTSTATUS;
10549+#else
10550+typedef AAC_UINT32 NVBATTSTATUS;
10551+#endif
10552+
10553+/*
10554+ * battery transition type
10555+ */
10556+typedef enum _NVBATT_TRANSITION {
10557+ NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10558+ NVBATT_TRANSITION_LOW, // battery is now low on power
10559+ NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10560+} _E_NVBATT_TRANSITION;
10561+
10562+#ifdef AAC_32BIT_ENUMS
10563+typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10564+#else
10565+typedef AAC_UINT32 NVBATT_TRANSITION;
10566+#endif
10567+
10568+/*
10569+ * NVRAM Info structure returned for NVRAM_GetInfo call
10570+ */
10571+typedef struct _NVRAMDEVINFO {
10572+ AAC_UINT32 NV_Enabled; /* write caching enabled */
10573+ AAC_UINT32 NV_Error; /* device in error state */
10574+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10575+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10576+} NVRAMDEVINFO, *PNVRAMDEVINFO;
10577+
10578+typedef struct _NVRAMINFO {
10579+ NVSTATUS NV_Status; /* nvram subsystem status */
10580+ NVBATTSTATUS NV_BattStatus; /* battery status */
10581+ AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10582+ AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10583+ AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10584+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10585+ AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10586+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10587+ AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10588+ NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10589+ AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10590+ AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10591+} NVRAMINFO, *PNVRAMINFO;
10592+
10593+#endif /* !_NVRAMIOCTL_H_ */
10594+
10595+
10596diff -burN linux-2.4.4/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10597--- linux-2.4.4/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 18:00:00 1969
10598+++ linux/drivers/scsi/aacraid/include/osheaders.h Mon Apr 30 09:43:34 2001
10599@@ -0,0 +1,150 @@
10600+/*++
10601+ * Adaptec aacraid device driver for Linux.
10602+ *
10603+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10604+ *
10605+ * This program is free software; you can redistribute it and/or modify
10606+ * it under the terms of the GNU General Public License as published by
10607+ * the Free Software Foundation; either version 2, or (at your option)
10608+ * any later version.
10609+ *
10610+ * This program is distributed in the hope that it will be useful,
10611+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10612+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10613+ * GNU General Public License for more details.
10614+ *
10615+ * You should have received a copy of the GNU General Public License
10616+ * along with this program; see the file COPYING. If not, write to
10617+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10618+ *
10619+ * Module Name:
10620+ * osheaders.h
10621+ *
10622+ * Abstract: Holds all of the header file includes for a particular O/S flavor.
10623+ *
10624+ --*/
10625+#ifndef _OSHEADERS_H_
10626+#define _OSHEADERS_H_
10627+
10628+static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10629+
10630+#include <linux/autoconf.h> // retrieve the kernel configuration info
10631+#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10632+#define MODVERSIONS // force it on
10633+#endif
10634+
10635+#include <linux/version.h>
10636+
10637+#if defined( MODVERSIONS ) && defined( MODULE )
10638+#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10639+#ifdef __SMP__
10640+#include <linux/modversions-smp.h>
10641+#elif defined( BOOT_DRIVER )
10642+#include <linux/modversions-BOOT.h>
10643+#else
10644+#include <linux/modversions-up.h>
10645+#endif // ifdef __SMP__
10646+#else
10647+#include <linux/modversions.h>
10648+#endif
10649+#endif
10650+
10651+
10652+#include <linux/kernel.h>
10653+#include <linux/config.h>
10654+#include <linux/init.h>
10655+#include <linux/types.h>
10656+#include <linux/blk.h>
10657+#include <linux/blkdev.h>
10658+#include <linux/delay.h>
10659+#include <linux/ioport.h>
10660+#include <linux/mm.h>
10661+#include <linux/sched.h>
10662+#include <linux/stat.h>
10663+#include <linux/pci.h>
10664+#include <linux/interrupt.h>
10665+#include <asm/dma.h>
10666+#include <asm/io.h>
10667+#include <linux/spinlock.h>
10668+#include <asm/system.h>
10669+#include <asm/bitops.h>
10670+#include <asm/uaccess.h>
10671+#include <linux/wait.h>
10672+#include <linux/malloc.h>
10673+#include <linux/tqueue.h>
10674+/* bmb fix
10675+#include <linux/tasks.h>
10676+*/
10677+#include <ostypes.h>
10678+#include "scsi.h"
10679+#include "hosts.h"
10680+
10681+#ifndef intptr_t
10682+#define intptr_t void *
10683+#endif
10684+
10685+#ifndef cred_t
10686+#define cred_t void
10687+#endif
10688+
10689+#ifndef paddr32_t
10690+#define paddr32_t unsigned
10691+#endif
10692+
10693+#ifndef bzero
10694+#define bzero(b,len) memset(b,0,len)
10695+#endif
10696+
10697+#ifndef bcopy
10698+#define bcopy(src,dst,len) memcpy(dst,src,len )
10699+#endif
10700+
10701+#ifndef DEVICE_NR
10702+#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10703+#endif
10704+
10705+typedef unsigned uint_t;
10706+
10707+typedef enum
10708+{
10709+ CE_PANIC = 0,
10710+ CE_WARN,
10711+ CE_NOTE,
10712+ CE_CONT,
10713+ CE_DEBUG,
10714+ CE_DEBUG2,
10715+ CE_TAIL
10716+} CE_ENUM_T;
10717+
10718+#define CMN_ERR_LEVEL CE_NOTE
10719+
10720+#ifndef IN
10721+#define IN
10722+#endif
10723+
10724+// usage of READ & WRITE as a typedefs in protocol.h
10725+// conflicts with <linux/fs.h> definition.
10726+#ifdef READ
10727+#undef READ
10728+#endif
10729+
10730+#ifdef WRITE
10731+#undef WRITE
10732+#endif
10733+
10734+typedef struct aac_options
10735+{
10736+ int message_level;
10737+ int reverse_scan;
10738+} aac_options_t;
10739+
10740+#endif // _OSHEADERS_H_
10741+
10742+
10743+
10744+
10745+
10746+
10747+
10748+
10749+
10750diff -burN linux-2.4.4/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10751--- linux-2.4.4/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 18:00:00 1969
10752+++ linux/drivers/scsi/aacraid/include/ostypes.h Mon Apr 30 09:43:34 2001
10753@@ -0,0 +1,149 @@
10754+/*++
10755+ * Adaptec aacraid device driver for Linux.
10756+ *
10757+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10758+ *
10759+ * This program is free software; you can redistribute it and/or modify
10760+ * it under the terms of the GNU General Public License as published by
10761+ * the Free Software Foundation; either version 2, or (at your option)
10762+ * any later version.
10763+ *
10764+ * This program is distributed in the hope that it will be useful,
10765+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10766+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10767+ * GNU General Public License for more details.
10768+ *
10769+ * You should have received a copy of the GNU General Public License
10770+ * along with this program; see the file COPYING. If not, write to
10771+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10772+ *
10773+ * Module Name:
10774+ * ostypes.h
10775+ *
10776+ * Abstract: Holds all of the O/S specific types.
10777+ *
10778+ --*/
10779+/*------------------------------------------------------------------------------
10780+ * D E F I N E S
10781+ *----------------------------------------------------------------------------*/
10782+#ifndef _OSTYPES_H_
10783+#define _OSTYPES_H_
10784+
10785+static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10786+
10787+#include <linux/types.h>
10788+
10789+#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10790+#define MAXIMUM_NUM_ADAPTERS 8
10791+
10792+#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10793+
10794+#define Os_remove_softintr OsSoftInterruptRemove
10795+#define OsPrintf printk
10796+#define FsaCommPrint
10797+
10798+// the return values for copy_from_user & copy_to_user is the
10799+// number of bytes not transferred. Thus if an internal error
10800+// occurs, the return value is greater than zero.
10801+#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10802+#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10803+
10804+#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10805+#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10806+
10807+/*------------------------------------------------------------------------------
10808+ * S T R U C T S / T Y P E D E F S
10809+ *----------------------------------------------------------------------------*/
10810+typedef struct OS_MUTEX
10811+{
10812+ unsigned long lock_var;
10813+ wait_queue_head_t wq;
10814+ unsigned owner;
10815+} OS_MUTEX;
10816+
10817+typedef struct OS_SPINLOCK
10818+{
10819+ spinlock_t spin_lock;
10820+ unsigned cpu_lock_count[NR_CPUS];
10821+ long cpu_flag;
10822+ long lockout_count;
10823+} OS_SPINLOCK;
10824+
10825+#ifdef CVLOCK_USE_SPINLOCK
10826+ typedef OS_SPINLOCK OS_CVLOCK;
10827+#else
10828+ typedef OS_MUTEX OS_CVLOCK;
10829+#endif
10830+
10831+typedef size_t OS_SIZE_T;
10832+
10833+typedef struct OS_CV_T
10834+{
10835+ unsigned long lock_var;
10836+ unsigned long type;
10837+ wait_queue_head_t wq;
10838+} OS_CV_T;
10839+
10840+struct fsa_scsi_hba {
10841+ void *CommonExtension;
10842+ unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10843+ unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10844+ unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10845+ unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10846+ unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10847+ unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10848+ long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10849+};
10850+
10851+typedef struct fsa_scsi_hba fsadev_t;
10852+
10853+typedef struct OsKI
10854+{
10855+ struct Scsi_Host *scsi_host_ptr;
10856+ void * dip; // #REVISIT#
10857+ fsadev_t fsa_dev;
10858+ int thread_pid;
10859+ int MiniPortIndex;
10860+} OsKI_t;
10861+
10862+#define dev_info_t fsadev_t
10863+
10864+typedef int OS_SPINLOCK_COOKIE;
10865+
10866+typedef unsigned int OS_STATUS;
10867+
10868+typedef struct tq_struct OS_SOFTINTR;
10869+
10870+typedef OS_SOFTINTR *ddi_softintr_t;
10871+
10872+
10873+
10874+//-----------------------------------------------------------------------------
10875+// Conditional variable functions
10876+
10877+void OsCv_init (
10878+ OS_CV_T *cv_ptr );
10879+
10880+
10881+//-----------------------------------------------------------------------------
10882+// Printing functions
10883+void printk_err(int flag, char *fmt, ...);
10884+
10885+#define cmn_err printk_err
10886+
10887+
10888+//
10889+// just ignore these solaris ddi functions in the code
10890+//
10891+#define DDI_SUCCESS 0
10892+
10893+#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10894+
10895+//#REVIEW#
10896+#define ddi_remove_softintr(A) 0
10897+#define ddi_get_soft_iblock_cookie(A, B, C) 0
10898+
10899+#define ASSERT(expr) ((void) 0)
10900+#define drv_usecwait udelay
10901+
10902+#endif // _OSTYPES_H_
10903diff -burN linux-2.4.4/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10904--- linux-2.4.4/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 18:00:00 1969
10905+++ linux/drivers/scsi/aacraid/include/pcisup.h Mon Apr 30 09:43:34 2001
10906@@ -0,0 +1,97 @@
10907+/*++
10908+ * Adaptec aacraid device driver for Linux.
10909+ *
10910+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10911+ *
10912+ * This program is free software; you can redistribute it and/or modify
10913+ * it under the terms of the GNU General Public License as published by
10914+ * the Free Software Foundation; either version 2, or (at your option)
10915+ * any later version.
10916+ *
10917+ * This program is distributed in the hope that it will be useful,
10918+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10919+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10920+ * GNU General Public License for more details.
10921+ *
10922+ * You should have received a copy of the GNU General Public License
10923+ * along with this program; see the file COPYING. If not, write to
10924+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10925+ *
10926+ * Module Name:
10927+ * pcisup.h
10928+ *
10929+ * Abstract: This module defines functions that are defined in PciSup.c
10930+ *
10931+ --*/
10932+#ifndef _PCISUP_
10933+#define _PCISUP_
10934+
10935+static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10936+
10937+
10938+/*
10939+ * define which interrupt handler needs to be installed
10940+ */
10941+
10942+#define SaISR 1
10943+#define RxISR 2
10944+
10945+typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10946+ ULONG AdapterNumber; // Which FSA# this miniport is
10947+
10948+ ULONG PciBusNumber; // Which PCI bus we are located on
10949+ ULONG PciSlotNumber; // Whiat PCI slot we are in
10950+
10951+ PVOID Adapter; // Back pointer to Fsa adapter object
10952+ ULONG AdapterIndex; // Index into PlxAdapterTypes array
10953+ PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10954+
10955+ FSAPORT_FUNCS AdapterFuncs;
10956+ ULONG FilesystemRevision; // Main driver's revision number
10957+
10958+
10959+ PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
10960+ PVOID PhysicalInitStruct; // Holds physical address of the init struct
10961+
10962+
10963+ PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
10964+
10965+ BOOLEAN AdapterPrintfsToScreen;
10966+ BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
10967+
10968+ void * MiniPort;
10969+
10970+ caddr_t CommAddress; // Base address of Comm area
10971+ paddr32_t CommPhysAddr; // Physical Address of Comm area
10972+ size_t CommSize;
10973+
10974+ OsKI_t OsDep; // OS dependent kernel interfaces
10975+
10976+
10977+} PCI_MINIPORT_COMMON_EXTENSION;
10978+
10979+typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
10980+
10981+typedef int
10982+(*PFSA_MINIPORT_INIT) (
10983+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
10984+ IN ULONG AdapterNumber,
10985+ IN ULONG PciBus,
10986+ IN ULONG PciSlot
10987+ );
10988+
10989+typedef struct _FSA_MINIPORT {
10990+ USHORT VendorId;
10991+ USHORT DeviceId;
10992+ USHORT SubVendorId;
10993+ USHORT SubSystemId;
10994+ PCHAR DevicePrefix;
10995+ PFSA_MINIPORT_INIT InitRoutine;
10996+ PCHAR DeviceName;
10997+ PCHAR Vendor;
10998+ PCHAR Model;
10999+} FSA_MINIPORT;
11000+typedef FSA_MINIPORT *PFSA_MINIPORT;
11001+
11002+
11003+#endif // _PCISUP_
11004diff -burN linux-2.4.4/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11005--- linux-2.4.4/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11006+++ linux/drivers/scsi/aacraid/include/perfpack.h Mon Apr 30 09:43:34 2001
11007@@ -0,0 +1,110 @@
11008+/*++
11009+ * Adaptec aacraid device driver for Linux.
11010+ *
11011+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11012+ *
11013+ * This program is free software; you can redistribute it and/or modify
11014+ * it under the terms of the GNU General Public License as published by
11015+ * the Free Software Foundation; either version 2, or (at your option)
11016+ * any later version.
11017+ *
11018+ * This program is distributed in the hope that it will be useful,
11019+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11020+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11021+ * GNU General Public License for more details.
11022+ *
11023+ * You should have received a copy of the GNU General Public License
11024+ * along with this program; see the file COPYING. If not, write to
11025+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11026+ *
11027+ * Module Name:
11028+ * perfpack.h
11029+ *
11030+ * Abstract: This file defines the layout of the performance data that is passed
11031+ * back from the FSA filesystem driver.
11032+ *
11033+ *
11034+ --*/
11035+
11036+#ifndef _FSA_PERFPACK_H_
11037+#define _FSA_PERFPACK_H_ 1
11038+
11039+static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11040+
11041+//#define FSA_DO_PERF 1 /* enable the engineering counters */
11042+
11043+#ifdef FSA_DO_PERF
11044+//
11045+// engineering counters
11046+//
11047+typedef struct _FSA_PERF_DATA {
11048+ ULONG FibsSent;
11049+ ULONG ReadDirs;
11050+ ULONG GetAttrs;
11051+ ULONG SetAttrs;
11052+ ULONG Lookups;
11053+ ULONG ReadFibs;
11054+ ULONG WriteFibs;
11055+ ULONG CreateFibs;
11056+ ULONG MakeDirs;
11057+ ULONG RemoveFibs;
11058+ ULONG RemoveDirs;
11059+ ULONG RenameFibs;
11060+ ULONG ReadDirPlus;
11061+ ULONG FsStat;
11062+ ULONG WriteBytes;
11063+ ULONG ReadBytes;
11064+// NT FSA entry points
11065+ ULONG FsaFsdCreateCount;
11066+ ULONG FsaFsdCloseCount;
11067+ ULONG FsaFsdReadCount;
11068+ ULONG FsaFsdWriteCount;
11069+ ULONG FsaFsdQueryInformationCount;
11070+
11071+ struct _FsaFsdSetInfomation{
11072+ ULONG FsaSetAllocationInfoCount;
11073+ ULONG FsaSetBasicInfoCount;
11074+ ULONG FsaSetDispositionInfoCount;
11075+ ULONG FsaSetEndOfFileInfoCount;
11076+ ULONG FsaSetPositionInfoCount;
11077+ ULONG FsaSetRenameInfoCount;
11078+ ULONG FsaClearArchiveBitCount;
11079+ };
11080+
11081+ ULONG FsaFsdFlushBuffersCount;
11082+ ULONG FsaFsdQueryVolumeInfoCount;
11083+ ULONG FsaFsdSetVolumeInfoCount;
11084+ ULONG FsaFsdCleanupCount;
11085+ ULONG FsaFsdDirectoryControlCount;
11086+ ULONG FsaFsdFileSystemControlCount;
11087+ ULONG FsaFsdLockControlCount;
11088+ ULONG FsaFsdDeviceControlCount;
11089+ ULONG FsaFsdShutdownCount;
11090+ ULONG FsaFsdQuerySecurityInfo;
11091+ ULONG FsaFsdSetSecurityInfo;
11092+ ULONG FastIoCheckIfPossibleCount;
11093+ ULONG FastIoReadCount;
11094+ ULONG FastIoWriteCount;
11095+ ULONG FastIoQueryBasicInfoCount;
11096+ ULONG FastIoQueryStandardInfoCount;
11097+ ULONG FastIoLockCount;
11098+ ULONG FastIoUnlockSingleCount;
11099+ ULONG FastIoUnlockAllCount;
11100+ ULONG FastIoUnlockAllByKeyCount;
11101+ ULONG FastIoDeviceControlCount;
11102+ } FSA_PERF_DATA;
11103+
11104+typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11105+
11106+
11107+#else /* FSA_DO_PERF */
11108+
11109+//
11110+// engineering performance counters are disabled
11111+//
11112+#define FSA_DO_PERF_INC(Counter) /* */
11113+#define FSA_DO_FSP_PERF_INC(Counter) /* */
11114+
11115+#endif /* FSA_DO_PERF */
11116+
11117+#endif // _FSA_PERFPACK_H_
11118diff -burN linux-2.4.4/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11119--- linux-2.4.4/drivers/scsi/aacraid/include/port.h Wed Dec 31 18:00:00 1969
11120+++ linux/drivers/scsi/aacraid/include/port.h Mon Apr 30 09:43:34 2001
11121@@ -0,0 +1,87 @@
11122+/*++
11123+ * Adaptec aacraid device driver for Linux.
11124+ *
11125+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11126+ *
11127+ * This program is free software; you can redistribute it and/or modify
11128+ * it under the terms of the GNU General Public License as published by
11129+ * the Free Software Foundation; either version 2, or (at your option)
11130+ * any later version.
11131+ *
11132+ * This program is distributed in the hope that it will be useful,
11133+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11134+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11135+ * GNU General Public License for more details.
11136+ *
11137+ * You should have received a copy of the GNU General Public License
11138+ * along with this program; see the file COPYING. If not, write to
11139+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11140+ *
11141+ * Module Name:
11142+ * port.h
11143+ *
11144+ * Abstract: This module defines functions and structures that are in common among all miniports
11145+ *
11146+ *
11147+ --*/
11148+
11149+#ifndef _PORT_
11150+#define _PORT_
11151+
11152+static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11153+
11154+#ifdef DBG
11155+#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11156+extern int AfaPortPrinting;
11157+#else
11158+#define AfaPortPrint
11159+#endif DBG
11160+
11161+extern int AfaPortPrinting;
11162+
11163+
11164+BOOLEAN
11165+AfaPortAllocateAdapterCommArea(
11166+ IN PVOID Arg1,
11167+ IN OUT PVOID *CommHeaderAddress,
11168+ IN ULONG CommAreaSize,
11169+ IN ULONG CommAreaAlignment
11170+ );
11171+
11172+
11173+BOOLEAN
11174+AfaPortFreeAdapterCommArea(
11175+ IN PVOID Arg1
11176+ );
11177+
11178+
11179+AAC_STATUS
11180+AfaPortBuildSgMap(
11181+ PVOID Arg1,
11182+ IN PSGMAP_CONTEXT SgMapContext
11183+ );
11184+
11185+
11186+VOID
11187+AfaPortFreeDmaResources(
11188+ PVOID Arg1,
11189+ IN PSGMAP_CONTEXT SgMapContext
11190+ );
11191+
11192+
11193+BOOLEAN
11194+AfaPortAllocateAndMapFibSpace(
11195+ PVOID Arg1,
11196+ IN PMAPFIB_CONTEXT MapFibContext
11197+ );
11198+
11199+
11200+BOOLEAN
11201+AfaPortUnmapAndFreeFibSpace(
11202+ PVOID Arg1,
11203+ IN PMAPFIB_CONTEXT MapFibContext
11204+ );
11205+
11206+
11207+#endif // _PORT_
11208+
11209diff -burN linux-2.4.4/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11210--- linux-2.4.4/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11211+++ linux/drivers/scsi/aacraid/include/protocol.h Mon Apr 30 09:43:34 2001
11212@@ -0,0 +1,249 @@
11213+/*++
11214+ * Adaptec aacraid device driver for Linux.
11215+ *
11216+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11217+ *
11218+ * This program is free software; you can redistribute it and/or modify
11219+ * it under the terms of the GNU General Public License as published by
11220+ * the Free Software Foundation; either version 2, or (at your option)
11221+ * any later version.
11222+ *
11223+ * This program is distributed in the hope that it will be useful,
11224+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11225+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11226+ * GNU General Public License for more details.
11227+ *
11228+ * You should have received a copy of the GNU General Public License
11229+ * along with this program; see the file COPYING. If not, write to
11230+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11231+ *
11232+ * Module Name:
11233+ * protocol.h
11234+ *
11235+ * Abstract: Defines the commands and command data which enables the nt
11236+ * filesystem driver to be the client of the fsa adapter
11237+ * filesystem. This protocol is largely modeled after the NFS
11238+ * V3 protocol with modifications allowed due to the unique
11239+ * client/server model FSA works under.
11240+ *
11241+ *
11242+ *
11243+ --*/
11244+
11245+#ifndef _PROTOCOL_H_
11246+#define _PROTOCOL_H_
11247+
11248+static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11249+
11250+#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11251+#include <nvramioctl.h> // for NVRAMINFO definition
11252+
11253+// #define MDL_READ_WRITE
11254+
11255+//
11256+// Define the command values
11257+//
11258+typedef enum _FSA_COMMANDS {
11259+ Null = 0,
11260+ GetAttributes,
11261+ SetAttributes,
11262+ Lookup,
11263+ ReadLink,
11264+ Read,
11265+ Write,
11266+ Create,
11267+ MakeDirectory,
11268+ SymbolicLink,
11269+ MakeNode,
11270+ Removex,
11271+ RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11272+ Rename,
11273+ Link,
11274+ ReadDirectory,
11275+ ReadDirectoryPlus,
11276+ FileSystemStatus,
11277+ FileSystemInfo,
11278+ PathConfigure,
11279+ Commit,
11280+ Mount,
11281+ UnMount,
11282+ Newfs,
11283+ FsCheck,
11284+ FsSync,
11285+ SimReadWrite,
11286+ SetFileSystemStatus,
11287+ BlockRead,
11288+ BlockWrite,
11289+ NvramIoctl,
11290+ FsSyncWait,
11291+ ClearArchiveBit,
11292+#ifdef MDL_READ_WRITE
11293+ MdlReadComplete,
11294+ MdlWriteComplete,
11295+ MdlRead, // these are used solely for stats, Mdl really controlled by
11296+ MdlWrite, // flags field in Fib.
11297+#endif
11298+ SetAcl,
11299+ GetAcl,
11300+ AssignAcl,
11301+ FaultInsertion, // Fault Insertion Command
11302+ CrazyCache, // crazycache
11303+ MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11304+} _E_FSACOMMAND;
11305+
11306+#ifdef AAC_32BIT_ENUMS
11307+typedef _E_FSACOMMAND FSACOMMAND;
11308+#else
11309+typedef AAC_UINT32 FSACOMMAND;
11310+#endif
11311+
11312+
11313+
11314+//
11315+// Define the status returns
11316+//
11317+// See include\comm\errno.h for adapter kernel errno's
11318+typedef enum _FSASTATUS {
11319+ ST_OK = 0,
11320+ ST_PERM = 1,
11321+ ST_NOENT = 2,
11322+ ST_IO = 5,
11323+ ST_NXIO = 6,
11324+ ST_E2BIG = 7,
11325+ ST_ACCES = 13,
11326+ ST_EXIST = 17,
11327+ ST_XDEV = 18,
11328+ ST_NODEV = 19,
11329+ ST_NOTDIR = 20,
11330+ ST_ISDIR = 21,
11331+ ST_INVAL = 22,
11332+ ST_FBIG = 27,
11333+ ST_NOSPC = 28,
11334+ ST_ROFS = 30,
11335+ ST_MLINK = 31,
11336+ ST_WOULDBLOCK = 35,
11337+ ST_NAMETOOLONG = 63,
11338+ ST_NOTEMPTY = 66,
11339+ ST_DQUOT = 69,
11340+ ST_STALE = 70,
11341+ ST_REMOTE = 71,
11342+ ST_BADHANDLE = 10001,
11343+ ST_NOT_SYNC = 10002,
11344+ ST_BAD_COOKIE = 10003,
11345+ ST_NOTSUPP = 10004,
11346+ ST_TOOSMALL = 10005,
11347+ ST_SERVERFAULT = 10006,
11348+ ST_BADTYPE = 10007,
11349+ ST_JUKEBOX = 10008,
11350+ ST_NOTMOUNTED = 10009,
11351+ ST_MAINTMODE = 10010,
11352+ ST_STALEACL = 10011
11353+} _E_FSASTATUS;
11354+
11355+#ifdef AAC_32BIT_ENUMS
11356+typedef _E_FSASTATUS FSASTATUS;
11357+#else
11358+typedef AAC_UINT32 FSASTATUS;
11359+#endif
11360+
11361+//
11362+// On writes how does the client want the data written.
11363+//
11364+
11365+typedef enum _CACHELEVEL {
11366+ CSTABLE = 1,
11367+ CUNSTABLE
11368+} _E_CACHELEVEL;
11369+
11370+#ifdef AAC_32BIT_ENUMS
11371+typedef _E_CACHELEVEL CACHELEVEL;
11372+#else
11373+typedef AAC_UINT32 CACHELEVEL;
11374+#endif
11375+
11376+//
11377+// Lets the client know at which level the data was commited on a write request
11378+//
11379+
11380+typedef enum _COMMITLEVEL {
11381+ CMFILE_SYNCH_NVRAM = 1,
11382+ CMDATA_SYNCH_NVRAM,
11383+ CMFILE_SYNCH,
11384+ CMDATA_SYNCH,
11385+ CMUNSTABLE
11386+} _E_COMMITLEVEL;
11387+
11388+#ifdef AAC_32BIT_ENUMS
11389+typedef _E_COMMITLEVEL COMMITLEVEL;
11390+#else
11391+typedef AAC_UINT32 COMMITLEVEL;
11392+#endif
11393+
11394+
11395+
11396+//
11397+// The following are all the different commands or FIBs which can be sent to the
11398+// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11399+// but others outside that subset are allowed to return not implemented. The client is then
11400+// responsible for dealing with the fact it is not implemented.
11401+//
11402+typedef AAC_INT8 FSASTRING[16];
11403+
11404+
11405+typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11406+
11407+
11408+
11409+//
11410+// BlockRead
11411+//
11412+
11413+typedef struct _BLOCKREAD { // variable size struct
11414+
11415+ FSACOMMAND Command;
11416+ AAC_UINT32 ContainerId;
11417+ BYTECOUNT BlockNumber;
11418+ BYTECOUNT ByteCount;
11419+ SGMAP SgMap; // Must be last in struct because it is variable
11420+
11421+} BLOCKREAD;
11422+typedef BLOCKREAD *PBLOCKREAD;
11423+
11424+typedef struct _BLOCKREADRESPONSE {
11425+
11426+ FSASTATUS Status;
11427+ BYTECOUNT ByteCount;
11428+
11429+} BLOCKREADRESPONSE;
11430+typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11431+
11432+//
11433+// BlockWrite
11434+//
11435+
11436+typedef struct _BLOCKWRITE { // variable size struct
11437+
11438+ FSACOMMAND Command;
11439+ AAC_UINT32 ContainerId;
11440+ BYTECOUNT BlockNumber;
11441+ BYTECOUNT ByteCount;
11442+ CACHELEVEL Stable;
11443+ SGMAP SgMap; // Must be last in struct because it is variable
11444+
11445+} BLOCKWRITE;
11446+typedef BLOCKWRITE *PBLOCKWRITE;
11447+
11448+
11449+typedef struct _BLOCKWRITERESPONSE {
11450+
11451+ FSASTATUS Status;
11452+ BYTECOUNT ByteCount;
11453+ COMMITLEVEL Committed;
11454+
11455+} BLOCKWRITERESPONSE;
11456+typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11457+
11458+
11459+
11460+#endif // _PROTOCOL_H_
11461+
11462diff -burN linux-2.4.4/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11463--- linux-2.4.4/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11464+++ linux/drivers/scsi/aacraid/include/revision.h Mon Apr 30 09:43:34 2001
11465@@ -0,0 +1,350 @@
11466+/*++
11467+ * Adaptec aacraid device driver for Linux.
11468+ *
11469+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11470+ *
11471+ * This program is free software; you can redistribute it and/or modify
11472+ * it under the terms of the GNU General Public License as published by
11473+ * the Free Software Foundation; either version 2, or (at your option)
11474+ * any later version.
11475+ *
11476+ * This program is distributed in the hope that it will be useful,
11477+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11478+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11479+ * GNU General Public License for more details.
11480+ *
11481+ * You should have received a copy of the GNU General Public License
11482+ * along with this program; see the file COPYING. If not, write to
11483+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11484+ *
11485+ * Module Name:
11486+ * revision.h
11487+ *
11488+ * Abstract: This module contains all of the revision information for
11489+ * the FSA product, as well as the support routines for
11490+ * checking module compatibility.
11491+ *
11492+ * Before editing anything in this module, make sure that
11493+ * you read the comments. Some lines are changed automatically
11494+ * as part of the build, and should never be changed by hand.
11495+ *
11496+ * Routines (all inlines):
11497+ *
11498+ * RevGetBuildNumber - Retrieve current build number
11499+ * RevGetExternalRev - Retrieve revision for external use
11500+ * RevGetFullRevision - Retrieve full revision structure
11501+ *
11502+ * RevCheckCompatibility - Checks compatibility base on internal table
11503+ *
11504+ * RevCheckCompatibilityFullInfo - Check for static component
11505+ * RevGetCompInfoTableSize - Get size for static component table
11506+ * RevGetCompInfoTable - Get actual table to place on static component
11507+ * RevGetBuildNumberFromInfo - Get build number for static component.
11508+ *
11509+ *
11510+ *
11511+ --*/
11512+
11513+#ifndef _REVISION_H
11514+#define _REVISION_H
11515+
11516+static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11517+
11518+#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11519+
11520+typedef int REV_BOOL;
11521+
11522+#define REV_TRUE 1
11523+#define REV_FALSE 0
11524+
11525+//
11526+// Define Revision Levels for this product
11527+//
11528+// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11529+// automatically by the build.
11530+//
11531+// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11532+//
11533+// IMPORTANT: Don't access these revisions directly. They can be
11534+// accessed via, the RevGetXxxxx rouines.
11535+//
11536+
11537+
11538+#define REV_AS_LONGWORD \
11539+ ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11540+
11541+
11542+
11543+#ifndef BIOS
11544+
11545+//
11546+// Enumerate the types of product levels we can have
11547+//
11548+enum {
11549+ RevType_Devo=1, // Development mode, testing all of latest
11550+ RevType_Alpha, // Alpha - Internal field test
11551+ RevType_Beta, // Beta - External field test
11552+ RevType_Release // Release - Retail version
11553+};
11554+
11555+//
11556+// Define the basic structure for all revision information. Note
11557+// that the ordering of the components is such that they should
11558+// always increase. dash will be updated the most, then the version
11559+// type, then minor and major.
11560+//
11561+typedef struct {
11562+ union {
11563+ struct {
11564+ unsigned char dash; // Dash version number
11565+ unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11566+ unsigned char minor;// Minor version minor
11567+ unsigned char major;// Major version number
11568+ } comp; // Components to external viewed rev number
11569+ unsigned long ul; // External revision as single 32-bit value
11570+ } external; // External revision number (union)
11571+ unsigned long buildNumber; // Automatically generated build number
11572+} FsaRevision;
11573+
11574+
11575+//
11576+// Define simple routines to get basic revision information. The
11577+// definitions should never be accessed directly. These routines
11578+// are meant to be used to access all relevant information no matter
11579+// how simple.
11580+//
11581+static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11582+
11583+static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11584+
11585+
11586+//
11587+// Enumerate different components that may have to check
11588+// compatibility. This list of components can be changed
11589+// at any time.
11590+//
11591+// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11592+// incompatibilities between component rev checking will
11593+// cause wrong checking results.
11594+//
11595+typedef enum {
11596+ RevApplication = 1, // Any user End application
11597+ RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11598+ RevNetService, // Network Service Revision (under API)
11599+ RevApi, // ADAPTEC User mode API
11600+ RevFileSysDriver, // FSA File System Driver
11601+ RevMiniportDriver, // FSA File System Miniport Driver
11602+ RevAdapterSW, // Adapter Software (or NT Simulator)
11603+ RevMonitor, // Monitor for adapter hardware (MON960 for now)
11604+ RevRemoteApi // The remote API.
11605+ // ALWAYS ADD NEW COMPONENTS HERE - AT END
11606+} RevComponent;
11607+
11608+//
11609+// Define a structure so that we can create a compatibility table.
11610+//
11611+typedef struct {
11612+ RevComponent A,B;
11613+ unsigned long BuildNumOfB_RequiredByA;
11614+ unsigned long BuildNumOfA_RequiredByB;
11615+} RevCompareElement;
11616+
11617+//
11618+// Now, define the table. This table should only be included once,
11619+// in one program. If it is linked from 2 modules, there will likely
11620+// be a multiply defined symbol error from the linker.
11621+//
11622+// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11623+// allow access to the revision information table without a redefinition
11624+// of the tables.
11625+//
11626+extern const int RevCompareTableLength;
11627+
11628+extern const RevCompareElement RevCompareTable[];
11629+
11630+/********************************************************************\
11631+* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11632+*
11633+* The following routine is used to check compatibility between
11634+* the calling component and a component that has some dependencies
11635+* on it. If this routine returns REV_FALSE, it is expected that the caller
11636+* will send an appropriate incompatibility message and stop.
11637+*
11638+* This routine is only meant to check for compatibility in the
11639+* absolute sense. If code wishes to execute a different path based
11640+* on the CompB_BuildNumber, then this routine is not useful. The
11641+* routine RevGetBuildNumber can be used to get the calling module's
11642+* current build number for a comparison check.
11643+*
11644+* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11645+* if the components are definitely not compatible, or there is an
11646+* error when trying to figure it out. To be more specific:
11647+*
11648+* 1) REV_TRUE if component B is newer than calling component. (In this
11649+* case, the revision check done by component B with respect to
11650+* this component will give the real compatibility information.
11651+* It is the only one with the knowledge, since this component
11652+* could not look into the future.)
11653+* 2) REV_TRUE if calling component is more recent and table shows okay
11654+* 3) REV_FALSE if calling component more recent and table show not okay
11655+* 4) REV_FALSE if calling component is more recent and table entry to
11656+* check does not exist.
11657+*
11658+* Note that the CompB_BuildNumber must be attained by the calling
11659+* routine through some mechanism done by the caller.
11660+*
11661+* Input:
11662+*
11663+* callerComp - Name of component making this call
11664+* compB - Name of component to check compatibility with
11665+* compB_BuildNumber - Build number to component B
11666+*
11667+* Output:
11668+*
11669+* None
11670+*
11671+* Return Value:
11672+*
11673+* REV_TRUE - Component compatibility is possible, continue as usual. compB
11674+* must give true compatibility information.
11675+* REV_FALSE - Incompatible components, notify and end
11676+*
11677+\********************************************************************/
11678+static inline REV_BOOL RevCheckCompatibility(
11679+ RevComponent callerComp,
11680+ RevComponent compB,
11681+ unsigned long compB_BuildNumber)
11682+{
11683+ int i;
11684+ unsigned long RevForB;
11685+
11686+ //
11687+ // Compatibility check is possible, so we should continue. When
11688+ // compB makes this call in its own component, it will get the
11689+ // true compatibility information, since only it can know.
11690+ //
11691+ if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11692+
11693+ //
11694+ // Go through rev table. When the components are found in the
11695+ // same table entry, return the approprate number.
11696+ //
11697+ for (i=0; i<RevCompareTableLength; i++) {
11698+ if (RevCompareTable[i].A == callerComp) {
11699+ if (RevCompareTable[i].B == compB) {
11700+ RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11701+ return (compB_BuildNumber >= RevForB);
11702+ }
11703+ } else if (RevCompareTable[i].B == callerComp) {
11704+ if (RevCompareTable[i].A == compB) {
11705+ RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11706+ return (compB_BuildNumber >= RevForB);
11707+ }
11708+ }
11709+ }
11710+
11711+ //
11712+ // Uh oh! No relevant table entry was found (this should never
11713+ // happen).
11714+ //
11715+ return REV_FALSE;
11716+}
11717+
11718+
11719+//
11720+// Now create a structure that can be used by a FIB to check
11721+// compatibility.
11722+//
11723+typedef struct _RevCheck {
11724+ RevComponent callingComponent;
11725+ FsaRevision callingRevision;
11726+} RevCheck;
11727+
11728+typedef struct _RevCheckResp {
11729+ REV_BOOL possiblyCompatible;
11730+ FsaRevision adapterSWRevision;
11731+} RevCheckResp;
11732+
11733+#endif /* bios */
11734+#endif /* _REVISION_H */
11735+
11736+//
11737+// The following allows for inclusion of revision.h in other h
11738+// files. when you include this file in another h file, simply
11739+// define REV_REFERENCE_ONLY. This will be undefined later, so that
11740+// the single C file inclusion in the module will be used to
11741+// implement the global structures.
11742+//
11743+#ifndef REV_REFERENCE_ONLY
11744+#ifndef _REVISION_H_GLOBAL
11745+#define _REVISION_H_GLOBAL
11746+
11747+
11748+
11749+//
11750+// The following array is the table of compatibility. This table
11751+// can be modified in two ways:
11752+//
11753+// 1) A component which has an incompatible change done to
11754+// it, can get a new build number.
11755+//
11756+// 2) A new component can be added, requiring more entries
11757+// to be place into this table.
11758+//
11759+//
11760+// In case (1), you must change the revision number in the appropriate
11761+// column, based on which component absolutely requires an upgrade.
11762+//
11763+// Example: A new FIB used by the API, in build number 105
11764+// {RevApi, RevAdapterSW, 100, 100}
11765+// ---> would be changed to <---
11766+// {RevApi, RevAdapterSW, 105, 100}
11767+//
11768+// Example: A structure is changed for a FIB that only the API uses
11769+// {RevApi, RevAdapterSW, 100, 100}
11770+// ---> would be changed to <---
11771+// {RevApi, RevAdapterSW, 105, 105}
11772+//
11773+//
11774+// In case (2), the less common case, the enumerated list of
11775+// components must be changed to include the new component. Then
11776+// entries need to be placed into this table.
11777+//
11778+// Since the revisions must be communicated between the two
11779+// components, it is likely that you would need to put in the
11780+// current build number for both columns. That is the recommended
11781+// way to start revision test.
11782+//
11783+const RevCompareElement RevCompareTable[] = {
11784+ // Component A Component B MinBForA MinAForB
11785+ // ----------- ----------- -------- --------
11786+ {RevApplication, RevApi, 2120, 2120 },
11787+ {RevDkiCli, RevApi, 2120, 2120 },
11788+ {RevDkiCli, RevFileSysDriver, 257, 257 },
11789+ {RevDkiCli, RevMiniportDriver, 257, 257 },
11790+ {RevDkiCli, RevAdapterSW, 257, 257 },
11791+ {RevApi, RevFileSysDriver, 2120, 2120 },
11792+ {RevApi, RevMiniportDriver, 2120, 2120 },
11793+ {RevApi, RevAdapterSW, 2120, 2120 },
11794+ {RevApi, RevNetService, 2120, 2120 },
11795+ {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11796+ {RevFileSysDriver, RevAdapterSW, 257, 257 },
11797+ {RevMiniportDriver, RevAdapterSW, 257, 257 },
11798+ {RevMiniportDriver, RevMonitor, 100, 100 },
11799+ {RevApi, RevNetService, 2120, 2120 },
11800+ {RevApi, RevRemoteApi, 2120, 2120 },
11801+ {RevNetService, RevRemoteApi, 2120, 2120 }
11802+};
11803+
11804+const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11805+
11806+#endif /* _REVISION_H_GLOBAL */
11807+#endif /* REV_REFERENCE_ONLY */
11808+#undef REV_REFERENCE_ONLY
11809+
11810+
11811+
11812+
11813+
11814+
11815+
11816diff -burN linux-2.4.4/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11817--- linux-2.4.4/drivers/scsi/aacraid/include/rx.h Wed Dec 31 18:00:00 1969
11818+++ linux/drivers/scsi/aacraid/include/rx.h Mon Apr 30 09:43:34 2001
11819@@ -0,0 +1,81 @@
11820+/*++
11821+ * Adaptec aacraid device driver for Linux.
11822+ *
11823+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11824+ *
11825+ * This program is free software; you can redistribute it and/or modify
11826+ * it under the terms of the GNU General Public License as published by
11827+ * the Free Software Foundation; either version 2, or (at your option)
11828+ * any later version.
11829+ *
11830+ * This program is distributed in the hope that it will be useful,
11831+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11832+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11833+ * GNU General Public License for more details.
11834+ *
11835+ * You should have received a copy of the GNU General Public License
11836+ * along with this program; see the file COPYING. If not, write to
11837+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11838+ *
11839+ * Module Name:
11840+ * rx.h
11841+ *
11842+ * Abstract: Prototypes and data structures unique to the Rx based controller board.
11843+ *
11844+ *
11845+ --*/
11846+
11847+static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11848+
11849+typedef struct _Rx_ADAPTER_EXTENSION {
11850+
11851+ //
11852+ // The following must be first.
11853+ //
11854+ PPCI_MINIPORT_COMMON_EXTENSION Common;
11855+ struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11856+ USHORT LocalMaskInterruptControl;
11857+ PRx_DEVICE_REGISTERS Device;
11858+
11859+} Rx_ADAPTER_EXTENSION;
11860+
11861+
11862+typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11863+
11864+
11865+
11866+#ifdef LINUX
11867+/*
11868+ *
11869+ */
11870+
11871+#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11872+
11873+
11874+
11875+#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11876+#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11877+
11878+
11879+#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11880+
11881+#endif /* LINUX */
11882+
11883+
11884+VOID
11885+RxInterruptAdapter(
11886+ PVOID Arg1
11887+ );
11888+
11889+VOID
11890+RxNotifyAdapter(
11891+ PVOID Arg1,
11892+ IN HOST_2_ADAP_EVENT AdapterEvent
11893+ );
11894+
11895+VOID
11896+RxResetDevice(
11897+ PVOID Arg1
11898+ );
11899+
11900+
11901diff -burN linux-2.4.4/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11902--- linux-2.4.4/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11903+++ linux/drivers/scsi/aacraid/include/rxcommon.h Mon Apr 30 09:43:34 2001
11904@@ -0,0 +1,105 @@
11905+/*++
11906+ * Adaptec aacraid device driver for Linux.
11907+ *
11908+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11909+ *
11910+ * This program is free software; you can redistribute it and/or modify
11911+ * it under the terms of the GNU General Public License as published by
11912+ * the Free Software Foundation; either version 2, or (at your option)
11913+ * any later version.
11914+ *
11915+ * This program is distributed in the hope that it will be useful,
11916+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11917+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11918+ * GNU General Public License for more details.
11919+ *
11920+ * You should have received a copy of the GNU General Public License
11921+ * along with this program; see the file COPYING. If not, write to
11922+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11923+ *
11924+ * Module Name:
11925+ * rxcommon.h
11926+ *
11927+ * Abstract: Structures and defines for the i960 Rx chip.
11928+ *
11929+ *
11930+ --*/
11931+
11932+#ifndef _Rx_COMMON_H_
11933+#define _Rx_COMMON_H_
11934+
11935+static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11936+
11937+//
11938+// Rx Message Unit Registers
11939+//
11940+
11941+typedef volatile struct _StructRxMURegisters {
11942+ // Local | PCI* | Name
11943+ // | |
11944+ unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11945+ unsigned reserved0; // 1304h | 04h | Reserved
11946+ unsigned AWR; // 1308h | 08h | APIC Window Register
11947+ unsigned reserved1; // 130Ch | 0Ch | Reserved
11948+ unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11949+ unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11950+ unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11951+ unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11952+ unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11953+ unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11954+ unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11955+ unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11956+ // * Must access trhough ATU Inbound Translation Window
11957+
11958+}Rx_MU_CONFIG;
11959+typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11960+
11961+typedef volatile struct _Rx_Inbound {
11962+
11963+ unsigned Mailbox[8];
11964+
11965+}Rx_Inbound;
11966+
11967+typedef Rx_Inbound *PRx_Inbound;
11968+
11969+#define InboundMailbox0 IndexRegs.Mailbox[0]
11970+#define InboundMailbox1 IndexRegs.Mailbox[1]
11971+#define InboundMailbox2 IndexRegs.Mailbox[2]
11972+#define InboundMailbox3 IndexRegs.Mailbox[3]
11973+#define InboundMailbox4 IndexRegs.Mailbox[4]
11974+
11975+
11976+
11977+#define INBOUNDDOORBELL_0 0x00000001
11978+#define INBOUNDDOORBELL_1 0x00000002
11979+#define INBOUNDDOORBELL_2 0x00000004
11980+#define INBOUNDDOORBELL_3 0x00000008
11981+#define INBOUNDDOORBELL_4 0x00000010
11982+#define INBOUNDDOORBELL_5 0x00000020
11983+#define INBOUNDDOORBELL_6 0x00000040
11984+
11985+
11986+#define OUTBOUNDDOORBELL_0 0x00000001
11987+#define OUTBOUNDDOORBELL_1 0x00000002
11988+#define OUTBOUNDDOORBELL_2 0x00000004
11989+#define OUTBOUNDDOORBELL_3 0x00000008
11990+#define OUTBOUNDDOORBELL_4 0x00000010
11991+
11992+
11993+#define InboundDoorbellReg MUnit.IDR
11994+
11995+#define OutboundDoorbellReg MUnit.ODR
11996+
11997+
11998+typedef struct _Rx_DEVICE_REGISTERS {
11999+ Rx_MU_CONFIG MUnit; // 1300h - 1334h
12000+ unsigned reserved1[6]; // 1338h - 134ch
12001+ Rx_Inbound IndexRegs;
12002+} Rx_DEVICE_REGISTERS;
12003+
12004+typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12005+
12006+
12007+#endif // _Rx_COMMON_H_
12008+
12009+
12010diff -burN linux-2.4.4/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12011--- linux-2.4.4/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 18:00:00 1969
12012+++ linux/drivers/scsi/aacraid/include/sap1.h Mon Apr 30 09:43:34 2001
12013@@ -0,0 +1,85 @@
12014+/*++
12015+ * Adaptec aacraid device driver for Linux.
12016+ *
12017+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12018+ *
12019+ * This program is free software; you can redistribute it and/or modify
12020+ * it under the terms of the GNU General Public License as published by
12021+ * the Free Software Foundation; either version 2, or (at your option)
12022+ * any later version.
12023+ *
12024+ * This program is distributed in the hope that it will be useful,
12025+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12026+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12027+ * GNU General Public License for more details.
12028+ *
12029+ * You should have received a copy of the GNU General Public License
12030+ * along with this program; see the file COPYING. If not, write to
12031+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12032+ *
12033+ * Module Name:
12034+ * sap1.h
12035+ *
12036+ * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12037+ *
12038+ *
12039+ --*/
12040+#ifndef _SAP1_H_
12041+#define _SAP1_H_
12042+
12043+static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12044+
12045+#define Sa_MINIPORT_REVISION 1
12046+
12047+typedef struct _Sa_ADAPTER_EXTENSION {
12048+
12049+ //
12050+ // The following must be first.
12051+ //
12052+ PPCI_MINIPORT_COMMON_EXTENSION Common;
12053+ struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12054+ USHORT LocalMaskInterruptControl;
12055+ PSa_DEVICE_REGISTERS Device;
12056+
12057+} Sa_ADAPTER_EXTENSION;
12058+
12059+typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12060+
12061+
12062+
12063+#ifdef LINUX
12064+/*
12065+ *
12066+ */
12067+
12068+
12069+#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12070+#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12071+
12072+
12073+#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12074+#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12075+
12076+#endif /* LINUX */
12077+
12078+
12079+VOID
12080+SaInterruptAdapter(
12081+ PVOID Arg1
12082+ );
12083+
12084+VOID
12085+SaNotifyAdapter(
12086+ PVOID Arg1,
12087+ IN HOST_2_ADAP_EVENT AdapterEvent
12088+ );
12089+
12090+VOID
12091+SaResetDevice(
12092+ PVOID Arg1
12093+ );
12094+
12095+
12096+#endif /* _SAP1_H_ */
12097+
12098+
12099diff -burN linux-2.4.4/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12100--- linux-2.4.4/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 18:00:00 1969
12101+++ linux/drivers/scsi/aacraid/include/sap1common.h Mon Apr 30 09:43:34 2001
12102@@ -0,0 +1,111 @@
12103+/*++
12104+ * Adaptec aacraid device driver for Linux.
12105+ *
12106+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12107+ *
12108+ * This program is free software; you can redistribute it and/or modify
12109+ * it under the terms of the GNU General Public License as published by
12110+ * the Free Software Foundation; either version 2, or (at your option)
12111+ * any later version.
12112+ *
12113+ * This program is distributed in the hope that it will be useful,
12114+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12115+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12116+ * GNU General Public License for more details.
12117+ *
12118+ * You should have received a copy of the GNU General Public License
12119+ * along with this program; see the file COPYING. If not, write to
12120+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12121+ *
12122+ * Module Name:
12123+ * sap1common.h
12124+ *
12125+ * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12126+ *
12127+ --*/
12128+
12129+#ifndef _Sa_COMMON_H_
12130+#define _Sa_COMMON_H_
12131+
12132+static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12133+
12134+//
12135+// SaP1 Message Unit Registers
12136+//
12137+
12138+typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12139+ // Offset | Name
12140+ unsigned reserved[10]; // 00h-27h | Reserved
12141+ unsigned char LUT_Offset; // 28h | Looup Table Offset
12142+ unsigned char reserved1[3]; // 29h-2bh | Reserved
12143+ unsigned LUT_Data; // 2ch | Looup Table Data
12144+ unsigned reserved2[26]; // 30h-97h | Reserved
12145+ unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12146+ unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12147+ unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12148+ unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12149+ unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12150+ unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12151+ unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12152+ unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12153+ unsigned MAILBOX0; // a8h | Scratchpad 0
12154+ unsigned MAILBOX1; // ach | Scratchpad 1
12155+ unsigned MAILBOX2; // b0h | Scratchpad 2
12156+ unsigned MAILBOX3; // b4h | Scratchpad 3
12157+ unsigned MAILBOX4; // b8h | Scratchpad 4
12158+ unsigned MAILBOX5; // bch | Scratchpad 5
12159+ unsigned MAILBOX6; // c0h | Scratchpad 6
12160+ unsigned MAILBOX7; // c4h | Scratchpad 7
12161+
12162+ unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12163+ unsigned ROM_Control_Addr; // cch | Rom Control and Address
12164+
12165+ unsigned reserved3[12]; // d0h-ffh | reserved
12166+ unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12167+
12168+ //
12169+ // TO DO
12170+ // need to add DMA, I2O, UART, etc registers form 80h to 364h
12171+ //
12172+
12173+}Sa_Drawbridge_CSR;
12174+
12175+typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12176+
12177+
12178+#define Mailbox0 SaDbCSR.MAILBOX0
12179+#define Mailbox1 SaDbCSR.MAILBOX1
12180+#define Mailbox2 SaDbCSR.MAILBOX2
12181+#define Mailbox3 SaDbCSR.MAILBOX3
12182+#define Mailbox4 SaDbCSR.MAILBOX4
12183+
12184+
12185+#define Mailbox7 SaDbCSR.MAILBOX7
12186+
12187+#define DoorbellReg_p SaDbCSR.PRISETIRQ
12188+#define DoorbellReg_s SaDbCSR.SECSETIRQ
12189+#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12190+
12191+
12192+#define DOORBELL_0 0x00000001
12193+#define DOORBELL_1 0x00000002
12194+#define DOORBELL_2 0x00000004
12195+#define DOORBELL_3 0x00000008
12196+#define DOORBELL_4 0x00000010
12197+#define DOORBELL_5 0x00000020
12198+#define DOORBELL_6 0x00000040
12199+
12200+
12201+#define PrintfReady DOORBELL_5
12202+#define PrintfDone DOORBELL_5
12203+
12204+typedef struct _Sa_DEVICE_REGISTERS {
12205+ Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12206+} Sa_DEVICE_REGISTERS;
12207+
12208+typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12209+
12210+
12211+#endif // _Sa_COMMON_H_
12212+
12213+
12214diff -burN linux-2.4.4/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12215--- linux-2.4.4/drivers/scsi/aacraid/include/version.h Wed Dec 31 18:00:00 1969
12216+++ linux/drivers/scsi/aacraid/include/version.h Mon Apr 30 09:43:34 2001
12217@@ -0,0 +1,40 @@
12218+/*++
12219+ * Adaptec aacraid device driver for Linux.
12220+ *
12221+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12222+ *
12223+ * This program is free software; you can redistribute it and/or modify
12224+ * it under the terms of the GNU General Public License as published by
12225+ * the Free Software Foundation; either version 2, or (at your option)
12226+ * any later version.
12227+ *
12228+ * This program is distributed in the hope that it will be useful,
12229+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12230+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12231+ * GNU General Public License for more details.
12232+ *
12233+ * You should have received a copy of the GNU General Public License
12234+ * along with this program; see the file COPYING. If not, write to
12235+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12236+ *
12237+ * Module Name:
12238+ * version.h
12239+ *
12240+ * Abstract: Keeps track of build number for development purposes.
12241+ *
12242+ --*/
12243+#ifndef _VERSION_H_
12244+#define _VERSION_H_
12245+
12246+static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12247+
12248+#include "build_number.h"
12249+
12250+#define REV_MAJOR 2
12251+#define REV_MINOR 1
12252+#define REV_TYPE RevType_Release
12253+#define REV_DASH 5
12254+
12255+#define FSA_VERSION_STRING "2.1.5.3857\0"
12256+
12257+#endif /* _VERSION_H_ */
12258diff -burN linux-2.4.4/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12259--- linux-2.4.4/drivers/scsi/aacraid/linit.c Wed Dec 31 18:00:00 1969
12260+++ linux/drivers/scsi/aacraid/linit.c Mon Apr 30 09:47:34 2001
12261@@ -0,0 +1,1062 @@
12262+/*++
12263+ * Adaptec aacraid device driver for Linux.
12264+ *
12265+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12266+ *
12267+ * This program is free software; you can redistribute it and/or modify
12268+ * it under the terms of the GNU General Public License as published by
12269+ * the Free Software Foundation; either version 2, or (at your option)
12270+ * any later version.
12271+ *
12272+ * This program is distributed in the hope that it will be useful,
12273+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12274+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12275+ * GNU General Public License for more details.
12276+ *
12277+ * You should have received a copy of the GNU General Public License
12278+ * along with this program; see the file COPYING. If not, write to
12279+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12280+ *
12281+ * Module Name:
12282+ * linit.c
12283+ *
12284+ * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12285+ *
12286+ * Provides the following driver entry points:
12287+ * AAC_DetectHostAdapter()
12288+ * AAC_ReleaseHostAdapter()
12289+ * AAC_QueueCommand()
12290+ * AAC_ResetCommand()
12291+ * AAC_BIOSDiskParameters()
12292+ *
12293+ --*/
12294+
12295+static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12296+
12297+/*------------------------------------------------------------------------------
12298+ * D E F I N E S
12299+ *----------------------------------------------------------------------------*/
12300+#define AAC_DRIVER_VERSION "0.1.1"
12301+#define AAC_DRIVER_BUILD_DATE __DATE__
12302+#define MAX_DRIVER_QUEUE_DEPTH 500
12303+
12304+/*------------------------------------------------------------------------------
12305+ * I N C L U D E S
12306+ *----------------------------------------------------------------------------*/
12307+#include "osheaders.h"
12308+
12309+#include "AacGenericTypes.h"
12310+
12311+#ifdef MODULE
12312+#include <linux/module.h>
12313+#endif
12314+#include "sd.h"
12315+#include "linit.h"
12316+#include "aac_unix_defs.h"
12317+#include "fsatypes.h"
12318+#include "comstruc.h"
12319+#include "fsaport.h"
12320+#include "pcisup.h"
12321+#include "port.h"
12322+#include "afacomm.h"
12323+#include "nodetype.h"
12324+#include "comsup.h"
12325+#include "adapter.h"
12326+
12327+/*------------------------------------------------------------------------------
12328+ * G L O B A L S
12329+ *----------------------------------------------------------------------------*/
12330+extern FSA_MINIPORT MiniPorts[];
12331+extern int CommPrinting;
12332+extern char DescriptionString[];
12333+extern char devicestr[];
12334+
12335+/*------------------------------------------------------------------------------
12336+ * M O D U L E G L O B A L S
12337+ *----------------------------------------------------------------------------*/
12338+aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12339+
12340+char g_DriverName[] = { "aacraid" };
12341+#define module_options aacraid_options
12342+static char * aacraid_options = NULL;
12343+
12344+PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12345+unsigned g_HostAdapterCount = 0;
12346+unsigned g_chardev_major = 0;
12347+
12348+int g_single_command_done = FALSE;
12349+
12350+/*------------------------------------------------------------------------------
12351+ * F U N C T I O N P R O T O T Y P E S
12352+ *----------------------------------------------------------------------------*/
12353+int AacHba_Ioctl(
12354+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12355+ int cmd,
12356+ void * arg );
12357+
12358+int AacHba_ProbeContainers(
12359+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12360+
12361+int AacHba_DoScsiCmd(
12362+ Scsi_Cmnd *scsi_cmnd_ptr,
12363+ int wait );
12364+
12365+void AacHba_DetachAdapter(
12366+ IN PVOID AdapterArg );
12367+
12368+int AacHba_ClassDriverInit(
12369+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12370+
12371+void AacHba_AbortScsiCommand(
12372+ Scsi_Cmnd *scsi_cmnd_ptr );
12373+
12374+
12375+/*------------------------------------------------------------------------------
12376+ * L O C A L F U N C T I O N P R O T O T Y P E S
12377+ *----------------------------------------------------------------------------*/
12378+static int parse_keyword(
12379+ char ** str_ptr,
12380+ char * keyword );
12381+
12382+static void AAC_ParseDriverOptions(
12383+ char * cmnd_line_options_str );
12384+
12385+static void AAC_AnnounceDriver( void );
12386+
12387+int AAC_ChardevIoctl(
12388+ struct inode * inode_ptr,
12389+ struct file * file_ptr,
12390+ unsigned int cmd,
12391+ unsigned long arg );
12392+
12393+int AAC_ChardevOpen(
12394+ struct inode * inode_ptr,
12395+ struct file * file_ptr );
12396+
12397+int AAC_ChardevRelease(
12398+ struct inode * inode_ptr,
12399+ struct file * file_ptr );
12400+
12401+struct file_operations AAC_fops = {
12402+ NULL, // module name
12403+ NULL, // lseek
12404+ NULL, // read
12405+ NULL, // write
12406+ NULL, // readdir
12407+ NULL, // poll
12408+ AAC_ChardevIoctl, // ioctl
12409+ NULL, // mmap
12410+ AAC_ChardevOpen, // open
12411+ NULL, // flush
12412+ AAC_ChardevRelease, // release
12413+ NULL, // fsync
12414+ NULL, // fasync
12415+ NULL, // check media change
12416+ NULL, // revalidate
12417+ NULL // lock
12418+};
12419+
12420+/*------------------------------------------------------------------------------
12421+ * F U N C T I O N S
12422+ *----------------------------------------------------------------------------*/
12423+/*------------------------------------------------------------------------------
12424+ AAC_AnnounceDriver()
12425+
12426+ Announce the driver name, version and date.
12427+ *----------------------------------------------------------------------------*/
12428+static void AAC_AnnounceDriver( void ){
12429+ printk("<1>%s, %s\n",
12430+ "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12431+ schedule();
12432+}
12433+
12434+
12435+/*------------------------------------------------------------------------------
12436+ AAC_DetectHostAdapter()
12437+
12438+ Probe for AAC Host Adapters initialize, register, and report the
12439+ configuration of each AAC Host Adapter found.
12440+
12441+ Preconditions:
12442+ Postconditions:
12443+ - Returns the number of adapters successfully initialized and
12444+ registered.
12445+ - Initialize all data necessary for this particular SCSI driver.
12446+ Notes:
12447+ The detect routine must not call any of the mid level functions
12448+ to queue commands because things are not guaranteed to be set
12449+ up yet. The detect routine can send commands to the host adapter
12450+ as long as the program control will not be passed to scsi.c in
12451+ the processing of the command. Note especially that
12452+ scsi_malloc/scsi_free must not be called.
12453+ *----------------------------------------------------------------------------*/
12454+int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12455+{
12456+ int index;
12457+ int ContainerId;
12458+ uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12459+ struct Scsi_Host *host_ptr;
12460+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12461+ struct pci_dev *dev = NULL;
12462+ extern int NumMiniPorts;
12463+ fsadev_t *fsa_dev_ptr;
12464+ char *DeviceName;
12465+
12466+ struct pci_dev *devp;
12467+
12468+ int first_index, last_index, increment;
12469+
12470+ CommPrinting = TRUE;
12471+
12472+#ifdef MODULE
12473+ EXPORT_NO_SYMBOLS;
12474+#endif
12475+
12476+ AAC_AnnounceDriver();
12477+
12478+ /* setting up the proc directory structure */
12479+ HostTemplate->proc_name = "aacraid";
12480+
12481+ if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12482+
12483+ // NumMiniPorts & MiniPorts[] defined in aacid.c
12484+ if (g_options.reverse_scan == 0) {
12485+ first_index = 0;
12486+ last_index = NumMiniPorts;
12487+ increment = 1;
12488+ } else {
12489+ first_index = NumMiniPorts -1;
12490+ last_index = -1;
12491+ increment = -1;
12492+ }
12493+
12494+ for( index = first_index; index != last_index; index += increment )
12495+ {
12496+ device_id = MiniPorts[index].DeviceId;
12497+ vendor_id = MiniPorts[index].VendorId;
12498+ DeviceName = MiniPorts[index].DeviceName;
12499+ cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12500+ DeviceName, vendor_id, device_id,
12501+ MiniPorts[index].SubVendorId,
12502+ MiniPorts[index].SubSystemId);
12503+
12504+
12505+ // pci_find_device traverses the pci_devices linked list for devices
12506+ // with matching vendor and device ids.
12507+
12508+ dev = NULL; // start from beginning of list
12509+ while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12510+ {
12511+ if (pci_enable_device(dev)) continue;
12512+
12513+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12514+ cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12515+ break;
12516+ }
12517+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12518+ cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12519+ break;
12520+ }
12521+
12522+ cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12523+ if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12524+ ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12525+ continue;
12526+ }
12527+
12528+
12529+ printk("<1>%s device detected\n", DeviceName );
12530+ cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12531+
12532+ // Increment the host adapter count
12533+ g_HostAdapterCount++;
12534+
12535+ // scsi_register() allocates memory for a Scsi_Hosts structure and
12536+ // links it into the linked list of host adapters. This linked list
12537+ // contains the data for all possible <supported> scsi hosts.
12538+ // This is similar to the Scsi_Host_Template, except that we have
12539+ // one entry for each actual physical host adapter on the system,
12540+ // stored as a linked list. If there are two AAC boards, then we
12541+ // will need to make two Scsi_Host entries, but there will be only
12542+ // one Scsi_Host_Template entry. The second argument to scsi_register()
12543+ // specifies the size of the extra memory we want to hold any device
12544+ // specific information.
12545+ host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12546+
12547+ // These three parameters can be used to allow for wide SCSI
12548+ // and for host adapters that support multiple buses.
12549+ host_ptr->max_id = 17;
12550+ host_ptr->max_lun = 8;
12551+ host_ptr->max_channel = 1;
12552+
12553+
12554+ host_ptr->irq = dev->irq; // Adapter IRQ number
12555+ /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12556+ host_ptr->base = ( char * )(dev->resource[0].start);
12557+ scsi_set_pci_device(host_ptr, dev);
12558+
12559+ cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12560+ cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12561+
12562+ // The unique_id field is a unique identifier that must be assigned
12563+ // so that we have some way of identifying each host adapter properly
12564+ // and uniquely. For hosts that do not support more than one card in the
12565+ // system, this does not need to be set. It is initialized to zero in
12566+ // scsi_register(). This is the value returned from OsGetDeviceInstance().
12567+
12568+ host_ptr->unique_id = g_HostAdapterCount - 1;
12569+ host_ptr->this_id = 16; // SCSI Id for the adapter itself
12570+
12571+ // Set the maximum number of simultaneous commands supported by the driver.
12572+ host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12573+
12574+ // Define the maximum number of scatter/gather elements supported by
12575+ // the driver.
12576+
12577+ host_ptr->sg_tablesize = 16;
12578+ host_ptr->max_sectors = 128;
12579+ host_ptr->cmd_per_lun = 1; // untagged queue depth
12580+
12581+ // This function is called after the device list has been built to find
12582+ // tagged queueing depth supported for each device.
12583+
12584+ host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12585+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12586+
12587+ // attach a pointer back to Scsi_Host
12588+ CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12589+ CommonExtensionPtr->OsDep.MiniPortIndex = index;
12590+
12591+ // Initialize the ordinal number of the device to -1
12592+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12593+ for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12594+ fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12595+
12596+ // Call initialization routine
12597+ cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12598+ if( ( *MiniPorts[index].InitRoutine )
12599+ ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12600+ {
12601+ // device initialization failed
12602+ cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12603+ scsi_unregister( host_ptr );
12604+ g_HostAdapterCount--;
12605+ } /* end if */
12606+ else
12607+ {
12608+ cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12609+ AacHba_ClassDriverInit( CommonExtensionPtr );
12610+ cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12611+ AacHba_ProbeContainers( CommonExtensionPtr );
12612+ g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12613+
12614+ } /* end else */
12615+
12616+ } /* end while */
12617+
12618+ } /* end for */
12619+
12620+ if( g_HostAdapterCount ){
12621+ if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12622+ cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12623+ }
12624+
12625+ HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12626+
12627+ return( g_HostAdapterCount );
12628+}
12629+
12630+
12631+/*------------------------------------------------------------------------------
12632+ AAC_ReleaseHostAdapter()
12633+
12634+ Release all resources previously acquired to support a specific Host
12635+ Adapter and unregister the AAC Host Adapter.
12636+ *----------------------------------------------------------------------------*/
12637+int AAC_ReleaseHostAdapter(
12638+ struct Scsi_Host *host_ptr )
12639+/*----------------------------------------------------------------------------*/
12640+{
12641+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12642+
12643+ cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12644+
12645+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12646+
12647+ // kill any threads we started
12648+ kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12649+
12650+ // Call the comm layer to detach from this adapter
12651+ AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12652+
12653+ // remove interrupt binding
12654+ OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12655+
12656+ SaDetachDevice( CommonExtensionPtr );
12657+
12658+ // unregister adapter
12659+ scsi_unregister( host_ptr );
12660+
12661+ if( g_chardev_major )
12662+ {
12663+ unregister_chrdev( g_chardev_major, devicestr );
12664+ g_chardev_major = 0;
12665+ }
12666+
12667+ return( 0 ); // #REVISIT# return code
12668+}
12669+
12670+
12671+/*------------------------------------------------------------------------------
12672+ AAC_QueueCommand()
12673+
12674+ Queues a command for execution by the associated Host Adapter.
12675+ *----------------------------------------------------------------------------*/
12676+int AAC_QueueCommand(
12677+ Scsi_Cmnd *scsi_cmnd_ptr,
12678+ void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12679+/*----------------------------------------------------------------------------*/
12680+{
12681+ scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12682+
12683+ // AacHba_DoScsiCmd() handles command processing, setting the
12684+ // result code and calling completion routine.
12685+ #ifdef SYNC_FIB
12686+ if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 ) ) // called with wait = TRUE
12687+ #else
12688+ if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 ) ) // called with wait = FALSE
12689+ #endif
12690+ cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12691+ return 0;
12692+}
12693+
12694+
12695+/*------------------------------------------------------------------------------
12696+ AAC_Done()
12697+
12698+ Callback function for a non-queued command.
12699+
12700+ Postconditions
12701+ Sets g_single_command done to TRUE
12702+ *----------------------------------------------------------------------------*/
12703+void AAC_Done(
12704+ Scsi_Cmnd * scsi_cmnd_ptr )
12705+/*----------------------------------------------------------------------------*/
12706+{
12707+ g_single_command_done = TRUE;
12708+}
12709+
12710+
12711+/*------------------------------------------------------------------------------
12712+ AAC_Command()
12713+
12714+ Accepts a single command for execution by the associated Host Adapter.
12715+
12716+ Postconditions
12717+ Returns an int where:
12718+ Byte 0 = SCSI status code
12719+ Byte 1 = SCSI 1 byte message
12720+ Byte 2 = host error return
12721+ Byte 3 = mid level error return
12722+ *----------------------------------------------------------------------------*/
12723+int AAC_Command(
12724+ Scsi_Cmnd *scsi_cmnd_ptr )
12725+/*----------------------------------------------------------------------------*/
12726+{
12727+ scsi_cmnd_ptr->scsi_done = AAC_Done;
12728+
12729+ cmn_err( CE_DEBUG, "AAC_Command" );
12730+
12731+ // AacHba_DoScsiCmd() handles command processing, setting the
12732+ // result code and calling completion routine.
12733+ g_single_command_done = FALSE;
12734+
12735+ AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12736+ while( !g_single_command_done );
12737+ return( scsi_cmnd_ptr->result );
12738+}
12739+
12740+
12741+/*------------------------------------------------------------------------------
12742+ AAC_AbortCommand()
12743+
12744+ Abort command if possible.
12745+ *----------------------------------------------------------------------------*/
12746+int AAC_AbortCommand(
12747+ Scsi_Cmnd *scsi_cmnd_ptr )
12748+/*----------------------------------------------------------------------------*/
12749+{
12750+ int target = scsi_cmnd_ptr->target;
12751+ int hba = scsi_cmnd_ptr->host->unique_id;
12752+ int result = 0;
12753+ u_short interrupt_status;
12754+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12755+ char *DeviceName;
12756+
12757+ cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12758+ AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12759+
12760+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12761+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12762+
12763+ /*
12764+ cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12765+ "command already completed", DeviceName, hba, target);
12766+ result = SCSI_ABORT_NOT_RUNNING;
12767+
12768+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12769+ "no command found\n", DeviceName, hba, target);
12770+ result = SCSI_ABORT_NOT_RUNNING;
12771+
12772+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12773+ "command reset\n", DeviceName, hba, target);
12774+ result = SCSI_ABORT_PENDING;
12775+
12776+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12777+ "abort tag not supported\n", DeviceName, hba, target);
12778+ result = SCSI_ABORT_SNOOZE;
12779+
12780+ cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12781+ DeviceName, hba, target);
12782+ result = SCSI_ABORT_PENDING;
12783+
12784+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12785+ DeviceName, hba, target);
12786+ result = SCSI_ABORT_BUSY;
12787+
12788+ cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12789+ DeviceName, hba, target);
12790+ result = SCSI_ABORT_SUCCESS;
12791+ */
12792+
12793+ // Abort not supported yet
12794+ result = SCSI_ABORT_BUSY;
12795+ return result;
12796+}
12797+
12798+
12799+/*------------------------------------------------------------------------------
12800+ AAC_ResetCommand()
12801+
12802+ Reset command handling.
12803+ *----------------------------------------------------------------------------*/
12804+int AAC_ResetCommand(
12805+ struct scsi_cmnd *scsi_cmnd_ptr,
12806+ unsigned int reset_flags )
12807+/*----------------------------------------------------------------------------*/
12808+{
12809+ int target = scsi_cmnd_ptr->target;
12810+ int hba = scsi_cmnd_ptr->host->unique_id;
12811+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12812+ char *DeviceName;
12813+
12814+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12815+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12816+
12817+ cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12818+
12819+ return SCSI_RESET_PUNT;
12820+}
12821+
12822+
12823+/*------------------------------------------------------------------------------
12824+ AAC_DriverInfo()
12825+
12826+ Returns the host adapter name
12827+ *----------------------------------------------------------------------------*/
12828+const char *AAC_DriverInfo(
12829+ struct Scsi_Host *host_ptr )
12830+/*----------------------------------------------------------------------------*/
12831+{
12832+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12833+ char *DeviceName;
12834+
12835+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12836+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12837+
12838+ cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12839+ return (DeviceName);
12840+}
12841+
12842+
12843+/*------------------------------------------------------------------------------
12844+ AAC_BIOSDiskParameters()
12845+
12846+ Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12847+ The default disk geometry is 64 heads, 32 sectors, and the appropriate
12848+ number of cylinders so as not to exceed drive capacity. In order for
12849+ disks equal to or larger than 1 GB to be addressable by the BIOS
12850+ without exceeding the BIOS limitation of 1024 cylinders, Extended
12851+ Translation should be enabled. With Extended Translation enabled,
12852+ drives between 1 GB inclusive and 2 GB exclusive are given a disk
12853+ geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12854+ are given a disk geometry of 255 heads and 63 sectors. However, if
12855+ the BIOS detects that the Extended Translation setting does not match
12856+ the geometry in the partition table, then the translation inferred
12857+ from the partition table will be used by the BIOS, and a warning may
12858+ be displayed.
12859+ *----------------------------------------------------------------------------*/
12860+int AAC_BIOSDiskParameters(
12861+ Scsi_Disk *scsi_disk_ptr,
12862+ kdev_t device,
12863+ int *parameter_ptr )
12864+/*----------------------------------------------------------------------------*/
12865+{
12866+ AAC_BIOS_DiskParameters_T *disk_parameters =
12867+ ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12868+ struct buffer_head * buffer_head_ptr;
12869+
12870+ cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12871+
12872+ // Assuming extended translation is enabled - #REVISIT#
12873+ if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12874+ {
12875+ if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12876+ {
12877+ disk_parameters->heads = 255;
12878+ disk_parameters->sectors = 63;
12879+ }
12880+ else
12881+ {
12882+ disk_parameters->heads = 128;
12883+ disk_parameters->sectors = 32;
12884+ }
12885+ }
12886+ else
12887+ {
12888+ disk_parameters->heads = 64;
12889+ disk_parameters->sectors = 32;
12890+ }
12891+
12892+ disk_parameters->cylinders = scsi_disk_ptr->capacity
12893+ /( disk_parameters->heads * disk_parameters->sectors );
12894+
12895+ // Read the first 1024 bytes from the disk device
12896+ buffer_head_ptr = bread(
12897+ MKDEV( MAJOR( device ),
12898+ MINOR( device ) & ~0x0F ),
12899+ 0, 1024 );
12900+
12901+ if( buffer_head_ptr == NULL )
12902+ return( 0 );
12903+ /*
12904+ If the boot sector partition table is valid, search for a partition
12905+ table entry whose end_head matches one of the standard geometry
12906+ translations ( 64/32, 128/32, 255/63 ).
12907+ */
12908+ if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12909+ {
12910+ struct partition *first_partition_entry =
12911+ ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12912+ struct partition *partition_entry = first_partition_entry;
12913+ int saved_cylinders = disk_parameters->cylinders;
12914+ int partition_number;
12915+ unsigned char partition_entry_end_head, partition_entry_end_sector;
12916+
12917+ for( partition_number = 0; partition_number < 4; partition_number++ )
12918+ {
12919+ partition_entry_end_head = partition_entry->end_head;
12920+ partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12921+
12922+ if( partition_entry_end_head == ( 64 - 1 ) )
12923+ {
12924+ disk_parameters->heads = 64;
12925+ disk_parameters->sectors = 32;
12926+ break;
12927+ }
12928+ else if( partition_entry_end_head == ( 128 - 1 ) )
12929+ {
12930+ disk_parameters->heads = 128;
12931+ disk_parameters->sectors = 32;
12932+ break;
12933+ }
12934+ else if( partition_entry_end_head == ( 255 - 1 ) )
12935+ {
12936+ disk_parameters->heads = 255;
12937+ disk_parameters->sectors = 63;
12938+ break;
12939+ }
12940+ partition_entry++;
12941+ }
12942+
12943+ if( partition_number == 4 )
12944+ {
12945+ partition_entry_end_head = first_partition_entry->end_head;
12946+ partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12947+ }
12948+
12949+ disk_parameters->cylinders = scsi_disk_ptr->capacity
12950+ /( disk_parameters->heads * disk_parameters->sectors );
12951+
12952+ if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
12953+ {
12954+ if( disk_parameters->cylinders != saved_cylinders )
12955+ cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12956+ disk_parameters->heads, disk_parameters->sectors, partition_number );
12957+ }
12958+ else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
12959+ {
12960+ cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
12961+ partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
12962+ cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
12963+ disk_parameters->heads, disk_parameters->sectors );
12964+ }
12965+ }
12966+
12967+ brelse( buffer_head_ptr );
12968+
12969+ return( 0 );
12970+}
12971+
12972+
12973+/*------------------------------------------------------------------------------
12974+ AAC_SelectQueueDepths()
12975+
12976+ Selects queue depths for each target device based on the host adapter's
12977+ total capacity and the queue depth supported by the target device.
12978+ A queue depth of one automatically disables tagged queueing.
12979+ *----------------------------------------------------------------------------*/
12980+void AAC_SelectQueueDepths(
12981+ struct Scsi_Host * host_ptr,
12982+ Scsi_Device * scsi_device_ptr )
12983+/*----------------------------------------------------------------------------*/
12984+{
12985+ Scsi_Device * device_ptr;
12986+
12987+ cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
12988+ cmn_err( CE_DEBUG, "Device # Q Depth Online" );
12989+ cmn_err( CE_DEBUG, "---------------------------" );
12990+ for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
12991+ if( device_ptr->host == host_ptr )
12992+ {
12993+ device_ptr->queue_depth = 10;
12994+ cmn_err( CE_DEBUG, " %2d %d %d",
12995+ device_ptr->id, device_ptr->queue_depth, device_ptr->online );
12996+ }
12997+}
12998+
12999+
13000+/*------------------------------------------------------------------------------
13001+ AAC_SearchBiosSignature()
13002+
13003+ Locate adapter signature in BIOS
13004+ *----------------------------------------------------------------------------*/
13005+int AAC_SearchBiosSignature( void )
13006+/*----------------------------------------------------------------------------*/
13007+{
13008+ unsigned base;
13009+ unsigned namep;
13010+ int index;
13011+ int val;
13012+ char name_buf[32];
13013+ int result = FALSE;
13014+
13015+ for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13016+ {
13017+ val = readb( base );
13018+ if( val != 0x55 )
13019+ continue;
13020+
13021+ result = TRUE;
13022+ namep = base + 0x1e;
13023+ memcpy_fromio( name_buf, namep, 32 );
13024+ name_buf[31] = '\0';
13025+ }
13026+ return( result );
13027+}
13028+
13029+
13030+/*------------------------------------------------------------------------------
13031+ AAC_Ioctl()
13032+
13033+ Handle SCSI ioctls
13034+ *----------------------------------------------------------------------------*/
13035+int AAC_Ioctl(
13036+ Scsi_Device * scsi_dev_ptr,
13037+ int cmd,
13038+ void * arg )
13039+/*----------------------------------------------------------------------------*/
13040+{
13041+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13042+
13043+ cmn_err( CE_DEBUG, "AAC_Ioctl" );
13044+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13045+ return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13046+}
13047+
13048+
13049+
13050+/*------------------------------------------------------------------------------
13051+ AAC_ChardevOpen()
13052+
13053+ Handle character device open
13054+
13055+ Preconditions:
13056+ Postconditions:
13057+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13058+ *----------------------------------------------------------------------------*/
13059+int AAC_ChardevOpen(
13060+ struct inode * inode_ptr,
13061+ struct file * file_ptr )
13062+/*----------------------------------------------------------------------------*/
13063+{
13064+ unsigned minor_number;
13065+
13066+ cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13067+
13068+ // check device permissions in file_ptr->f_mode ??
13069+
13070+ // extract & check the minor number
13071+ minor_number = MINOR( inode_ptr->i_rdev );
13072+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13073+ {
13074+ cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13075+ return( -ENODEV );
13076+ }
13077+
13078+#ifdef MODULE
13079+ MOD_INC_USE_COUNT;
13080+#endif
13081+
13082+ return( 0 );
13083+}
13084+
13085+
13086+/*------------------------------------------------------------------------------
13087+ AAC_ChardevRelease()
13088+
13089+ Handle character device release.
13090+
13091+ Preconditions:
13092+ Postconditions:
13093+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13094+ *----------------------------------------------------------------------------*/
13095+int AAC_ChardevRelease(
13096+ struct inode * inode_ptr,
13097+ struct file * file_ptr )
13098+/*----------------------------------------------------------------------------*/
13099+{
13100+ cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13101+
13102+#ifdef MODULE
13103+ MOD_DEC_USE_COUNT;
13104+#endif
13105+
13106+ return( 0 );
13107+}
13108+
13109+
13110+/*------------------------------------------------------------------------------
13111+ AAC_ChardevIoctl()
13112+
13113+ Handle character device interface ioctls
13114+
13115+ Preconditions:
13116+ Postconditions:
13117+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13118+ *----------------------------------------------------------------------------*/
13119+int AAC_ChardevIoctl(
13120+ struct inode * inode_ptr,
13121+ struct file * file_ptr,
13122+ unsigned int cmd,
13123+ unsigned long arg )
13124+{
13125+ unsigned minor_number;
13126+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13127+
13128+ cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13129+
13130+ // check device permissions in file_ptr->f_mode ??
13131+
13132+ // extract & check the minor number
13133+ minor_number = MINOR( inode_ptr->i_rdev );
13134+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13135+ {
13136+ cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13137+ return( -ENODEV );
13138+ }
13139+
13140+ // get device pointer
13141+ CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13142+
13143+ // dispatch ioctl - AacHba_Ioctl() returns zero on success
13144+ if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13145+ return( -EINVAL );
13146+
13147+ return( 0 );
13148+}
13149+
13150+
13151+/*------------------------------------------------------------------------------
13152+ parse_keyword()
13153+
13154+ Look for the keyword in str_ptr
13155+
13156+ Preconditions:
13157+ Postconditions:
13158+ If keyword found
13159+ - return true and update the pointer str_ptr.
13160+ otherwise
13161+ - return false
13162+ *----------------------------------------------------------------------------*/
13163+static int parse_keyword(
13164+ char ** str_ptr,
13165+ char * keyword )
13166+/*----------------------------------------------------------------------------*/
13167+{
13168+ char * ptr = *str_ptr;
13169+
13170+ while( *keyword != '\0' )
13171+ {
13172+ char string_char = *ptr++;
13173+ char keyword_char = *keyword++;
13174+
13175+ if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13176+ string_char += 'a' - 'Z';
13177+ if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13178+ keyword_char += 'a' - 'Z';
13179+ if( string_char != keyword_char )
13180+ return FALSE;
13181+ }
13182+ *str_ptr = ptr;
13183+ return TRUE;
13184+}
13185+
13186+
13187+/*------------------------------------------------------------------------------
13188+ AAC_ParseDriverOptions()
13189+
13190+ For modules the usage is:
13191+ insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13192+ *----------------------------------------------------------------------------*/
13193+static void AAC_ParseDriverOptions(
13194+ char * cmnd_line_options_str )
13195+/*----------------------------------------------------------------------------*/
13196+{
13197+ int message_level;
13198+ int reverse_scan;
13199+ char *cp;
13200+ char *endp;
13201+
13202+ cp = cmnd_line_options_str;
13203+
13204+ cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13205+
13206+ while( *cp ) {
13207+ if( parse_keyword( &cp, "message_level:" ) ) {
13208+ message_level = simple_strtoul( cp, 0, 0 );
13209+ if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13210+ g_options.message_level = message_level;
13211+ cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13212+ }
13213+ else {
13214+ cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13215+ }
13216+ } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13217+ reverse_scan = simple_strtoul( cp, 0, 0 );
13218+ if (reverse_scan) {
13219+ g_options.reverse_scan = 1;
13220+ cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13221+ }
13222+ }
13223+ else {
13224+ cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13225+ }
13226+
13227+ /*
13228+ * skip to next option, accept " ", ";", and "," as delimiters
13229+ */
13230+ while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13231+ cp++;
13232+
13233+ if (*cp) /* skip over the delimiter */
13234+ cp++;
13235+ }
13236+
13237+}
13238+
13239+
13240+/*------------------------------------------------------------------------------
13241+ Include Module support if requested.
13242+
13243+ To use the low level SCSI driver support using the linux kernel loadable
13244+ module interface we should initialize the global variable driver_interface
13245+ (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13246+ This should also be wrapped in a #ifdef MODULE/#endif
13247+ *----------------------------------------------------------------------------*/
13248+#ifdef MODULE
13249+
13250+/*
13251+ The Loadable Kernel Module Installation Facility may pass us
13252+ a pointer to a driver specific options string to be parsed,
13253+ we assign this to options string.
13254+*/
13255+MODULE_PARM( module_options, "s" );
13256+
13257+Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13258+
13259+#include "scsi_module.c"
13260+
13261+#else
13262+Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13263+
13264+#include "scsi_module.c"
13265+#endif
13266+
13267+/*********************************************************************
13268+ AAC_ProcDirectoryInfo()
13269+
13270+ Implement /proc/scsi/<drivername>/<n>.
13271+ Used to export driver statistics and other infos to the world outside
13272+ the kernel using the proc file system. Also provides an interface to
13273+ feed the driver with information.
13274+
13275+ Postconditions
13276+ For reads
13277+ - if offset > 0 return 0
13278+ - if offset == 0 write data to proc_buffer and set the start_ptr to
13279+ beginning of proc_buffer, return the number of characters written.
13280+ For writes
13281+ - writes currently not supported, return 0
13282+************************************************************/
13283+int AAC_ProcDirectoryInfo(
13284+ char *proc_buffer, // read/write buffer
13285+ char **start_ptr, // start of valid data in the buffer
13286+ off_t offset, // offset from the beginning of the imaginary file
13287+ int bytes_available, // bytes available
13288+ int host_no, // SCSI host number
13289+ int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13290+{
13291+ int length = 0;
13292+ cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13293+
13294+ if( ( write ) || ( offset > 0 ) )
13295+ return( 0 );
13296+
13297+ *start_ptr = proc_buffer;
13298+
13299+ return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13300+}
13301+
13302+void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13303+{
13304+ void *BaseAddress;
13305+ ULONG PhysAddress;
13306+ int size;
13307+ int npages;
13308+ int i;
13309+
13310+ AFA_COMM_ADAPTER *Adapter;
13311+ Adapter = CommonExtension->Adapter;
13312+
13313+
13314+ // Allocate 1 fib for synch fibs
13315+ // Allocate 1 page.
13316+ BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13317+ bzero(BaseAddress, PAGE_SIZE);
13318+ PhysAddress = virt_to_phys (BaseAddress);
13319+ Adapter->SyncFib = BaseAddress;
13320+ Adapter->SyncFibPhysicalAddress = PhysAddress;
13321+ cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13322+
13323+}
13324diff -burN linux-2.4.4/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13325--- linux-2.4.4/drivers/scsi/aacraid/osddi.c Wed Dec 31 18:00:00 1969
13326+++ linux/drivers/scsi/aacraid/osddi.c Mon Apr 30 09:43:34 2001
13327@@ -0,0 +1,512 @@
13328+/*++
13329+ * Adaptec aacraid device driver for Linux.
13330+ *
13331+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13332+ *
13333+ * This program is free software; you can redistribute it and/or modify
13334+ * it under the terms of the GNU General Public License as published by
13335+ * the Free Software Foundation; either version 2, or (at your option)
13336+ * any later version.
13337+ *
13338+ * This program is distributed in the hope that it will be useful,
13339+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13340+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13341+ * GNU General Public License for more details.
13342+ *
13343+ * You should have received a copy of the GNU General Public License
13344+ * along with this program; see the file COPYING. If not, write to
13345+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13346+ *
13347+ * Module Name:
13348+ * osddi.c
13349+ *
13350+ * Abstract: This file contains all the proceedures which use LINUX specific Device
13351+ * Driver Interfaces.
13352+ *
13353+ --*/
13354+
13355+static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13356+
13357+#include "osheaders.h"
13358+
13359+#include <linux/smp_lock.h>
13360+
13361+#ifdef fsid_t
13362+#undef fsid_t
13363+#endif
13364+#include "AacGenericTypes.h"
13365+#include "aac_unix_defs.h"
13366+#include "comstruc.h"
13367+#include "monkerapi.h"
13368+#include "protocol.h"
13369+#include "fsafs.h"
13370+
13371+#include "sap1common.h"
13372+#include "fsaport.h"
13373+#include "pcisup.h"
13374+#include "sap1.h"
13375+#include "nodetype.h"
13376+#include "comsup.h"
13377+#include "afacomm.h"
13378+#include "adapter.h"
13379+
13380+
13381+void AacSaPciIsr(
13382+ int irq,
13383+ void * irq_data,
13384+ struct pt_regs *regs);
13385+
13386+void AacRxPciIsr(
13387+ int irq,
13388+ void * irq_data,
13389+ struct pt_regs *regs);
13390+
13391+unsigned SaPciIsr (
13392+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13393+
13394+unsigned RxPciIsr (
13395+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13396+
13397+
13398+/*----------------------------------------------------------------------------*/
13399+VOID AfaCommInterruptHost(
13400+ PVOID AdapterArg,
13401+ ADAPTER_EVENT AdapterEvent )
13402+/*----------------------------------------------------------------------------*/
13403+{
13404+ PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13405+ PCOMM_REGION CommRegion = Adapter->CommRegion;
13406+
13407+ switch (AdapterEvent) {
13408+
13409+ case HostNormRespQue:
13410+ OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13411+
13412+ // #REVIEW# - what do we do with this
13413+ // if (FsaCommData.HardInterruptModeration)
13414+ // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13415+
13416+ break;
13417+
13418+ case AdapNormCmdNotFull:
13419+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13420+ break;
13421+
13422+ case HostNormCmdQue:
13423+ OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13424+ break;
13425+
13426+ case AdapNormRespNotFull:
13427+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13428+ break;
13429+
13430+ // #REVIEW# - what do we do with these
13431+ case HostHighCmdQue:
13432+ case HostHighRespQue:
13433+ case AdapHighCmdNotFull:
13434+ case AdapHighRespNotFull:
13435+ case SynchCommandComplete:
13436+ case AdapInternalError:
13437+ break;
13438+ }
13439+}
13440+
13441+
13442+// get the device name associated with this instance of the device
13443+/*----------------------------------------------------------------------------*/
13444+char *OsGetDeviceName(
13445+ void *AdapterExtension )
13446+/*----------------------------------------------------------------------------*/
13447+{
13448+ return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13449+ OsDep.scsi_host_ptr->hostt->name );
13450+}
13451+
13452+
13453+/*----------------------------------------------------------------------------*/
13454+int OsGetDeviceInstance(
13455+ void *AdapterExtension )
13456+/*----------------------------------------------------------------------------*/
13457+{
13458+ return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13459+ OsDep.scsi_host_ptr->unique_id );
13460+}
13461+
13462+
13463+/*------------------------------------------------------------------------------
13464+ OsMapDeviceRegisters()
13465+
13466+ Postconditions:
13467+ Return zero on success non-zero otherwise.
13468+ *----------------------------------------------------------------------------*/
13469+int OsMapDeviceRegisters(
13470+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13471+/*----------------------------------------------------------------------------*/
13472+{
13473+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13474+
13475+ CommonExtension = AdapterExtension->Common;
13476+
13477+ if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13478+ ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13479+ {
13480+ cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13481+ return( 0 );
13482+ }
13483+ else
13484+ {
13485+ cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13486+ return( 1 );
13487+ }
13488+}
13489+
13490+
13491+/*------------------------------------------------------------------------------
13492+ OsUnMapDeviceRegisters()
13493+
13494+ Postconditions:
13495+ *----------------------------------------------------------------------------*/
13496+void OsUnMapDeviceRegisters(
13497+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13498+/*----------------------------------------------------------------------------*/
13499+{
13500+ iounmap( ( void * )AdapterExtension->Device );
13501+}
13502+
13503+
13504+/*----------------------------------------------------------------------------*/
13505+int OsAttachInterrupt(
13506+ Sa_ADAPTER_EXTENSION *AdapterExtension ,
13507+ int WhichIsr )
13508+/*----------------------------------------------------------------------------*/
13509+{
13510+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13511+ void *irq_data;
13512+ void (*Isr)();
13513+
13514+ CommonExtension = AdapterExtension->Common;
13515+ irq_data = ( void * )AdapterExtension;
13516+
13517+ switch (WhichIsr) {
13518+ case SaISR:
13519+ Isr = AacSaPciIsr;
13520+ break;
13521+ case RxISR:
13522+ Isr = AacRxPciIsr;
13523+ break;
13524+ default:
13525+ cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13526+ return( FAILURE );
13527+ break;
13528+ }
13529+
13530+
13531+ if ( OsRegisterInterrupt (
13532+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13533+ Isr, // handler function
13534+ irq_data )
13535+ )
13536+ {
13537+ cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13538+ CommonExtension->OsDep.scsi_host_ptr->irq );
13539+ return( FAILURE );
13540+ }
13541+
13542+ return ( 0 );
13543+}
13544+
13545+
13546+/*----------------------------------------------------------------------------*/
13547+void AacSaPciIsr(
13548+ int irq,
13549+ void * irq_data,
13550+ struct pt_regs *regs)
13551+/*----------------------------------------------------------------------------*/
13552+{
13553+ // call the actual interrupt handler
13554+ SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13555+}
13556+
13557+/*----------------------------------------------------------------------------*/
13558+void AacRxPciIsr(
13559+ int irq,
13560+ void * irq_data,
13561+ struct pt_regs *regs)
13562+/*----------------------------------------------------------------------------*/
13563+{
13564+ // call the actual interrupt handler
13565+ RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13566+}
13567+
13568+
13569+/*----------------------------------------------------------------------------*/
13570+void OsDetachInterrupt(
13571+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13572+/*----------------------------------------------------------------------------*/
13573+{
13574+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13575+ void *irq_data;
13576+
13577+ CommonExtension = AdapterExtension->Common;
13578+ irq_data = ( void * )AdapterExtension;
13579+
13580+ OsUnregisterInterrupt (
13581+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13582+ irq_data );
13583+}
13584+
13585+
13586+/*----------------------------------------------------------------------------*/
13587+int OsAttachDMA(
13588+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13589+/*----------------------------------------------------------------------------*/
13590+{
13591+ return( 0 );
13592+}
13593+
13594+/*----------------------------------------------------------------------------*/
13595+int OsAttachHBA(
13596+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13597+/*----------------------------------------------------------------------------*/
13598+{
13599+ return( 0 );
13600+}
13601+
13602+/*----------------------------------------------------------------------------*/
13603+void OsDetachDevice(
13604+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13605+/*----------------------------------------------------------------------------*/
13606+{
13607+ OsUnMapDeviceRegisters( AdapterExtension );
13608+ return( 0 );
13609+}
13610+
13611+/*----------------------------------------------------------------------------*/
13612+ULONG *OsAllocCommPhysMem(
13613+ Sa_ADAPTER_EXTENSION *AdapterExtension,
13614+ ULONG size,
13615+ ULONG **virt_addr_pptr,
13616+ ULONG *phys_addr_ptr )
13617+/*----------------------------------------------------------------------------*/
13618+{
13619+ if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13620+ {
13621+ *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13622+ if( !*phys_addr_ptr )
13623+ {
13624+ cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13625+ }
13626+
13627+ return( *virt_addr_pptr );
13628+ }
13629+ else
13630+ return( NULL );
13631+}
13632+
13633+OsAifKernelThread(
13634+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13635+{
13636+
13637+ struct fs_struct *fs;
13638+ int i;
13639+ struct task_struct *tsk;
13640+
13641+ tsk = current;
13642+
13643+
13644+ /*
13645+ * set up the name that will appear in 'ps'
13646+ * stored in task_struct.comm[16].
13647+ */
13648+
13649+ sprintf(tsk->comm, "AIFd");
13650+
13651+
13652+ // use_init_fs_context(); only exists in 2.2.13 onward.
13653+
13654+#ifdef __SMP__
13655+ lock_kernel();
13656+#endif
13657+
13658+ /*
13659+ * we were started as a result of loading the module.
13660+ * free all of user space pages
13661+ */
13662+
13663+ exit_mm(tsk);
13664+
13665+ exit_files(tsk);
13666+
13667+ exit_fs(tsk);
13668+
13669+ fs = init_task.fs;
13670+ tsk->fs = fs;
13671+
13672+ tsk->session = 1;
13673+ tsk->pgrp = 1;
13674+
13675+ if (fs)
13676+ atomic_inc(&fs->count);
13677+
13678+#ifdef __SMP__
13679+ unlock_kernel();
13680+#endif
13681+
13682+
13683+
13684+
13685+ NormCommandThread(AdapterExtension);
13686+ /* NOT REACHED */
13687+}
13688+
13689+/*----------------------------------------------------------------------------*/
13690+void OsStartKernelThreads(
13691+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13692+/*----------------------------------------------------------------------------*/
13693+{
13694+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13695+ AFA_COMM_ADAPTER *Adapter;
13696+ extern void NormCommandThread(void *Adapter);
13697+
13698+ CommonExtension = AdapterExtension->Common;
13699+ Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13700+
13701+ //
13702+ // Start thread which will handle interrupts for this adapter
13703+ //
13704+ //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13705+
13706+ //
13707+ // Start thread which will handle AdapterInititatedFibs from this adapter
13708+ //
13709+ CommonExtension->OsDep.thread_pid =
13710+ kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13711+// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13712+}
13713+
13714+/*----------------------------------------------------------------------------*/
13715+BOOLEAN AfaPortAllocateAndMapFibSpace(
13716+ PVOID Arg1,
13717+ IN PMAPFIB_CONTEXT MapFibContext )
13718+/*----------------------------------------------------------------------------*/
13719+{
13720+ PVOID BaseAddress;
13721+ ULONG PhysAddress;
13722+
13723+ if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13724+ {
13725+ cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13726+ return( FALSE );
13727+ }
13728+
13729+ PhysAddress = OsVirtToPhys( BaseAddress );
13730+
13731+ MapFibContext->FibVirtualAddress = BaseAddress;
13732+ MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13733+
13734+ return (TRUE);
13735+}
13736+
13737+/*----------------------------------------------------------------------------*/
13738+BOOLEAN AfaPortUnmapAndFreeFibSpace(
13739+ PVOID Arg1,
13740+ IN PMAPFIB_CONTEXT MapFibContext )
13741+/*----------------------------------------------------------------------------*/
13742+{
13743+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13744+
13745+ OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13746+
13747+ return (TRUE);
13748+}
13749+
13750+/*----------------------------------------------------------------------------*/
13751+BOOLEAN AfaPortFreeAdapterCommArea(
13752+ IN PVOID Arg1 )
13753+/*----------------------------------------------------------------------------*/
13754+{
13755+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13756+
13757+ OsFreeMemory( CommonExtension->CommAddress, 0 );
13758+
13759+ return (TRUE);
13760+}
13761+
13762+
13763+/* ================================================================================ */
13764+/*
13765+ * Not sure if the functions below here ever get called in the current code
13766+ * These probably should be a different file.
13767+ */
13768+/*
13769+ddi_dma_attr_t AfaPortDmaAttributes = {
13770+ //rpbfix : we may want something different for I/O
13771+ DMA_ATTR_V0,
13772+ 0,
13773+ 0xffffffff,
13774+ 0x0000ffff,
13775+ 1,
13776+ 1,
13777+ 1,
13778+ 0x0000ffff,
13779+ 0x0000ffff,
13780+ 17,
13781+ 512,
13782+ 0
13783+};
13784+*/
13785+
13786+AAC_STATUS
13787+AfaPortBuildSgMap(
13788+ PVOID Arg1,
13789+ IN PSGMAP_CONTEXT SgMapContext
13790+ )
13791+
13792+/*++
13793+
13794+Routine Description:
13795+
13796+ This routine build a scatter gather map using the information
13797+ in the SgMapContext.
13798+
13799+Arguments:
13800+
13801+ AdapterExtension - Pointer to adapter extension structure.
13802+ SgMapContext - Pointer to the SgMapContext for the request.
13803+
13804+
13805+Return Value:
13806+
13807+ AAC_STATUS
13808+--*/
13809+{
13810+ printk( "<1>AfaPortBuildSgMap: unimplemented function called" );
13811+ return (STATUS_UNSUCCESSFUL);
13812+}
13813+
13814+VOID
13815+AfaPortFreeDmaResources(
13816+ PVOID Arg1,
13817+ IN PSGMAP_CONTEXT SgMapContext
13818+ )
13819+
13820+/*++
13821+
13822+Routine Description:
13823+
13824+ Given a pointer to the IRP context will free all reserved DMA resources allocated for
13825+ the completed IO operation.
13826+
13827+Arguments:
13828+
13829+ Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13830+ Context - Pointer to the Irp Context we use to store the dma mapping information
13831+ we need to do and complete the IO.
13832+
13833+Return Value:
13834+
13835+ Nothing
13836+
13837+--*/
13838+{
13839+}
13840diff -burN linux-2.4.4/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13841--- linux-2.4.4/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 18:00:00 1969
13842+++ linux/drivers/scsi/aacraid/osfuncs.c Mon Apr 30 09:43:34 2001
13843@@ -0,0 +1,596 @@
13844+/*++
13845+ * Adaptec aacraid device driver for Linux.
13846+ *
13847+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13848+ *
13849+ * This program is free software; you can redistribute it and/or modify
13850+ * it under the terms of the GNU General Public License as published by
13851+ * the Free Software Foundation; either version 2, or (at your option)
13852+ * any later version.
13853+ *
13854+ * This program is distributed in the hope that it will be useful,
13855+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13856+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13857+ * GNU General Public License for more details.
13858+ *
13859+ * You should have received a copy of the GNU General Public License
13860+ * along with this program; see the file COPYING. If not, write to
13861+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13862+ *
13863+ * Module Name:
13864+ * osfuncs.c
13865+ *
13866+ * Abstract: Holds all of the O/S specific interface functions.
13867+ *
13868+ --*/
13869+
13870+static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13871+
13872+#include "osheaders.h"
13873+
13874+//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13875+
13876+extern aac_options_t g_options;
13877+
13878+OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13879+wait_queue_t * g_wait_queue_ptr = NULL;
13880+wait_queue_t g_wait;
13881+
13882+void OsTimeoutHandler(
13883+ struct semaphore * sem );
13884+
13885+int * OsIdleTask( void * data );
13886+
13887+//-----------------------------------------------------------------------------
13888+// Memory Allocation functions
13889+
13890+/*----------------------------------------------------------------------------*/
13891+void * OsAllocMemory(
13892+ OS_SIZE_T Size,
13893+ unsigned int Flags )
13894+/*----------------------------------------------------------------------------*/
13895+{
13896+ void *mem_ptr;
13897+
13898+ if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13899+ cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13900+ return( mem_ptr );
13901+}
13902+
13903+
13904+/*----------------------------------------------------------------------------*/
13905+void OsFreeMemory(
13906+ void * Buffer,
13907+ OS_SIZE_T Size )
13908+/*----------------------------------------------------------------------------*/
13909+{
13910+ kfree( Buffer );
13911+}
13912+
13913+
13914+/*----------------------------------------------------------------------------*/
13915+int OsRegisterInterrupt(
13916+ unsigned int irq, // interrupt number
13917+ void ( *handler )( int, void*, struct pt_regs * ), // handler function
13918+ void *irq_data ) // argument to handler function
13919+/*----------------------------------------------------------------------------*/
13920+{
13921+ return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13922+}
13923+
13924+
13925+/*----------------------------------------------------------------------------*/
13926+void OsUnregisterInterrupt(
13927+ unsigned int irq, // interrupt number
13928+ void *irq_data)
13929+/*----------------------------------------------------------------------------*/
13930+{
13931+ free_irq (
13932+ irq, // interrupt number
13933+ irq_data );
13934+}
13935+
13936+
13937+/*----------------------------------------------------------------------------*/
13938+unsigned long OsVirtToPhys(
13939+ void * virtual_address )
13940+/*----------------------------------------------------------------------------*/
13941+{
13942+ return( virt_to_phys( virtual_address ) );
13943+}
13944+
13945+
13946+//-----------------------------------------------------------------------------
13947+// MUTEX functions
13948+
13949+/*----------------------------------------------------------------------------*/
13950+OS_STATUS OsMutexInit(
13951+ OS_MUTEX *Mutex,
13952+ OS_SPINLOCK_COOKIE Cookie )
13953+/*----------------------------------------------------------------------------*/
13954+{
13955+ Mutex->lock_var = 0;
13956+ // bzero (&Mutex->wq, sizeof (Mutex->wq));
13957+ init_waitqueue_head (&Mutex->wq);
13958+ return ( 0 );
13959+}
13960+
13961+
13962+/*----------------------------------------------------------------------------*/
13963+void OsMutexDestroy(
13964+ OS_MUTEX *Mutex )
13965+/*----------------------------------------------------------------------------*/
13966+{
13967+}
13968+
13969+
13970+/*----------------------------------------------------------------------------*/
13971+void OsMutexAcquire(
13972+ OS_MUTEX *Mutex )
13973+/*----------------------------------------------------------------------------*/
13974+{
13975+ // wait_queue_t wait = { current, NULL };
13976+ unsigned long time_stamp;
13977+
13978+ DECLARE_WAITQUEUE (wait, current);
13979+
13980+ time_stamp = jiffies;
13981+
13982+ if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13983+ {
13984+ if( in_interrupt() )
13985+ panic( "OsMutexAcquire going to sleep at interrupt time\n" );
13986+ current->state = TASK_INTERRUPTIBLE;
13987+ add_wait_queue( &( Mutex->wq ), &wait );
13988+ while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13989+ schedule();
13990+ remove_wait_queue( &( Mutex->wq ), &wait );
13991+ }
13992+
13993+ if( ( jiffies - 1 ) > time_stamp )
13994+ cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
13995+ Mutex, jiffies - time_stamp );
13996+}
13997+
13998+
13999+/*----------------------------------------------------------------------------*/
14000+void OsMutexRelease(
14001+ OS_MUTEX *Mutex )
14002+/*----------------------------------------------------------------------------*/
14003+{
14004+ if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14005+ cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14006+ wake_up_interruptible( &( Mutex->wq ) );
14007+}
14008+
14009+// see man hierarchy(D5)
14010+#define FSA_LOCK 1
14011+
14012+//-----------------------------------------------------------------------------
14013+// Spinlock functions
14014+
14015+/*----------------------------------------------------------------------------*/
14016+OS_SPINLOCK * OsSpinLockAlloc( void )
14017+/*----------------------------------------------------------------------------*/
14018+{
14019+ OS_SPINLOCK *SpinLock;
14020+ int i;
14021+
14022+
14023+ SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14024+
14025+ if (SpinLock == NULL)
14026+ cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14027+
14028+ SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14029+ for( i = 0; i < NR_CPUS; i++ )
14030+ SpinLock->cpu_lock_count[ i ] = 0;
14031+ return( SpinLock );
14032+}
14033+
14034+
14035+/*----------------------------------------------------------------------------*/
14036+OS_STATUS OsSpinLockInit(
14037+ OS_SPINLOCK *SpinLock,
14038+ OS_SPINLOCK_COOKIE Cookie )
14039+/*----------------------------------------------------------------------------*/
14040+{
14041+ return( 0 );
14042+}
14043+
14044+
14045+/*----------------------------------------------------------------------------*/
14046+void OsSpinLockDestroy(
14047+ OS_SPINLOCK *SpinLock )
14048+/*----------------------------------------------------------------------------*/
14049+{
14050+ kfree( SpinLock );
14051+ SpinLock = NULL;
14052+}
14053+
14054+
14055+/*----------------------------------------------------------------------------*/
14056+void OsSpinLockAcquire(
14057+ OS_SPINLOCK *SpinLock )
14058+/*----------------------------------------------------------------------------*/
14059+{
14060+ unsigned cpu_id, i;
14061+
14062+
14063+ if( SpinLock )
14064+ {
14065+ cpu_id = smp_processor_id();
14066+ if( SpinLock->cpu_lock_count[ cpu_id ] ){
14067+ cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14068+ cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14069+ }
14070+
14071+ spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14072+ SpinLock->cpu_lock_count[ cpu_id ]++;
14073+
14074+ } else {
14075+ cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14076+ }
14077+}
14078+
14079+
14080+/*----------------------------------------------------------------------------*/
14081+void OsSpinLockRelease(
14082+ OS_SPINLOCK *SpinLock )
14083+/*----------------------------------------------------------------------------*/
14084+{
14085+ if( SpinLock )
14086+ {
14087+ SpinLock->cpu_lock_count[ smp_processor_id() ]--;
14088+ spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14089+ }
14090+ else
14091+ cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14092+}
14093+
14094+
14095+/*----------------------------------------------------------------------------*/
14096+int OsSpinLockOwned(
14097+ OS_SPINLOCK *SpinLock )
14098+/*----------------------------------------------------------------------------*/
14099+{
14100+#ifdef __SMP__
14101+ if( SpinLock->spin_lock.lock != 0 )
14102+ return( 1 );
14103+ else
14104+#endif
14105+ return( 0 );
14106+}
14107+
14108+
14109+//-----------------------------------------------------------------------------
14110+// CvLock functions
14111+
14112+/*----------------------------------------------------------------------------*/
14113+OS_CVLOCK *OsCvLockAlloc( void )
14114+{
14115+ OS_CVLOCK *cv_lock;
14116+
14117+
14118+#ifdef CVLOCK_USE_SPINLOCK
14119+ cv_lock = OsSpinLockAlloc();
14120+#else
14121+ cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14122+ cv_lock->wq = NULL;
14123+ cv_lock->lock_var = 0;
14124+#endif
14125+
14126+ return( cv_lock );
14127+}
14128+
14129+
14130+/*----------------------------------------------------------------------------*/
14131+OS_STATUS OsCvLockInit(
14132+ OS_CVLOCK *cv_lock,
14133+ OS_SPINLOCK_COOKIE Cookie )
14134+/*----------------------------------------------------------------------------*/
14135+{
14136+ return ( 0 );
14137+}
14138+
14139+
14140+/*----------------------------------------------------------------------------*/
14141+void OsCvLockDestroy(
14142+ OS_CVLOCK *cv_lock )
14143+/*----------------------------------------------------------------------------*/
14144+{
14145+ if( cv_lock )
14146+ kfree( cv_lock );
14147+ cv_lock = NULL;
14148+}
14149+
14150+
14151+/*----------------------------------------------------------------------------*/
14152+void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14153+{
14154+#ifdef CVLOCK_USE_SPINLOCK
14155+ OsSpinLockAcquire( cv_lock );
14156+#else
14157+ OsMutexAcquire( cv_lock );
14158+#endif
14159+}
14160+
14161+
14162+/*----------------------------------------------------------------------------*/
14163+void OsCvLockRelease(
14164+ OS_CVLOCK *cv_lock )
14165+/*----------------------------------------------------------------------------*/
14166+{
14167+#ifdef CVLOCK_USE_SPINLOCK
14168+ OsSpinLockRelease( cv_lock );
14169+#else
14170+ OsMutexRelease( cv_lock );
14171+#endif
14172+}
14173+
14174+
14175+/*----------------------------------------------------------------------------*/
14176+int OsCvLockOwned(
14177+ OS_CVLOCK *cv_lock )
14178+/*----------------------------------------------------------------------------*/
14179+{
14180+ return( 1 );
14181+}
14182+
14183+
14184+//-----------------------------------------------------------------------------
14185+// Conditional variable functions
14186+
14187+/*----------------------------------------------------------------------------*/
14188+void OsCv_init (
14189+ OS_CV_T *cv_ptr )
14190+/*----------------------------------------------------------------------------*/
14191+{
14192+ cv_ptr->lock_var = 1;
14193+ init_waitqueue_head (&cv_ptr->wq);
14194+}
14195+
14196+
14197+/*----------------------------------------------------------------------------*/
14198+void OsCv_destroy(
14199+ OS_CV_T *cv_ptr )
14200+/*----------------------------------------------------------------------------*/
14201+{
14202+}
14203+
14204+
14205+/*______________________________________________________________________________
14206+ -
14207+ -
14208+ -----------------------------------------------------------------------------*/
14209+OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14210+{
14211+ unsigned long flags;
14212+
14213+ DECLARE_WAITQUEUE (wait, current);
14214+
14215+ if( in_interrupt() )
14216+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14217+
14218+ cv_ptr->type = TASK_UNINTERRUPTIBLE;
14219+ current->state = TASK_UNINTERRUPTIBLE;
14220+
14221+ add_wait_queue( &cv_ptr->wq, &wait );
14222+
14223+ OsCvLockRelease( cv_lock_ptr );
14224+ schedule();
14225+
14226+ while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14227+ {
14228+ if( in_interrupt() )
14229+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14230+ schedule();
14231+ }
14232+
14233+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14234+
14235+ OsCvLockAcquire( cv_lock_ptr );
14236+}
14237+
14238+
14239+/*----------------------------------------------------------------------------*/
14240+int OsCv_wait_sig(
14241+ OS_CV_T *cv_ptr,
14242+ OS_CVLOCK *cv_lock_ptr )
14243+/*----------------------------------------------------------------------------*/
14244+{
14245+ unsigned long flags;
14246+ int signal_state = 1;
14247+
14248+ DECLARE_WAITQUEUE (wait, current);
14249+
14250+ if( in_interrupt() )
14251+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14252+
14253+ cv_ptr->type = TASK_INTERRUPTIBLE;
14254+ current->state = TASK_INTERRUPTIBLE;
14255+
14256+ add_wait_queue( &( cv_ptr->wq ), &wait );
14257+
14258+ OsCvLockRelease( cv_lock_ptr );
14259+ schedule();
14260+
14261+ while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14262+ ( !signal_pending( current ) ) )
14263+ {
14264+ if( in_interrupt() )
14265+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14266+ schedule();
14267+ }
14268+
14269+ if( signal_pending( current ) )
14270+ signal_state = 0;
14271+
14272+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14273+
14274+ OsCvLockAcquire( cv_lock_ptr );
14275+ return( signal_state );
14276+}
14277+
14278+
14279+/*----------------------------------------------------------------------------*/
14280+void OsCv_signal(
14281+ OS_CV_T *cv_ptr )
14282+/*----------------------------------------------------------------------------*/
14283+{
14284+
14285+ clear_bit( 0, &( cv_ptr->lock_var ) );
14286+ if( cv_ptr->type == TASK_INTERRUPTIBLE )
14287+ wake_up_interruptible( &( cv_ptr->wq ) );
14288+ else{
14289+ wake_up( &( cv_ptr->wq ) );
14290+ }
14291+}
14292+
14293+
14294+// return time in seconds
14295+/*----------------------------------------------------------------------------*/
14296+unsigned long OsGetSeconds( void )
14297+/*----------------------------------------------------------------------------*/
14298+{
14299+ return( jiffies/HZ );
14300+}
14301+
14302+
14303+//-----------------------------------------------------------------------------
14304+// Deferred procedure call functions
14305+
14306+// create a soft interrupt object
14307+/*----------------------------------------------------------------------------*/
14308+int OsSoftInterruptAdd(
14309+ OS_SOFTINTR **ptr,
14310+ void * handler,
14311+ void * data )
14312+/*----------------------------------------------------------------------------*/
14313+{
14314+ OS_SOFTINTR *tmp_ptr;
14315+
14316+ if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14317+ return( -1 );
14318+ tmp_ptr->routine = handler;
14319+ tmp_ptr->data = data;
14320+ tmp_ptr->sync = 0;
14321+
14322+ *ptr = tmp_ptr;
14323+
14324+ return( 0 );
14325+}
14326+
14327+/*
14328+ Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14329+*/
14330+/*----------------------------------------------------------------------------*/
14331+int * OsIdleTask( void * data )
14332+/*----------------------------------------------------------------------------*/
14333+{
14334+ DECLARE_WAITQUEUE (wait, current);
14335+
14336+ while( 1 )
14337+ {
14338+ current->state = TASK_INTERRUPTIBLE;
14339+ add_wait_queue( &g_wait_queue_ptr, &wait );
14340+ schedule();
14341+ remove_wait_queue( &g_wait_queue_ptr, &wait );
14342+ wait.task = current;
14343+ wait.task_list.next = NULL;
14344+ }
14345+ return( NULL );
14346+}
14347+
14348+
14349+// dispatch a soft interrupt
14350+/*----------------------------------------------------------------------------*/
14351+void OsSoftInterruptTrigger(
14352+ OS_SOFTINTR *soft_intr_ptr )
14353+/*----------------------------------------------------------------------------*/
14354+{
14355+ // call the completion routine directly
14356+ soft_intr_ptr->routine( soft_intr_ptr->data );
14357+}
14358+
14359+
14360+// delete a soft interrupt object
14361+/*----------------------------------------------------------------------------*/
14362+void OsSoftInterruptRemove(
14363+ OS_SOFTINTR *arg )
14364+/*----------------------------------------------------------------------------*/
14365+{
14366+ if( arg )
14367+ kfree( arg );
14368+ arg = NULL;
14369+}
14370+
14371+
14372+/*----------------------------------------------------------------------------*/
14373+void OsSleep(
14374+ unsigned time ) // in seconds
14375+/*----------------------------------------------------------------------------*/
14376+{
14377+ struct semaphore sem;
14378+ struct timer_list timer_var;
14379+
14380+ init_MUTEX_LOCKED (&sem);
14381+
14382+ // if( in_interrupt() )
14383+ // panic( "OsSleep going to sleep at interrupt time\n" );
14384+
14385+ init_timer( &timer_var );
14386+ timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14387+ timer_var.data = ( unsigned long )&sem;
14388+ timer_var.expires = jiffies + time * HZ;
14389+
14390+ add_timer( &timer_var );
14391+ down( &sem );
14392+
14393+ del_timer( &timer_var );
14394+}
14395+
14396+
14397+/*----------------------------------------------------------------------------*/
14398+void OsTimeoutHandler(
14399+ struct semaphore * sem )
14400+/*----------------------------------------------------------------------------*/
14401+{
14402+ if( sem != NULL )
14403+ up( sem );
14404+}
14405+
14406+
14407+/*----------------------------------------------------------------------------*/
14408+void printk_err(
14409+ int flag,
14410+ char *fmt,
14411+ ...)
14412+/*----------------------------------------------------------------------------*/
14413+{
14414+ char buf[256];
14415+ va_list ap;
14416+
14417+ va_start(ap, fmt);
14418+ (void) vsprintf(buf, fmt, ap);
14419+ va_end(ap);
14420+
14421+ if( flag <= g_options.message_level )
14422+ printk("<1>%s\n", buf);
14423+}
14424+
14425+/* void aac_show_tasks (struct list_head *our_tasks){ */
14426+
14427+/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14428+
14429+/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14430+/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14431+/* else */
14432+/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14433+
14434+/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14435+/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14436+/* else */
14437+/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14438+
14439+/* } */
14440diff -burN linux-2.4.4/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14441--- linux-2.4.4/drivers/scsi/aacraid/ossup.c Wed Dec 31 18:00:00 1969
14442+++ linux/drivers/scsi/aacraid/ossup.c Mon Apr 30 09:43:34 2001
14443@@ -0,0 +1,199 @@
14444+/*++
14445+ * Adaptec aacraid device driver for Linux.
14446+ *
14447+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14448+ *
14449+ * This program is free software; you can redistribute it and/or modify
14450+ * it under the terms of the GNU General Public License as published by
14451+ * the Free Software Foundation; either version 2, or (at your option)
14452+ * any later version.
14453+ *
14454+ * This program is distributed in the hope that it will be useful,
14455+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14456+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14457+ * GNU General Public License for more details.
14458+ *
14459+ * You should have received a copy of the GNU General Public License
14460+ * along with this program; see the file COPYING. If not, write to
14461+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14462+ *
14463+ * Module Name:
14464+ * ossup.c
14465+ *
14466+ *
14467+ *
14468+ --*/
14469+
14470+static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14471+
14472+#include "osheaders.h"
14473+
14474+#include "aac_unix_defs.h"
14475+
14476+
14477+AAC_STATUS
14478+ExInitializeZone(
14479+ IN PZONE_HEADER Zone,
14480+ IN ULONG BlockSize,
14481+ IN PVOID InitialSegment,
14482+ IN ULONG InitialSegmentSize
14483+ )
14484+
14485+/*++
14486+
14487+Routine Description:
14488+
14489+ This function initializes a zone header. Once successfully
14490+ initialized, blocks can be allocated and freed from the zone, and
14491+ the zone can be extended.
14492+
14493+Arguments:
14494+
14495+ Zone - Supplies the address of a zone header to be initialized.
14496+
14497+ BlockSize - Supplies the block size of the allocatable unit within
14498+ the zone. The size must be larger that the size of the
14499+ initial segment, and must be 64-bit aligned.
14500+
14501+ InitialSegment - Supplies the address of a segment of storage. The
14502+ first ZONE_SEGMENT_HEADER-sized portion of the segment
14503+ is used by the zone allocator. The remainder of
14504+ the segment is carved up into fixed size
14505+ (BlockSize) blocks and is made available for
14506+ allocation and deallocation from the zone. The
14507+ address of the segment must be aligned on a 64-bit
14508+ boundary.
14509+
14510+ InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14511+
14512+Return Value:
14513+
14514+ STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14515+ 64-bit boundaries, or BlockSize was larger than
14516+ the initial segment size.
14517+
14518+ STATUS_SUCCESS - The zone was successfully initialized.
14519+
14520+--*/
14521+
14522+{
14523+ ULONG i;
14524+ PCHAR p;
14525+
14526+
14527+ Zone->BlockSize = BlockSize;
14528+
14529+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14530+ ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14531+ ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14532+
14533+ Zone->FreeList.Next = NULL;
14534+
14535+ p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14536+
14537+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14538+ i <= InitialSegmentSize - BlockSize;
14539+ i += BlockSize
14540+ ) {
14541+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14542+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14543+ p += BlockSize;
14544+ }
14545+ Zone->TotalSegmentSize = i;
14546+
14547+#if 0
14548+ DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14549+ Zone, InitialSegment, InitialSegmentSize,
14550+ BlockSize, p
14551+ );
14552+#endif
14553+
14554+ return STATUS_SUCCESS;
14555+}
14556+
14557+AAC_STATUS
14558+ExExtendZone(
14559+ IN PZONE_HEADER Zone,
14560+ IN PVOID Segment,
14561+ IN ULONG SegmentSize
14562+ )
14563+
14564+/*++
14565+
14566+Routine Description:
14567+
14568+ This function extends a zone by adding another segment's worth of
14569+ blocks to the zone.
14570+
14571+Arguments:
14572+
14573+ Zone - Supplies the address of a zone header to be extended.
14574+
14575+ Segment - Supplies the address of a segment of storage. The first
14576+ ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14577+ zone allocator. The remainder of the segment is carved up
14578+ into fixed-size (BlockSize) blocks and is added to the
14579+ zone. The address of the segment must be aligned on a 64-
14580+ bit boundary.
14581+
14582+ SegmentSize - Supplies the size in bytes of Segment.
14583+
14584+Return Value:
14585+
14586+ STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14587+ 64-bit boundaries, or BlockSize was larger than
14588+ the segment size.
14589+
14590+ STATUS_SUCCESS - The zone was successfully extended.
14591+
14592+--*/
14593+
14594+{
14595+ ULONG i;
14596+ PCHAR p;
14597+
14598+
14599+ ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14600+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14601+
14602+ p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14603+
14604+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14605+ i <= SegmentSize - Zone->BlockSize;
14606+ i += Zone->BlockSize
14607+ ) {
14608+
14609+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14610+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14611+ p += Zone->BlockSize;
14612+ }
14613+ Zone->TotalSegmentSize += i;
14614+
14615+#if 0
14616+ DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14617+ Zone, Segment, SegmentSize, Zone->BlockSize, p
14618+ );
14619+#endif
14620+
14621+ return STATUS_SUCCESS;
14622+}
14623+
14624+DbgPrint()
14625+{
14626+}
14627+
14628+/* Function: InqStrCopy()
14629+ *
14630+ * Arguments: [2] pointer to char
14631+ *
14632+ * Purpose: Copy a String from one location to another
14633+ * without copying \0
14634+ */
14635+void
14636+InqStrCopy(char *a, char *b)
14637+{
14638+
14639+ while(*a != (char)0)
14640+ *b++ = *a++;
14641+}
14642+
14643diff -burN linux-2.4.4/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14644--- linux-2.4.4/drivers/scsi/aacraid/port.c Wed Dec 31 18:00:00 1969
14645+++ linux/drivers/scsi/aacraid/port.c Mon Apr 30 09:43:34 2001
14646@@ -0,0 +1,287 @@
14647+/*++
14648+ * Adaptec aacraid device driver for Linux.
14649+ *
14650+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14651+ *
14652+ * This program is free software; you can redistribute it and/or modify
14653+ * it under the terms of the GNU General Public License as published by
14654+ * the Free Software Foundation; either version 2, or (at your option)
14655+ * any later version.
14656+ *
14657+ * This program is distributed in the hope that it will be useful,
14658+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14659+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14660+ * GNU General Public License for more details.
14661+ *
14662+ * You should have received a copy of the GNU General Public License
14663+ * along with this program; see the file COPYING. If not, write to
14664+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14665+ *
14666+ * Module Name:
14667+ * port.c
14668+ *
14669+ * Abstract: All support routines for FSA communication which are miniport specific.
14670+ *
14671+ --*/
14672+
14673+static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14674+
14675+#include "osheaders.h"
14676+
14677+
14678+#include "AacGenericTypes.h"
14679+
14680+#include "aac_unix_defs.h"
14681+
14682+#include "fsatypes.h"
14683+#include "comstruc.h"
14684+#include "protocol.h"
14685+
14686+#include "fsaport.h"
14687+#include "fsaioctl.h"
14688+
14689+#include "pcisup.h"
14690+#include "port.h"
14691+
14692+int AfaPortPrinting = 1;
14693+
14694+extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14695+extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14696+extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14697+extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14698+
14699+
14700+
14701+VOID
14702+AfaPortLogError(
14703+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14704+ IN AAC_STATUS ErrorCode,
14705+ IN PUCHAR StringBuffer,
14706+ IN ULONG StringLength
14707+ )
14708+/*++
14709+
14710+Routine Description:
14711+
14712+ Does all of the work to log an error log entry
14713+Arguments:
14714+
14715+ CommonExtension - Pointer to the adapter that caused the error.
14716+
14717+ ErrorCode - Which error is being logged.
14718+
14719+ StringBuffer - Pointer to optional String for error log entry.
14720+
14721+ StringLength - Length of StringBuffer.
14722+
14723+Return Value:
14724+
14725+ Nothing
14726+
14727+--*/
14728+
14729+{
14730+
14731+}
14732+
14733+BOOLEAN
14734+AfaPortGetNextAdapterNumber(
14735+ IN PDRIVER_OBJECT DriverObject,
14736+ OUT PDEVICE_OBJECT *FsaDeviceObject,
14737+ OUT PFILE_OBJECT *FileObject,
14738+ OUT PULONG AdapterNumber
14739+ )
14740+{
14741+}
14742+BOOLEAN
14743+AfaPortAllocateAdapterCommArea(
14744+ IN PVOID Arg1,
14745+ IN OUT PVOID *CommHeaderAddress,
14746+ IN ULONG CommAreaSize,
14747+ IN ULONG CommAreaAlignment
14748+ )
14749+{
14750+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14751+ PVOID BaseAddress;
14752+ PHYSICAL_ADDRESS PhysicalBaseAddress;
14753+ ULONG TotalSize, BytesToAlign;
14754+ size_t RealLength;
14755+ uint_t Count;
14756+// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14757+// ULONG AdapterFibsSize = PAGE_SIZE;
14758+ ULONG AdapterFibsSize = 4096;
14759+ ULONG PrintfBufferSize = 256;
14760+ PADAPTER_INIT_STRUCT InitStruct;
14761+ extern int MiniPortRevision;
14762+ ULONG PhysAddress;
14763+
14764+// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14765+// SizeOfFastIoComm + PrintfBufferSize;
14766+ TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14767+ PrintfBufferSize;
14768+
14769+
14770+ OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14771+
14772+ CommonExtension->CommAddress = BaseAddress;
14773+ CommonExtension->CommPhysAddr = PhysAddress;
14774+ CommonExtension->CommSize = TotalSize;
14775+
14776+ PhysicalBaseAddress.HighPart = 0;
14777+ PhysicalBaseAddress.LowPart = PhysAddress;
14778+
14779+ CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14780+ CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14781+
14782+ InitStruct = CommonExtension->InitStruct;
14783+
14784+ InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14785+ InitStruct->MiniPortRevision = MiniPortRevision;
14786+ InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14787+
14788+ //
14789+ // Adapter Fibs are the first thing allocated so that they start page aligned
14790+ //
14791+ InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14792+ InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14793+ InitStruct->AdapterFibsSize = AdapterFibsSize;
14794+ InitStruct->AdapterFibAlign = sizeof(FIB);
14795+
14796+ //
14797+ // Increment the base address by the amount already used
14798+ //
14799+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14800+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14801+
14802+ //
14803+ // Align the beginning of Headers to CommAreaAlignment
14804+ //
14805+ BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14806+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14807+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14808+
14809+ //
14810+ // Fill in addresses of the Comm Area Headers and Queues
14811+ //
14812+ *CommHeaderAddress = BaseAddress;
14813+ InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14814+
14815+ //
14816+ // Increment the base address by the size of the CommArea
14817+ //
14818+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14819+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14820+
14821+
14822+ //
14823+ // Place the Printf buffer area after the Fast I/O comm area.
14824+ //
14825+ CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14826+ InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14827+ InitStruct->PrintfBufferSize = PrintfBufferSize;
14828+ bzero (BaseAddress, PrintfBufferSize);
14829+
14830+ AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14831+ TotalSize, InitStruct->AdapterFibsVirtualAddress,
14832+ (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14833+
14834+ AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14835+
14836+ return (TRUE);
14837+}
14838+
14839+AAC_STATUS
14840+AfaPortCreate (
14841+ IN PDEVICE_OBJECT DeviceObject,
14842+ IN PIRP Irp
14843+ )
14844+/*++
14845+
14846+Routine Description:
14847+
14848+ The routine will get called each time a user issues a CreateFile on the DeviceObject
14849+ for the adapter.
14850+
14851+ The main purpose of this routine is to set up any data structures that may be needed
14852+ to handle any requests made on this DeviceObject.
14853+
14854+Arguments:
14855+
14856+ DeviceObject - Pointer to device object representing adapter
14857+
14858+ Irp - Pointer to Irp that caused this open
14859+
14860+
14861+Return Value:
14862+
14863+ Status value returned from File system driver AdapterOpen
14864+
14865+--*/
14866+
14867+{
14868+}
14869+
14870+AAC_STATUS
14871+AfaPortClose (
14872+ IN PDEVICE_OBJECT DeviceObject,
14873+ IN PIRP Irp
14874+ )
14875+/*++
14876+
14877+Routine Description:
14878+
14879+ This routine will get called each time a user issues a CloseHandle on the DeviceObject
14880+ for the adapter.
14881+
14882+ The main purpose of this routine is to cleanup any data structures that have been set up
14883+ while this FileObject has been opened.
14884+
14885+Arguments:
14886+
14887+ DeviceObject - Pointer to device object representing adapter
14888+
14889+ Irp - Pointer to Irp that caused this close
14890+
14891+Return Value:
14892+
14893+ Status value returned from File system driver AdapterClose
14894+
14895+--*/
14896+
14897+{
14898+
14899+}
14900+
14901+AAC_STATUS
14902+AfaPortDeviceControl (
14903+ IN PDEVICE_OBJECT DeviceObject,
14904+ IN PIRP Irp
14905+ )
14906+{
14907+
14908+}
14909+
14910+ULONG
14911+AfaPortGetMaxPhysicalPage(
14912+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14913+ )
14914+/*++
14915+
14916+Routine Description:
14917+
14918+ This routine determines the max physical page in host memory.
14919+
14920+Arguments:
14921+
14922+ AdapterExtension
14923+
14924+Return Value:
14925+
14926+ Max physical page in host memory.
14927+
14928+--*/
14929+{
14930+
14931+}
14932+
14933+
14934diff -burN linux-2.4.4/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14935--- linux-2.4.4/drivers/scsi/aacraid/rx.c Wed Dec 31 18:00:00 1969
14936+++ linux/drivers/scsi/aacraid/rx.c Mon Apr 30 09:43:34 2001
14937@@ -0,0 +1,917 @@
14938+/*++
14939+ * Adaptec aacraid device driver for Linux.
14940+ *
14941+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14942+ *
14943+ * This program is free software; you can redistribute it and/or modify
14944+ * it under the terms of the GNU General Public License as published by
14945+ * the Free Software Foundation; either version 2, or (at your option)
14946+ * any later version.
14947+ *
14948+ * This program is distributed in the hope that it will be useful,
14949+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14950+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14951+ * GNU General Public License for more details.
14952+ *
14953+ * You should have received a copy of the GNU General Public License
14954+ * along with this program; see the file COPYING. If not, write to
14955+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14956+ *
14957+ * Module Name:
14958+ * rx.c
14959+ *
14960+ * Abstract: Hardware miniport for Drawbridge specific hardware functions.
14961+ *
14962+ --*/
14963+
14964+static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
14965+
14966+#include "osheaders.h"
14967+
14968+
14969+#include "AacGenericTypes.h"
14970+
14971+#include "aac_unix_defs.h"
14972+
14973+#include "fsatypes.h"
14974+#include "comstruc.h"
14975+#include "fsact.h"
14976+#include "protocol.h"
14977+
14978+#define DEFINE_PCI_IDS
14979+#include "rxcommon.h"
14980+#include "monkerapi.h"
14981+
14982+#include "fsaport.h"
14983+#include "fsaioctl.h"
14984+
14985+#include "pcisup.h"
14986+#include "rx.h"
14987+
14988+#include "port.h"
14989+
14990+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
14991+
14992+// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
14993+
14994+#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
14995+
14996+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
14997+
14998+
14999+//
15000+// The list of all the Rx adapter structures
15001+//
15002+
15003+PRx_ADAPTER_EXTENSION RxAdapterList;
15004+
15005+int
15006+RxInitDevice(
15007+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15008+ IN ULONG AdapterNumber,
15009+ IN ULONG PciBus,
15010+ IN ULONG PciSlot
15011+);
15012+
15013+BOOLEAN
15014+RxSendSynchFib(
15015+ PVOID Arg1,
15016+ ULONG FibPhysicalAddress
15017+ );
15018+
15019+FSA_USER_VAR RxUserVars[] = {
15020+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15021+};
15022+
15023+
15024+//
15025+// Declare private use routines for this modual
15026+//
15027+
15028+u_int
15029+RxPciIsr (
15030+ IN PRx_ADAPTER_EXTENSION AdapterExtension
15031+ )
15032+
15033+/*++
15034+
15035+Routine Description:
15036+
15037+ The Isr routine for fsa Rx based adapter boards.
15038+
15039+Arguments:
15040+
15041+
15042+Return Value:
15043+
15044+ TRUE - if the interrupt was handled by this isr
15045+ FALSE - if the interrupt was not handled by this isr
15046+
15047+--*/
15048+
15049+{
15050+ ULONG DoorbellBits;
15051+ UCHAR InterruptStatus, Mask;
15052+ u_int OurInterrupt = INTR_UNCLAIMED;
15053+
15054+ //cmn_err(CE_WARN, "RxPciIsr entered\n");
15055+
15056+ InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15057+
15058+ //
15059+ // Read mask and invert because drawbridge is reversed.
15060+ //
15061+ // This allows us to only service interrupts that have been enabled.
15062+ //
15063+
15064+ Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15065+
15066+ // Check to see if this is our interrupt. If it isn't just return FALSE.
15067+
15068+
15069+ if (InterruptStatus & Mask) {
15070+
15071+ DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15072+
15073+ OurInterrupt = INTR_CLAIMED;
15074+
15075+ if (DoorbellBits & DoorBellPrintfReady) {
15076+
15077+ ULONG Length, Level;
15078+ unsigned char *cp;
15079+
15080+ cp = AdapterExtension->Common->PrintfBufferAddress;
15081+
15082+ //
15083+ // The size of the Printfbuffer is set in port.c
15084+ // There is no variable or define for it
15085+ //
15086+ if (Length > 255)
15087+ Length = 255;
15088+
15089+ if (cp[Length] != 0) {
15090+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15091+ cp[Length] = 0;
15092+ }
15093+
15094+ if (Level == LOG_HIGH_ERROR)
15095+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15096+ else
15097+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15098+
15099+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15100+
15101+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15102+
15103+ Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15104+
15105+
15106+ } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15107+
15108+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15109+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15110+
15111+ } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15112+
15113+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15114+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15115+
15116+ } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15117+
15118+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15119+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15120+
15121+ } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15122+
15123+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15124+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15125+
15126+ }
15127+
15128+ }
15129+ return(OurInterrupt);
15130+}
15131+
15132+VOID
15133+RxEnableInterrupt(
15134+ PVOID Arg1,
15135+ ADAPTER_EVENT AdapterEvent,
15136+ BOOLEAN AtDeviceIrq
15137+ )
15138+/*++
15139+
15140+Routine Description:
15141+
15142+ This routine will enable the corresponding adapter event to cause an interrupt on
15143+ the host.
15144+
15145+Arguments:
15146+
15147+ AdapterExtension - Which adapter to enable.
15148+
15149+ AdapterEvent - Which adapter event.
15150+
15151+ AtDeviceIrq - Whether the system is in DEVICE irql
15152+
15153+Return Value:
15154+
15155+ Nothing.
15156+
15157+--*/
15158+{
15159+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15160+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15161+
15162+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15163+ switch (AdapterEvent) {
15164+
15165+ case HostNormCmdQue:
15166+
15167+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15168+
15169+ break;
15170+
15171+ case HostNormRespQue:
15172+
15173+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15174+
15175+ break;
15176+
15177+ case AdapNormCmdNotFull:
15178+
15179+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15180+
15181+ break;
15182+
15183+ case AdapNormRespNotFull:
15184+
15185+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15186+
15187+ break;
15188+
15189+ }
15190+
15191+}
15192+
15193+VOID
15194+RxDisableInterrupt(
15195+ PVOID Arg1,
15196+ ADAPTER_EVENT AdapterEvent,
15197+ BOOLEAN AtDeviceIrq
15198+ )
15199+/*++
15200+
15201+Routine Description:
15202+
15203+ This routine will disable the corresponding adapter event to cause an interrupt on
15204+ the host.
15205+
15206+Arguments:
15207+
15208+ AdapterExtension - Which adapter to enable.
15209+
15210+ AdapterEvent - Which adapter event.
15211+
15212+ AtDeviceIrq - Whether the system is in DEVICE irql
15213+
15214+Return Value:
15215+
15216+ Nothing.
15217+
15218+--*/
15219+{
15220+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15221+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15222+
15223+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15224+
15225+ switch (AdapterEvent) {
15226+
15227+
15228+ case HostNormCmdQue:
15229+
15230+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15231+
15232+ break;
15233+
15234+ case HostNormRespQue:
15235+
15236+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15237+
15238+ break;
15239+
15240+ case AdapNormCmdNotFull:
15241+
15242+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15243+
15244+ break;
15245+
15246+
15247+ case AdapNormRespNotFull:
15248+
15249+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15250+
15251+ break;
15252+
15253+ }
15254+
15255+}
15256+
15257+
15258+
15259+RxDetachDevice(
15260+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15261+ )
15262+{
15263+ PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15264+
15265+ //
15266+ // Free the register mapping.
15267+ //
15268+
15269+ OsDetachDevice( AdapterExtension);
15270+
15271+ OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15272+
15273+}
15274+
15275+int
15276+RxInitDevice(
15277+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15278+ IN ULONG AdapterNumber,
15279+ IN ULONG PciBus,
15280+ IN ULONG PciSlot
15281+)
15282+
15283+/*++
15284+
15285+Routine Description:
15286+
15287+ Scans the PCI bus looking for the Rx card. When found all resources for the
15288+ device will be allocated and the interrupt vectors and csrs will be allocated and
15289+ mapped.
15290+
15291+ The device_interface in the commregion will be allocated and linked to the comm region.
15292+
15293+Arguments:
15294+
15295+
15296+Return Value:
15297+
15298+ TRUE - if the device was setup with not problems
15299+ FALSE - if the device could not be mapped and init successfully
15300+
15301+--*/
15302+
15303+{
15304+ AAC_STATUS Status;
15305+ PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15306+ FSA_NEW_ADAPTER NewAdapter;
15307+ ULONG StartTime, EndTime, WaitTime;
15308+ ULONG InitStatus;
15309+ int instance;
15310+ int nIntrs;
15311+ char * name;
15312+
15313+ AfaPortPrint("In init device.\n");
15314+
15315+ //cmn_err(CE_WARN, "In RxInitDevice");
15316+
15317+// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15318+ CommonExtension->AdapterNumber = AdapterNumber;
15319+
15320+
15321+ CommonExtension->PciBusNumber = PciBus;
15322+ CommonExtension->PciSlotNumber = PciSlot;
15323+
15324+
15325+ AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15326+ AdapterExtension->Common = CommonExtension;
15327+ CommonExtension->MiniPort = AdapterExtension;
15328+
15329+ instance = OsGetDeviceInstance(AdapterExtension);
15330+ name = OsGetDeviceName(AdapterExtension);
15331+ //
15332+ // Map in the registers from the adapter, register space 0 is config space,
15333+ // register space 1 is the memery space.
15334+ //
15335+
15336+ if (OsMapDeviceRegisters(AdapterExtension)) {
15337+
15338+ cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15339+ OsGetDeviceName(AdapterExtension), instance);
15340+ return(FAILURE);
15341+ }
15342+
15343+ //
15344+ // Check to see if the board failed any self tests.
15345+ //
15346+
15347+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15348+
15349+ cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15350+ OsGetDeviceName(AdapterExtension), instance);
15351+ return(FAILURE);
15352+
15353+ }
15354+ //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15355+ // OsGetDeviceName(AdapterExtension), instance);
15356+
15357+ //
15358+ // Check to see if the board panic'd while booting.
15359+ //
15360+
15361+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15362+
15363+ cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15364+ OsGetDeviceName(AdapterExtension), instance);
15365+ return(FAILURE);
15366+
15367+ }
15368+
15369+ StartTime = OsGetSeconds();
15370+ WaitTime = 0;
15371+
15372+
15373+ //
15374+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
15375+ //
15376+
15377+ while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15378+
15379+ EndTime = OsGetSeconds();
15380+
15381+ WaitTime = EndTime - StartTime;
15382+
15383+ if ( WaitTime > (3 * 10) ) {
15384+
15385+ InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15386+
15387+ cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15388+ OsGetDeviceName(AdapterExtension), instance, InitStatus);
15389+ return(FAILURE);
15390+
15391+ }
15392+ }
15393+
15394+ if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15395+ cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15396+ return(FAILURE);
15397+ }
15398+
15399+
15400+ if (OsAttachDMA(AdapterExtension)) {
15401+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15402+ return(FAILURE);
15403+ }
15404+
15405+ //
15406+ // Fill in the function dispatch table.
15407+ //
15408+
15409+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15410+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15411+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15412+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15413+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15414+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15415+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15416+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15417+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15418+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15419+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15420+ AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15421+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15422+
15423+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15424+
15425+ NewAdapter.AdapterExtension = CommonExtension;
15426+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15427+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15428+ NewAdapter.AdapterUserVars = RxUserVars;
15429+ NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15430+
15431+ NewAdapter.Dip = CommonExtension->OsDep.dip;
15432+
15433+
15434+ if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15435+
15436+ cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15437+ return (FAILURE);
15438+ }
15439+
15440+
15441+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15442+
15443+ if (AdapterExtension->Common->Adapter == NULL) {
15444+
15445+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15446+ cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15447+
15448+
15449+ return (FAILURE);
15450+ }
15451+
15452+
15453+ //
15454+ // Start any kernel threads needed
15455+ //
15456+ OsStartKernelThreads(AdapterExtension);
15457+
15458+ //
15459+ // Tell the adapter that all is configure, and it can start accepting requests
15460+ //
15461+
15462+ RxStartAdapter(AdapterExtension);
15463+
15464+
15465+#ifdef AACDISK
15466+#endif
15467+
15468+
15469+ //
15470+ // Put this adapter into the list of Rx adapters
15471+ //
15472+
15473+ AdapterExtension->Next = RxAdapterList;
15474+ RxAdapterList = AdapterExtension;
15475+
15476+ AdapterExtension->Common->AdapterConfigured = TRUE;
15477+
15478+
15479+#ifdef AACDISK
15480+ //
15481+ // Call the disk layer to initialize itself.
15482+ //
15483+
15484+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15485+#endif
15486+
15487+
15488+init_done:
15489+
15490+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15491+
15492+
15493+
15494+ OsAttachHBA(AdapterExtension);
15495+
15496+ return(0);
15497+}
15498+
15499+VOID
15500+RxStartAdapter(
15501+ PRx_ADAPTER_EXTENSION AdapterExtension
15502+ )
15503+{
15504+ ULONG ReturnStatus;
15505+ LARGE_INTEGER HostTime;
15506+ ULONG ElapsedSeconds;
15507+ PADAPTER_INIT_STRUCT InitStruct;
15508+
15509+ //cmn_err(CE_WARN, "RxStartAdapter");
15510+ //
15511+ // Fill in the remaining pieces of the InitStruct.
15512+ //
15513+
15514+ InitStruct = AdapterExtension->Common->InitStruct;
15515+
15516+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15517+
15518+ ElapsedSeconds = OsGetSeconds();
15519+
15520+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
15521+
15522+ //
15523+ // Tell the adapter we are back and up and running so it will scan its command
15524+ // queues and enable our interrupts
15525+ //
15526+
15527+ AdapterExtension->LocalMaskInterruptControl =
15528+ (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15529+
15530+ //
15531+ // First clear out all interrupts. Then enable the one's that we can handle.
15532+ //
15533+
15534+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15535+ Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15536+// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15537+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15538+
15539+ RxSendSynchCommand(AdapterExtension,
15540+ INIT_STRUCT_BASE_ADDRESS,
15541+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15542+ 0,
15543+ 0,
15544+ 0,
15545+ &ReturnStatus);
15546+
15547+}
15548+
15549+
15550+VOID
15551+RxResetDevice(
15552+ PVOID Arg1
15553+ )
15554+
15555+{
15556+}
15557+
15558+VOID
15559+RxInterruptAdapter(
15560+ PVOID Arg1
15561+ )
15562+/*++
15563+
15564+Routine Description:
15565+
15566+ The will cause the adapter to take a break point.
15567+
15568+Arguments:
15569+
15570+ None
15571+
15572+Return Value:
15573+
15574+ Nothing
15575+
15576+--*/
15577+{
15578+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15579+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15580+
15581+ ULONG ReturnStatus;
15582+
15583+ RxSendSynchCommand(AdapterExtension,
15584+ BREAKPOINT_REQUEST,
15585+ 0,
15586+ 0,
15587+ 0,
15588+ 0,
15589+ &ReturnStatus);
15590+
15591+}
15592+
15593+VOID
15594+RxNotifyAdapter(
15595+ PVOID Arg1,
15596+ IN HOST_2_ADAP_EVENT AdapterEvent
15597+ )
15598+/*++
15599+
15600+Routine Description:
15601+
15602+ Will read the adapter CSRs to find the reason the adapter has
15603+ interrupted us.
15604+
15605+Arguments:
15606+
15607+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15608+
15609+Return Value:
15610+
15611+ Nothing
15612+
15613+--*/
15614+{
15615+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15616+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15617+ ULONG ReturnStatus;
15618+
15619+ //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15620+
15621+ switch (AdapterEvent) {
15622+ case AdapNormCmdQue:
15623+
15624+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15625+ break;
15626+
15627+ case HostNormRespNotFull:
15628+
15629+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15630+ break;
15631+
15632+ case AdapNormRespQue:
15633+
15634+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15635+ break;
15636+
15637+ case HostNormCmdNotFull:
15638+
15639+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15640+ break;
15641+
15642+ case HostShutdown:
15643+
15644+// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15645+
15646+ break;
15647+
15648+ case FastIo:
15649+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15650+ break;
15651+
15652+ case AdapPrintfDone:
15653+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15654+ break;
15655+
15656+ default:
15657+
15658+ RxBugCheck(0,0,0);
15659+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15660+ break;
15661+ }
15662+}
15663+
15664+AAC_STATUS
15665+RxSendSynchCommand(
15666+ PVOID Arg1,
15667+ ULONG Command,
15668+ ULONG Parameter1,
15669+ ULONG Parameter2,
15670+ ULONG Parameter3,
15671+ ULONG Parameter4,
15672+ PULONG ReturnStatus
15673+ )
15674+/*++
15675+
15676+Routine Description:
15677+
15678+ This routine will send a synchronous comamnd to the adapter and wait for its
15679+ completion.
15680+
15681+Arguments:
15682+
15683+ AdapterExtension - Pointer to adapter extension structure.
15684+ Command - Which command to send
15685+ Parameter1 - 4 - Parameters for command
15686+ ReturnStatus - return status from adapter after completion of command
15687+
15688+
15689+Return Value:
15690+
15691+ AAC_STATUS
15692+
15693+--*/
15694+{
15695+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15696+ ULONG StartTime,EndTime,WaitTime;
15697+ BOOLEAN CommandSucceeded;
15698+
15699+ //cmn_err(CE_WARN, "RxSendSyncCommand");
15700+ //
15701+ // Write the Command into Mailbox 0
15702+ //
15703+
15704+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15705+
15706+ //
15707+ // Write the parameters into Mailboxes 1 - 4
15708+ //
15709+
15710+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15711+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15712+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15713+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15714+
15715+ //
15716+ // Clear the synch command doorbell to start on a clean slate.
15717+ //
15718+
15719+ Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15720+
15721+ //
15722+ // disable doorbell interrupts
15723+ //
15724+
15725+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15726+ Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15727+
15728+ //
15729+ // force the completion of the mask register write before issuing the interrupt.
15730+ //
15731+
15732+ Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15733+
15734+ //
15735+ // Signal that there is a new synch command
15736+ //
15737+
15738+ Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15739+
15740+ CommandSucceeded = FALSE;
15741+
15742+ StartTime = OsGetSeconds();
15743+ WaitTime = 0;
15744+
15745+ while (WaitTime < 30) { // wait up to 30 seconds
15746+
15747+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15748+
15749+ //
15750+ // Mon110 will set doorbell0 bit when it has completed the command.
15751+ //
15752+
15753+ if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15754+
15755+ //
15756+ // clear the doorbell.
15757+ //
15758+
15759+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15760+
15761+ CommandSucceeded = TRUE;
15762+ break;
15763+ }
15764+
15765+ EndTime = OsGetSeconds();
15766+ WaitTime = EndTime - StartTime;
15767+
15768+ }
15769+
15770+ if (CommandSucceeded != TRUE) {
15771+
15772+ //
15773+ // restore interrupt mask even though we timed out
15774+ //
15775+
15776+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15777+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15778+
15779+ return (STATUS_IO_TIMEOUT);
15780+
15781+ }
15782+
15783+ //
15784+ // Pull the synch status from Mailbox 0.
15785+ //
15786+
15787+ *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15788+
15789+ //
15790+ // Clear the synch command doorbell.
15791+ //
15792+
15793+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15794+
15795+ //
15796+ // restore interrupt mask
15797+ //
15798+
15799+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15800+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15801+
15802+ //
15803+ // Return SUCCESS
15804+ //
15805+
15806+ return (STATUS_SUCCESS);
15807+
15808+}
15809+
15810+BOOLEAN
15811+RxSendSynchFib(
15812+ PVOID Arg1,
15813+ ULONG FibPhysicalAddress
15814+ )
15815+/*++
15816+
15817+Routine Description:
15818+
15819+ This routine will send a synchronous fib to the adapter and wait for its
15820+ completion.
15821+
15822+Arguments:
15823+
15824+ AdapterExtension - Pointer to adapter extension structure.
15825+ FibPhysicalAddress - Physical address of fib to send.
15826+
15827+
15828+Return Value:
15829+
15830+ BOOLEAN
15831+
15832+--*/
15833+{
15834+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15835+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15836+ ULONG returnStatus;
15837+
15838+ if (RxSendSynchCommand( AdapterExtension,
15839+ SEND_SYNCHRONOUS_FIB,
15840+ FibPhysicalAddress,
15841+ 0,
15842+ 0,
15843+ 0,
15844+ &returnStatus ) != STATUS_SUCCESS ) {
15845+
15846+ return (FALSE);
15847+
15848+ }
15849+
15850+ return (TRUE);
15851+
15852+}
15853+
15854+
15855diff -burN linux-2.4.4/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15856--- linux-2.4.4/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 18:00:00 1969
15857+++ linux/drivers/scsi/aacraid/sap1sup.c Mon Apr 30 09:43:34 2001
15858@@ -0,0 +1,859 @@
15859+/*++
15860+ * Adaptec aacraid device driver for Linux.
15861+ *
15862+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15863+ *
15864+ * This program is free software; you can redistribute it and/or modify
15865+ * it under the terms of the GNU General Public License as published by
15866+ * the Free Software Foundation; either version 2, or (at your option)
15867+ * any later version.
15868+ *
15869+ * This program is distributed in the hope that it will be useful,
15870+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15871+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15872+ * GNU General Public License for more details.
15873+ *
15874+ * You should have received a copy of the GNU General Public License
15875+ * along with this program; see the file COPYING. If not, write to
15876+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15877+ *
15878+ * Module Name:
15879+ * sap1sup.c
15880+ *
15881+ * Abstract: Drawbridge specific support functions
15882+ *
15883+ --*/
15884+
15885+static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15886+
15887+#include "osheaders.h"
15888+
15889+
15890+#include "AacGenericTypes.h"
15891+
15892+#include "aac_unix_defs.h"
15893+
15894+#include "fsatypes.h"
15895+#include "comstruc.h"
15896+#include "fsact.h"
15897+#include "protocol.h"
15898+
15899+#define DEFINE_PCI_IDS
15900+#include "sap1common.h"
15901+#include "monkerapi.h"
15902+
15903+#include "fsaport.h"
15904+#include "fsaioctl.h"
15905+
15906+
15907+#include "pcisup.h"
15908+#include "sap1.h"
15909+
15910+#include "port.h"
15911+
15912+#include "nodetype.h"
15913+#include "comsup.h"
15914+#include "afacomm.h"
15915+#include "adapter.h"
15916+
15917+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15918+
15919+// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15920+
15921+#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15922+
15923+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15924+
15925+int MiniPortRevision = Sa_MINIPORT_REVISION;
15926+
15927+
15928+//
15929+// The list of all the Sa adapter structures
15930+//
15931+
15932+PSa_ADAPTER_EXTENSION SaAdapterList;
15933+
15934+int
15935+SaInitDevice(
15936+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15937+ IN ULONG AdapterNumber,
15938+ IN ULONG PciBus,
15939+ IN ULONG PciSlot
15940+);
15941+
15942+BOOLEAN
15943+SaSendSynchFib(
15944+ PVOID Arg1,
15945+ ULONG FibPhysicalAddress
15946+ );
15947+
15948+FSA_USER_VAR SaUserVars[] = {
15949+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15950+};
15951+
15952+
15953+//
15954+// Declare private use routines for this modual
15955+//
15956+
15957+
15958+/*++
15959+
15960+Routine Description:
15961+
15962+ The Isr routine for fsa Sa based adapter boards.
15963+
15964+Arguments:
15965+
15966+
15967+Return Value:
15968+
15969+ TRUE - if the interrupt was handled by this isr
15970+ FALSE - if the interrupt was not handled by this isr
15971+
15972+--*/
15973+u_int
15974+SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
15975+{
15976+ USHORT InterruptStatus, Mask;
15977+ u_int OurInterrupt = INTR_UNCLAIMED;
15978+
15979+ InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
15980+
15981+ //
15982+ // Read mask and invert because drawbridge is reversed.
15983+ //
15984+ // This allows us to only service interrupts that have been enabled.
15985+ //
15986+
15987+ Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
15988+
15989+ // Check to see if this is our interrupt. If it isn't just return FALSE.
15990+
15991+
15992+ if (InterruptStatus & Mask) {
15993+
15994+ OurInterrupt = INTR_CLAIMED;
15995+
15996+ if (InterruptStatus & PrintfReady) {
15997+
15998+ ULONG Length, Level;
15999+ unsigned char *cp;
16000+
16001+ cp = AdapterExtension->Common->PrintfBufferAddress;
16002+
16003+ //
16004+ // The size of the Printbuffer is set in port.c
16005+ // There is no variable or define for it
16006+ //
16007+ if (Length > 255)
16008+ Length = 255;
16009+
16010+ if (cp[Length] != 0) {
16011+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16012+ cp[Length] = 0;
16013+ }
16014+
16015+ if (Level == LOG_HIGH_ERROR)
16016+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16017+ else
16018+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16019+
16020+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16021+
16022+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16023+
16024+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16025+
16026+ } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
16027+
16028+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16029+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16030+
16031+ } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
16032+
16033+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16034+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16035+
16036+ } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
16037+
16038+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16039+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16040+
16041+ } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
16042+
16043+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16044+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16045+
16046+ }
16047+
16048+ }
16049+ return(OurInterrupt);
16050+}
16051+
16052+
16053+/*++
16054+
16055+Routine Description:
16056+
16057+ This routine will enable the corresponding adapter event to cause an interrupt on
16058+ the host.
16059+
16060+Arguments:
16061+
16062+ AdapterExtension - Which adapter to enable.
16063+
16064+ AdapterEvent - Which adapter event.
16065+
16066+ AtDeviceIrq - Whether the system is in DEVICE irql
16067+
16068+Return Value:
16069+
16070+ Nothing.
16071+
16072+--*/
16073+VOID
16074+SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16075+{
16076+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16077+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16078+
16079+ switch (AdapterEvent) {
16080+
16081+ case HostNormCmdQue:
16082+
16083+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16084+
16085+ break;
16086+
16087+ case HostNormRespQue:
16088+
16089+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16090+
16091+ break;
16092+
16093+ case AdapNormCmdNotFull:
16094+
16095+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16096+
16097+ break;
16098+
16099+ case AdapNormRespNotFull:
16100+
16101+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16102+
16103+ break;
16104+
16105+ }
16106+
16107+}
16108+
16109+
16110+
16111+/*++
16112+
16113+Routine Description:
16114+
16115+ This routine will disable the corresponding adapter event to cause an interrupt on
16116+ the host.
16117+
16118+Arguments:
16119+
16120+ AdapterExtension - Which adapter to enable.
16121+
16122+ AdapterEvent - Which adapter event.
16123+
16124+ AtDeviceIrq - Whether the system is in DEVICE irql
16125+
16126+Return Value:
16127+
16128+ Nothing.
16129+
16130+--*/
16131+VOID
16132+SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16133+{
16134+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16135+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16136+
16137+ switch (AdapterEvent) {
16138+
16139+
16140+ case HostNormCmdQue:
16141+
16142+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16143+
16144+ break;
16145+
16146+ case HostNormRespQue:
16147+
16148+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16149+
16150+ break;
16151+
16152+ case AdapNormCmdNotFull:
16153+
16154+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16155+
16156+ break;
16157+
16158+
16159+ case AdapNormRespNotFull:
16160+
16161+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16162+
16163+ break;
16164+
16165+ }
16166+
16167+}
16168+
16169+
16170+SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16171+{
16172+ PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16173+
16174+ //
16175+ // Free the register mapping.
16176+ //
16177+
16178+ OsDetachDevice(AdapterExtension);
16179+
16180+ OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16181+
16182+}
16183+
16184+
16185+/*++
16186+
16187+Routine Description:
16188+
16189+ Scans the PCI bus looking for the Sa card. When found all resources for the
16190+ device will be allocated and the interrupt vectors and csrs will be allocated and
16191+ mapped.
16192+
16193+ The device_interface in the commregion will be allocated and linked to the comm region.
16194+
16195+Arguments:
16196+
16197+
16198+Return Value:
16199+
16200+ TRUE - if the device was setup with not problems
16201+ FALSE - if the device could not be mapped and init successfully
16202+
16203+--*/
16204+int
16205+SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16206+ IN ULONG AdapterNumber, IN ULONG PciBus,
16207+ IN ULONG PciSlot)
16208+{
16209+ AAC_STATUS Status;
16210+ PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16211+ FSA_NEW_ADAPTER NewAdapter;
16212+ ULONG StartTime, EndTime, WaitTime;
16213+ ULONG InitStatus;
16214+ int instance;
16215+ char *name;
16216+
16217+ AfaPortPrint("In init device.\n");
16218+
16219+ CommonExtension->AdapterNumber = AdapterNumber;
16220+
16221+ CommonExtension->PciBusNumber = PciBus;
16222+ CommonExtension->PciSlotNumber = PciSlot;
16223+
16224+ AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16225+ AdapterExtension->Common = CommonExtension;
16226+ CommonExtension->MiniPort = AdapterExtension;
16227+
16228+ instance = OsGetDeviceInstance(AdapterExtension);
16229+ name = OsGetDeviceName(AdapterExtension);
16230+
16231+ //
16232+ // Map in the registers from the adapter, register space 0 is config space,
16233+ // register space 1 is the memery space.
16234+ //
16235+
16236+ if (OsMapDeviceRegisters(AdapterExtension)){
16237+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16238+ return(FAILURE);
16239+ }
16240+
16241+
16242+ //
16243+ // Check to see if the board failed any self tests.
16244+ //
16245+
16246+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16247+
16248+ cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16249+ name, instance);
16250+ return(FAILURE);
16251+ }
16252+
16253+ //
16254+ // Check to see if the board panic'd while booting.
16255+ //
16256+
16257+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16258+
16259+ cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16260+ name, instance);
16261+ return(FAILURE);
16262+ }
16263+
16264+
16265+ StartTime = OsGetSeconds();
16266+ WaitTime = 0;
16267+
16268+
16269+ //
16270+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
16271+ //
16272+
16273+ while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16274+
16275+ EndTime = OsGetSeconds();
16276+
16277+ WaitTime = EndTime - StartTime;
16278+
16279+ if ( WaitTime > (3 * 60) ) {
16280+
16281+ InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16282+
16283+ cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16284+ name, instance, InitStatus);
16285+ return(FAILURE);
16286+
16287+ }
16288+ }
16289+
16290+ if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16291+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16292+ return(FAILURE);
16293+ }
16294+
16295+ if (OsAttachDMA(AdapterExtension)) {
16296+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16297+ return(FAILURE);
16298+ }
16299+
16300+
16301+ //
16302+ // Fill in the function dispatch table.
16303+ //
16304+
16305+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16306+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16307+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16308+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16309+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16310+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16311+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16312+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16313+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16314+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16315+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16316+ AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16317+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16318+
16319+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16320+
16321+ NewAdapter.AdapterExtension = CommonExtension;
16322+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16323+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16324+ NewAdapter.AdapterUserVars = SaUserVars;
16325+ NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16326+
16327+ NewAdapter.Dip = CommonExtension->OsDep.dip;
16328+
16329+
16330+ if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16331+ cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16332+ return (FAILURE);
16333+ };
16334+
16335+
16336+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16337+
16338+ if (AdapterExtension->Common->Adapter == NULL) {
16339+
16340+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16341+ cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16342+
16343+ return (FAILURE);
16344+ }
16345+
16346+
16347+ //
16348+ // Start any kernel threads needed
16349+ OsStartKernelThreads(AdapterExtension);
16350+
16351+ //
16352+ // Tell the adapter that all is configure, and it can start accepting requests
16353+ //
16354+
16355+ SaStartAdapter(AdapterExtension);
16356+
16357+
16358+
16359+ //
16360+ // Put this adapter into the list of Sa adapters
16361+ //
16362+
16363+ AdapterExtension->Next = SaAdapterList;
16364+ SaAdapterList = AdapterExtension;
16365+
16366+ AdapterExtension->Common->AdapterConfigured = TRUE;
16367+
16368+
16369+#ifdef AACDISK
16370+ //
16371+ // Call the disk layer to initialize itself.
16372+ //
16373+
16374+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16375+#endif
16376+
16377+
16378+init_done:
16379+
16380+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16381+
16382+ OsAttachHBA(AdapterExtension);
16383+
16384+ return (0);
16385+
16386+init_error:
16387+
16388+ return (FAILURE);
16389+}
16390+
16391+
16392+
16393+VOID
16394+SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16395+{
16396+ ULONG ReturnStatus;
16397+ LARGE_INTEGER HostTime;
16398+ ULONG ElapsedSeconds;
16399+ PADAPTER_INIT_STRUCT InitStruct;
16400+
16401+ //
16402+ // Fill in the remaining pieces of the InitStruct.
16403+ //
16404+
16405+ InitStruct = AdapterExtension->Common->InitStruct;
16406+
16407+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16408+
16409+ ElapsedSeconds = OsGetSeconds();
16410+
16411+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
16412+
16413+ //
16414+ // Tell the adapter we are back and up and running so it will scan its command
16415+ // queues and enable our interrupts
16416+ //
16417+
16418+ AdapterExtension->LocalMaskInterruptControl =
16419+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16420+
16421+
16422+ //
16423+ // First clear out all interrupts. Then enable the one's that we can handle.
16424+ //
16425+
16426+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16427+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16428+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16429+
16430+ SaSendSynchCommand(AdapterExtension,
16431+ INIT_STRUCT_BASE_ADDRESS,
16432+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16433+ 0,
16434+ 0,
16435+ 0,
16436+ &ReturnStatus);
16437+
16438+}
16439+
16440+
16441+VOID
16442+SaResetDevice (PVOID Arg1){
16443+
16444+}
16445+
16446+
16447+/*++
16448+
16449+Routine Description:
16450+
16451+ The will cause the adapter to take a break point.
16452+
16453+Arguments:
16454+
16455+ None
16456+
16457+Return Value:
16458+
16459+ Nothing
16460+
16461+--*/
16462+VOID
16463+SaInterruptAdapter (PVOID Arg1)
16464+{
16465+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16466+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16467+
16468+ ULONG ReturnStatus;
16469+
16470+ SaSendSynchCommand(AdapterExtension,
16471+ BREAKPOINT_REQUEST,
16472+ 0,
16473+ 0,
16474+ 0,
16475+ 0,
16476+ &ReturnStatus);
16477+
16478+}
16479+
16480+
16481+/*++
16482+
16483+Routine Description:
16484+
16485+ Will read the adapter CSRs to find the reason the adapter has
16486+ interrupted us.
16487+
16488+Arguments:
16489+
16490+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16491+
16492+Return Value:
16493+
16494+ Nothing
16495+
16496+--*/
16497+VOID
16498+SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16499+{
16500+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16501+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16502+ ULONG ReturnStatus;
16503+
16504+ switch (AdapterEvent) {
16505+ case AdapNormCmdQue:
16506+
16507+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16508+ break;
16509+
16510+ case HostNormRespNotFull:
16511+
16512+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16513+ break;
16514+
16515+ case AdapNormRespQue:
16516+
16517+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16518+ break;
16519+
16520+ case HostNormCmdNotFull:
16521+
16522+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16523+ break;
16524+
16525+ case HostShutdown:
16526+
16527+// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16528+
16529+ break;
16530+
16531+ case FastIo:
16532+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16533+ break;
16534+
16535+ case AdapPrintfDone:
16536+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16537+ break;
16538+
16539+ default:
16540+
16541+ SaBugCheck(0,0,0);
16542+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16543+ break;
16544+ }
16545+}
16546+
16547+
16548+/*++
16549+
16550+Routine Description:
16551+
16552+ This routine will send a synchronous comamnd to the adapter and wait for its
16553+ completion.
16554+
16555+Arguments:
16556+
16557+ AdapterExtension - Pointer to adapter extension structure.
16558+ Command - Which command to send
16559+ Parameter1 - 4 - Parameters for command
16560+ ReturnStatus - return status from adapter after completion of command
16561+
16562+
16563+Return Value:
16564+
16565+ AAC_STATUS
16566+
16567+--*/
16568+AAC_STATUS
16569+SaSendSynchCommand(
16570+ PVOID Arg1,
16571+ ULONG Command,
16572+ ULONG Parameter1,
16573+ ULONG Parameter2,
16574+ ULONG Parameter3,
16575+ ULONG Parameter4,
16576+ PULONG ReturnStatus
16577+ )
16578+{
16579+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16580+ ULONG StartTime,EndTime,WaitTime;
16581+ BOOLEAN CommandSucceeded;
16582+
16583+ //
16584+ // Write the Command into Mailbox 0
16585+ //
16586+
16587+ Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16588+
16589+ //
16590+ // Write the parameters into Mailboxes 1 - 4
16591+ //
16592+
16593+ Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16594+ Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16595+ Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16596+ Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16597+
16598+ //
16599+ // Clear the synch command doorbell to start on a clean slate.
16600+ //
16601+
16602+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16603+
16604+ //
16605+ // Signal that there is a new synch command
16606+ //
16607+
16608+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16609+
16610+ CommandSucceeded = FALSE;
16611+
16612+ StartTime = OsGetSeconds();
16613+ WaitTime = 0;
16614+
16615+ while (WaitTime < 30) { // wait up to 30 seconds
16616+
16617+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16618+
16619+ //
16620+ // Mon110 will set doorbell0 bit when it has completed the command.
16621+ //
16622+
16623+ if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16624+
16625+ CommandSucceeded = TRUE;
16626+ break;
16627+ }
16628+
16629+ EndTime = OsGetSeconds();
16630+ WaitTime = EndTime - StartTime;
16631+
16632+ }
16633+
16634+ if (CommandSucceeded != TRUE) {
16635+
16636+ return (STATUS_IO_TIMEOUT);
16637+
16638+ }
16639+
16640+ //
16641+ // Clear the synch command doorbell.
16642+ //
16643+
16644+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16645+
16646+ //
16647+ // Pull the synch status from Mailbox 0.
16648+ //
16649+
16650+ *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16651+
16652+ //
16653+ // Return SUCCESS
16654+ //
16655+
16656+ return (STATUS_SUCCESS);
16657+
16658+}
16659+
16660+
16661+/*++
16662+
16663+Routine Description:
16664+
16665+ This routine will send a synchronous fib to the adapter and wait for its
16666+ completion.
16667+
16668+Arguments:
16669+
16670+ AdapterExtension - Pointer to adapter extension structure.
16671+ FibPhysicalAddress - Physical address of fib to send.
16672+
16673+
16674+Return Value:
16675+
16676+ BOOLEAN
16677+
16678+--*/
16679+BOOLEAN
16680+SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16681+{
16682+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16683+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16684+ ULONG returnStatus;
16685+
16686+ if (SaSendSynchCommand( AdapterExtension,
16687+ SEND_SYNCHRONOUS_FIB,
16688+ FibPhysicalAddress,
16689+ 0,
16690+ 0,
16691+ 0,
16692+ &returnStatus ) != STATUS_SUCCESS ) {
16693+
16694+ return (FALSE);
16695+
16696+ }
16697+
16698+ return (TRUE);
16699+
16700+}
16701+
16702+BOOLEAN
16703+WriteFlash(
16704+ PVOID AdapterExtension,
16705+ ULONG *MappedBuffer)
16706+{
16707+ return (FALSE);
16708+}
16709+
16710+BOOLEAN
16711+ReadFlash(
16712+ PVOID AdapterExtension,
16713+ ULONG *MappedBuffer)
16714+{
16715+ return (FALSE);
16716+}
16717+
This page took 2.207804 seconds and 4 git commands to generate.