]> git.pld-linux.org Git - packages/kernel.git/blame - aacraid-2.4.1-1.0.6.patch
- obsolete
[packages/kernel.git] / aacraid-2.4.1-1.0.6.patch
CommitLineData
ce27390f 1diff -urN linux/arch/i386/defconfig linux/arch/i386/defconfig
2--- linux/arch/i386/defconfig Thu Nov 16 21:20:29 2000
3+++ linux/arch/i386/defconfig Thu Dec 21 13:27:04 2000
4@@ -276,6 +276,7 @@
5 # CONFIG_SCSI_AHA152X is not set
6 # CONFIG_SCSI_AHA1542 is not set
7 # CONFIG_SCSI_AHA1740 is not set
8+# CONFIG_SCSI_AACRAID is not set
9 # CONFIG_SCSI_AIC7XXX is not set
10 # CONFIG_SCSI_ADVANSYS is not set
11 # CONFIG_SCSI_IN2000 is not set
12diff -urN linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
13--- linux/drivers/scsi/Config.in Thu Dec 21 12:07:01 2000
14+++ linux/drivers/scsi/Config.in Thu Dec 21 13:28:36 2000
15@@ -48,6 +48,7 @@
16 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
17 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
18 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
19+dep_tristate 'Adaptec AACRAID support EXPERIMENTAL' CONFIG_SCSI_AACRAID $CONFIG_SCSI
20 dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
21 if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
22 bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
23diff -urN linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
24--- linux/drivers/scsi/Makefile Thu Dec 21 12:07:01 2000
25+++ linux/drivers/scsi/Makefile Thu Dec 21 14:20:35 2000
26@@ -62,6 +62,7 @@
27 obj-$(CONFIG_SCSI_AHA152X) += aha152x.o
28 obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
29 obj-$(CONFIG_SCSI_AHA1740) += aha1740.o
30+obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
31 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o
32 obj-$(CONFIG_SCSI_IPS) += ips.o
33 obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
34@@ -195,3 +196,7 @@
35 sim710_u.h: sim710_d.h
36
37 sim710.o : sim710_d.h
38+
39+aacraid.o:
40+ cd aacraid; make
41+
42diff -urN linux/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
43--- linux/drivers/scsi/aacraid/Makefile Wed Dec 31 19:00:00 1969
44+++ linux/drivers/scsi/aacraid/Makefile Thu Dec 21 13:14:30 2000
45@@ -0,0 +1,171 @@
46+#
47+# Makefile aacraid Raid Controller
48+#
49+
50+###############################################################################
51+### SOURCE FILES DEFINES
52+###############################################################################
53+
54+CFILES_DRIVER=\
55+ ./aachba.c \
56+ ./aacid.c \
57+ ./commctrl.c \
58+ ./comminit.c \
59+ ./commsup.c \
60+ ./dpcsup.c \
61+ ./linit.c \
62+ ./osddi.c \
63+ ./osfuncs.c \
64+ ./ossup.c \
65+ ./port.c \
66+ ./rx.c \
67+ ./sap1sup.c
68+
69+IFILES_DRIVER=\
70+ ./include/AacGenericTypes.h \
71+ ./include/aac_unix_defs.h \
72+ ./include/adapter.h \
73+ ./include/afacomm.h \
74+ ./include/aifstruc.h \
75+ ./include/build_number.h \
76+ ./include/commdata.h \
77+ ./include/commerr.h \
78+ ./include/commfibcontext.h \
79+ ./include/comprocs.h \
80+ ./include/comproto.h \
81+ ./include/comstruc.h \
82+ ./include/comsup.h \
83+ ./include/fsact.h \
84+ ./include/fsafs.h \
85+ ./include/fsaioctl.h \
86+ ./include/fsaport.h \
87+ ./include/fsatypes.h \
88+ ./include/linit.h \
89+ ./include/monkerapi.h \
90+ ./include/nodetype.h \
91+ ./include/nvramioctl.h \
92+ ./include/osheaders.h \
93+ ./include/ostypes.h \
94+ ./include/pcisup.h \
95+ ./include/perfpack.h \
96+ ./include/port.h \
97+ ./include/protocol.h \
98+ ./include/revision.h \
99+ ./include/rxcommon.h \
100+ ./include/rx.h \
101+ ./include/sap1common.h \
102+ ./include/sap1.h \
103+ ./include/version.h
104+
105+ALL_SOURCE=\
106+ ${CFILES_DRIVER} \
107+ ${IFILES_DRIVER}
108+
109+###############################################################################
110+### OBJECT FILES DEFINES
111+###############################################################################
112+
113+
114+OFILES_DRIVER=\
115+ linit.o \
116+ osfuncs.o \
117+ osddi.o \
118+ aachba.o \
119+ commctrl.o \
120+ comminit.o \
121+ commsup.o \
122+ dpcsup.o \
123+ ossup.o \
124+ port.o \
125+ rx.o \
126+ sap1sup.o
127+
128+TARGET_OFILES= ${OFILES_DRIVER} aacid.o
129+
130+###############################################################################
131+### GENERAL DEFINES
132+###############################################################################
133+
134+# Remember that we're doing a chdir one level lower, so we need an extra ../
135+INCS= \
136+ -I./include \
137+ -I../../../include -I..
138+
139+WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
140+
141+
142+COMMON_FLAGS=\
143+ -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
144+ -Wall -Wstrict-prototypes \
145+ ${INCS} \
146+ ${WARNINGS} \
147+ -O1 -g
148+
149+AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
150+
151+###############################################################################
152+### DO GENERAL STUFF
153+###############################################################################
154+
155+.SUFFIXES:
156+.SUFFIXES: .c .o .h .a
157+
158+all: source ${TARGET_OFILES} aacraid.o
159+
160+source: ${ALL_SOURCE}
161+
162+clean:
163+ rm *.o
164+
165+###############################################################################
166+### DRIVER LINKS
167+###############################################################################
168+
169+aacraid.o: source ${TARGET_OFILES}
170+ ld -r -o $@ $(TARGET_OFILES)
171+ cp -r aacraid.o ../
172+
173+###############################################################################
174+### SIMPLE COMPILES
175+###############################################################################
176+
177+linit.o: ./linit.c
178+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
179+
180+aachba.o: ./aachba.c
181+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
182+
183+osddi.o: ./osddi.c
184+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
185+
186+osfuncs.o: ./osfuncs.c
187+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
188+
189+commctrl.o: ./commctrl.c
190+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
191+
192+comminit.o: ./comminit.c
193+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
194+
195+commsup.o: ./commsup.c
196+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
197+
198+dpcsup.o: ./dpcsup.c
199+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
200+
201+aacid.o: ./aacid.c
202+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
203+
204+port.o: ./port.c
205+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
206+
207+ossup.o: ./ossup.c
208+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
209+
210+rx.o: ./rx.c
211+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
212+
213+sap1sup.o: ./sap1sup.c
214+ $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
215+
216+
217diff -urN linux/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
218--- linux/drivers/scsi/aacraid/README Wed Dec 31 19:00:00 1969
219+++ linux/drivers/scsi/aacraid/README Thu Dec 21 13:14:30 2000
220@@ -0,0 +1,30 @@
221+ AACRAID Driver for Linux
222+
223+Introduction
224+-------------------------
225+The aacraid driver adds support for Adaptec (http://www.adaptec.com)
226+OEM based RAID controllers.
227+
228+Supported Cards/Chipsets
229+-------------------------
230+ Dell Computer Corporation PERC 2 Quad Channel
231+ Dell Computer Corporation PERC 3/Di
232+ Dell Computer Corporation PERC 3/Si
233+ HP NetRAID-4M
234+
235+Not Supported Devices
236+-------------------------
237+ Any and All Adaptec branded raid controllers.
238+
239+People
240+-------------------------
241+ Brian M. Boerner
242+
243+Mailing List
244+-------------------------
245+There is currently a mailing list being created for aacraid. This
246+will all be straitened out before the driver is submitted for
247+inclusion in the standard kernel distribution.
248+
249+$Revision$
250+Modified by Brian Boerner 2000
251\ No newline at end of file
252diff -urN linux/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
253--- linux/drivers/scsi/aacraid/aachba.c Wed Dec 31 19:00:00 1969
254+++ linux/drivers/scsi/aacraid/aachba.c Thu Dec 21 13:14:30 2000
255@@ -0,0 +1,1874 @@
256+/*++
257+ * Adaptec aacraid device driver for Linux.
258+ *
259+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
260+ *
261+ * This program is free software; you can redistribute it and/or modify
262+ * it under the terms of the GNU General Public License as published by
263+ * the Free Software Foundation; either version 2, or (at your option)
264+ * any later version.
265+ *
266+ * This program is distributed in the hope that it will be useful,
267+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
268+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
269+ * GNU General Public License for more details.
270+ *
271+ * You should have received a copy of the GNU General Public License
272+ * along with this program; see the file COPYING. If not, write to
273+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
274+ *
275+ * Module Name:
276+ * aachba.c
277+ *
278+ * Abstract: driver...
279+ *
280+--*/
281+
282+static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
283+
284+/*------------------------------------------------------------------------------
285+ * I N C L U D E S
286+ *----------------------------------------------------------------------------*/
287+#include "osheaders.h"
288+#include "AacGenericTypes.h"
289+#include "aac_unix_defs.h"
290+#include "comstruc.h"
291+#include "monkerapi.h"
292+#include "protocol.h"
293+#include "fsafs.h"
294+#include "fsact.h"
295+#include "fsaioctl.h"
296+
297+#include "sap1common.h"
298+#include "fsaport.h"
299+#include "pcisup.h"
300+#include "sap1.h"
301+#include "nodetype.h"
302+#include "comsup.h"
303+#include "afacomm.h"
304+#include "adapter.h"
305+
306+/*------------------------------------------------------------------------------
307+ * D E F I N E S
308+ *----------------------------------------------------------------------------*/
309+/* SCSI Commands */
310+#define SS_TEST 0x00 /* Test unit ready */
311+#define SS_REZERO 0x01 /* Rezero unit */
312+#define SS_REQSEN 0x03 /* Request Sense */
313+#define SS_REASGN 0x07 /* Reassign blocks */
314+#define SS_READ 0x08 /* Read 6 */
315+#define SS_WRITE 0x0A /* Write 6 */
316+#define SS_INQUIR 0x12 /* inquiry */
317+#define SS_ST_SP 0x1B /* Start/Stop unit */
318+#define SS_LOCK 0x1E /* prevent/allow medium removal */
319+#define SS_RESERV 0x16 /* Reserve */
320+#define SS_RELES 0x17 /* Release */
321+#define SS_MODESEN 0x1A /* Mode Sense 6 */
322+#define SS_RDCAP 0x25 /* Read Capacity */
323+#define SM_READ 0x28 /* Read 10 */
324+#define SM_WRITE 0x2A /* Write 10 */
325+#define SS_SEEK 0x2B /* Seek */
326+
327+/* values for inqd_pdt: Peripheral device type in plain English */
328+#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
329+#define INQD_PDT_PROC 0x03 /* Processor device */
330+#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
331+#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
332+#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
333+#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
334+
335+#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
336+#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
337+
338+#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
339+#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
340+#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
341+
342+#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
343+
344+#define MAX_DRIVER_SG_SEGMENT_COUNT 17
345+
346+// ------------------------------------------------------
347+// Sense keys
348+//
349+#define SENKEY_NO_SENSE 0x00 //
350+#define SENKEY_UNDEFINED 0x01 //
351+#define SENKEY_NOT_READY 0x02 //
352+#define SENKEY_MEDIUM_ERR 0x03 //
353+#define SENKEY_HW_ERR 0x04 //
354+#define SENKEY_ILLEGAL 0x05 //
355+#define SENKEY_ATTENTION 0x06 //
356+#define SENKEY_PROTECTED 0x07 //
357+#define SENKEY_BLANK 0x08 //
358+#define SENKEY_V_UNIQUE 0x09 //
359+#define SENKEY_CPY_ABORT 0x0A //
360+#define SENKEY_ABORT 0x0B //
361+#define SENKEY_EQUAL 0x0C //
362+#define SENKEY_VOL_OVERFLOW 0x0D //
363+#define SENKEY_MISCOMP 0x0E //
364+#define SENKEY_RESERVED 0x0F //
365+
366+// ------------------------------------------------------
367+// Sense codes
368+//
369+#define SENCODE_NO_SENSE 0x00
370+#define SENCODE_END_OF_DATA 0x00
371+#define SENCODE_BECOMING_READY 0x04
372+#define SENCODE_INIT_CMD_REQUIRED 0x04
373+#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
374+#define SENCODE_INVALID_COMMAND 0x20
375+#define SENCODE_LBA_OUT_OF_RANGE 0x21
376+#define SENCODE_INVALID_CDB_FIELD 0x24
377+#define SENCODE_LUN_NOT_SUPPORTED 0x25
378+#define SENCODE_INVALID_PARAM_FIELD 0x26
379+#define SENCODE_PARAM_NOT_SUPPORTED 0x26
380+#define SENCODE_PARAM_VALUE_INVALID 0x26
381+#define SENCODE_RESET_OCCURRED 0x29
382+#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
383+#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
384+#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
385+#define SENCODE_DIAGNOSTIC_FAILURE 0x40
386+#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
387+#define SENCODE_INVALID_MESSAGE_ERROR 0x49
388+#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
389+#define SENCODE_OVERLAPPED_COMMAND 0x4E
390+
391+// ------------------------------------------------------
392+// Additional sense codes
393+//
394+#define ASENCODE_NO_SENSE 0x00
395+#define ASENCODE_END_OF_DATA 0x05
396+#define ASENCODE_BECOMING_READY 0x01
397+#define ASENCODE_INIT_CMD_REQUIRED 0x02
398+#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
399+#define ASENCODE_INVALID_COMMAND 0x00
400+#define ASENCODE_LBA_OUT_OF_RANGE 0x00
401+#define ASENCODE_INVALID_CDB_FIELD 0x00
402+#define ASENCODE_LUN_NOT_SUPPORTED 0x00
403+#define ASENCODE_INVALID_PARAM_FIELD 0x00
404+#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
405+#define ASENCODE_PARAM_VALUE_INVALID 0x02
406+#define ASENCODE_RESET_OCCURRED 0x00
407+#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
408+#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
409+#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
410+#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
411+#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
412+#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
413+#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
414+#define ASENCODE_OVERLAPPED_COMMAND 0x00
415+
416+#define BYTE0( x ) ( unsigned char )( x )
417+#define BYTE1( x ) ( unsigned char )( x >> 8 )
418+#define BYTE2( x ) ( unsigned char )( x >> 16 )
419+#define BYTE3( x ) ( unsigned char )( x >> 24 )
420+
421+/*------------------------------------------------------------------------------
422+ * S T R U C T S / T Y P E D E F S
423+ *----------------------------------------------------------------------------*/
424+/* SCSI inquiry data */
425+struct inquiry_data {
426+ unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
427+ unchar inqd_dtq; /* RMB | Device Type Qualifier */
428+ unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
429+ unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
430+ unchar inqd_len; /* Additional length (n-4) */
431+ unchar inqd_pad1[2]; /* Reserved - must be zero */
432+ unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
433+ unchar inqd_vid[8]; /* Vendor ID */
434+ unchar inqd_pid[16]; /* Product ID */
435+ unchar inqd_prl[4]; /* Product Revision Level */
436+};
437+
438+struct sense_data {
439+ unchar error_code; // 70h (current errors), 71h(deferred errors)
440+ unchar valid:1; // A valid bit of one indicates that the information
441+ // field contains valid information as defined in the
442+ // SCSI-2 Standard.
443+
444+ unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
445+ // commands
446+
447+ unchar sense_key:4; // Sense Key
448+ unchar reserved:1;
449+ unchar ILI:1; // Incorrect Length Indicator
450+ unchar EOM:1; // End Of Medium - reserved for random access devices
451+ unchar filemark:1; // Filemark - reserved for random access devices
452+
453+ unchar information[4]; // for direct-access devices, contains the unsigned
454+ // logical block address or residue associated with
455+ // the sense key
456+ unchar add_sense_len; // number of additional sense bytes to follow this field
457+ unchar cmnd_info[4]; // not used
458+ unchar ASC; // Additional Sense Code
459+ unchar ASCQ; // Additional Sense Code Qualifier
460+ unchar FRUC; // Field Replaceable Unit Code - not used
461+
462+ unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
463+ // was in error
464+ unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
465+ // the bit_ptr field has valid value
466+ unchar reserved2:2;
467+ unchar CD:1; // command data bit: 1- illegal parameter in CDB.
468+ // 0- illegal parameter in data.
469+ unchar SKSV:1;
470+
471+ unchar field_ptr[2]; // byte of the CDB or parameter data in error
472+};
473+
474+/*------------------------------------------------------------------------------
475+ * G L O B A L S
476+ *----------------------------------------------------------------------------*/
477+/*------------------------------------------------------------------------------
478+ * M O D U L E G L O B A L S
479+ *----------------------------------------------------------------------------*/
480+static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
481+static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
482+
483+/*------------------------------------------------------------------------------
484+ * F U N C T I O N P R O T O T Y P E S
485+ *----------------------------------------------------------------------------*/
486+AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
487+AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
488+BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
489+BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
490+ PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
491+
492+void AacHba_CompleteScsi(
493+ Scsi_Cmnd *scsi_cmnd_ptr );
494+
495+void AacHba_CompleteScsiNoLock(
496+ Scsi_Cmnd *scsi_cmnd_ptr );
497+
498+static void AacHba_ReadCallback(
499+ void *Context,
500+ PFIB_CONTEXT FibContext,
501+ int FibStatus );
502+
503+static void AacHba_WriteCallback(
504+ void *Context,
505+ PFIB_CONTEXT FibContext,
506+ int FibStatus );
507+
508+int AacHba_DoScsiRead(
509+ Scsi_Cmnd *scsi_cmnd_ptr,
510+ int ContainerId,
511+ int wait );
512+
513+int AacHba_DoScsiWrite(
514+ Scsi_Cmnd *scsi_cmnd_ptr,
515+ int ContainerId,
516+ int wait );
517+
518+int AacHba_QueryDisk(
519+ PVOID AdapterArg, // CommonExtensionPtr
520+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
521+
522+int AacHba_ForceDeleteDisk(
523+ PVOID AdapterArg, // CommonExtensionPtr
524+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
525+
526+int AacHba_DeleteDisk(
527+ PVOID AdapterArg,
528+ IN PAFA_IOCTL_CMD IoctlCmdPtr );
529+
530+void AacHba_DetachAdapter(
531+ IN PVOID AdapterArg );
532+
533+BOOLEAN AacCommDetachAdapter(
534+ IN PAFA_COMM_ADAPTER Adapter );
535+
536+void AacHba_SetSenseData(
537+ char * sense_buf,
538+ unchar sense_key,
539+ unchar sense_code,
540+ unchar a_sense_code,
541+ unchar incorrect_length,
542+ unchar bit_pointer,
543+ unsigned field_pointer,
544+ unsigned long residue );
545+
546+static void get_sd_devname(
547+ long disknum,
548+ char * buffer);
549+
550+// Keep these here for the time being - #REVIEW#
551+int
552+AfaCommAdapterDeviceControl (
553+ IN PVOID AdapterArg,
554+ IN PAFA_IOCTL_CMD IoctlCmdPtr
555+ );
556+
557+AAC_STATUS
558+AfaCommRegisterNewClassDriver(
559+ IN PAFA_COMM_ADAPTER Adapter,
560+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
561+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
562+ );
563+
564+void
565+SetInqDataStr (int, void *, int);
566+/*------------------------------------------------------------------------------
567+ * F U N C T I O N S
568+ *----------------------------------------------------------------------------*/
569+
570+/*------------------------------------------------------------------------------
571+ AacHba_ClassDriverInit()
572+
573+ Setup 'core' class driver to answer ioctl's
574+ *----------------------------------------------------------------------------*/
575+int AacHba_ClassDriverInit(
576+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
577+/*----------------------------------------------------------------------------*/
578+{
579+ AFA_NEW_CLASS_DRIVER NewClassDriver;
580+ AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
581+ PAFA_COMM_ADAPTER Adapter;
582+
583+ Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
584+
585+ RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
586+
587+ // ClassDriverExtension is the first argument passed to class driver functions below
588+ NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
589+
590+ NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
591+ NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
592+ NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
593+ NewClassDriver.HandleAif = AacHba_HandleAif;
594+ AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
595+
596+ return(0);
597+}
598+
599+
600+/*------------------------------------------------------------------------------
601+ AacHba_ProbeContainers()
602+
603+ Make a list of all containers in the system.
604+------------------------------------------------------------------------------*/
605+int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
606+{
607+ fsadev_t *fsa_dev_ptr;
608+ int Index, Status;
609+ PMNTINFO DiskInfo;
610+ PMNTINFORESPONSE DiskInfoResponse;
611+ PFIB_CONTEXT FibContext;
612+ AFA_COMM_ADAPTER *Adapter;
613+ unsigned instance;
614+ char *bufp;
615+ int size;
616+
617+
618+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
619+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
620+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
621+
622+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
623+ {
624+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
625+ return( STATUS_UNSUCCESSFUL );
626+ }
627+
628+ for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
629+ {
630+ Adapter->CommFuncs.InitializeFib( FibContext );
631+
632+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
633+
634+ DiskInfo->Command = VM_NameServe;
635+ DiskInfo->MntCount = Index;
636+ DiskInfo->MntType = FT_FILESYS;
637+
638+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
639+ FibContext,
640+ sizeof(MNTINFO),
641+ FsaNormal,
642+ TRUE,
643+ NULL,
644+ TRUE,
645+ NULL,
646+ NULL );
647+ if ( Status )
648+ {
649+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
650+ break;
651+ }
652+
653+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
654+
655+
656+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
657+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
658+ {
659+
660+
661+ fsa_dev_ptr->ContainerValid[Index] = TRUE;
662+ fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
663+ fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
664+
665+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
666+ fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
667+ }
668+
669+ Adapter->CommFuncs.CompleteFib( FibContext );
670+
671+ // If there are no more containers, then stop asking.
672+ if ((Index + 1) >= DiskInfoResponse->MntRespCount)
673+ break;
674+ } // end for()
675+
676+ Adapter->CommFuncs.FreeFib( FibContext );
677+
678+ g_fsa_dev_array[instance] = fsa_dev_ptr;
679+ return( Status );
680+}
681+
682+
683+/*------------------------------------------------------------------------------
684+ AacHba_ProbeContainer()
685+
686+ Probe a single container.
687+ *----------------------------------------------------------------------------*/
688+int AacHba_ProbeContainer(
689+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
690+ int ContainerId )
691+/*----------------------------------------------------------------------------*/
692+{
693+ fsadev_t *fsa_dev_ptr;
694+ int Status;
695+ PMNTINFO DiskInfo;
696+ PMNTINFORESPONSE DiskInfoResponse;
697+ PFIB_CONTEXT FibContext;
698+ AFA_COMM_ADAPTER *Adapter;
699+ unsigned instance;
700+
701+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
702+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
703+ instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
704+
705+ if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
706+ {
707+ cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
708+ return( STATUS_UNSUCCESSFUL );
709+ }
710+
711+ Adapter->CommFuncs.InitializeFib( FibContext );
712+
713+ DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
714+
715+ DiskInfo->Command = VM_NameServe;
716+ DiskInfo->MntCount = ContainerId;
717+ DiskInfo->MntType = FT_FILESYS;
718+
719+ Status = Adapter->CommFuncs.SendFib (ContainerCommand,
720+ FibContext,
721+ sizeof(MNTINFO),
722+ FsaNormal,
723+ TRUE,
724+ NULL,
725+ TRUE,
726+ NULL,
727+ NULL );
728+ if ( Status )
729+ {
730+ cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
731+ Adapter->CommFuncs.CompleteFib( FibContext );
732+ Adapter->CommFuncs.FreeFib( FibContext );
733+ return( Status );
734+ }
735+
736+ DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
737+
738+
739+ if ( ( DiskInfoResponse->Status == ST_OK ) &&
740+ ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
741+ {
742+
743+ fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
744+ fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
745+ fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
746+ if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
747+ fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
748+ }
749+
750+ Adapter->CommFuncs.CompleteFib( FibContext );
751+ Adapter->CommFuncs.FreeFib( FibContext );
752+
753+ return( Status );
754+}
755+
756+
757+/*------------------------------------------------------------------------------
758+ AacHba_CompleteScsi()
759+
760+ Call SCSI completion routine after acquiring io_request_lock
761+
762+ Preconditions:
763+ Postconditions:
764+ *----------------------------------------------------------------------------*/
765+void AacHba_CompleteScsi(
766+ Scsi_Cmnd *scsi_cmnd_ptr )
767+{
768+ unsigned long cpu_flags;
769+
770+ spin_lock_irqsave( &io_request_lock, cpu_flags );
771+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
772+ spin_unlock_irqrestore( &io_request_lock, cpu_flags );
773+}
774+
775+
776+/*------------------------------------------------------------------------------
777+ AacHba_CompleteScsiNoLock()
778+
779+ Call SCSI completion routine
780+
781+ Preconditions:
782+ Postconditions:
783+ *----------------------------------------------------------------------------*/
784+void AacHba_CompleteScsiNoLock(
785+ Scsi_Cmnd *scsi_cmnd_ptr )
786+{
787+ scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
788+}
789+
790+/*------------------------------------------------------------------------------
791+ AacHba_DoScsiCmd()
792+
793+ Process SCSI command
794+
795+ Preconditions:
796+ Postconditions:
797+ Returns 0 on success, -1 on failure
798+ *----------------------------------------------------------------------------*/
799+int AacHba_DoScsiCmd(
800+ Scsi_Cmnd *scsi_cmnd_ptr,
801+ int wait )
802+{
803+ int ContainerId = 0;
804+ fsadev_t *fsa_dev_ptr;
805+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
806+ int MiniPortIndex;
807+
808+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
809+ MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
810+
811+ fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
812+
813+ // If the bus, target or lun is out of range, return fail
814+ // Test does not apply to ID 16, the pseudo id for the controller itself.
815+ if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
816+ {
817+ if( ( scsi_cmnd_ptr->channel > 0 ) ||
818+ ( scsi_cmnd_ptr->target > 15 ) ||
819+ ( scsi_cmnd_ptr->lun > 7 ) )
820+ {
821+ cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
822+ scsi_cmnd_ptr->channel,
823+ scsi_cmnd_ptr->target,
824+ scsi_cmnd_ptr->lun );
825+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
826+
827+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
828+
829+ return ( -1 );
830+ }
831+
832+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
833+
834+
835+ // If the target container doesn't exist, it may have been newly created
836+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
837+ {
838+ switch( scsi_cmnd_ptr->cmnd[0] )
839+ {
840+ case SS_INQUIR:
841+ case SS_RDCAP:
842+ case SS_TEST:
843+ spin_unlock_irq( &io_request_lock );
844+ AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
845+ spin_lock_irq( &io_request_lock );
846+ default:
847+ break;
848+ }
849+ }
850+
851+ // If the target container still doesn't exist, return failure
852+ if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
853+ {
854+
855+ scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
856+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
857+
858+ return ( -1 );
859+ }
860+ }
861+ else // the command is for the controller itself
862+ if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
863+ ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
864+ {
865+ cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
866+ scsi_cmnd_ptr->cmnd[0] );
867+
868+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
869+
870+ AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
871+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
872+ 0, 0, 0, 0 );
873+
874+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
875+
876+ return ( -1 );
877+ }
878+
879+ // Handle commands here that don't really require going out to the adapter
880+ switch ( scsi_cmnd_ptr->cmnd[0] )
881+ {
882+ case SS_INQUIR:
883+ {
884+ struct inquiry_data *inq_data_ptr;
885+
886+ cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
887+ inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
888+ bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
889+
890+ inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
891+
892+ inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
893+ // that the medium is removable
894+ inq_data_ptr->inqd_rdf = 2; // A response data format value of
895+ // two indicates that the data shall
896+ // be in the format specified in SCSI-2
897+ inq_data_ptr->inqd_len = 31;
898+
899+ // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
900+ SetInqDataStr( MiniPortIndex,
901+ (void *)(inq_data_ptr->inqd_vid),
902+ fsa_dev_ptr->ContainerType[ContainerId]);
903+
904+ if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
905+ inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
906+ else
907+ inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
908+
909+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
910+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
911+
912+ return ( 0 );
913+ }
914+
915+ case SS_RDCAP:
916+ {
917+ int capacity;
918+ char *cp;
919+
920+ cmn_err( CE_DEBUG, "READ CAPACITY command" );
921+ capacity = fsa_dev_ptr->ContainerSize[ContainerId];
922+ cp = scsi_cmnd_ptr->request_buffer;
923+ cp[0] = ( capacity >> 24 ) & 0xff;
924+ cp[1] = ( capacity >> 16 ) & 0xff;
925+ cp[2] = ( capacity >> 8 ) & 0xff;
926+ cp[3] = ( capacity >> 0 ) & 0xff;
927+ cp[4] = 0;
928+ cp[5] = 0;
929+ cp[6] = 2;
930+ cp[7] = 0;
931+
932+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
933+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
934+
935+ return ( 0 );
936+ }
937+
938+ case SS_MODESEN:
939+ {
940+ char *mode_buf;
941+
942+ cmn_err( CE_DEBUG, "MODE SENSE command" );
943+ mode_buf = scsi_cmnd_ptr->request_buffer;
944+ mode_buf[0] = 0; // Mode data length (MSB)
945+ mode_buf[1] = 6; // Mode data length (LSB)
946+ mode_buf[2] = 0; // Medium type - default
947+ mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
948+ mode_buf[4] = 0; // reserved
949+ mode_buf[5] = 0; // reserved
950+ mode_buf[6] = 0; // Block descriptor length (MSB)
951+ mode_buf[7] = 0; // Block descriptor length (LSB)
952+
953+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
954+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
955+
956+ return ( 0 );
957+ }
958+
959+
960+ // These commands are all No-Ops
961+ case SS_TEST:
962+ cmn_err( CE_DEBUG, "TEST UNIT READY command" );
963+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
964+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
965+ return ( 0 );
966+
967+ case SS_REQSEN:
968+ cmn_err( CE_DEBUG, "REQUEST SENSE command" );
969+
970+ memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
971+ sizeof( struct sense_data ) );
972+ bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
973+
974+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
975+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
976+ return ( 0 );
977+
978+ case SS_LOCK:
979+ cmn_err(CE_DEBUG, "LOCK command");
980+
981+ if( scsi_cmnd_ptr->cmnd[4] )
982+ fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
983+ else
984+ fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
985+
986+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
987+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
988+ return ( 0 );
989+
990+ case SS_RESERV:
991+ cmn_err( CE_DEBUG, "RESERVE command" );
992+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
993+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
994+ return ( 0 );
995+
996+ case SS_RELES:
997+ cmn_err( CE_DEBUG, "RELEASE command" );
998+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
999+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1000+ return ( 0 );
1001+
1002+ case SS_REZERO:
1003+ cmn_err( CE_DEBUG, "REZERO command" );
1004+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1005+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1006+ return ( 0 );
1007+
1008+ case SS_REASGN:
1009+ cmn_err( CE_DEBUG, "REASSIGN command" );
1010+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1011+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1012+ return ( 0 );
1013+
1014+ case SS_SEEK:
1015+ cmn_err( CE_DEBUG, "SEEK command" );
1016+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1017+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1018+ return ( 0 );
1019+
1020+ case SS_ST_SP:
1021+ cmn_err( CE_DEBUG, "START/STOP command" );
1022+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1023+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1024+ return ( 0 );
1025+ }
1026+
1027+ switch ( scsi_cmnd_ptr->cmnd[0] )
1028+ {
1029+ case SS_READ:
1030+ case SM_READ:
1031+ // Hack to keep track of ordinal number of the device that corresponds
1032+ // to a container. Needed to convert containers to /dev/sd device names
1033+ fsa_dev_ptr->ContainerDevNo[ContainerId] =
1034+ DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1035+
1036+ return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1037+ break;
1038+
1039+ case SS_WRITE:
1040+ case SM_WRITE:
1041+
1042+ return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1043+ break;
1044+ }
1045+ //
1046+ // Unhandled commands
1047+ //
1048+ cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1049+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1050+
1051+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1052+ SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1053+ 0, 0, 0, 0 );
1054+
1055+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1056+ return ( -1 );
1057+}
1058+
1059+
1060+/*------------------------------------------------------------------------------
1061+ AacHba_DoScsiRead()
1062+
1063+ Handles SCSI READ requests
1064+
1065+ Preconditions:
1066+ Postconditions:
1067+ Returns 0 on success, -1 on failure
1068+ *----------------------------------------------------------------------------*/
1069+int AacHba_DoScsiRead(
1070+ Scsi_Cmnd *scsi_cmnd_ptr,
1071+ int ContainerId,
1072+ int wait )
1073+/*----------------------------------------------------------------------------*/
1074+{
1075+ u_long lba;
1076+ u_long count;
1077+ u_long byte_count;
1078+ int Status;
1079+
1080+ PBLOCKREAD BlockReadDisk;
1081+ PBLOCKREADRESPONSE BlockReadResponse;
1082+ uint16_t FibSize;
1083+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1084+ AFA_COMM_ADAPTER *Adapter;
1085+ PFIB_CONTEXT cmd_fibcontext;
1086+
1087+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1088+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1089+
1090+ // Get block address and transfer length
1091+ if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1092+ {
1093+ cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1094+
1095+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1096+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1097+ scsi_cmnd_ptr->cmnd[3];
1098+ count = scsi_cmnd_ptr->cmnd[4];
1099+
1100+ if ( count == 0 )
1101+ count = 256;
1102+ }
1103+ else
1104+ {
1105+ cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1106+
1107+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1108+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1109+
1110+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1111+ }
1112+ cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1113+
1114+ //-------------------------------------------------------------------------
1115+ // Alocate and initialize a Fib
1116+ // Setup BlockRead command
1117+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1118+ {
1119+ cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1120+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1121+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1122+ return ( -1 );
1123+ }
1124+
1125+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1126+
1127+ BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1128+ BlockReadDisk->Command = VM_CtBlockRead;
1129+ BlockReadDisk->ContainerId = ContainerId;
1130+ BlockReadDisk->BlockNumber = lba;
1131+ BlockReadDisk->ByteCount = count * 512;
1132+ BlockReadDisk->SgMap.SgCount = 1;
1133+
1134+ if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1135+ {
1136+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1137+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1138+
1139+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1140+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1141+ 0, 0, 7, 0 );
1142+
1143+ goto err_return;
1144+ }
1145+
1146+ //-------------------------------------------------------------------------
1147+ // Build Scatter/Gather list
1148+ //
1149+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1150+ {
1151+ struct scatterlist *scatterlist_ptr;
1152+ int segment;
1153+
1154+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1155+
1156+ byte_count = 0;
1157+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1158+ {
1159+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1160+ ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1161+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1162+ scatterlist_ptr[segment].length;
1163+
1164+#ifdef DEBUG_SGBUFFER
1165+ memset( scatterlist_ptr[segment].address, 0xa5,
1166+ scatterlist_ptr[segment].length );
1167+#endif
1168+
1169+ byte_count += scatterlist_ptr[segment].length;
1170+
1171+ if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1172+ {
1173+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1174+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1175+
1176+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1177+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1178+ 0, 0, 7, 0 );
1179+
1180+ goto err_return;
1181+ }
1182+ /*
1183+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1184+ segment,
1185+ BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1186+ BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1187+ */
1188+ }
1189+ BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1190+
1191+ if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1192+ {
1193+ cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1194+ MAX_DRIVER_SG_SEGMENT_COUNT );
1195+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1196+ goto err_return;
1197+ }
1198+ }
1199+ else // one piece of contiguous phys mem
1200+ {
1201+ BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1202+ ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1203+ BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1204+
1205+ byte_count = scsi_cmnd_ptr->request_bufflen;
1206+
1207+ if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1208+ {
1209+ cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1210+ cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1211+ cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1212+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1213+
1214+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1215+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1216+ 0, 0, 7, 0 );
1217+
1218+ goto err_return;
1219+ }
1220+ }
1221+
1222+ if( byte_count != BlockReadDisk->ByteCount )
1223+ cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1224+
1225+ //-------------------------------------------------------------------------
1226+ // Now send the Fib to the adapter
1227+ //
1228+ FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1229+
1230+ if( wait )
1231+ {
1232+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1233+ cmd_fibcontext,
1234+ FibSize,
1235+ FsaNormal,
1236+ TRUE,
1237+ NULL,
1238+ TRUE,
1239+ NULL,
1240+ NULL);
1241+
1242+ BlockReadResponse = ( PBLOCKREADRESPONSE )
1243+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1244+
1245+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1246+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1247+
1248+ if( BlockReadResponse->Status != ST_OK )
1249+ {
1250+ cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1251+ BlockReadResponse->Status );
1252+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1253+
1254+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1255+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1256+ 0, 0, 0, 0 );
1257+
1258+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1259+ return ( -1 );
1260+ }
1261+ else
1262+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1263+
1264+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1265+ return ( 0 );
1266+ }
1267+ else
1268+ {
1269+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1270+ cmd_fibcontext,
1271+ FibSize,
1272+ FsaNormal,
1273+ FALSE,
1274+ NULL,
1275+ TRUE,
1276+ ( PFIB_CALLBACK )AacHba_ReadCallback,
1277+ ( void *)scsi_cmnd_ptr );
1278+ // don't call done func here
1279+ return ( 0 );
1280+ }
1281+
1282+err_return:
1283+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1284+
1285+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1286+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1287+
1288+ return ( -1 );
1289+}
1290+
1291+
1292+/*------------------------------------------------------------------------------
1293+ AacHba_DoScsiWrite()
1294+
1295+ Handles SCSI WRITE requests
1296+
1297+ Preconditions:
1298+ Postconditions:
1299+ Returns 0 on success, -1 on failure
1300+ *----------------------------------------------------------------------------*/
1301+int AacHba_DoScsiWrite(
1302+ Scsi_Cmnd *scsi_cmnd_ptr,
1303+ int ContainerId,
1304+ int wait )
1305+/*----------------------------------------------------------------------------*/
1306+{
1307+ u_long lba;
1308+ u_long count;
1309+ u_long byte_count;
1310+ int Status;
1311+
1312+ PBLOCKWRITE BlockWriteDisk;
1313+ PBLOCKWRITERESPONSE BlockWriteResponse;
1314+ uint16_t FibSize;
1315+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1316+ AFA_COMM_ADAPTER *Adapter;
1317+ PFIB_CONTEXT cmd_fibcontext;
1318+
1319+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1320+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1321+
1322+ // Get block address and transfer length
1323+ if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1324+ {
1325+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1326+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1327+ scsi_cmnd_ptr->cmnd[3];
1328+ count = scsi_cmnd_ptr->cmnd[4];
1329+
1330+ if ( count == 0 )
1331+ count = 256;
1332+ }
1333+ else
1334+ {
1335+ cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1336+
1337+ lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1338+ ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1339+
1340+ count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1341+
1342+ }
1343+ cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1344+
1345+ //-------------------------------------------------------------------------
1346+ // Alocate and initialize a Fib
1347+ // Setup BlockWrite command
1348+ if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1349+ {
1350+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1351+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1352+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1353+ return ( -1 );
1354+ }
1355+
1356+ Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1357+
1358+ BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1359+ BlockWriteDisk->Command = VM_CtBlockWrite;
1360+ BlockWriteDisk->ContainerId = ContainerId;
1361+ BlockWriteDisk->BlockNumber = lba;
1362+ BlockWriteDisk->ByteCount = count * 512;
1363+ BlockWriteDisk->SgMap.SgCount = 1;
1364+
1365+
1366+ if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1367+ {
1368+ struct scatterlist *scatterlist_ptr;
1369+ int segment;
1370+ scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1371+
1372+ cmn_err( CE_WARN, "\n");
1373+ cmn_err( CE_WARN, "AacHba_`DoScsiWrite: WRITE request is larger than 64K");
1374+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1375+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1376+ cmn_err( CE_WARN, "Dump SG Element Size...");
1377+ for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1378+ {
1379+ cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length);
1380+ }
1381+ cmn_err (CE_WARN, "\n");
1382+
1383+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1384+
1385+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1386+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1387+ 0, 0, 7, 0 );
1388+
1389+ goto err_return;
1390+ }
1391+
1392+ //-------------------------------------------------------------------------
1393+ // Build Scatter/Gather list
1394+ //
1395+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1396+ {
1397+ struct scatterlist *scatterlist_ptr;
1398+ int segment;
1399+
1400+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1401+
1402+ byte_count = 0;
1403+ for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1404+ {
1405+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1406+ ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1407+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1408+ scatterlist_ptr[segment].length;
1409+
1410+ byte_count += scatterlist_ptr[segment].length;
1411+
1412+ if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1413+ {
1414+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1415+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1416+
1417+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1418+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1419+ 0, 0, 7, 0 );
1420+
1421+ goto err_return;
1422+ }
1423+
1424+ /*
1425+ cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1426+ segment,
1427+ BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1428+ BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1429+ */
1430+ }
1431+ BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1432+
1433+ if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1434+ {
1435+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1436+ MAX_DRIVER_SG_SEGMENT_COUNT );
1437+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1438+ goto err_return;
1439+ }
1440+ }
1441+ else // one piece of contiguous phys mem
1442+ {
1443+ BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1444+ ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1445+ BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1446+
1447+ byte_count = scsi_cmnd_ptr->request_bufflen;
1448+
1449+ if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1450+ {
1451+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1452+
1453+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1454+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1455+ SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1456+ 0, 0, 7, 0 );
1457+
1458+ goto err_return;
1459+ }
1460+ }
1461+
1462+ if( byte_count != BlockWriteDisk->ByteCount )
1463+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1464+
1465+ //-------------------------------------------------------------------------
1466+ // Now send the Fib to the adapter
1467+ //
1468+ FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1469+
1470+ if( wait )
1471+ {
1472+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1473+ cmd_fibcontext,
1474+ FibSize,
1475+ FsaNormal,
1476+ TRUE,
1477+ NULL,
1478+ TRUE,
1479+ NULL,
1480+ NULL );
1481+
1482+ BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1483+ Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1484+
1485+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1486+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1487+
1488+ if( BlockWriteResponse->Status != ST_OK )
1489+ {
1490+ cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1491+ BlockWriteResponse->Status );
1492+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1493+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1494+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1495+ 0, 0, 0, 0 );
1496+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1497+ return ( -1 );
1498+ }
1499+ else
1500+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1501+
1502+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1503+ return ( 0 );
1504+ }
1505+ else
1506+ {
1507+ Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1508+ cmd_fibcontext,
1509+ FibSize,
1510+ FsaNormal,
1511+ FALSE,
1512+ NULL,
1513+ TRUE,
1514+ ( PFIB_CALLBACK )AacHba_WriteCallback,
1515+ ( void * )scsi_cmnd_ptr );
1516+
1517+ // don't call done func here - it should be called by the WriteCallback
1518+ return ( 0 );
1519+ }
1520+
1521+err_return:
1522+ AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1523+
1524+ Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1525+ Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1526+
1527+ return ( -1 );
1528+}
1529+
1530+
1531+/*------------------------------------------------------------------------------
1532+ AacHba_ReadCallback()
1533+ *----------------------------------------------------------------------------*/
1534+void AacHba_ReadCallback(
1535+ VOID *Context,
1536+ PFIB_CONTEXT FibContext,
1537+ int FibStatus )
1538+/*----------------------------------------------------------------------------*/
1539+{
1540+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1541+ AFA_COMM_ADAPTER *Adapter;
1542+ BLOCKREADRESPONSE *BlockReadResponse;
1543+ Scsi_Cmnd * scsi_cmnd_ptr;
1544+ u_long lba;
1545+ int ContainerId;
1546+
1547+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1548+
1549+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1550+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1551+
1552+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1553+
1554+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1555+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1556+ scsi_cmnd_ptr->cmnd[3];
1557+ cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1558+
1559+ if( FibContext == 0 )
1560+ {
1561+ cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1562+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1563+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1564+ return;
1565+ }
1566+
1567+ BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1568+
1569+ if ( BlockReadResponse->Status == ST_OK )
1570+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1571+ else
1572+ {
1573+ cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1574+ BlockReadResponse->Status );
1575+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1576+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1577+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1578+ 0, 0, 0, 0 );
1579+ }
1580+
1581+#ifdef DEBUG_SGBUFFER
1582+ if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1583+ {
1584+ struct scatterlist *scatterlist_ptr;
1585+ int i, segment, count;
1586+ char *ptr;
1587+
1588+ scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1589+
1590+ for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1591+ {
1592+ count = 0;
1593+ ptr = scatterlist_ptr[segment].address;
1594+ for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1595+ {
1596+ if( *( ptr++ ) == 0xa5 )
1597+ count++;
1598+ }
1599+ if( count == scatterlist_ptr[segment].length )
1600+ cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1601+
1602+ }
1603+ }
1604+#endif
1605+
1606+ Adapter->CommFuncs.CompleteFib( FibContext );
1607+ Adapter->CommFuncs.FreeFib( FibContext );
1608+
1609+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1610+}
1611+
1612+/*------------------------------------------------------------------------------
1613+ AacHba_WriteCallback()
1614+ *----------------------------------------------------------------------------*/
1615+void AacHba_WriteCallback(
1616+ VOID *Context,
1617+ PFIB_CONTEXT FibContext,
1618+ int FibStatus )
1619+/*----------------------------------------------------------------------------*/
1620+{
1621+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1622+ AFA_COMM_ADAPTER *Adapter;
1623+ BLOCKWRITERESPONSE *BlockWriteResponse;
1624+ Scsi_Cmnd *scsi_cmnd_ptr;
1625+ u_long lba;
1626+ int ContainerId;
1627+
1628+ scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1629+
1630+ CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1631+ Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1632+
1633+ ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1634+
1635+ lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1636+ ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1637+ scsi_cmnd_ptr->cmnd[3];
1638+ cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1639+ if( FibContext == 0 )
1640+ {
1641+ cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1642+ scsi_cmnd_ptr->result = DID_ERROR << 16;
1643+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1644+ return;
1645+ }
1646+
1647+ BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1648+ if (BlockWriteResponse->Status == ST_OK)
1649+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1650+ else
1651+ {
1652+ cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1653+ BlockWriteResponse->Status );
1654+ scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1655+ AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1656+ SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1657+ 0, 0, 0, 0 );
1658+ }
1659+
1660+ Adapter->CommFuncs.CompleteFib( FibContext );
1661+ Adapter->CommFuncs.FreeFib( FibContext );
1662+
1663+ AacHba_CompleteScsi( scsi_cmnd_ptr );
1664+}
1665+
1666+
1667+/*------------------------------------------------------------------------------
1668+ AacHba_Ioctl()
1669+
1670+ Handle IOCTL requests
1671+
1672+ Preconditions:
1673+ Postconditions:
1674+ *----------------------------------------------------------------------------*/
1675+int AacHba_Ioctl(
1676+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1677+ int cmd,
1678+ void * arg )
1679+/*----------------------------------------------------------------------------*/
1680+{
1681+ Sa_ADAPTER_EXTENSION *AdapterExtension;
1682+ AFA_IOCTL_CMD IoctlCmd;
1683+ int status;
1684+
1685+ AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1686+
1687+ cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1688+ switch( cmd )
1689+ {
1690+ case FSACTL_SENDFIB:
1691+ cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1692+ break;
1693+
1694+ case FSACTL_AIF_THREAD:
1695+ cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1696+ break;
1697+
1698+ case FSACTL_NULL_IO_TEST:
1699+ cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1700+ break;
1701+
1702+ case FSACTL_SIM_IO_TEST:
1703+ cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1704+ break;
1705+
1706+ case FSACTL_GET_FIBTIMES:
1707+ cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1708+ break;
1709+
1710+ case FSACTL_ZERO_FIBTIMES:
1711+ cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1712+ break;
1713+
1714+ case FSACTL_GET_VAR:
1715+ cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1716+ break;
1717+
1718+ case FSACTL_SET_VAR:
1719+ cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1720+ break;
1721+
1722+ case FSACTL_OPEN_ADAPTER_CONFIG:
1723+ cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1724+ break;
1725+
1726+ case FSACTL_CLOSE_ADAPTER_CONFIG:
1727+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1728+ break;
1729+
1730+ case FSACTL_QUERY_ADAPTER_CONFIG:
1731+ cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1732+ break;
1733+
1734+ case FSACTL_OPEN_GET_ADAPTER_FIB:
1735+ cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1736+ break;
1737+
1738+ case FSACTL_GET_NEXT_ADAPTER_FIB:
1739+ cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1740+ break;
1741+
1742+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
1743+ cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1744+ break;
1745+
1746+ case FSACTL_MINIPORT_REV_CHECK:
1747+ cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1748+ break;
1749+
1750+ case FSACTL_OPENCLS_COMM_PERF_DATA:
1751+ cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1752+ break;
1753+
1754+ case FSACTL_GET_COMM_PERF_DATA:
1755+ cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1756+ break;
1757+
1758+ case FSACTL_QUERY_DISK:
1759+ cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1760+ break;
1761+
1762+ case FSACTL_DELETE_DISK:
1763+ cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1764+ break;
1765+
1766+ default:
1767+ cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1768+ }
1769+
1770+ IoctlCmd.cmd = cmd;
1771+ IoctlCmd.arg = ( intptr_t )arg;
1772+ IoctlCmd.flag = 0;
1773+ IoctlCmd.cred_p = 0;
1774+ IoctlCmd.rval_p = 0;
1775+
1776+ status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1777+ cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1778+ return( status );
1779+}
1780+
1781+
1782+/*------------------------------------------------------------------------------
1783+ AacHba_AdapterDeviceControl()
1784+
1785+ Preconditions:
1786+ Postconditions:
1787+ Returns TRUE if ioctl handled, FALSE otherwise
1788+ *ReturnStatus set to completion status
1789+ *----------------------------------------------------------------------------*/
1790+BOOLEAN AacHba_AdapterDeviceControl (
1791+ PVOID AdapterArg, // CommonExtensionPtr
1792+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
1793+ OUT int * ReturnStatus )
1794+/*----------------------------------------------------------------------------*/
1795+{
1796+ BOOLEAN Handled = TRUE; // start out handling it.
1797+ int Status = EFAULT;
1798+
1799+ switch( IoctlCmdPtr->cmd )
1800+ {
1801+ case FSACTL_QUERY_DISK:
1802+ Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1803+ break;
1804+
1805+ case FSACTL_DELETE_DISK:
1806+ Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1807+ break;
1808+
1809+ case FSACTL_FORCE_DELETE_DISK:
1810+ Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1811+ break;
1812+
1813+ case 2131:
1814+ if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1815+ Status = -EFAULT;
1816+ break;
1817+
1818+ default:
1819+ Handled = FALSE;
1820+ break;
1821+ }
1822+
1823+ *ReturnStatus = Status;
1824+
1825+ return( Handled );
1826+}
1827+
1828+
1829+/*------------------------------------------------------------------------------
1830+ AacHba_QueryDisk()
1831+
1832+ Postconditions:
1833+ Return values
1834+ 0 = OK
1835+ -EFAULT = Bad address
1836+ -EINVAL = Bad container number
1837+ *----------------------------------------------------------------------------*/
1838+int AacHba_QueryDisk(
1839+ PVOID AdapterArg, // CommonExtensionPtr
1840+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
1841+/*----------------------------------------------------------------------------*/
1842+{
1843+ UNIX_QUERY_DISK QueryDisk;
1844+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1845+ fsadev_t *fsa_dev_ptr;
1846+
1847+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1848+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1849+
1850+ if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1851+ return( -EFAULT );
1852+
1853+ if (QueryDisk.ContainerNumber == -1)
1854+ QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1855+ else
1856+ if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1857+ {
1858+ if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1859+ return( -EINVAL );
1860+
1861+ QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1862+ QueryDisk.Bus = 0;
1863+ QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1864+ QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1865+ }
1866+ else
1867+ return( -EINVAL );
1868+
1869+ QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1870+ QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1871+ QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1872+
1873+ if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1874+ QueryDisk.UnMapped = TRUE;
1875+ else
1876+ QueryDisk.UnMapped = FALSE;
1877+
1878+ get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1879+ QueryDisk.diskDeviceName );
1880+
1881+ if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1882+ return( -EFAULT );
1883+
1884+ return( 0 );
1885+}
1886+
1887+
1888+/*------------------------------------------------------------------------------
1889+ get_sd_devname()
1890+ *----------------------------------------------------------------------------*/
1891+static void get_sd_devname(
1892+ long disknum,
1893+ char * buffer)
1894+/*----------------------------------------------------------------------------*/
1895+{
1896+ if( disknum < 0 )
1897+ {
1898+ sprintf(buffer, "%s", "");
1899+ return;
1900+ }
1901+
1902+ if( disknum < 26 )
1903+ sprintf(buffer, "sd%c", 'a' + disknum);
1904+ else {
1905+ unsigned int min1;
1906+ unsigned int min2;
1907+ /*
1908+ * For larger numbers of disks, we need to go to a new
1909+ * naming scheme.
1910+ */
1911+ min1 = disknum / 26;
1912+ min2 = disknum % 26;
1913+ sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1914+ }
1915+}
1916+
1917+
1918+/*------------------------------------------------------------------------------
1919+ AacHba_ForceDeleteDisk()
1920+
1921+ Postconditions:
1922+ Return values
1923+ 0 = OK
1924+ -EFAULT = Bad address
1925+ -EINVAL = Bad container number
1926+ *----------------------------------------------------------------------------*/
1927+int AacHba_ForceDeleteDisk(
1928+ PVOID AdapterArg, // CommonExtensionPtr
1929+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
1930+/*----------------------------------------------------------------------------*/
1931+{
1932+ DELETE_DISK DeleteDisk;
1933+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1934+ fsadev_t *fsa_dev_ptr;
1935+
1936+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1937+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1938+
1939+ if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
1940+ return( -EFAULT );
1941+
1942+ if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1943+ return( -EINVAL );
1944+
1945+ // Mark this container as being deleted.
1946+ fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
1947+
1948+ // Mark the container as no longer valid
1949+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1950+
1951+ return( 0 );
1952+}
1953+
1954+
1955+/*------------------------------------------------------------------------------
1956+ AacHba_DeleteDisk()
1957+
1958+ Postconditions:
1959+ Return values
1960+ 0 = OK
1961+ -EFAULT = Bad address
1962+ -EINVAL = Bad container number
1963+ -EBUSY = Device locked
1964+ *----------------------------------------------------------------------------*/
1965+int AacHba_DeleteDisk(
1966+ PVOID AdapterArg,
1967+ IN PAFA_IOCTL_CMD IoctlCmdPtr )
1968+/*----------------------------------------------------------------------------*/
1969+{
1970+ DELETE_DISK DeleteDisk;
1971+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1972+ fsadev_t *fsa_dev_ptr;
1973+
1974+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1975+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1976+
1977+ if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
1978+ return( -EFAULT );
1979+
1980+ if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1981+ return( -EINVAL );
1982+
1983+ // If the container is locked, it can not be deleted by the API.
1984+ if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
1985+ return( -EBUSY );
1986+ else
1987+ {
1988+ // Mark the container as no longer being valid.
1989+ fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1990+ fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
1991+ return(0);
1992+ }
1993+}
1994+
1995+
1996+/*------------------------------------------------------------------------------
1997+ AacHba_OpenAdapter()
1998+ *----------------------------------------------------------------------------*/
1999+AAC_STATUS AacHba_OpenAdapter(
2000+ IN PVOID AdapterArg )
2001+/*----------------------------------------------------------------------------*/
2002+{
2003+ return( STATUS_SUCCESS );
2004+}
2005+
2006+
2007+/*------------------------------------------------------------------------------
2008+ AacHba_CloseAdapter()
2009+ *----------------------------------------------------------------------------*/
2010+AAC_STATUS AacHba_CloseAdapter(
2011+ IN PVOID AdapterArg )
2012+/*----------------------------------------------------------------------------*/
2013+{
2014+ return( STATUS_SUCCESS );
2015+}
2016+
2017+
2018+/*------------------------------------------------------------------------------
2019+ AacHba_DetachAdapter()
2020+ *----------------------------------------------------------------------------*/
2021+void AacHba_DetachAdapter(
2022+ IN PVOID AdapterArg )
2023+/*----------------------------------------------------------------------------*/
2024+{
2025+ AacCommDetachAdapter( AdapterArg );
2026+}
2027+
2028+
2029+/*------------------------------------------------------------------------------
2030+ AacHba_AbortScsiCommand()
2031+ *----------------------------------------------------------------------------*/
2032+void AacHba_AbortScsiCommand(
2033+ Scsi_Cmnd *scsi_cmnd_ptr )
2034+/*----------------------------------------------------------------------------*/
2035+{
2036+ u_short interrupt_status;
2037+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2038+
2039+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2040+ interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2041+ DoorbellReg_p );
2042+ cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2043+
2044+ if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2045+ cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2046+ }
2047+
2048+ if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2049+ cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2050+ }
2051+
2052+ if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2053+ cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2054+ }
2055+
2056+ if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2057+ cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2058+ }
2059+
2060+}
2061+
2062+
2063+/*------------------------------------------------------------------------------
2064+ AacHba_HandleAif()
2065+ *----------------------------------------------------------------------------*/
2066+BOOLEAN AacHba_HandleAif(
2067+ IN PVOID AdapterArg,
2068+ IN PFIB_CONTEXT FibContext )
2069+/*----------------------------------------------------------------------------*/
2070+{
2071+ return( FALSE );
2072+}
2073+
2074+
2075+/*------------------------------------------------------------------------------
2076+ AacHba_SetSenseData()
2077+ Fill in the sense data.
2078+ Preconditions:
2079+ Postconditions:
2080+ *----------------------------------------------------------------------------*/
2081+void AacHba_SetSenseData(
2082+ char * sense_buf,
2083+ unchar sense_key,
2084+ unchar sense_code,
2085+ unchar a_sense_code,
2086+ unchar incorrect_length,
2087+ unchar bit_pointer,
2088+ unsigned field_pointer,
2089+ unsigned long residue )
2090+/*----------------------------------------------------------------------------*/
2091+{
2092+ sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2093+ sense_buf[1] = 0; // Segment number, always zero
2094+
2095+ if( incorrect_length )
2096+ {
2097+ sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2098+ sense_buf[3] = BYTE3(residue);
2099+ sense_buf[4] = BYTE2(residue);
2100+ sense_buf[5] = BYTE1(residue);
2101+ sense_buf[6] = BYTE0(residue);
2102+ }
2103+ else
2104+ sense_buf[2] = sense_key; // Sense key
2105+
2106+ if( sense_key == SENKEY_ILLEGAL )
2107+ sense_buf[7] = 10; // Additional sense length
2108+ else
2109+ sense_buf[7] = 6; // Additional sense length
2110+
2111+ sense_buf[12] = sense_code; // Additional sense code
2112+ sense_buf[13] = a_sense_code; // Additional sense code qualifier
2113+ if( sense_key == SENKEY_ILLEGAL )
2114+ {
2115+ sense_buf[15] = 0;
2116+
2117+ if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2118+ sense_buf[15] = 0x80; // Std sense key specific field
2119+ // Illegal parameter is in the parameter block
2120+
2121+ if( sense_code == SENCODE_INVALID_CDB_FIELD )
2122+ sense_buf[15] = 0xc0; // Std sense key specific field
2123+ // Illegal parameter is in the CDB block
2124+ sense_buf[15] |= bit_pointer;
2125+ sense_buf[16] = field_pointer >> 8; // MSB
2126+ sense_buf[17] = field_pointer; // LSB
2127+ }
2128+}
2129+
2130diff -urN linux/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2131--- linux/drivers/scsi/aacraid/aacid.c Wed Dec 31 19:00:00 1969
2132+++ linux/drivers/scsi/aacraid/aacid.c Thu Dec 21 13:14:30 2000
2133@@ -0,0 +1,153 @@
2134+/*++
2135+ * Adaptec aacraid device driver for Linux.
2136+ *
2137+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2138+ *
2139+ * This program is free software; you can redistribute it and/or modify
2140+ * it under the terms of the GNU General Public License as published by
2141+ * the Free Software Foundation; either version 2, or (at your option)
2142+ * any later version.
2143+ *
2144+ * This program is distributed in the hope that it will be useful,
2145+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2146+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2147+ * GNU General Public License for more details.
2148+ *
2149+ * You should have received a copy of the GNU General Public License
2150+ * along with this program; see the file COPYING. If not, write to
2151+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2152+ *
2153+ * Module Name:
2154+ * aac.c
2155+ *
2156+ * Abstract: Data structures for controller specific info.
2157+ *
2158+--*/
2159+
2160+static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2161+
2162+#include "osheaders.h"
2163+
2164+#include "AacGenericTypes.h"
2165+
2166+#include "aac_unix_defs.h"
2167+
2168+#include "fsatypes.h"
2169+#include "comstruc.h"
2170+#include "fsaport.h"
2171+#include "pcisup.h"
2172+
2173+#include "version.h"
2174+
2175+
2176+/* Function Prototypes */
2177+void InqStrCopy(char *a, char *b); /* ossup.c */
2178+
2179+/* Device name used to register and unregister
2180+ the device in linit.c */
2181+char devicestr[]="aac";
2182+
2183+char *container_types[] = {
2184+ "None",
2185+ "Volume",
2186+ "Mirror",
2187+ "Stripe",
2188+ "RAID5",
2189+ "SSRW",
2190+ "SSRO",
2191+ "Morph",
2192+ "Legacy",
2193+ "RAID4",
2194+ "RAID10",
2195+ "RAID00",
2196+ "V-MIRRORS",
2197+ "PSEUDO R4",
2198+ "RAID50",
2199+ "Unknown"
2200+};
2201+
2202+/* Local Structure to set SCSI inquiry data strings */
2203+typedef struct _INQSTR {
2204+ char vid[8]; /* Vendor ID */
2205+ char pid[16]; /* Product ID */
2206+ char prl[4]; /* Product Revision Level */
2207+} INQSTR, *INQSTRP;
2208+
2209+FSA_MINIPORT MiniPorts[];
2210+
2211+/* Function: SetInqDataStr
2212+ *
2213+ * Arguments: [1] pointer to void [1] int
2214+ *
2215+ * Purpose: Sets SCSI inquiry data strings for vendor, product
2216+ * and revision level. Allows strings to be set in platform dependant
2217+ * files instead of in OS dependant driver source.
2218+ */
2219+void
2220+SetInqDataStr (
2221+ int MiniPortIndex,
2222+ void *dataPtr,
2223+ int tindex)
2224+{
2225+ INQSTRP InqStrPtr;
2226+ char *findit;
2227+ FSA_MINIPORT *mp;
2228+
2229+ mp = &MiniPorts[MiniPortIndex];
2230+
2231+ InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2232+
2233+ InqStrCopy (mp->Vendor, InqStrPtr->vid);
2234+ InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2235+
2236+ findit = InqStrPtr->pid;
2237+
2238+ for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2239+ findit++;
2240+
2241+ if (tindex < (sizeof(container_types)/sizeof(char *))){
2242+ InqStrCopy (container_types[tindex], findit);
2243+ }
2244+ InqStrCopy ("0001", InqStrPtr->prl);
2245+}
2246+
2247+int
2248+SaInitDevice(
2249+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2250+ IN ULONG AdapterNumber,
2251+ IN ULONG PciBus,
2252+ IN ULONG PciSlot
2253+);
2254+
2255+int
2256+RxInitDevice(
2257+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2258+ IN ULONG AdapterNumber,
2259+ IN ULONG PciBus,
2260+ IN ULONG PciSlot
2261+);
2262+
2263+
2264+/*
2265+ * Because of the way Linux names scsi devices, the order in this table has
2266+ * become important. Check for on-board Raid first, add-in cards second.
2267+ */
2268+
2269+FSA_MINIPORT MiniPorts[] = {
2270+ { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2271+ { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2272+ { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2273+ { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2274+ { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2275+ { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2276+ { 0x1028, 0x0008, 0x1028, 0x00cf, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2277+ { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel */
2278+ { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2279+};
2280+
2281+
2282+#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2283+
2284+int NumMiniPorts = NUM_MINIPORTS;
2285+
2286+char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2287diff -urN linux/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2288--- linux/drivers/scsi/aacraid/commctrl.c Wed Dec 31 19:00:00 1969
2289+++ linux/drivers/scsi/aacraid/commctrl.c Thu Dec 21 13:14:30 2000
2290@@ -0,0 +1,1098 @@
2291+/*++
2292+ * Adaptec aacraid device driver for Linux.
2293+ *
2294+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2295+ *
2296+ * This program is free software; you can redistribute it and/or modify
2297+ * it under the terms of the GNU General Public License as published by
2298+ * the Free Software Foundation; either version 2, or (at your option)
2299+ * any later version.
2300+ *
2301+ * This program is distributed in the hope that it will be useful,
2302+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2303+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2304+ * GNU General Public License for more details.
2305+ *
2306+ * You should have received a copy of the GNU General Public License
2307+ * along with this program; see the file COPYING. If not, write to
2308+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2309+ *
2310+ * Module Name:
2311+ * commctrl.c
2312+ *
2313+ * Abstract: Contains all routines for control of the AFA comm layer
2314+ *
2315+--*/
2316+
2317+static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2318+
2319+#include "comprocs.h"
2320+#include "osheaders.h"
2321+#include "ostypes.h"
2322+
2323+
2324+
2325+
2326+
2327+typedef BOOLEAN BOOL;
2328+#define inline /* _inline */
2329+
2330+#include <revision.h>
2331+AAC_STATUS
2332+FsaCtlCheckRevision(
2333+ IN PAFA_COMM_ADAPTER Adapter,
2334+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2335+ )
2336+/*++
2337+
2338+Routine Description:
2339+
2340+ This routine validates the revision of the caller with the current revision
2341+ of the filesystem.
2342+
2343+Arguments:
2344+
2345+ Adapter - Supplies which adapter is being processed.
2346+
2347+ Irp - Supplies the Irp being processed.
2348+
2349+ IrpContext - Supplies the IrpContext.
2350+
2351+Return Value:
2352+
2353+ AAC_STATUS
2354+
2355+--*/
2356+
2357+{
2358+ RevCheck APIRevCheck;
2359+ RevCheckResp APIRevCheckResp;
2360+ RevComponent APICallingComponent;
2361+ ULONG APIBuildNumber;
2362+
2363+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2364+ return (EFAULT);
2365+ }
2366+
2367+ APICallingComponent = APIRevCheck.callingComponent;
2368+ APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2369+
2370+ APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2371+
2372+ APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2373+ APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2374+
2375+ if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2376+ return (EFAULT);
2377+ }
2378+
2379+ return (0);
2380+}
2381+
2382+
2383+int
2384+AfaCommAdapterDeviceControl(
2385+ IN PVOID AdapterArg,
2386+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2387+ )
2388+{
2389+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2390+ int Status = ENOTTY;
2391+// PIO_STACK_LOCATION IrpSp;
2392+ PAFA_CLASS_DRIVER ClassDriver;
2393+
2394+ //
2395+ // First loop through all of the class drivers to give them a chance to handle
2396+ // the Device control first.
2397+ //
2398+
2399+ ClassDriver = Adapter->ClassDriverList;
2400+
2401+ while (ClassDriver) {
2402+
2403+ if (ClassDriver->DeviceControl) {
2404+
2405+ if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2406+
2407+ return (Status);
2408+
2409+ }
2410+ }
2411+
2412+ ClassDriver = ClassDriver->Next;
2413+ }
2414+
2415+ switch (IoctlCmdPtr->cmd) {
2416+
2417+
2418+ case FSACTL_SENDFIB:
2419+
2420+ Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2421+ break;
2422+
2423+ case FSACTL_AIF_THREAD:
2424+
2425+ Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2426+ break;
2427+
2428+
2429+ case FSACTL_OPEN_GET_ADAPTER_FIB:
2430+
2431+ Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2432+ break;
2433+
2434+ case FSACTL_GET_NEXT_ADAPTER_FIB:
2435+
2436+ Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2437+ break;
2438+
2439+ case FSACTL_CLOSE_GET_ADAPTER_FIB:
2440+
2441+ Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2442+ break;
2443+
2444+ case FSACTL_MINIPORT_REV_CHECK:
2445+
2446+ Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2447+ break;
2448+
2449+
2450+ default:
2451+
2452+ Status = ENOTTY;
2453+ break;
2454+
2455+ }
2456+
2457+
2458+ return (Status);
2459+}
2460+
2461+AAC_STATUS
2462+AfaCommRegisterNewClassDriver(
2463+ IN PAFA_COMM_ADAPTER Adapter,
2464+ IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2465+ OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2466+ )
2467+/*++
2468+
2469+Routine Description:
2470+
2471+ This routine registers a new class driver for the comm layer.
2472+
2473+ It will return a pointer to the communication functions for the class driver
2474+ to use.
2475+
2476+Arguments:
2477+
2478+ Adapter - Supplies which adapter is being processed.
2479+
2480+ Irp - Supplies the Irp being processed.
2481+
2482+Return Value:
2483+
2484+ STATUS_SUCCESS - Everything OK.
2485+
2486+--*/
2487+{
2488+ AAC_STATUS Status;
2489+ PAFA_CLASS_DRIVER ClassDriver;
2490+
2491+
2492+ ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2493+
2494+ if (ClassDriver == NULL) {
2495+
2496+ Status = STATUS_INSUFFICIENT_RESOURCES;
2497+
2498+ return Status;
2499+ }
2500+
2501+ //
2502+ // If the class driver has sent in user Vars, then copy them into the global
2503+ // area.
2504+ //
2505+
2506+ if (NewClassDriver->NumUserVars) {
2507+
2508+ PFSA_USER_VAR NewUserVars;
2509+
2510+ NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2511+ NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2512+
2513+ //
2514+ // First copy the existing into the new area.
2515+ //
2516+
2517+ RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2518+
2519+ //
2520+ // Next copy the new vars passed in from class driver.
2521+ //
2522+
2523+ RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2524+ NewClassDriver->UserVars,
2525+ NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2526+
2527+ //
2528+ // Free up the old user vars.
2529+ //
2530+
2531+ OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2532+
2533+ //
2534+ // Point the global to the new area.
2535+ //
2536+
2537+ FsaCommData.UserVars = NewUserVars;
2538+
2539+ //
2540+ // Update the total count.
2541+ //
2542+
2543+ FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2544+
2545+ }
2546+
2547+ ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2548+ ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2549+ ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2550+ ClassDriver->HandleAif = NewClassDriver->HandleAif;
2551+ ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2552+
2553+ ClassDriver->Next = Adapter->ClassDriverList;
2554+ Adapter->ClassDriverList = ClassDriver;
2555+
2556+ //
2557+ // Now return the information needed by the class driver to communicate to us.
2558+ //
2559+
2560+ NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2561+ NewClassDriverResponse->CommPortExtension = Adapter;
2562+ NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2563+ NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2564+ NewClassDriverResponse->Dip = Adapter->Dip;
2565+
2566+ return (STATUS_SUCCESS);
2567+
2568+
2569+}
2570+
2571+int
2572+AfaCommCtlSendFib(
2573+ IN PAFA_COMM_ADAPTER Adapter,
2574+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2575+)
2576+/*++
2577+
2578+Routine Description:
2579+
2580+ This routine sends a fib to the adapter on behalf of a user level
2581+ program.
2582+
2583+Arguments:
2584+
2585+ Adapter - Supplies which adapter is being processed.
2586+
2587+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2588+
2589+Return Value:
2590+
2591+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2592+
2593+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2594+
2595+ STATUS_SUCCESS - Everything OK.
2596+
2597+--*/
2598+{
2599+ PFIB KFib;
2600+// PMDL DmaMdl = NULL;
2601+ PCOMM_FIB_CONTEXT FibContext;
2602+ PSGMAP_CONTEXT SgMapContext;
2603+ SGMAP_CONTEXT _SgMapContext;
2604+ QUEUE_TYPES WhichQueue;
2605+ PVOID UsersAddress;
2606+ AAC_STATUS Status;
2607+
2608+ FibContext = AllocateFib( Adapter );
2609+
2610+ KFib = FibContext->Fib;
2611+
2612+ //
2613+ // First copy in the header so that we can check the size field.
2614+ //
2615+
2616+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2617+ FreeFib( FibContext );
2618+ Status = EFAULT;
2619+ return (Status);
2620+ }
2621+
2622+ //
2623+ // Since we copy based on the fib header size, make sure that we
2624+ // will not overrun the buffer when we copy the memory. Return
2625+ // an error if we would.
2626+ //
2627+
2628+ if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2629+ FreeFib( FibContext );
2630+ Status = EINVAL;
2631+ return Status;
2632+
2633+ }
2634+
2635+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2636+ FreeFib( FibContext );
2637+ Status = EFAULT;
2638+ return (Status);
2639+ }
2640+
2641+ WhichQueue = AdapNormCmdQueue;
2642+
2643+
2644+ if (KFib->Header.Command == TakeABreakPt) {
2645+
2646+ InterruptAdapter(Adapter);
2647+
2648+ //
2649+ // Since we didn't really send a fib, zero out the state to allow
2650+ // cleanup code not to assert.
2651+ //
2652+
2653+ KFib->Header.XferState = 0;
2654+
2655+
2656+ } else {
2657+
2658+ if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2659+ TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2660+ FsaCommPrint("User SendFib failed!.\n");
2661+
2662+
2663+ FreeFib( FibContext );
2664+ return (ENXIO);
2665+ }
2666+
2667+ if (CompleteFib(FibContext) != FSA_SUCCESS) {
2668+ FsaCommPrint("User Complete FIB failed.\n");
2669+
2670+ FreeFib( FibContext );
2671+ return (ENXIO);
2672+ }
2673+
2674+
2675+ }
2676+
2677+
2678+ //
2679+ // Make sure that the size returned by the adapter (which includes
2680+ // the header) is less than or equal to the size of a fib, so we
2681+ // don't corrupt application data. Then copy that size to the user
2682+ // buffer. (Don't try to add the header information again, since it
2683+ // was already included by the adapter.)
2684+ //
2685+ ASSERT(KFib->Header.Size <= sizeof(FIB));
2686+
2687+ if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2688+ FreeFib( FibContext );
2689+ Status = EFAULT;
2690+ return (Status);
2691+ }
2692+
2693+ FreeFib( FibContext );
2694+
2695+ return (0);
2696+
2697+}
2698+
2699+int
2700+AfaCommCtlAifThread(
2701+ IN PAFA_COMM_ADAPTER Adapter,
2702+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2703+)
2704+/*++
2705+
2706+Routine Description:
2707+
2708+ This routine will act as the AIF thread for this adapter.
2709+
2710+Arguments:
2711+
2712+ Adapter - Supplies which adapter is being processed.
2713+
2714+ IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2715+
2716+Return Value:
2717+
2718+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2719+
2720+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2721+
2722+ STATUS_SUCCESS - Everything OK.
2723+
2724+--*/
2725+{
2726+ return (NormCommandThread(Adapter));
2727+}
2728+
2729+
2730+
2731+#ifdef GATHER_FIB_TIMES
2732+AAC_STATUS
2733+AfaCommGetFibTimes(
2734+ IN PAFA_COMM_ADAPTER Adapter,
2735+ IN PIRP Irp
2736+ )
2737+/*++
2738+
2739+Routine Description:
2740+
2741+ This routine returns the gathered fibtimes to the user.
2742+
2743+Arguments:
2744+
2745+ Adapter - Supplies which adapter is being processed.
2746+
2747+ Irp - Supplies the Irp being processed.
2748+
2749+Return Value:
2750+
2751+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2752+
2753+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2754+
2755+ STATUS_SUCCESS - Everything OK.
2756+
2757+--*/
2758+{
2759+ PALL_FIB_TIMES AllFibTimes;
2760+ PLARGE_INTEGER FreqPtr;
2761+ PIO_STACK_LOCATION IrpSp;
2762+
2763+ //
2764+ // Get a pointer to the current Irp stack location
2765+ //
2766+
2767+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2768+
2769+ FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2770+
2771+ *FreqPtr = Adapter->FibTimesFrequency;
2772+
2773+ AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2774+
2775+ RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2776+
2777+ Irp->IoStatus.Information = 0;
2778+
2779+ return (STATUS_SUCCESS);
2780+
2781+}
2782+
2783+AAC_STATUS
2784+AfaCommZeroFibTimes(
2785+ IN PAFA_COMM_ADAPTER Adapter,
2786+ IN PIRP Irp
2787+ )
2788+/*++
2789+
2790+Routine Description:
2791+
2792+ This routine zero's the FibTimes structure within the adapter structure.
2793+
2794+Arguments:
2795+
2796+ Adapter - Supplies which adapter is being processed.
2797+
2798+ Irp - Supplies the Irp being processed.
2799+
2800+Return Value:
2801+
2802+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2803+
2804+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2805+
2806+ STATUS_SUCCESS - Everything OK.
2807+
2808+--*/
2809+{
2810+ PFIB_TIMES FibTimesPtr;
2811+ int i;
2812+ PIO_STACK_LOCATION IrpSp;
2813+
2814+ //
2815+ // Get a pointer to the current Irp stack location
2816+ //
2817+
2818+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
2819+
2820+ //
2821+ // Initialize the Fib timing data structures
2822+ //
2823+ RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2824+
2825+ for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2826+
2827+ FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2828+
2829+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2830+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2831+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2832+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2833+ }
2834+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2835+
2836+ FibTimesPtr = &Adapter->FibTimes->Read[i];
2837+
2838+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2839+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2840+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2841+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2842+ }
2843+ for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2844+
2845+ FibTimesPtr = &Adapter->FibTimes->Write[i];
2846+
2847+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2848+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2849+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2850+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2851+ }
2852+
2853+ FibTimesPtr = &Adapter->FibTimes->Other;
2854+
2855+ FibTimesPtr->Minimum.LowPart = 0xffffffff;
2856+ FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2857+ FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2858+ FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2859+
2860+ Irp->IoStatus.Information = 0;
2861+
2862+ return (STATUS_SUCCESS);
2863+
2864+}
2865+#endif // GATHER_FIB_TIMES
2866+
2867+#ifndef unix_aif
2868+int
2869+FsaCtlOpenGetAdapterFib(
2870+ IN PAFA_COMM_ADAPTER Adapter,
2871+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2872+ )
2873+/*++
2874+
2875+Routine Description:
2876+
2877+ This routine will get the next Fib, if available, from the AdapterFibContext
2878+ passed in from the user.
2879+
2880+Arguments:
2881+
2882+ Adapter - Supplies which adapter is being processed.
2883+
2884+ Irp - Supplies the Irp being processed.
2885+
2886+Return Value:
2887+
2888+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2889+
2890+ STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2891+
2892+ STATUS_SUCCESS - Everything OK.
2893+
2894+--*/
2895+{
2896+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2897+// HANDLE Event;
2898+// PKEVENT eventObject = (PKEVENT) NULL;
2899+ int Status;
2900+
2901+ //
2902+ // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2903+ //
2904+
2905+ AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2906+
2907+ if (AdapterFibContext == NULL) {
2908+
2909+ Status = ENOMEM;
2910+
2911+ } else {
2912+
2913+ AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2914+ AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2915+
2916+
2917+ //
2918+ // Initialize the conditional variable use to wait for the next AIF.
2919+ //
2920+
2921+ OsCv_init( &AdapterFibContext->UserEvent);
2922+
2923+ //
2924+ // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
2925+ //
2926+
2927+ AdapterFibContext->WaitingForFib = FALSE;
2928+
2929+ //
2930+ // Initialize the FibList and set the count of fibs on the list to 0.
2931+ //
2932+
2933+ AdapterFibContext->FibCount = 0;
2934+ InitializeListHead(&AdapterFibContext->FibList);
2935+
2936+ //
2937+ // Overload FileObject with a time stamp.
2938+ //
2939+ AdapterFibContext->FileObject = (void *)OsGetSeconds();
2940+
2941+ //
2942+ // Now add this context onto the adapter's AdapterFibContext list.
2943+ //
2944+
2945+ OsCvLockAcquire(Adapter->AdapterFibMutex);
2946+
2947+ InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
2948+
2949+ OsCvLockRelease(Adapter->AdapterFibMutex);
2950+
2951+ if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
2952+ IoctlCmdPtr->flag )) {
2953+
2954+ Status = EFAULT;
2955+
2956+ } else {
2957+
2958+ Status = 0;
2959+
2960+ }
2961+
2962+ }
2963+
2964+ return (Status);
2965+}
2966+
2967+int
2968+FsaCtlGetNextAdapterFib(
2969+ IN PAFA_COMM_ADAPTER Adapter,
2970+ IN PAFA_IOCTL_CMD IoctlCmdPtr
2971+ )
2972+/*++
2973+
2974+Routine Description:
2975+
2976+ This routine will get the next Fib, if available, from the AdapterFibContext
2977+ passed in from the user.
2978+
2979+Arguments:
2980+
2981+ Adapter - Supplies which adapter is being processed.
2982+
2983+ Irp - Supplies the Irp being processed.
2984+
2985+Return Value:
2986+
2987+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2988+
2989+ STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
2990+
2991+ STATUS_SUCCESS - Everything OK.
2992+
2993+--*/
2994+{
2995+ GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
2996+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
2997+ PFIB Fib;
2998+ int Status;
2999+ PLIST_ENTRY Entry;
3000+ int found;
3001+
3002+ if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3003+ sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3004+ return (EFAULT);
3005+ }
3006+
3007+ //
3008+ // Extract the AdapterFibContext from the Input parameters.
3009+ //
3010+
3011+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3012+
3013+ //
3014+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3015+ //
3016+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3017+ // this is a valid address
3018+
3019+ found = 0;
3020+ Entry = Adapter->AdapterFibContextList.Flink;
3021+
3022+ while ( Entry != &Adapter->AdapterFibContextList ) {
3023+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3024+ if ( AdapterFibContext == aifcp ) { // We found a winner
3025+ found = 1;
3026+ break;
3027+ }
3028+ Entry = Entry->Flink;
3029+ }
3030+
3031+ if ( found == 0 ) {
3032+ return ( EINVAL );;
3033+ }
3034+
3035+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3036+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3037+
3038+ return ( EINVAL );
3039+
3040+ }
3041+
3042+ Status = STATUS_SUCCESS;
3043+
3044+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3045+
3046+ //
3047+ // If there are no fibs to send back, then either wait or return EAGAIN
3048+ //
3049+return_fib:
3050+
3051+ if (!IsListEmpty(&AdapterFibContext->FibList)) {
3052+
3053+ PLIST_ENTRY Entry;
3054+
3055+ //
3056+ // Pull the next fib from the FibList
3057+ //
3058+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3059+
3060+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3061+
3062+ AdapterFibContext->FibCount--;
3063+
3064+ if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3065+
3066+ OsCvLockRelease( Adapter->AdapterFibMutex );
3067+ OsFreeMemory( Fib, sizeof(Fib) );
3068+ return (EFAULT);
3069+
3070+ }
3071+
3072+ //
3073+ // Free the space occupied by this copy of the fib.
3074+ //
3075+
3076+ OsFreeMemory(Fib, sizeof(FIB));
3077+
3078+ Status = 0;
3079+
3080+ //
3081+ // Overload FileObject with a time stamp
3082+ //
3083+ AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3084+
3085+ } else {
3086+
3087+ if (AdapterFibIoctl.Wait) {
3088+
3089+ if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3090+
3091+ Status = EINTR;
3092+
3093+ } else {
3094+
3095+ goto return_fib;
3096+
3097+ }
3098+ } else {
3099+
3100+ Status = EAGAIN;
3101+
3102+ }
3103+
3104+ }
3105+ OsCvLockRelease( Adapter->AdapterFibMutex );
3106+
3107+ return (Status);
3108+}
3109+
3110+int
3111+FsaCtlCloseGetAdapterFib(
3112+ IN PAFA_COMM_ADAPTER Adapter,
3113+ IN PAFA_IOCTL_CMD IoctlCmdPtr
3114+ )
3115+/*++
3116+
3117+Routine Description:
3118+
3119+ This routine will close down the AdapterFibContext passed in from the user.
3120+
3121+Arguments:
3122+
3123+ Adapter - Supplies which adapter is being processed.
3124+
3125+ Irp - Supplies the Irp being processed.
3126+
3127+Return Value:
3128+
3129+ STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3130+
3131+ STATUS_SUCCESS - Everything OK.
3132+
3133+--*/
3134+{
3135+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3136+ AAC_STATUS Status;
3137+
3138+ PLIST_ENTRY Entry;
3139+ int found;
3140+
3141+ //
3142+ // Extract the AdapterFibContext from the Input parameters
3143+ //
3144+
3145+ AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3146+
3147+ if (AdapterFibContext == 0) {
3148+ cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3149+ return(EINVAL);
3150+ }
3151+
3152+ //
3153+ // Verify that the HANDLE passed in was a valid AdapterFibContext
3154+ //
3155+ // Search the list of AdapterFibContext addresses on the adapter to be sure
3156+ // this is a valid address
3157+
3158+ found = 0;
3159+ Entry = Adapter->AdapterFibContextList.Flink;
3160+
3161+ while ( Entry != &Adapter->AdapterFibContextList ) {
3162+ aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3163+ if ( AdapterFibContext == aifcp ) { // We found a winner
3164+ found = 1;
3165+ break;
3166+ }
3167+ Entry = Entry->Flink;
3168+ }
3169+
3170+ if ( found == 0 ) {
3171+ return ( 0 ); // Already Gone
3172+ }
3173+
3174+ if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3175+ (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3176+
3177+ return (EINVAL);
3178+
3179+ }
3180+
3181+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3182+
3183+ Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3184+
3185+ OsCvLockRelease(Adapter->AdapterFibMutex);
3186+
3187+ return (Status);
3188+}
3189+
3190+int
3191+FsaCloseAdapterFibContext(
3192+ IN PAFA_COMM_ADAPTER Adapter,
3193+ IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3194+ )
3195+{
3196+ int Status;
3197+ PFIB Fib;
3198+
3199+ //
3200+ // First free any FIBs that have not been consumed yet.
3201+ //
3202+
3203+ while (!IsListEmpty(&AdapterFibContext->FibList)) {
3204+
3205+ PLIST_ENTRY Entry;
3206+
3207+ //
3208+ // Pull the next fib from the FibList
3209+ //
3210+
3211+ Entry = RemoveHeadList(&AdapterFibContext->FibList);
3212+
3213+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3214+
3215+ AdapterFibContext->FibCount--;
3216+
3217+ //
3218+ // Free the space occupied by this copy of the fib.
3219+ //
3220+
3221+ OsFreeMemory(Fib, sizeof(FIB));
3222+ }
3223+
3224+ //
3225+ // Remove the Context from the AdapterFibContext List
3226+ //
3227+
3228+ RemoveEntryList(&AdapterFibContext->NextContext);
3229+
3230+ OsCv_destroy( &AdapterFibContext->UserEvent );
3231+
3232+ //
3233+ // Invalidate context
3234+ //
3235+
3236+ AdapterFibContext->NodeTypeCode = 0;
3237+
3238+ //
3239+ // Free the space occupied by the Context
3240+ //
3241+
3242+ OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3243+
3244+ Status = STATUS_SUCCESS;
3245+
3246+ return Status;
3247+}
3248+#endif
3249+
3250+AAC_STATUS
3251+AfaCommOpenAdapter(
3252+ IN PVOID Arg
3253+ )
3254+/*++
3255+
3256+Routine Description:
3257+
3258+ The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3259+ for the adapter.
3260+
3261+ The main purpose of this routine is to set up any data structures that may be needed
3262+ to handle any requests made on this DeviceObject.
3263+
3264+Arguments:
3265+
3266+ Adapter - Pointer to which adapter miniport was opened.
3267+
3268+
3269+Return Value:
3270+
3271+ STATUS_SUCCESS
3272+
3273+--*/
3274+
3275+{
3276+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3277+ AAC_STATUS Status = STATUS_SUCCESS;
3278+ PAFA_CLASS_DRIVER ClassDriver;
3279+
3280+ ClassDriver = Adapter->ClassDriverList;
3281+
3282+ while (ClassDriver) {
3283+
3284+ if (ClassDriver->OpenAdapter) {
3285+
3286+ Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3287+
3288+ if (Status != STATUS_SUCCESS)
3289+ break;
3290+ }
3291+
3292+ ClassDriver = ClassDriver->Next;
3293+ }
3294+
3295+ return ( Status );
3296+}
3297+
3298+AAC_STATUS
3299+AfaCommCloseAdapter(
3300+ IN PVOID Arg
3301+ )
3302+/*++
3303+
3304+Routine Description:
3305+
3306+ This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3307+ for the adapter.
3308+
3309+ The main purpose of this routine is to cleanup any data structures that have been set up
3310+ while this FileObject has been opened.
3311+
3312+ This routine loops through all of the AdapterFibContext structures to determine if any need
3313+ to be deleted for this FileObject.
3314+
3315+Arguments:
3316+
3317+ Adapter - Pointer to adapter miniport
3318+
3319+ Irp - Pointer to Irp that caused this close
3320+
3321+Return Value:
3322+
3323+ Status value returned from File system driver AdapterClose
3324+
3325+--*/
3326+{
3327+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3328+ PLIST_ENTRY Entry, NextEntry;
3329+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3330+ AAC_STATUS Status = STATUS_SUCCESS;
3331+ PAFA_CLASS_DRIVER ClassDriver;
3332+
3333+ OsCvLockAcquire(Adapter->AdapterFibMutex);
3334+
3335+ Entry = Adapter->AdapterFibContextList.Flink;
3336+
3337+ //
3338+ // Loop through all of the AdapterFibContext, looking for any that
3339+ // were created with the FileObject that is being closed.
3340+ //
3341+ while (Entry != &Adapter->AdapterFibContextList) {
3342+
3343+ //
3344+ // Extract the AdapterFibContext
3345+ //
3346+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3347+
3348+ //
3349+ // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3350+ //
3351+ NextEntry = Entry->Flink;
3352+
3353+ Entry = NextEntry;
3354+
3355+ }
3356+
3357+#ifdef unix_config_file
3358+ //
3359+ // If this FileObject had the adapter open for configuration, then release it.
3360+ //
3361+ if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3362+
3363+ Adapter->AdapterConfigFileObject = NULL;
3364+
3365+ }
3366+#endif
3367+
3368+ OsCvLockRelease(Adapter->AdapterFibMutex);
3369+
3370+ ClassDriver = Adapter->ClassDriverList;
3371+
3372+ while (ClassDriver) {
3373+
3374+ if (ClassDriver->CloseAdapter) {
3375+
3376+ Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3377+
3378+ if (Status != STATUS_SUCCESS)
3379+ break;
3380+ }
3381+
3382+ ClassDriver = ClassDriver->Next;
3383+ }
3384+
3385+ return ( Status );
3386+
3387+}
3388+
3389diff -urN linux/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3390--- linux/drivers/scsi/aacraid/comminit.c Wed Dec 31 19:00:00 1969
3391+++ linux/drivers/scsi/aacraid/comminit.c Thu Dec 21 13:14:30 2000
3392@@ -0,0 +1,986 @@
3393+/*++
3394+ * Adaptec aacraid device driver for Linux.
3395+ *
3396+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3397+ *
3398+ * This program is free software; you can redistribute it and/or modify
3399+ * it under the terms of the GNU General Public License as published by
3400+ * the Free Software Foundation; either version 2, or (at your option)
3401+ * any later version.
3402+ *
3403+ * This program is distributed in the hope that it will be useful,
3404+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3405+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3406+ * GNU General Public License for more details.
3407+ *
3408+ * You should have received a copy of the GNU General Public License
3409+ * along with this program; see the file COPYING. If not, write to
3410+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3411+ *
3412+ * Module Name:
3413+ * comminit.c
3414+ *
3415+ * Abstract: This supports the initialization of the host adapter commuication interface.
3416+ * This is a platform dependent module for the pci cyclone board.
3417+ *
3418+ --*/
3419+
3420+static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3421+
3422+#include "comprocs.h"
3423+
3424+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3425+
3426+VOID
3427+AfaCommBugcheckHandler(
3428+ IN PVOID Buffer,
3429+ IN ULONG Length
3430+ );
3431+
3432+VOID
3433+ThrottlePeriodEndDpcRtn(
3434+ IN PKDPC Dpc,
3435+ IN PVOID DeferredContext,
3436+ IN PVOID SystemArgument1,
3437+ IN PVOID SystemArgument2);
3438+
3439+FSA_COMM_DATA FsaCommData;
3440+
3441+AAC_STATUS
3442+HardInterruptModeration1Changed(
3443+ IN PVOID AdapterContext,
3444+ IN ULONG NewValue
3445+ )
3446+{
3447+ PAFA_COMM_ADAPTER Adapter = AdapterContext;
3448+
3449+ //
3450+ // If we are using interrupt moderation, then disable the interrupt
3451+ // until we need to use it.
3452+ //
3453+ if (FsaCommData.HardInterruptModeration1)
3454+ DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3455+ else
3456+ EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3457+
3458+ return (STATUS_SUCCESS);
3459+}
3460+
3461+AAC_STATUS
3462+FsaFibTimeoutChanged(
3463+ IN PVOID AdapterContext,
3464+ IN ULONG NewValue
3465+ )
3466+{
3467+ //
3468+ // scale the new timeout from seconds to 100 nsec units
3469+ //
3470+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3471+
3472+ return (STATUS_SUCCESS);
3473+}
3474+
3475+#ifdef GATHER_FIB_TIMES
3476+extern int GatherFibTimes;
3477+#endif
3478+
3479+FSA_USER_VAR FsaCommUserVars[] = {
3480+#ifdef FIB_CHECKSUMS
3481+ { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3482+#endif
3483+#ifdef GATHER_FIB_TIMES
3484+ { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3485+#endif
3486+ { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3487+ { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3488+ { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3489+ { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3490+ { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3491+ { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3492+ { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3493+ { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3494+ { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3495+ { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3496+};
3497+
3498+#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3499+
3500+\f
3501+AAC_STATUS
3502+AacCommDriverEntry(
3503+ )
3504+
3505+/*++
3506+
3507+Routine Description:
3508+
3509+ This is the initialization routine for the FileArray Comm layer device driver.
3510+
3511+Arguments:
3512+
3513+ DriverObject - Pointer to driver object created by the system.
3514+
3515+Return Value:
3516+
3517+ AAC_STATUS - The function value is the final status from the initialization
3518+ operation.
3519+
3520+--*/
3521+
3522+{
3523+ AAC_STATUS Status;
3524+ PVOID BugCheckBuffer;
3525+
3526+ RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3527+
3528+
3529+ //
3530+ // Load the global timeout value for the adapter timeout
3531+ // Also init the global that enables or disables adapter timeouts
3532+ //
3533+
3534+// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3535+
3536+ FsaCommData.FibTimeoutSeconds = 180;
3537+
3538+ FsaCommData.EnableAdapterTimeouts = TRUE;
3539+
3540+// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3541+
3542+#ifdef unix_fib_timeout
3543+ FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3544+#endif
3545+
3546+ FsaCommData.EnableInterruptModeration = FALSE;
3547+
3548+ //
3549+ // Preload UserVars with all variables from the comm layer. The class layers will
3550+ // include theirs when they register.
3551+ //
3552+
3553+ FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3554+ FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3555+
3556+ RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3557+
3558+
3559+#ifdef AACDISK
3560+ //
3561+ // Call the disk driver to initialize itself.
3562+ //
3563+
3564+ AacDiskDriverEntry();
3565+
3566+#endif
3567+
3568+
3569+
3570+ return (STATUS_SUCCESS);
3571+}
3572+
3573+
3574+VOID
3575+DetachNTQueue(
3576+ IN PAFA_COMM_ADAPTER Adapter,
3577+ IN OUT PCOMM_QUE Queue,
3578+ IN QUEUE_TYPES WhichQueue
3579+ )
3580+/*++
3581+
3582+Routine Description:
3583+
3584+ This routine will release all of the resources used by a given queue.
3585+
3586+Arguments:
3587+
3588+ Adapter - Which adapter the queue belongs to
3589+ Queue - Pointer to the queue itself
3590+ WhichQueue - Identifies which of the host queues this is.
3591+
3592+Return Value:
3593+
3594+ NONE.
3595+
3596+--*/
3597+{
3598+ switch (WhichQueue) {
3599+
3600+ case HostNormCmdQueue:
3601+
3602+ Os_remove_softintr( Queue->ConsumerRoutine );
3603+ OsSpinLockDestroy( Queue->QueueLock );
3604+ OsCv_destroy( &Queue->CommandReady );
3605+
3606+ break;
3607+
3608+ case HostHighCmdQueue:
3609+
3610+ Os_remove_softintr( Queue->ConsumerRoutine );
3611+ OsSpinLockDestroy( Queue->QueueLock );
3612+ OsCv_destroy( &Queue->CommandReady );
3613+
3614+ break;
3615+
3616+ case HostNormRespQueue:
3617+
3618+ Os_remove_softintr( Queue->ConsumerRoutine );
3619+ OsSpinLockDestroy( Queue->QueueLock );
3620+ break;
3621+
3622+ case HostHighRespQueue:
3623+
3624+ Os_remove_softintr( Queue->ConsumerRoutine );
3625+ OsSpinLockDestroy( Queue->QueueLock );
3626+ break;
3627+
3628+ case AdapNormCmdQueue:
3629+ case AdapHighCmdQueue:
3630+ case AdapNormRespQueue:
3631+ case AdapHighRespQueue:
3632+ OsCv_destroy( &Queue->QueueFull );
3633+ break;
3634+ }
3635+}
3636+
3637+VOID
3638+InitializeNTQueue(
3639+ IN PAFA_COMM_ADAPTER Adapter,
3640+ IN OUT PCOMM_QUE Queue,
3641+ IN QUEUE_TYPES WhichQueue
3642+ )
3643+/*++
3644+
3645+Routine Description:
3646+
3647+ Will initialize all entries in the queue that is NT specific.
3648+
3649+Arguments:
3650+
3651+Return Value:
3652+
3653+ Nothing there is nothing to allocate so nothing should fail
3654+
3655+--*/
3656+{
3657+
3658+ Queue->NumOutstandingIos = 0;
3659+
3660+ //
3661+ // Store a pointer to the adapter structure.
3662+ //
3663+
3664+ Queue->Adapter = Adapter;
3665+
3666+ InitializeListHead( &Queue->OutstandingIoQueue );
3667+
3668+ switch (WhichQueue) {
3669+
3670+ case HostNormCmdQueue:
3671+
3672+ OsCv_init( &Queue->CommandReady);
3673+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3674+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3675+ NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3676+ (caddr_t)Queue ) != DDI_SUCCESS) {
3677+
3678+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3679+ }
3680+
3681+ InitializeListHead(&Queue->CommandQueue);
3682+
3683+ break;
3684+
3685+ case HostHighCmdQueue:
3686+
3687+ OsCv_init( &Queue->CommandReady);
3688+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3689+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3690+ NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3691+ (caddr_t) Queue ) != DDI_SUCCESS) {
3692+
3693+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3694+ }
3695+
3696+ InitializeListHead(&Queue->CommandQueue);
3697+ break;
3698+
3699+ case HostNormRespQueue:
3700+
3701+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3702+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3703+ NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3704+ (caddr_t) Queue ) != DDI_SUCCESS) {
3705+
3706+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3707+ }
3708+ break;
3709+
3710+ case HostHighRespQueue:
3711+
3712+
3713+ OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3714+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3715+ NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3716+ (caddr_t) Queue ) != DDI_SUCCESS) {
3717+
3718+ cmn_err(CE_CONT, "OS_addr_intr failed\n");
3719+ }
3720+ break;
3721+
3722+ case AdapNormCmdQueue:
3723+ case AdapHighCmdQueue:
3724+ case AdapNormRespQueue:
3725+ case AdapHighRespQueue:
3726+
3727+ OsCv_init( &Queue->QueueFull);
3728+ break;
3729+ }
3730+}
3731+
3732+BOOLEAN
3733+StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3734+/*++
3735+
3736+Routine Description:
3737+
3738+ Create and start the command receiver threads.
3739+
3740+Arguments:
3741+
3742+
3743+Return Value:
3744+
3745+ Nothing
3746+
3747+--*/
3748+
3749+{
3750+ return(TRUE);
3751+}
3752+
3753+
3754+
3755+/*++
3756+
3757+Routine Description:
3758+
3759+ This routine gets called to detach all resources that have been allocated for
3760+ this adapter.
3761+
3762+Arguments:
3763+
3764+ Adapter - Pointer to the adapter structure to detach.
3765+
3766+Return Value:
3767+
3768+ TRUE - All resources have been properly released.
3769+ FALSE - An error occured while trying to release resources.
3770+--*/
3771+BOOLEAN
3772+AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3773+{
3774+ PAFA_CLASS_DRIVER ClassDriver;
3775+ //
3776+ // First remove this adapter from the list of adapters.
3777+ //
3778+
3779+ if (FsaCommData.AdapterList == Adapter) {
3780+
3781+ FsaCommData.AdapterList = Adapter->NextAdapter;
3782+
3783+ } else {
3784+
3785+ PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3786+
3787+ CurrentAdapter = FsaCommData.AdapterList;
3788+ NextAdapter = CurrentAdapter->NextAdapter;
3789+
3790+ while (NextAdapter) {
3791+
3792+ if (NextAdapter == Adapter) {
3793+
3794+ CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3795+ break;
3796+
3797+ }
3798+
3799+ CurrentAdapter = NextAdapter;
3800+ NextAdapter = CurrentAdapter->NextAdapter;
3801+ }
3802+ }
3803+
3804+ //
3805+ // First send a shutdown to the adapter.
3806+ //
3807+
3808+ AfaCommShutdown( Adapter );
3809+
3810+ //
3811+ // Destroy the FibContextZone for this adapter. This will free up all
3812+ // of the fib space used by this adapter.
3813+ //
3814+
3815+ FsaFreeFibContextZone( Adapter );
3816+
3817+ //
3818+ // Destroy the mutex used for synch'ing adapter fibs.
3819+ //
3820+
3821+ OsCvLockDestroy( Adapter->AdapterFibMutex );
3822+
3823+ //
3824+ // Detach all of the host queues.
3825+ //
3826+
3827+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3828+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3829+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3830+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3831+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3832+ DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3833+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3834+ DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3835+
3836+ //
3837+ // Destroy the mutex used to protect the FibContextZone
3838+ //
3839+
3840+ OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3841+
3842+ //
3843+ // Call the miniport to free the space allocated for the shared comm queues
3844+ // between the host and the adapter.
3845+ //
3846+
3847+ FsaFreeAdapterCommArea( Adapter );
3848+
3849+ //
3850+ // Free the memory used by the comm region for this adapter
3851+ //
3852+
3853+ OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3854+
3855+ //
3856+ // Free the memory used by the adapter structure.
3857+ //
3858+ ClassDriver = Adapter->ClassDriverList;
3859+ Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3860+ OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3861+
3862+ OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3863+
3864+ return (TRUE);
3865+}
3866+
3867+PVOID
3868+AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3869+{
3870+ PVOID BugCheckBuffer;
3871+ PAFA_COMM_ADAPTER Adapter;
3872+ MAPFIB_CONTEXT MapFibContext;
3873+ LARGE_INTEGER Time;
3874+ char ErrorBuffer[60];
3875+
3876+ Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3877+
3878+ if (Adapter == NULL)
3879+ return (NULL);
3880+
3881+ RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3882+
3883+
3884+ //
3885+ // Save the current adapter number and increment the total number.
3886+ //
3887+
3888+ Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3889+
3890+
3891+ //
3892+ // Fill in the pointer back to the device specific structures.
3893+ // The device specific driver has also passed a pointer for us to
3894+ // fill in with the Adapter object that we have created.
3895+ //
3896+
3897+ Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3898+ Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3899+ Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3900+ Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3901+ Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3902+
3903+ Adapter->Dip = NewAdapter->Dip;
3904+
3905+ //
3906+ // Fill in Our address into the function dispatch table
3907+ //
3908+
3909+ NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3910+ NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3911+ NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3912+ NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3913+
3914+ //
3915+ // Ok now init the communication subsystem
3916+ //
3917+
3918+ Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3919+ if (Adapter->CommRegion == NULL) {
3920+ cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3921+ return (NULL);
3922+ }
3923+ RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3924+
3925+ //
3926+ // Get a pointer to the iblock_cookie
3927+ //
3928+
3929+ ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
3930+
3931+ if (!CommInit(Adapter)) {
3932+ FsaCommPrint("Failed to init the commuication subsystem.\n");
3933+ return(NULL);
3934+ }
3935+
3936+
3937+ //
3938+ // Initialize the list of AdapterFibContext's.
3939+ //
3940+
3941+ InitializeListHead(&Adapter->AdapterFibContextList);
3942+
3943+ //
3944+ // Initialize the fast mutex used for synchronization of the adapter fibs
3945+ //
3946+
3947+ Adapter->AdapterFibMutex = OsCvLockAlloc();
3948+ OsCvLockInit(Adapter->AdapterFibMutex, NULL);
3949+
3950+ //
3951+ // Allocate and start the FSA command threads. These threads will handle
3952+ // command requests from the adapter. They will wait on an event then pull
3953+ // all CDBs off the thread's queue. Each CDB will be given to a worker thread
3954+ // upto a defined limit. When that limit is reached wait a event will be waited
3955+ // on till a worker thread is finished.
3956+ //
3957+
3958+ if (!StartFsaCommandThreads(Adapter)) {
3959+ FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
3960+ return (NULL);
3961+ }
3962+
3963+#ifdef unix_crash_dump
3964+ //
3965+ // Allocate and map a fib for use by the synch path, which is used for crash
3966+ // dumps.
3967+ //
3968+ // Allocate an entire page so that alignment is correct.
3969+ //
3970+
3971+ Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
3972+ MapFibContext.Fib = Adapter->SyncFib;
3973+ MapFibContext.Size = sizeof(FIB);
3974+ MapFib( Adapter, &MapFibContext );
3975+ Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
3976+#endif
3977+
3978+ Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
3979+
3980+ Adapter->CommFuncs.AllocateFib = AllocateFib;
3981+
3982+ Adapter->CommFuncs.FreeFib = FreeFib;
3983+ Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
3984+ Adapter->CommFuncs.DeallocateFib = DeallocateFib;
3985+
3986+ Adapter->CommFuncs.InitializeFib = InitializeFib;
3987+ Adapter->CommFuncs.GetFibData = FsaGetFibData;
3988+ Adapter->CommFuncs.SendFib = SendFib;
3989+ Adapter->CommFuncs.CompleteFib = CompleteFib;
3990+ Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
3991+
3992+ Adapter->CommFuncs.SendSynchFib = SendSynchFib;
3993+
3994+ Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
3995+ Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
3996+
3997+ //
3998+ // Add this adapter in to our Adapter List.
3999+ //
4000+
4001+ Adapter->NextAdapter = FsaCommData.AdapterList;
4002+ FsaCommData.AdapterList = Adapter;
4003+
4004+ NewAdapter->Adapter = Adapter;
4005+
4006+// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4007+
4008+ return (Adapter);
4009+}
4010+
4011+AAC_STATUS
4012+CommInitialize(
4013+ PAFA_COMM_ADAPTER Adapter
4014+ )
4015+{
4016+ //
4017+ // Now allocate and initialize the zone structures used as our pool
4018+ // of FIB context records. The size of the zone is based on the
4019+ // system memory size. We also initialize the mutex used to protect
4020+ // the zone.
4021+ //
4022+ Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4023+ OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4024+
4025+ Adapter->FibContextZoneExtendSize = 64;
4026+
4027+ return (STATUS_SUCCESS);
4028+}
4029+
4030+
4031+
4032+/*++
4033+
4034+Routine Description:
4035+
4036+ Initializes the data structures that are required for the FSA commuication
4037+ interface to operate.
4038+
4039+Arguments:
4040+
4041+ None - all global or allocated data.
4042+
4043+Return Value:
4044+
4045+ TRUE - if we were able to init the commuication interface.
4046+ FALSE - If there were errors initing. This is a fatal error.
4047+--*/
4048+BOOLEAN
4049+CommInit(PAFA_COMM_ADAPTER Adapter)
4050+{
4051+
4052+ ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4053+ ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4054+ PQUEUE_INDEX Headers;
4055+ PQUEUE_ENTRY Queues;
4056+ ULONG TotalSize;
4057+ PCOMM_REGION CommRegion = Adapter->CommRegion;
4058+
4059+ CommInitialize( Adapter );
4060+
4061+ FsaCommPrint("CommInit: Queue entry size is 0x%x, Queue index size is 0x%x, Number of total entries is 0x%x, # queues = 0x%x.\n",
4062+ sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4063+ //
4064+ //
4065+ // Allocate the physically contigous space for the commuication queue
4066+ // headers.
4067+ //
4068+
4069+ TotalSize = SizeOfHeaders + SizeOfQueues;
4070+
4071+ if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4072+ return (FALSE);
4073+
4074+ Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4075+
4076+ if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4077+ NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4078+ (caddr_t)CommRegion ) != DDI_SUCCESS) {
4079+
4080+ cmn_err(CE_CONT, "Os_addr_intr failed\n");
4081+ }
4082+
4083+
4084+ // Adapter to Host normal priority Command queue
4085+
4086+
4087+ CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4088+ CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4089+ *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4090+ *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4091+
4092+ CommRegion->HostNormCmdQue.SavedIrql = 0;
4093+ CommRegion->HostNormCmdQue.BaseAddress = Queues;
4094+ CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4095+
4096+ CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4097+ if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4098+ return (FALSE);
4099+ }
4100+ InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4101+
4102+
4103+ Queues += HOST_NORM_CMD_ENTRIES;
4104+
4105+ // Adapter to Host high priority command queue
4106+
4107+ CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4108+ CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4109+ *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4110+ *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4111+
4112+ CommRegion->HostHighCmdQue.SavedIrql = 0;
4113+ CommRegion->HostHighCmdQue.BaseAddress = Queues;
4114+ CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4115+// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4116+ CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4117+ if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4118+ return (FALSE);
4119+ }
4120+ InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4121+
4122+ Queues += HOST_HIGH_CMD_ENTRIES;
4123+
4124+ // Host to adapter normal priority command queue
4125+
4126+ CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4127+ CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4128+ *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4129+ *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4130+
4131+ CommRegion->AdapNormCmdQue.SavedIrql = 0;
4132+ CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4133+ CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4134+ InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4135+
4136+ Queues += ADAP_NORM_CMD_ENTRIES;
4137+
4138+ // host to adapter high priority command queue
4139+
4140+ CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4141+ CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4142+ *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4143+ *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4144+
4145+ CommRegion->AdapHighCmdQue.SavedIrql = 0;
4146+ CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4147+ CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4148+ InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4149+
4150+ Queues += ADAP_HIGH_CMD_ENTRIES;
4151+
4152+ // adapter to host normal priority response queue
4153+
4154+ CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4155+ CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4156+ *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4157+ *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4158+
4159+ CommRegion->HostNormRespQue.SavedIrql = 0;
4160+ CommRegion->HostNormRespQue.BaseAddress = Queues;
4161+ CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4162+// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4163+ CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4164+ if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4165+ return (FALSE);
4166+ }
4167+ InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4168+
4169+ Queues += HOST_NORM_RESP_ENTRIES;
4170+
4171+ // adapter to host high priority response queue
4172+
4173+ CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4174+ CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4175+ *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4176+ *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4177+
4178+ CommRegion->HostHighRespQue.SavedIrql = 0;
4179+ CommRegion->HostHighRespQue.BaseAddress = Queues;
4180+ CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4181+// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4182+ CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4183+ if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4184+ return (FALSE);
4185+ }
4186+ InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4187+
4188+ Queues += HOST_HIGH_RESP_ENTRIES;
4189+
4190+ // host to adapter normal priority response queue
4191+
4192+ CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4193+ CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4194+ *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4195+ *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4196+
4197+ CommRegion->AdapNormRespQue.SavedIrql = 0;
4198+ CommRegion->AdapNormRespQue.BaseAddress = Queues;
4199+ CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4200+ InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4201+
4202+ Queues += ADAP_NORM_RESP_ENTRIES;
4203+
4204+ // host to adapter high priority response queue
4205+
4206+ CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4207+ CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4208+ *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4209+ *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4210+
4211+ CommRegion->AdapHighRespQue.SavedIrql = 0;
4212+ CommRegion->AdapHighRespQue.BaseAddress = Queues;
4213+ CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4214+ InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4215+
4216+ CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4217+ CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4218+ CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4219+ CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4220+
4221+ return(TRUE);
4222+}
4223+
4224+AAC_STATUS
4225+AfaCommShutdown(
4226+ PAFA_COMM_ADAPTER Adapter
4227+ )
4228+/*++
4229+
4230+Routine Description:
4231+
4232+ This routine will send a shutdown request to each adapter.
4233+
4234+Arguments:
4235+
4236+ Adapter - which adapter to send the shutdown to.
4237+
4238+Return Value:
4239+
4240+ NT Status success.
4241+
4242+--*/
4243+
4244+{
4245+ PFIB_CONTEXT FibContext;
4246+ PCLOSECOMMAND CloseCommand;
4247+ AAC_STATUS Status;
4248+
4249+ FibContext = AllocateFib( Adapter );
4250+
4251+ InitializeFib( FibContext );
4252+
4253+ CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4254+
4255+ CloseCommand->Command = VM_CloseAll;
4256+ CloseCommand->ContainerId = 0xffffffff;
4257+
4258+ Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4259+
4260+ if (Status != STATUS_SUCCESS) {
4261+
4262+ FreeFib( FibContext );
4263+
4264+ goto ret;
4265+
4266+ }
4267+
4268+ CompleteFib( FibContext );
4269+
4270+ FreeFib( FibContext );
4271+
4272+
4273+ Status = STATUS_SUCCESS;
4274+
4275+ret:
4276+
4277+ return (Status);
4278+
4279+}
4280+
4281+VOID
4282+AfaCommBugcheckHandler(
4283+ IN PVOID Buffer,
4284+ IN ULONG Length
4285+ )
4286+/*++
4287+
4288+Routine Description:
4289+
4290+ This routine will shutdown the adapter if there is a bugcheck and
4291+ copy the shutdown data from the adapter response into the buffer
4292+ so it will show up in the host dump file.
4293+p
4294+Arguments:
4295+
4296+ Buffer - This buffer will be written to the host dump by nt for us.
4297+
4298+ Length - The size of the buffer.
4299+
4300+Return Value:
4301+
4302+ N/A
4303+
4304+--*/
4305+{
4306+ PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4307+
4308+ while (Adapter) {
4309+
4310+ NotifyAdapter(Adapter, HostShutdown);
4311+
4312+ Adapter = Adapter->NextAdapter;
4313+
4314+ }
4315+
4316+}
4317+
4318+VOID
4319+FsaCommLogEvent(
4320+ PFIB_CONTEXT FibContext,
4321+ PDEVICE_OBJECT DeviceObject,
4322+ AAC_STATUS FsaStatus,
4323+ AAC_STATUS AacStatus,
4324+ ULONG LocationCode,
4325+ USHORT Category,
4326+ PUCHAR String,
4327+ BOOLEAN DumpFib
4328+)
4329+{
4330+}
4331+
4332+AfaCommProbeDisks(
4333+ PAFA_COMM_ADAPTER Adapter
4334+ )
4335+{
4336+ PMNTINFO DiskInfo;
4337+ PMNTINFORESPONSE DiskInfoResponse;
4338+ AAC_STATUS Status;
4339+ PCOMM_FIB_CONTEXT FibContext;
4340+
4341+ FibContext = AllocateFib( Adapter );
4342+
4343+ InitializeFib( FibContext );
4344+
4345+ DiskInfo = (PMNTINFO) FibContext->Fib->data;
4346+ DiskInfo->Command = VM_NameServe;
4347+ DiskInfo->MntCount = 0;
4348+ DiskInfo->MntType = FT_FILESYS;
4349+
4350+ Status = SendFib(ContainerCommand,
4351+ FibContext,
4352+ sizeof(MNTINFO),
4353+ FsaNormal,
4354+ TRUE,
4355+ NULL,
4356+ TRUE,
4357+ NULL,
4358+ NULL);
4359+
4360+ DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4361+
4362+ if (DiskInfoResponse->MntRespCount) {
4363+
4364+ cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4365+ DiskInfoResponse->MntTable[0].Capacity);
4366+
4367+ } else {
4368+
4369+ cmn_err(CE_CONT, "no containers found on adapter\n");
4370+
4371+ }
4372+
4373+ CompleteFib( FibContext );
4374+
4375+ FreeFib( FibContext );
4376+}
4377+
4378+
4379diff -urN linux/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4380--- linux/drivers/scsi/aacraid/commsup.c Wed Dec 31 19:00:00 1969
4381+++ linux/drivers/scsi/aacraid/commsup.c Thu Dec 21 13:14:30 2000
4382@@ -0,0 +1,2180 @@
4383+/*++
4384+ * Adaptec aacraid device driver for Linux.
4385+ *
4386+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4387+ *
4388+ * This program is free software; you can redistribute it and/or modify
4389+ * it under the terms of the GNU General Public License as published by
4390+ * the Free Software Foundation; either version 2, or (at your option)
4391+ * any later version.
4392+ *
4393+ * This program is distributed in the hope that it will be useful,
4394+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4395+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4396+ * GNU General Public License for more details.
4397+ *
4398+ * You should have received a copy of the GNU General Public License
4399+ * along with this program; see the file COPYING. If not, write to
4400+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4401+ *
4402+ * Module Name:
4403+ * commsup.c
4404+ *
4405+ * Abstract: Contain all routines that are required for FSA host/adapter
4406+ * commuication.
4407+ *
4408+ *
4409+ --*/
4410+
4411+static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4412+
4413+#include "comprocs.h"
4414+
4415+#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4416+
4417+int CommPrinting;
4418+
4419+void
4420+ThrottleExceptionHandler(
4421+ IN PCOMM_REGION CommRegion,
4422+ AAC_STATUS Status
4423+ );
4424+
4425+void ThrottlePeriodEndDpcRtn(
4426+ IN PKDPC Dpc,
4427+ IN PVOID DeferredContext,
4428+ IN PVOID SystemArgument1,
4429+ IN PVOID SystemArgument2
4430+ );
4431+
4432+
4433+/*++
4434+
4435+Routine Description:
4436+
4437+ This routine will free all resources used by a given FibContextSegment.
4438+
4439+Arguments:
4440+
4441+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4442+ ZoneSegment - The segment to release resources from.
4443+
4444+Return Value:
4445+
4446+ TRUE - All resources were properly freed.
4447+ FALSE - An Error occured while freeing resources.
4448+
4449+--*/
4450+BOOLEAN
4451+FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4452+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4453+{
4454+ PCOMM_FIB_CONTEXT FibContext;
4455+ int i;
4456+
4457+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4458+
4459+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4460+ i < ZoneSegment->ExtendSize; i++, FibContext++) {
4461+
4462+ OsCvLockDestroy( FibContext->FsaEventMutex );
4463+ OsCv_destroy( &FibContext->FsaEvent );
4464+
4465+ }
4466+
4467+ UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4468+
4469+ OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4470+
4471+ OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4472+
4473+ return (TRUE);
4474+}
4475+
4476+BOOLEAN
4477+FsaFreeFibContextZone(
4478+ PAFA_COMM_ADAPTER Adapter
4479+ )
4480+/*++
4481+
4482+Routine Description:
4483+
4484+ This routine will walk through the FibContextSegmentList and free up all
4485+ resources used by the FibContextZone.
4486+
4487+Arguments:
4488+
4489+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4490+
4491+Return Value:
4492+
4493+ TRUE - All resources were properly freed.
4494+ FALSE - An Error occured while freeing resources.
4495+
4496+--*/
4497+
4498+{
4499+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4500+
4501+ ZoneSegment = Adapter->FibContextSegmentList;
4502+
4503+ while (ZoneSegment) {
4504+
4505+ NextZoneSegment = ZoneSegment->Next;
4506+
4507+ FsaFreeFibContextSegment( Adapter, ZoneSegment );
4508+
4509+ ZoneSegment = NextZoneSegment;
4510+ }
4511+
4512+ return (TRUE);
4513+}
4514+
4515+
4516+
4517+BOOLEAN
4518+FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4519+{
4520+ int ExtendSize;
4521+ KIRQL SavedIrql;
4522+ ULONG ZoneSegmentAllocSize, FibAllocSize;
4523+ PVOID FibContextSegment;
4524+ PCOMM_FIB_CONTEXT FibContext;
4525+ PFIB Fib;
4526+ PVOID FibPhysicalAddress;
4527+ int i;
4528+ PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4529+
4530+ //
4531+ // Allocate space to describe this zone segment.
4532+ //
4533+
4534+ cmn_err (CE_DEBUG, "Entered FsaExtendFibConextZone");
4535+ ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4536+
4537+ ExtendSize = Adapter->FibContextZoneExtendSize;
4538+ ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4539+
4540+ FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4541+
4542+ if (FibContextSegment == NULL) {
4543+ return (FALSE);
4544+ }
4545+
4546+ RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4547+
4548+ ZoneSegment->FibContextSegment = FibContextSegment;
4549+ ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4550+ ZoneSegment->ExtendSize = ExtendSize;
4551+
4552+ FibAllocSize = ExtendSize * sizeof(FIB);
4553+
4554+
4555+ ZoneSegment->MapFibContext.Size = FibAllocSize;
4556+
4557+ AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4558+
4559+ Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4560+ FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4561+
4562+ RtlZeroMemory( Fib, FibAllocSize );
4563+
4564+ // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4565+
4566+ for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4567+ i < ExtendSize; i++, FibContext++) {
4568+
4569+ FibContext->Adapter = Adapter;
4570+
4571+ FibContext->Fib = Fib;
4572+ FibContext->FibData = (PVOID) FibContext->Fib->data;
4573+
4574+ OsCv_init( &FibContext->FsaEvent);
4575+ FibContext->FsaEventMutex = OsCvLockAlloc();
4576+ OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4577+
4578+ Fib->Header.XferState = 0xffffffff;
4579+ Fib->Header.SenderSize = sizeof(FIB);
4580+
4581+ FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4582+
4583+ Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4584+ FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4585+ }
4586+
4587+ //
4588+ // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4589+ // initialized, we just need to extend it.
4590+ //
4591+
4592+ if (Adapter->FibContextZone.TotalSegmentSize) {
4593+
4594+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4595+
4596+ ExExtendZone( &Adapter->FibContextZone,
4597+ FibContextSegment,
4598+ ZoneSegmentAllocSize );
4599+
4600+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4601+
4602+ } else {
4603+
4604+ if (ExInitializeZone( &Adapter->FibContextZone,
4605+ sizeof(COMM_FIB_CONTEXT),
4606+ FibContextSegment,
4607+ ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4608+ FsaBugCheck(0,0,0);
4609+
4610+ }
4611+
4612+ //
4613+ // Add this segment to the adapter's list of segments
4614+ //
4615+
4616+ ZoneSegment->Next = Adapter->FibContextSegmentList;
4617+ Adapter->FibContextSegmentList = ZoneSegment;
4618+
4619+ return (TRUE);
4620+}
4621+
4622+
4623+
4624+/*++
4625+
4626+Routine Description:
4627+
4628+ This routine creates a new COMM_FIB_CONTEXT record
4629+
4630+Arguments:
4631+
4632+ Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4633+
4634+Return Value:
4635+
4636+ PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4637+
4638+--*/
4639+PFIB_CONTEXT
4640+AllocateFib (IN PVOID AdapterArg)
4641+{
4642+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4643+ KIRQL SavedIrql;
4644+ PCOMM_FIB_CONTEXT FibContext;
4645+ int FullZoneLoopCounter = 0;
4646+
4647+
4648+ //
4649+ // Acquire the zone spin lock, and check to see if the zone is full.
4650+ // If it is, then release the spin lock and allocate more fibs for the
4651+ // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4652+ // the new fibs onto the zone.
4653+ //
4654+
4655+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4656+
4657+ while (ExIsFullZone( &Adapter->FibContextZone )) {
4658+
4659+ if (++FullZoneLoopCounter > 10)
4660+ FsaBugCheck(0,0,0);
4661+
4662+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4663+
4664+ // bmb debug
4665+ cmn_err (CE_DEBUG, "Extending FibContextZone");
4666+ if (FsaExtendFibContextZone(Adapter) == FALSE) {
4667+ return (NULL);
4668+ }
4669+
4670+ OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4671+
4672+ }
4673+
4674+ //
4675+ // At this point we now know that the zone has at least one more
4676+ // IRP context record available. So allocate from the zone and
4677+ // then release the mutex.
4678+ //
4679+
4680+ FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4681+
4682+ OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4683+
4684+ //
4685+ // Set the proper node type code and node byte size
4686+ //
4687+
4688+ FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4689+ FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4690+
4691+ //
4692+ // Null out fields that depend on being zero at the start of each I/O
4693+ //
4694+
4695+ FibContext->Fib->Header.XferState = 0;
4696+ FibContext->FibCallback = NULL;
4697+ FibContext->FibCallbackContext = NULL;
4698+
4699+
4700+ //
4701+ // return and tell the caller
4702+ //
4703+
4704+ return ((PFIB_CONTEXT) FibContext);
4705+}
4706+
4707+
4708+/*++
4709+
4710+Routine Description:
4711+
4712+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4713+ from the Fsafs in memory data structures. It should only be called
4714+ by FsaCompleteRequest.
4715+
4716+Arguments:
4717+
4718+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4719+
4720+Return Value:
4721+
4722+ None
4723+
4724+--*/
4725+VOID
4726+FreeFib (IN PFIB_CONTEXT Context)
4727+{
4728+ KIRQL SavedIrql;
4729+ PCOMM_FIB_CONTEXT FibContext = Context;
4730+
4731+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4732+
4733+ OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4734+
4735+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4736+
4737+ FsaCommData.TimedOutFibs++;
4738+
4739+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4740+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4741+
4742+ } else {
4743+
4744+ ASSERT(FibContext->Fib->Header.XferState == 0);
4745+
4746+ if (FibContext->Fib->Header.XferState != 0) {
4747+ cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4748+ FibContext, FibContext->Fib->Header.XferState);
4749+ }
4750+
4751+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4752+
4753+ }
4754+
4755+ OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4756+
4757+ //
4758+ // return and tell the caller
4759+ //
4760+
4761+ return;
4762+}
4763+
4764+
4765+/*++
4766+
4767+Routine Description:
4768+
4769+ This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4770+ from the Fsafs in memory data structures. It should only be called
4771+ from the dpc routines to from dpc to free an FibContext from an async or
4772+ no response io
4773+
4774+Arguments:
4775+
4776+ FibContext - Supplies the COMM_FIB_CONTEXT to remove
4777+
4778+Return Value:
4779+
4780+ None
4781+
4782+--*/
4783+VOID
4784+FreeFibFromDpc (IN PFIB_CONTEXT Context)
4785+{
4786+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4787+
4788+ ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4789+
4790+ OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4791+
4792+ if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4793+
4794+ FsaCommData.TimedOutFibs++;
4795+
4796+ FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4797+ FibContext->Adapter->FibContextTimedOutList = FibContext;
4798+
4799+ } else {
4800+
4801+ ASSERT(FibContext->Fib->Header.XferState == 0);
4802+
4803+ if (FibContext->Fib->Header.XferState != 0) {
4804+ cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4805+ FibContext, FibContext->Fib->Header.XferState);
4806+ }
4807+
4808+
4809+ ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4810+
4811+ }
4812+
4813+ OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4814+
4815+ //
4816+ // return and tell the caller
4817+ //
4818+
4819+ return;
4820+}
4821+
4822+
4823+/*++
4824+
4825+Routine Description:
4826+
4827+ Will initialize a FIB of the requested size.
4828+
4829+Arguments:
4830+
4831+ Fib is a pointer to a location which will receive the address of the allocated
4832+ FIB.
4833+
4834+ Size is the size of the Fib to allocate.
4835+
4836+Return Value:
4837+
4838+ NT_SUCCESS if a Fib was returned to the caller.
4839+ NT_ERROR if event was an invalid event.
4840+
4841+--*/
4842+AAC_STATUS
4843+InitializeFib (IN PFIB_CONTEXT Context)
4844+{
4845+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4846+ PFIB Fib = FibContext->Fib;
4847+
4848+ Fib->Header.StructType = TFib;
4849+ Fib->Header.Size = sizeof(FIB);
4850+// if (Fib->Header.XferState & AllocatedFromPool)
4851+// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4852+// else
4853+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4854+ Fib->Header.SenderFibAddress = 0;
4855+ Fib->Header.ReceiverFibAddress = 0;
4856+ Fib->Header.SenderSize = sizeof(FIB);
4857+
4858+ return(STATUS_SUCCESS);
4859+}
4860+
4861+
4862+/*++
4863+
4864+Routine Description:
4865+
4866+ Will allocate and initialize a FIB of the requested size and return a
4867+ pointer to the structure. The size allocated may be larger than the size
4868+ requested due to allocation performace optimizations.
4869+
4870+Arguments:
4871+
4872+ Fib is a pointer to a location which will receive the address of the allocated
4873+ FIB.
4874+
4875+ Size is the size of the Fib to allocate.
4876+
4877+ JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4878+ imbedded structure the FS always allocates. So just initiaize it and return.
4879+
4880+Return Value:
4881+
4882+ NT_SUCCESS if a Fib was returned to the caller.
4883+ NT_ERROR if event was an invalid event.
4884+
4885+--*/
4886+AAC_STATUS
4887+AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4888+{}
4889+
4890+
4891+/*++
4892+
4893+Routine Description:
4894+
4895+ Will deallocate and return to the free pool the FIB pointed to by the
4896+ caller. Upon return accessing locations pointed to by the FIB parameter
4897+ could cause system access faults.
4898+
4899+Arguments:
4900+
4901+ Fib is a pointer to the FIB that caller wishes to deallocate.
4902+
4903+Return Value:
4904+
4905+ NT_SUCCESS if a Fib was returned to the caller.
4906+ NT_ERROR if event was an invalid event.
4907+
4908+--*/
4909+AAC_STATUS
4910+DeallocateFib (PFIB_CONTEXT Context)
4911+{
4912+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4913+ PFIB Fib = FibContext->Fib;
4914+
4915+ if ( Fib->Header.StructType != TFib ) {
4916+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4917+ return(STATUS_UNSUCCESSFUL);
4918+ }
4919+
4920+
4921+ Fib->Header.XferState = 0;
4922+
4923+ return(STATUS_SUCCESS);
4924+
4925+}
4926+
4927+
4928+AAC_STATUS
4929+GetResponse(
4930+ IN PCOMM_QUE ResponseQueue,
4931+ OUT PFIB Fib
4932+ )
4933+/*++
4934+
4935+Routine Description:
4936+
4937+ Gets a QE off the requested response queue and gets the response FIB into
4938+ host memory. The FIB may already be in host memory depending on the bus
4939+ interface, or may require the host to DMA it over from the adapter. The routine
4940+ will return the FIB to the caller.
4941+
4942+Arguments:
4943+
4944+ ResponseQueue - Is the queue the caller wishes to have the response gotten from.
4945+ Fib - Is the Fib which was the response from the adapter
4946+
4947+Return Value:
4948+
4949+ NT_SUCCESS if a Fib was returned to the caller.
4950+ NT_ERROR if there was no Fib to return to the caller.
4951+ bkpfix - add in all the other possible errors ect
4952+
4953+--*/
4954+{
4955+return(STATUS_UNSUCCESSFUL);
4956+}
4957+
4958+//
4959+// Commuication primitives define and support the queuing method we use to
4960+// support host to adapter commuication. All queue accesses happen through
4961+// these routines and are the only routines which have a knowledge of the
4962+// how these queues are implemented.
4963+//
4964+
4965+
4966+/*++
4967+
4968+Routine Description:
4969+
4970+ With a priority the routine returns a queue entry if the queue has free entries. If the queue
4971+ is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
4972+ returned.
4973+
4974+Arguments:
4975+
4976+ Priority is an enumerated type which determines which priority level
4977+ command queue the QE is going to be queued on.
4978+
4979+ Entry is a pointer to the address of where to return the address of
4980+ the queue entry from the requested command queue.
4981+
4982+ Index is a pointer to the address of where to store the index of the new
4983+ queue entry returned.
4984+
4985+ DontInterrupt - We set this true if the queue state is such that we don't
4986+ need to interrupt the adapter for this queue entry.
4987+
4988+Return Value:
4989+
4990+ TRUE - If a queue entry is returned
4991+ FALSE - If there are no free queue entries on the requested command queue.
4992+
4993+--*/
4994+BOOLEAN
4995+GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
4996+ OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
4997+ OUT ULONG *DontInterrupt)
4998+{
4999+ ULONG QueueOffset;
5000+ BOOLEAN status;
5001+ PCOMM_REGION CommRegion;
5002+
5003+ CommRegion = Adapter->CommRegion;
5004+
5005+ //
5006+ // All of the queues wrap when they reach the end, so we check to see if they
5007+ // have reached the end and if they have we just set the index back to zero.
5008+ // This is a wrap. You could or off the high bits in all updates but this is
5009+ // a bit faster I think.
5010+ //
5011+
5012+ if (WhichQueue == AdapHighCmdQueue) {
5013+ *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5014+
5015+ if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5016+ *DontInterrupt = TRUE;
5017+
5018+ if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5019+ *Index = 0;
5020+
5021+ if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5022+ status = FALSE;
5023+ cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5024+ CommRegion->AdapHighCmdQue.NumOutstandingIos);
5025+ } else {
5026+ QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5027+ *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5028+
5029+ status = TRUE;
5030+ }
5031+ } else if (WhichQueue == AdapNormCmdQueue) {
5032+
5033+ *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5034+
5035+ if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5036+ *DontInterrupt = TRUE;
5037+
5038+ //
5039+ // If we are at the end of the QUEUE then wrap back to
5040+ // the beginning.
5041+ //
5042+
5043+ if (*Index >= ADAP_NORM_CMD_ENTRIES)
5044+ *Index = 0; // Wrap to front of the Producer Queue.
5045+
5046+ //
5047+ // The IEEE spec says that it the producer is one behind the consumer then
5048+ // the queue is full.
5049+ //
5050+
5051+ ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5052+
5053+ if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5054+ cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5055+ CommRegion->AdapNormCmdQue.NumOutstandingIos);
5056+ status = FALSE;
5057+ } else {
5058+ //
5059+ // The success case just falls through and returns the a valid queue entry.
5060+ //
5061+
5062+#ifdef commdebug
5063+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5064+ FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5065+ *Index, QueueOffset, Entry, *Entry);
5066+#endif
5067+ *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5068+
5069+ status = TRUE;
5070+ }
5071+ } else if (WhichQueue == AdapHighRespQueue) {
5072+
5073+ *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5074+
5075+ if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5076+ *DontInterrupt = TRUE;
5077+
5078+ if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5079+ *Index = 0;
5080+
5081+ if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5082+ status = FALSE;
5083+ cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5084+ CommRegion->AdapHighRespQue.NumOutstandingIos);
5085+ } else {
5086+ *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5087+ status = TRUE;
5088+ }
5089+ } else if (WhichQueue == AdapNormRespQueue) {
5090+
5091+ *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5092+
5093+ if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5094+ *DontInterrupt = TRUE;
5095+
5096+ //
5097+ // If we are at the end of the QUEUE then wrap back to
5098+ // the beginning.
5099+ //
5100+
5101+ if (*Index >= ADAP_NORM_RESP_ENTRIES)
5102+ *Index = 0; // Wrap to front of the Producer Queue.
5103+
5104+ //
5105+ // The IEEE spec says that it the producer is one behind the consumer then
5106+ // the queue is full.
5107+ //
5108+
5109+ if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5110+ status = FALSE;
5111+ cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5112+ CommRegion->AdapNormRespQue.NumOutstandingIos);
5113+ } else {
5114+ //
5115+ // The success case just falls through and returns the a valid queue entry.
5116+ //
5117+
5118+ *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5119+
5120+#ifdef commdebug
5121+ FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5122+ FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5123+#endif
5124+ status = TRUE;
5125+ }
5126+ } else {
5127+ cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5128+ }
5129+
5130+
5131+ return (status);
5132+}
5133+
5134+
5135+
5136+#ifdef API_THROTTLE
5137+
5138+void ThrottleCheck(
5139+ IN PAFA_COMM_ADAPTER Adapter,
5140+ IN PFIB Fib
5141+ )
5142+/*++
5143+
5144+Routine Description:
5145+
5146+ This routine implements data I/O throttling. Throttling occurs when
5147+ a CLI FIB is detected. To ensure the CLI responds quickly (the user
5148+ is waiting for the response), this mechanism restricts the queue
5149+ depth of data IOs at the adapter for a period of time (called the
5150+ Throttle Period, default 5 seconds).
5151+
5152+ The mechanism uses a counted semaphore to place threads into a wait
5153+ state should there be too many data I/Os outstanding.
5154+
5155+ At the start of a throttle period (indicated by the first CLI FIB)
5156+ a timer is started. When the timer expires, new requests can go to
5157+ the adapter freely. Throttled requests gradually drain to the
5158+ adapter as each outstanding throttle I/O completes.
5159+
5160+ To avoid hurting regular I/O performance, we use a flag in the FIB
5161+ header to mark FIBs involved in throttling. This means we only need
5162+ take the extra spinlock in the response DPC routine for FIBs who
5163+ were subject to throttling. If no throttling is occurring, the cost
5164+ to the regular code paths is a handful of instructions.
5165+
5166+Arguments:
5167+
5168+ Adapter - Pointer to per-adapter context. This is used to locate the
5169+ throttle information for this adapter.
5170+
5171+ Fib - Pointer to the header for the fib being sent.
5172+
5173+Return Value:
5174+
5175+ None.
5176+
5177+--*/
5178+{
5179+ PCOMM_REGION CommRegion = Adapter->CommRegion;
5180+ AAC_STATUS Status;
5181+
5182+ //
5183+ // This routine is called under protection of the queue spinlock.
5184+ // As such we are allowed to check and change the counts for the
5185+ // throttle.
5186+ // Check the FIB. If its not a data operation, send it on without
5187+ // throttle check. If it is a data operation, check for throttle.
5188+ //
5189+
5190+ CommRegion->TotalFibs++; // Keep statistics
5191+
5192+ if ((Fib->Header.XferState & ApiFib) != 0) {
5193+
5194+ CommRegion->ApiFibs++; // Keep statistics
5195+
5196+ //
5197+ // Its an API fib. If the throttle is not already active,
5198+ // make it so. This will prevent new data Fibs being sent
5199+ // if they exceed the throttle check.
5200+ //
5201+
5202+ if (!CommRegion->ThrottleActive) {
5203+ BOOLEAN InQue;
5204+
5205+ CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5206+
5207+ //
5208+ // Schedule a timer for the throttle active period. When
5209+ // it expires, we'll be called back at routine ThrottleDpcRoutine
5210+ // above. This will signify the throttle active period ended
5211+ // and any waiting threads will be signalled to restart.
5212+ //
5213+
5214+ FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5215+ CommRegion->ThrottleTimerSets++;
5216+ InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5217+ CommRegion->ThrottleTimeout,
5218+ &CommRegion->ThrottleDpc);
5219+ ASSERT(InQue == FALSE);
5220+ }
5221+
5222+ return;
5223+ }
5224+
5225+ //
5226+ // Its a non-API fib, so subject to throttle checks.
5227+ // The following are exempt from throttling:
5228+ // o FIBs marked as "throttle exempt" by upper layers.
5229+ // o I/Os issued from a raised IRQL. We can't suspend
5230+ // a thread when at raised IRQL so throttling is exempt.
5231+ //
5232+
5233+ if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5234+
5235+ CommRegion->NonPassiveFibs++;
5236+ FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5237+ return;
5238+
5239+ }
5240+
5241+ if (CommRegion->ThrottleActive) {
5242+
5243+ //
5244+ // Throttle is active.
5245+ // Check if the FIB is a read or write. If so, and its to the
5246+ // file system information area, let it through without throttling.
5247+ //
5248+
5249+ if (Fib->Header.Command == ContainerCommand) {
5250+ PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5251+
5252+ //
5253+ // *** Note *** We are using read and write command formats
5254+ // interchangably here. This is ok for this purpose as the
5255+ // command is in the same place for both. Read and write command
5256+ // formats are different at higher offsets though.
5257+ //
5258+
5259+ if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5260+ (BlockDisk->Command == VM_CtBlockWrite)) &&
5261+ (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5262+
5263+ CommRegion->FSInfoFibs++; // Keep statistics
5264+ return;
5265+
5266+ }
5267+
5268+ }
5269+
5270+ //
5271+ // Throttle the FIB.
5272+ // Mark it as throttle active so that it can signal a waiter
5273+ // when it completes.
5274+
5275+ CommRegion->ThrottledFibs++;
5276+ Fib->Header.Flags |= ThrottledFib;
5277+
5278+ //
5279+ // Release the spinlock so we can wait the thread if necessary.
5280+ // Since we specify a timeout, check the caller is at passive level.
5281+ //
5282+
5283+ OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5284+
5285+ FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5286+
5287+ Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5288+ Executive, // Don't allow user APCs to wake us
5289+ KernelMode, // Wait in kernel mode
5290+ FALSE, // Not alertable
5291+ &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5292+
5293+ //
5294+ // Check the signal status. If we've timed out, clear the throttle
5295+ // flag on the FIB to avoid us signalling the semaphore on completion.
5296+ // We never acquired the semaphore.
5297+ //
5298+ if (Status == STATUS_TIMEOUT) {
5299+
5300+ CommRegion->ThrottleTimedoutFibs++;
5301+ FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5302+ Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5303+
5304+ } else {
5305+
5306+ ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5307+
5308+ }
5309+
5310+ //
5311+ // We've been woken up and can now send the FIB to the adapter.
5312+ // Acquire the spinlock again so we can get a queue entry. This
5313+ // returns to GetQueueEntry.
5314+ //
5315+
5316+ FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5317+ KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5318+ CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5319+ return;
5320+
5321+ }
5322+}
5323+
5324+#endif //#ifdef API_THROTTLE
5325+
5326+int GetQueueEntryTimeouts = 0;
5327+
5328+
5329+/*++
5330+
5331+Routine Description:
5332+
5333+ Gets the next free QE off the requested priorty adapter command queue and
5334+ associates the Fib with the QE. The QE represented by index is ready to
5335+ insert on the queue when this routine returns success.
5336+
5337+Arguments:
5338+
5339+ Index is the returned value which represents the QE which is ready to
5340+ insert on the adapter's command queue.
5341+
5342+ Priority is an enumerated type which determines which priority level
5343+ command queue the QE is going to be queued on.
5344+
5345+ Fib is a pointer to the FIB the caller wishes to have associated with the
5346+ QE.
5347+
5348+ Wait is a boolean which determines if the routine will wait if there are
5349+ no free QEs on the requested priority command queue.
5350+
5351+ FibContext is where the driver stores all system resources required to execute the
5352+ command requested from the calling thread. This includes mapping resources for
5353+ the FIB and the 'users' buffer.
5354+
5355+ DontInterrupt - We set this true if the queue state is such that we don't
5356+ need to interrupt the adapter for this queue entry.
5357+
5358+Return Value:
5359+
5360+ NT_SUCCESS if a Fib was returned to the caller.
5361+ NT_ERROR if event was an invalid event.
5362+
5363+--*/
5364+AAC_STATUS
5365+GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5366+ IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5367+ IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5368+{
5369+ PQUEUE_ENTRY QueueEntry = NULL;
5370+ BOOLEAN MapAddress = FALSE;
5371+ int timeouts = 0;
5372+ AAC_STATUS Status;
5373+ PCOMM_REGION CommRegion;
5374+
5375+ CommRegion = Adapter->CommRegion;
5376+
5377+ //
5378+ // Get the spinlock for the queue we are putting a command on
5379+ //
5380+
5381+ if (WhichQueue == AdapHighCmdQueue)
5382+ OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5383+ else if (WhichQueue == AdapNormCmdQueue)
5384+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5385+ else if (WhichQueue == AdapHighRespQueue)
5386+ OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5387+ else if (WhichQueue == AdapNormRespQueue)
5388+ OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5389+ else {
5390+ FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5391+ return(FSA_INVALID_QUEUE);
5392+ }
5393+
5394+ //
5395+ // Get the pointers to a queue entry on the queue the caller wishes to queue
5396+ // a command request on. If there are no entries then wait if that is what the
5397+ // caller requested.
5398+ //
5399+
5400+ if (WhichQueue == AdapHighCmdQueue) {
5401+ // if no entries wait for some if caller wants to
5402+ while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5403+ cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5404+ }
5405+
5406+ //
5407+ // Setup queue entry with a command, status and Fib mapped
5408+ //
5409+
5410+ QueueEntry->Size = Fib->Header.Size;
5411+ MapAddress = TRUE;
5412+
5413+ } else if (WhichQueue == AdapNormCmdQueue) {
5414+ // if no entries wait for some if caller wants to
5415+ while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5416+ cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5417+ }
5418+
5419+ //
5420+ // Setup queue entry with command, status and Fib mapped
5421+ //
5422+
5423+ QueueEntry->Size = Fib->Header.Size;
5424+ MapAddress = TRUE;
5425+
5426+ } else if (WhichQueue == AdapHighRespQueue) {
5427+
5428+ while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5429+ }
5430+
5431+ //
5432+ // Setup queue entry with command, status and Fib mapped
5433+ //
5434+
5435+ QueueEntry->Size = Fib->Header.Size;
5436+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5437+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5438+ MapAddress = FALSE;
5439+
5440+ } else if (WhichQueue == AdapNormRespQueue) {
5441+ while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5442+ }
5443+
5444+ //
5445+ // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5446+ //
5447+
5448+ QueueEntry->Size = Fib->Header.Size;
5449+ QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5450+ Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5451+ MapAddress = FALSE;
5452+ }
5453+
5454+ //
5455+ // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5456+ //
5457+
5458+ if (MapAddress) {
5459+ QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5460+ }
5461+
5462+ //
5463+ // Return
5464+ //
5465+#ifdef commdebug
5466+ FsaCommPrint("Queue Entry contents:.\n");
5467+ FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5468+ FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5469+ FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5470+ FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5471+#endif
5472+
5473+ return(FSA_SUCCESS);
5474+}
5475+
5476+
5477+/*++
5478+
5479+Routine Description:
5480+
5481+ Gets the next free QE off the requested priorty adapter command queue and
5482+ associates the Fib with the QE. The QE represented by index is ready to
5483+ insert on the queue when this routine returns success.
5484+
5485+Arguments:
5486+
5487+ Index is the returned value which represents the QE which is ready to
5488+ insert on the adapter's command queue.
5489+
5490+ WhichQueue tells us which queue the caller wishes to have the entry put.
5491+
5492+Return Value:
5493+
5494+ NT_SUCCESS if a Fib was returned to the caller.
5495+ NT_ERROR if event was an invalid event.
5496+
5497+--*/
5498+AAC_STATUS
5499+InsertQueueEntry(
5500+ IN PAFA_COMM_ADAPTER Adapter,
5501+ IN QUEUE_INDEX Index,
5502+ IN QUEUE_TYPES WhichQueue,
5503+ IN ULONG DontInterrupt
5504+ )
5505+{
5506+ PCOMM_REGION CommRegion;
5507+
5508+ CommRegion = Adapter->CommRegion;
5509+
5510+ //
5511+ // We have already verified the queue in getentry, but we still have to make
5512+ // sure we don't wrap here too.
5513+ //
5514+
5515+ if (WhichQueue == AdapHighCmdQueue) {
5516+
5517+ *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5518+
5519+ OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5520+
5521+ if (!DontInterrupt)
5522+ NotifyAdapter(Adapter, AdapHighCmdQue);
5523+
5524+ } else if (WhichQueue == AdapNormCmdQueue) {
5525+
5526+#ifdef commdebug
5527+ FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5528+#endif
5529+ *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5530+
5531+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5532+
5533+ if (!DontInterrupt)
5534+ NotifyAdapter(Adapter, AdapNormCmdQue);
5535+
5536+ } else if (WhichQueue == AdapHighRespQueue) {
5537+
5538+ *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5539+
5540+ OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5541+
5542+ if (!DontInterrupt)
5543+ NotifyAdapter(Adapter, AdapHighRespQue);
5544+
5545+ } else if (WhichQueue == AdapNormRespQueue) {
5546+
5547+ *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5548+
5549+ OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5550+
5551+ if (!DontInterrupt)
5552+ NotifyAdapter(Adapter, AdapNormRespQue);
5553+
5554+ } else {
5555+ FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5556+ return(FSA_INVALID_QUEUE_PRIORITY);
5557+ }
5558+
5559+ return(FSA_SUCCESS);
5560+}
5561+
5562+extern int GatherFibTimes;
5563+
5564+BOOLEAN
5565+SendSynchFib(
5566+ PVOID Arg,
5567+ FIB_COMMAND Command,
5568+ PVOID Data,
5569+ USHORT Size,
5570+ PVOID Response,
5571+ USHORT *ResponseSize
5572+ )
5573+/*++
5574+
5575+Routine Description:
5576+
5577+ This routine will send a synchronous FIB to the adapter and wait for its
5578+ completion.
5579+
5580+Arguments:
5581+
5582+ DeviceExtension - Pointer to adapter extension structure.
5583+
5584+
5585+Return Value:
5586+
5587+ BOOLEAN
5588+
5589+--*/
5590+{
5591+ PAFA_COMM_ADAPTER Adapter = Arg;
5592+ FIB *Fib;
5593+ ULONG returnStatus;
5594+
5595+ Fib = Adapter->SyncFib;
5596+
5597+ Fib->Header.StructType = TFib;
5598+ Fib->Header.Size = sizeof(FIB);
5599+ Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5600+ Fib->Header.ReceiverFibAddress = 0;
5601+ Fib->Header.SenderSize = sizeof(FIB);
5602+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5603+ Fib->Header.Command = Command;
5604+
5605+ //
5606+ // Copy the Data portion into the Fib.
5607+ //
5608+
5609+ RtlCopyMemory( Fib->data, Data, Size );
5610+
5611+
5612+ Fib->Header.XferState |= (SentFromHost | NormalPriority);
5613+
5614+ //
5615+ // Set the size of the Fib we want to send to the adapter
5616+ //
5617+
5618+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5619+
5620+ if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5621+ Adapter->SyncFibPhysicalAddress )) {
5622+
5623+ return (FALSE);
5624+
5625+ }
5626+
5627+ //
5628+ // Copy the response back to the caller's buffer.
5629+ //
5630+
5631+ RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5632+
5633+ *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5634+
5635+ //
5636+ // Indicate success
5637+ //
5638+
5639+ return (TRUE);
5640+}
5641+
5642+//
5643+// Define the highest level of host to adapter communication routines. These
5644+// routines will support host to adapter FS commuication. These routines have
5645+// no knowledge of the commuication method used. This level sends and receives
5646+// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5647+//
5648+
5649+
5650+
5651+/*++
5652+
5653+Routine Description:
5654+
5655+ Sends the requested FIB to the adapter and optionally will wait for a
5656+ response FIB. If the caller does not wish to wait for a response than
5657+ an event to wait on must be supplied. This event will be set when a
5658+ response FIB is received from the adapter.
5659+
5660+Arguments:
5661+
5662+ Fib is a pointer to the FIB the caller wishes to send to the adapter.
5663+
5664+ Size - Size of the data portion of the Fib.
5665+
5666+ Priority is an enumerated type which determines which priority level
5667+ the caller wishes to send this command at.
5668+
5669+ Wait is a boolean which determines if the routine will wait for the
5670+ completion Fib to be returned(TRUE), or return when the Fib has been
5671+ successfully received by the adapter(FALSE).
5672+
5673+ WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5674+ FIB has been returned by the adapter.
5675+
5676+ ReturnFib is an optional pointer to a FIB that if present the response FIB will
5677+ copied to.
5678+
5679+Return Value:
5680+
5681+ NT_SUCCESS if a Fib was returned to the caller.
5682+ NT_ERROR if event was an invalid event.
5683+
5684+ --*/
5685+AAC_STATUS
5686+SendFib (IN FIB_COMMAND Command,
5687+ IN PFIB_CONTEXT Context,
5688+ IN ULONG Size,
5689+ IN COMM_PRIORITIES Priority,
5690+ IN BOOLEAN Wait,
5691+ IN PVOID WaitOn,
5692+ IN BOOLEAN ResponseExpected,
5693+ IN PFIB_CALLBACK FibCallback,
5694+ IN PVOID FibCallbackContext)
5695+{
5696+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5697+ QUEUE_INDEX Index;
5698+ QUEUE_TYPES WhichQueue;
5699+ LARGE_INTEGER Timeout;
5700+ AAC_STATUS Status;
5701+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5702+ ULONG DontInterrupt = FALSE;
5703+ PFIB Fib = FibContext->Fib;
5704+ IN PCOMM_QUE OurQueue;
5705+
5706+ Timeout = FsaCommData.AdapterTimeout;
5707+
5708+ if (!(Fib->Header.XferState & HostOwned)) {
5709+ FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5710+ FsaCommLogEvent(FibContext,
5711+ FsaCommData.DeviceObject,
5712+ FSAFS_FIB_INVALID,
5713+ STATUS_UNSUCCESSFUL,
5714+ BugCheckFileId | __LINE__,
5715+ FACILITY_FSAFS_ERROR_CODE,
5716+ NULL,
5717+ TRUE);
5718+
5719+ return(STATUS_UNSUCCESSFUL);
5720+
5721+ }
5722+
5723+ //
5724+ // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5725+ // are if the caller requests to wait and does not request a response and if the
5726+ // caller does not want a response and the Fib is not allocated from pool. If a response
5727+ // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5728+ // comes back from the adapter. No further processing will be done besides deleting the
5729+ // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5730+ // and the host can log that fact.
5731+
5732+ if (Wait && !ResponseExpected) {
5733+
5734+ FsaCommLogEvent(FibContext,
5735+ FsaCommData.DeviceObject,
5736+ FSAFS_FIB_INVALID,
5737+ STATUS_UNSUCCESSFUL,
5738+ BugCheckFileId | __LINE__,
5739+ FACILITY_FSAFS_ERROR_CODE,
5740+ NULL,
5741+ TRUE);
5742+
5743+ return(STATUS_UNSUCCESSFUL);
5744+
5745+ } else if (!Wait && ResponseExpected) {
5746+ Fib->Header.XferState |= (Async | ResponseExpected);
5747+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5748+ } else if (!Wait && !ResponseExpected) {
5749+ Fib->Header.XferState |= NoResponseExpected;
5750+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5751+ } else if (Wait && ResponseExpected) {
5752+ Fib->Header.XferState |= ResponseExpected;
5753+ FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5754+ }
5755+
5756+ Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5757+
5758+ //
5759+ // Set FIB state to indicate where it came from and if we want a response from the
5760+ // adapter. Also load the command from the caller.
5761+ //
5762+
5763+ Fib->Header.SenderFibAddress = (ULONG)Fib;
5764+ Fib->Header.Command = Command;
5765+ Fib->Header.XferState |= SentFromHost;
5766+ FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5767+
5768+ //
5769+ // Set the size of the Fib we want to send to the adapter
5770+ //
5771+
5772+ Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5773+ if (Fib->Header.Size > Fib->Header.SenderSize) {
5774+ return(STATUS_BUFFER_OVERFLOW);
5775+ }
5776+
5777+ //
5778+ // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5779+ //
5780+
5781+ if (Priority == FsaHigh) {
5782+ Fib->Header.XferState |= HighPriority;
5783+ WhichQueue = AdapHighCmdQueue;
5784+ OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5785+ } else {
5786+ Fib->Header.XferState |= NormalPriority;
5787+ WhichQueue = AdapNormCmdQueue;
5788+ OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5789+ }
5790+
5791+ if (Wait) {
5792+ OsCvLockAcquire( FibContext->FsaEventMutex );
5793+ }
5794+
5795+ if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5796+ return(STATUS_UNSUCCESSFUL);
5797+
5798+ // bmb debug
5799+
5800+ cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5801+ cmn_err (CE_DEBUG,"Fib contents:.\n");
5802+ cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5803+ cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5804+
5805+ //
5806+ // Fill in the Callback and CallbackContext if we are not going to wait.
5807+ //
5808+
5809+ if (!Wait) {
5810+
5811+ FibContext->FibCallback = FibCallback;
5812+ FibContext->FibCallbackContext = FibCallbackContext;
5813+
5814+ }
5815+
5816+ FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5817+
5818+ InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5819+ OurQueue->NumOutstandingIos++;
5820+
5821+ FibContext->FibComplete = 0;
5822+
5823+
5824+
5825+ if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5826+ return(STATUS_UNSUCCESSFUL);
5827+
5828+ //
5829+ // If the caller wanted us to wait for response wait now.
5830+ // If Timeouts are enabled than set the timeout otherwise wait forever.
5831+ //
5832+
5833+ if (Wait) {
5834+ while (FibContext->FibComplete == 0) {
5835+ OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5836+ }
5837+
5838+ OsCvLockRelease( FibContext->FsaEventMutex );
5839+
5840+ if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5841+ return(STATUS_IO_TIMEOUT);
5842+ } else {
5843+ return(STATUS_SUCCESS);
5844+ }
5845+ }
5846+
5847+ //
5848+ // If the user does not want a response than return success otherwise return pending
5849+ //
5850+
5851+ ASSERT( FibCallback );
5852+
5853+ if (ResponseExpected)
5854+ return(STATUS_PENDING);
5855+ else
5856+ return(STATUS_SUCCESS);
5857+}
5858+
5859+BOOLEAN
5860+GetConsumerEntry(
5861+ IN PAFA_COMM_ADAPTER Adapter,
5862+ PCOMM_QUE OurQueue,
5863+ OUT PQUEUE_ENTRY *Entry
5864+ )
5865+/*++
5866+
5867+Routine Description:
5868+
5869+ Will return a pointer to the entry on the top of the queue requested that we are a consumer
5870+ of, and return the address of the queue entry. It does not change the state of the queue.
5871+
5872+Arguments:
5873+
5874+ OurQueue - is the queue the queue entry should be removed from.
5875+
5876+ Entry - is a pointer where the address of the queue entry should be returned.
5877+
5878+Return Value:
5879+
5880+ TRUE if there was a queue entry on the response queue for the host to consume.
5881+ FALSE if there were no queue entries to consume.
5882+
5883+--*/
5884+
5885+{
5886+ QUEUE_INDEX Index;
5887+ BOOLEAN status;
5888+
5889+ if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5890+ status = FALSE;
5891+ } else {
5892+
5893+ //
5894+ // The consumer index must be wrapped if we have reached the end of
5895+ // the queue.
5896+ // Else we just use the entry pointed to by the header index
5897+ //
5898+
5899+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5900+ Index = 0;
5901+ else
5902+ Index = *OurQueue->Headers.ConsumerIndex;
5903+
5904+ *Entry = OurQueue->BaseAddress + Index;
5905+
5906+#ifdef commdebug
5907+ FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5908+#endif
5909+ status = TRUE;
5910+ }
5911+
5912+ return(status);
5913+}
5914+
5915+BOOLEAN
5916+ConsumerEntryAvailable(
5917+ IN PAFA_COMM_ADAPTER Adapter,
5918+ PCOMM_QUE OurQueue
5919+ )
5920+{
5921+ return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
5922+}
5923+
5924+VOID
5925+FreeConsumerEntry(
5926+ IN PAFA_COMM_ADAPTER Adapter,
5927+ PCOMM_QUE OurQueue,
5928+ QUEUE_TYPES WhichQueue
5929+ )
5930+/*++
5931+
5932+Routine Description:
5933+
5934+ Frees up the current top of the queue we are a consumer of. If the queue was full
5935+ notify the producer that the queue is no longer full.
5936+
5937+Arguments:
5938+
5939+ OurQueue - is the queue we will free the current consumer entry on.
5940+
5941+Return Value:
5942+
5943+ TRUE if there was a queue entry on the response queue for the host to consume.
5944+ FALSE if there were no queue entries to consume.
5945+
5946+--*/
5947+
5948+{
5949+ BOOLEAN WasFull = FALSE;
5950+ HOST_2_ADAP_EVENT Notify;
5951+
5952+ if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
5953+ WasFull = TRUE;
5954+
5955+ if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5956+ *OurQueue->Headers.ConsumerIndex = 1;
5957+ else
5958+ *OurQueue->Headers.ConsumerIndex += 1;
5959+
5960+ if (WasFull) {
5961+ switch (WhichQueue) {
5962+
5963+ case HostNormCmdQueue:
5964+ Notify = HostNormCmdNotFull;
5965+ break;
5966+ case HostHighCmdQueue:
5967+ Notify = HostHighCmdNotFull;
5968+ break;
5969+
5970+ case HostNormRespQueue:
5971+ Notify = HostNormRespNotFull;
5972+ break;
5973+
5974+ case HostHighRespQueue:
5975+ Notify = HostHighRespNotFull;
5976+ break;
5977+
5978+ }
5979+ NotifyAdapter(Adapter, Notify);
5980+ }
5981+
5982+}
5983+
5984+AAC_STATUS
5985+CompleteAdapterFib(
5986+ IN PFIB_CONTEXT Context,
5987+ IN USHORT Size
5988+ )
5989+/*++
5990+
5991+Routine Description:
5992+
5993+ Will do all necessary work to complete a FIB that was sent from the adapter.
5994+
5995+Arguments:
5996+
5997+ Fib is a pointer to the FIB that caller wishes to complete processing on.
5998+
5999+ Size - Size of the completion Packet(Opitional). If not present than the current
6000+ largest size in the Fib will be used
6001+
6002+ Adapter - Pointer to which adapter sent this FIB
6003+
6004+Return Value:
6005+
6006+ NT_SUCCESS if a Fib was returned to the caller.
6007+ NT_ERROR if event was an invalid event.
6008+
6009+--*/
6010+{
6011+ PCOMM_FIB_CONTEXT FibContext = Context;
6012+ PFIB Fib = FibContext->Fib;
6013+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6014+ ULONG DontInterrupt = FALSE;
6015+
6016+ if (Fib->Header.XferState == 0)
6017+ return(STATUS_SUCCESS);
6018+
6019+ //
6020+ // If we plan to do anything check the structure type first.
6021+ //
6022+
6023+ if ( Fib->Header.StructType != TFib ) {
6024+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6025+ return(STATUS_UNSUCCESSFUL);
6026+ }
6027+
6028+ //
6029+ // This block handles the case where the adapter had sent us a command and we
6030+ // have finished processing the command. We call completeFib when we are done
6031+ // processing the command and want to send a response back to the adapter. This
6032+ // will send the completed cdb to the adapter.
6033+ //
6034+
6035+ if (Fib->Header.XferState & SentFromAdapter) {
6036+ Fib->Header.XferState |= HostProcessed;
6037+ if (Fib->Header.XferState & HighPriority) {
6038+ QUEUE_INDEX Index;
6039+
6040+ if (Size) {
6041+ Size += sizeof(FIB_HEADER);
6042+ if (Size > Fib->Header.SenderSize)
6043+ return(STATUS_BUFFER_OVERFLOW);
6044+ Fib->Header.Size = Size;
6045+ }
6046+
6047+ if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6048+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6049+ return(FSA_FATAL);
6050+ }
6051+ if (InsertQueueEntry(Adapter,
6052+ Index,
6053+ AdapHighRespQueue,
6054+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6055+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6056+ }
6057+ } else if (Fib->Header.XferState & NormalPriority) {
6058+ QUEUE_INDEX Index;
6059+
6060+ if (Size) {
6061+ Size += sizeof(FIB_HEADER);
6062+ if (Size > Fib->Header.SenderSize)
6063+ return(STATUS_BUFFER_OVERFLOW);
6064+ Fib->Header.Size = Size;
6065+ }
6066+
6067+ if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6068+ FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6069+ return(FSA_FATAL);
6070+ }
6071+ if (InsertQueueEntry(Adapter,
6072+ Index,
6073+ AdapNormRespQueue,
6074+ (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6075+ FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6076+ }
6077+ }
6078+ } else {
6079+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6080+ FsaBugCheck(0,0,0);
6081+ }
6082+ return(STATUS_SUCCESS);
6083+}
6084+
6085+AAC_STATUS
6086+CompleteFib(
6087+ IN PFIB_CONTEXT Context
6088+ )
6089+/*++
6090+
6091+Routine Description:
6092+
6093+ Will do all necessary work to complete a FIB. If the caller wishes to
6094+ reuse the FIB after post processing has been completed Reinitialize
6095+ should be called set to TRUE, otherwise the FIB will be returned to the
6096+ free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6097+ reinitialzied and is ready for reuse on return from this routine.
6098+
6099+Arguments:
6100+
6101+ Fib is a pointer to the FIB that caller wishes to complete processing on.
6102+
6103+ Size - Size of the completion Packet(Opitional). If not present than the current
6104+ largest size in the Fib will be used
6105+
6106+ Reinitialize is a boolean which determines if the routine will ready the
6107+ completed FIB for reuse(TRUE) or not(FALSE).
6108+
6109+Return Value:
6110+
6111+ NT_SUCCESS if a Fib was returned to the caller.
6112+ NT_ERROR if event was an invalid event.
6113+
6114+--*/
6115+{
6116+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6117+ PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6118+ PFIB Fib = FibContext->Fib;
6119+
6120+ //
6121+ // Check for a fib which has already been completed
6122+ //
6123+
6124+// ASSERT(Fib->Header.XferState & AdapterProcessed);
6125+ if (Fib->Header.XferState == 0)
6126+ return(STATUS_SUCCESS);
6127+
6128+ //
6129+ // If we plan to do anything check the structure type first.
6130+ //
6131+
6132+ if ( Fib->Header.StructType != TFib ) {
6133+ FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6134+ return(STATUS_UNSUCCESSFUL);
6135+ }
6136+
6137+#if 0
6138+//#if FSA_ADAPTER_METER
6139+ //
6140+ // Meter the completion
6141+ //
6142+ fsaMeterEnd( // meter the end of an operation
6143+ &(Adapter->FibMeter), // .. the meter
6144+ IrpContext->FibMeterType, // .. type of operation
6145+ &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6146+ FibGetMeterSize(Fib, // .. number of bytes in operation
6147+ IrpContext->FibMeterType,
6148+ IrpContext->FibSubCommand));
6149+#endif // FSA_ADAPTER_METER
6150+
6151+ //
6152+ // This block completes a cdb which orginated on the host and we just need
6153+ // to deallocate the cdb or reinit it. At this point the command is complete
6154+ // that we had sent to the adapter and this cdb could be reused.
6155+ //
6156+
6157+ if ( (Fib->Header.XferState & SentFromHost) &&
6158+ (Fib->Header.XferState & AdapterProcessed)) {
6159+
6160+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6161+
6162+ return( DeallocateFib(FibContext) );
6163+
6164+ //
6165+ // This handles the case when the host has aborted the I/O to the
6166+ // adapter because the adapter is not responding
6167+ //
6168+
6169+ } else if (Fib->Header.XferState & SentFromHost) {
6170+
6171+ ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6172+
6173+
6174+ return( DeallocateFib(FibContext) );
6175+
6176+ } else if (Fib->Header.XferState & HostOwned) {
6177+
6178+ return(DeallocateFib(FibContext));
6179+
6180+ } else {
6181+ cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6182+ FsaBugCheck(0,0,0);
6183+ }
6184+ return(STATUS_SUCCESS);
6185+}
6186+
6187+VOID
6188+HandleDriverAif(
6189+ IN PAFA_COMM_ADAPTER Adapter,
6190+ IN PCOMM_FIB_CONTEXT FibContext
6191+ )
6192+/*++
6193+
6194+Routine Description:
6195+
6196+ This routine handles a driver notify fib from the adapter and dispatches it to
6197+ the appropriate routine for handling.
6198+
6199+Arguments:
6200+
6201+ Adapter - Which adapter this fib is from
6202+ FibContext - Pointer to FibContext from adapter.
6203+
6204+Return Value:
6205+
6206+ Nothing.
6207+
6208+--*/
6209+{
6210+ PFIB Fib = FibContext->Fib;
6211+ PAFA_CLASS_DRIVER ClassDriver;
6212+ BOOLEAN Handled = FALSE;
6213+
6214+
6215+ //
6216+ // First loop through all of the class drivers to give them a chance to handle
6217+ // the Fib.
6218+ //
6219+
6220+ ClassDriver = Adapter->ClassDriverList;
6221+
6222+ while (ClassDriver) {
6223+
6224+ if (ClassDriver->HandleAif) {
6225+
6226+ if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6227+
6228+ Handled = TRUE;
6229+ break;
6230+
6231+ }
6232+ }
6233+
6234+ ClassDriver = ClassDriver->Next;
6235+ }
6236+
6237+ if (!Handled) {
6238+
6239+ //
6240+ // Set the status of this FIB to be Invalid parameter.
6241+ //
6242+
6243+// *(FSASTATUS *)Fib->data = ST_INVAL;
6244+ *(FSASTATUS *)Fib->data = ST_OK;
6245+
6246+
6247+ CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6248+
6249+ }
6250+}
6251+
6252+int
6253+NormCommandThread(
6254+ IN PAFA_COMM_ADAPTER Adapter
6255+ )
6256+/*++
6257+
6258+Routine Description:
6259+
6260+ Waits on the commandready event in it's queue. When the event gets set it will
6261+ pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6262+ When the queue is empty it will wait for more FIBs.
6263+
6264+Arguments:
6265+
6266+ Context is used. All data os global
6267+
6268+Return Value:
6269+ Nothing.
6270+
6271+--*/
6272+{
6273+ PFIB Fib, NewFib;
6274+ COMM_FIB_CONTEXT FibContext; // for error logging
6275+ KIRQL SavedIrql;
6276+ PCOMM_REGION CommRegion = Adapter->CommRegion;
6277+ PLIST_ENTRY Entry;
6278+ PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6279+
6280+ //
6281+ // We can only have one thread per adapter for AIF's.
6282+ //
6283+
6284+ if (Adapter->AifThreadStarted) {
6285+ return (EINVAL);
6286+ }
6287+
6288+// cmn_err(CE_DEBUG, "AIF thread started");
6289+
6290+ //
6291+ // Let the DPC know it has a place to send the AIF's to.
6292+ //
6293+
6294+ Adapter->AifThreadStarted = TRUE;
6295+
6296+ RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6297+
6298+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6299+
6300+ while (TRUE) {
6301+
6302+ //
6303+ // NOTE : the QueueLock is held at the top of each loop.
6304+ //
6305+
6306+ ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6307+
6308+ while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6309+ PLIST_ENTRY Entry;
6310+ PAIFCOMMANDTOHOST AifCommandToHost;
6311+
6312+ Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6313+
6314+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6315+
6316+ Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6317+
6318+ //
6319+ // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6320+ // can't do anything at this point since we don't have anything defined for this thread to
6321+ // do.
6322+ //
6323+
6324+ // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6325+
6326+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6327+
6328+
6329+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6330+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6331+ FibContext.Fib = Fib;
6332+ FibContext.FibData = Fib->data;
6333+ FibContext.Adapter = Adapter;
6334+
6335+
6336+ //
6337+ // We only handle AifRequest fibs from the adapter.
6338+ //
6339+
6340+ ASSERT(Fib->Header.Command == AifRequest);
6341+
6342+
6343+ AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6344+
6345+ if (AifCommandToHost->command == AifCmdDriverNotify) {
6346+
6347+
6348+
6349+ HandleDriverAif( Adapter, &FibContext );
6350+
6351+ } else {
6352+ AAC_UINT32 time_now, time_last;
6353+ time_now = (AAC_UINT32)OsGetSeconds();
6354+
6355+
6356+ OsCvLockAcquire(Adapter->AdapterFibMutex);
6357+
6358+ Entry = Adapter->AdapterFibContextList.Flink;
6359+
6360+ //
6361+ // For each Context that is on the AdapterFibContextList, make a copy of the
6362+ // fib, and then set the event to wake up the thread that is waiting for it.
6363+ //
6364+
6365+ while (Entry != &Adapter->AdapterFibContextList) {
6366+
6367+ //
6368+ // Extract the AdapterFibContext
6369+ //
6370+
6371+ AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6372+
6373+ //
6374+ // Check if the queue is getting backlogged
6375+ //
6376+ if ( AdapterFibContext->FibCount > 20 ) {
6377+ time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6378+
6379+ //
6380+ // has it been > 2 minutes since the last read off the queue?
6381+ //
6382+ if ((time_now - time_last) > 120) {
6383+ Entry = Entry->Flink;
6384+ // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6385+ // time_now - time_last,
6386+ // AdapterFibContext->FibCount);
6387+ FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6388+ continue;
6389+ }
6390+ }
6391+
6392+// Warning: sleep possible while holding spinlock
6393+ NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6394+
6395+ if (NewFib) {
6396+
6397+ //
6398+ // Make the copy of the FIB
6399+ //
6400+
6401+ RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6402+
6403+ //
6404+ // Put the FIB onto the AdapterFibContext's FibList
6405+ //
6406+
6407+ InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6408+ AdapterFibContext->FibCount++;
6409+
6410+ //
6411+ // Set the event to wake up the thread that will waiting.
6412+ //
6413+
6414+ OsCv_signal(&AdapterFibContext->UserEvent);
6415+
6416+ } else {
6417+
6418+
6419+ }
6420+
6421+ Entry = Entry->Flink;
6422+ }
6423+
6424+ //
6425+ // Set the status of this FIB
6426+ //
6427+
6428+ *(FSASTATUS *)Fib->data = ST_OK;
6429+
6430+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6431+
6432+ OsCvLockRelease(Adapter->AdapterFibMutex);
6433+
6434+ }
6435+
6436+ OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6437+
6438+ }
6439+
6440+ //
6441+ // There are no more AIF's, call cv_wait_sig to wait for more
6442+ // to process.
6443+ //
6444+
6445+ // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6446+
6447+ if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6448+ CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6449+
6450+ OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6451+
6452+ Adapter->AifThreadStarted = FALSE;
6453+
6454+ // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6455+
6456+ return (EINTR);
6457+
6458+ }
6459+
6460+ // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6461+
6462+ }
6463+}
6464+
6465+
6466+PVOID
6467+FsaGetFibData(
6468+ IN PFIB_CONTEXT Context
6469+ )
6470+{
6471+ PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6472+
6473+ return ((PVOID)FibContext->Fib->data);
6474+}
6475+
6476+
6477+#ifdef API_THROTTLE
6478+
6479+void ThrottlePeriodEndDpcRtn(
6480+ IN PKDPC Dpc,
6481+ IN PVOID DeferredContext,
6482+ IN PVOID SystemArgument1,
6483+ IN PVOID SystemArgument2
6484+ )
6485+/*++
6486+
6487+Routine Description:
6488+
6489+ This routine is called as a DPC when a throttle period expires. It
6490+ restarts all threads suspended due to the throttling flow control.
6491+
6492+ The throttling counted semaphore is signalled for all waiting threads
6493+ and the indicator of throttling active is cleared.
6494+
6495+Arguments:
6496+
6497+ Dpc - Pointer to Dpc structure. Not used.
6498+ DefferedContext - Pointer to per-adapter context. This is used to locate the
6499+ throttle information for this adapter.
6500+ SystemArgument1 - Not used
6501+ SystemArgument2 - Not used
6502+
6503+Return Value:
6504+
6505+ None.
6506+
6507+--*/
6508+{
6509+ PCOMM_REGION CommRegion;
6510+ PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6511+
6512+ CommRegion = Adapter->CommRegion;
6513+
6514+ //
6515+ // Acquire the spinlock protecting the throttle status.
6516+ //
6517+ OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6518+
6519+ FsaCommPrint("ThrottlePeriodEndDpc\n");
6520+
6521+ //
6522+ // Check that the timer has fired as many times as it was set !
6523+ //
6524+
6525+ CommRegion->ThrottleTimerFires++;
6526+ ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6527+
6528+ //
6529+ // The throttle period is now over. Restart all threads waiting
6530+ // on the throttle being released.
6531+ // Clear the throttle active indicator. This will allow new FIBs
6532+ // to be sent to the adapter once we release the spinlock on exiting
6533+ // the DPC. This means all restarted threads will be runnable
6534+ // threads by then.
6535+ //
6536+
6537+ ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6538+ CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6539+
6540+ OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6541+}
6542+
6543+#endif // #ifdef API_THROTTLE
6544+
6545+/*
6546+ * Overrides for Emacs so that we almost follow Linus's tabbing style.
6547+ * Emacs will notice this stuff at the end of the file and automatically
6548+ * adjust the settings for this buffer only. This must remain at the end
6549+ * of the file.
6550+ * ---------------------------------------------------------------------------
6551+ * Local variables:
6552+ * c-indent-level: 4
6553+ * c-brace-imaginary-offset: 0
6554+ * c-brace-offset: -4
6555+ * c-argdecl-indent: 4
6556+ * c-label-offset: -4
6557+ * c-continued-statement-offset: 4
6558+ * c-continued-brace-offset: 0
6559+ * indent-tabs-mode: nil
6560+ * tab-width: 8
6561+ * End:
6562+ */
6563diff -urN linux/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6564--- linux/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 19:00:00 1969
6565+++ linux/drivers/scsi/aacraid/dpcsup.c Thu Dec 21 13:14:30 2000
6566@@ -0,0 +1,443 @@
6567+/*++
6568+ * Adaptec aacraid device driver for Linux.
6569+ *
6570+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6571+ *
6572+ * This program is free software; you can redistribute it and/or modify
6573+ * it under the terms of the GNU General Public License as published by
6574+ * the Free Software Foundation; either version 2, or (at your option)
6575+ * any later version.
6576+ *
6577+ * This program is distributed in the hope that it will be useful,
6578+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6579+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6580+ * GNU General Public License for more details.
6581+ *
6582+ * You should have received a copy of the GNU General Public License
6583+ * along with this program; see the file COPYING. If not, write to
6584+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6585+ *
6586+ * Module Name:
6587+ * dpcsup.c
6588+ *
6589+ * Abstract: All DPC processing routines for the cyclone board occur here.
6590+ *
6591+ *
6592+ --*/
6593+
6594+static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6595+
6596+#include "comprocs.h"
6597+
6598+
6599+//
6600+// The Bug check file id for this module
6601+//
6602+
6603+#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6604+
6605+#define Dbg (DEBUG_TRACE_DPCSUP)
6606+
6607+u_int
6608+CommonNotFullDpc(
6609+ IN PCOMM_REGION CommRegion
6610+ )
6611+/*++
6612+
6613+Routine Description:
6614+
6615+ This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6616+ no longer full. The Isr will pass the queue that we will set the not full event.
6617+
6618+Arguments:
6619+
6620+ Dpc - Pointer to this routine.
6621+
6622+ Dummy - is a pointer to the comm region which is global so we don't need it anyway
6623+
6624+ Queue is a pointer to the queue structure we will operate on.
6625+
6626+ MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6627+ stuff in here.
6628+
6629+Return Value:
6630+ Nothing.
6631+
6632+--*/
6633+{
6634+
6635+#ifdef unix_queue_full
6636+ KeSetEvent(&Queue->QueueFull, 0, FALSE);
6637+#endif
6638+
6639+}
6640+
6641+int GatherFibTimes = 0;
6642+
6643+// XXX - hack this in until I figure out which header file should contain it. <smb>
6644+extern ULONG
6645+FibGetMeterSize(
6646+ PFIB pFib,
6647+ ULONG MeterType,
6648+ char SubCommand
6649+ );
6650+
6651+
6652+/*++
6653+
6654+Routine Description:
6655+
6656+ This DPC routine will be queued when the adapter interrupts us to let us know there
6657+ is a response on our normal priority queue. We will pull off all QE there are and wake
6658+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6659+ on it.
6660+
6661+Arguments:
6662+
6663+ Dpc - Pointer to this routine.
6664+
6665+ OurQueue is a pointer to the queue structure we will operate on.
6666+
6667+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6668+ stuff in here.
6669+
6670+Return Value:
6671+ Nothing.
6672+
6673+--*/
6674+u_int
6675+HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6676+{
6677+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6678+ PQUEUE_ENTRY QueueEntry;
6679+ PFIB Fib;
6680+ PCOMM_FIB_CONTEXT FibContext;
6681+ int Consumed = 0;
6682+ KIRQL OldIrql;
6683+
6684+ LARGE_INTEGER ResponseAllocSize;
6685+
6686+#ifdef commdebug
6687+ FsaCommPrint("entering the host normal reponse dpc routine.\n");
6688+#endif
6689+
6690+ OsSpinLockAcquire( OurQueue->QueueLock );
6691+
6692+ //
6693+ // Keep pulling response QEs off the response queue and waking
6694+ // up the waiters until there are no more QEs. We then return
6695+ // back to the system. If no response was requesed we just
6696+ // deallocate the Fib here and continue.
6697+ //
6698+
6699+ loop:
6700+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6701+
6702+ int IsFastResponse;
6703+
6704+ IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6705+ Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6706+
6707+ FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6708+
6709+ FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6710+
6711+ ASSERT(FibContext->Fib == Fib);
6712+
6713+ //
6714+ // Remove this FibContext from the Outstanding I/O queue.
6715+ // But only if it has not already been timed out.
6716+ //
6717+ // If the fib has been timed out already, then just continue.
6718+ // The caller has already been notified that the fib timed out.
6719+ //
6720+
6721+ if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6722+
6723+ RemoveEntryList( &FibContext->QueueEntry );
6724+ Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6725+
6726+ } else {
6727+
6728+ FsaCommLogEvent(FibContext,
6729+ FsaCommData.DeviceObject,
6730+ FSAFS_TIMED_OUT_FIB_COMPLETED,
6731+ STATUS_UNSUCCESSFUL,
6732+ BugCheckFileId | __LINE__,
6733+ FACILITY_FSAFS_ERROR_CODE,
6734+ NULL,
6735+ TRUE);
6736+
6737+ continue;
6738+
6739+ }
6740+
6741+ OsSpinLockRelease( OurQueue->QueueLock );
6742+
6743+ if (IsFastResponse) {
6744+
6745+ //
6746+ // doctor the fib
6747+ //
6748+
6749+ *(FSASTATUS *)Fib->data = ST_OK;
6750+
6751+ Fib->Header.XferState |= AdapterProcessed;
6752+
6753+ }
6754+
6755+ ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6756+
6757+ FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6758+
6759+ ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6760+
6761+
6762+ if (Fib->Header.Command == NuFileSystem) {
6763+
6764+ FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6765+
6766+ if (*pStatus & 0xffff0000) {
6767+
6768+ ULONG Hint = *pStatus;
6769+
6770+ *pStatus = ST_OK;
6771+
6772+/*
6773+ DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6774+ IrpContext->NonPaged->FileId.fid_driveno,
6775+ IrpContext->NonPaged->FileId.fid_f1,
6776+ IrpContext->NonPaged->FileId.fid_f2,
6777+ IrpContext->NonPaged->FileId.fid_hint,
6778+ Hint);
6779+*/
6780+
6781+ }
6782+
6783+ }
6784+
6785+ if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6786+
6787+ ASSERT(FibContext->FibCallback);
6788+
6789+ if (Fib->Header.XferState & NoResponseExpected)
6790+ FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6791+ else
6792+ FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6793+
6794+ //
6795+ // NOTE: we can not touch the FibContext after this call, because it may have been
6796+ // deallocated.
6797+ //
6798+
6799+ FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6800+
6801+ } else {
6802+
6803+ OsCvLockAcquire( FibContext->FsaEventMutex);
6804+
6805+ FibContext->FibComplete = 1;
6806+
6807+ OsCv_signal( &FibContext->FsaEvent );
6808+
6809+ OsCvLockRelease( FibContext->FsaEventMutex );
6810+
6811+ FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6812+
6813+ }
6814+
6815+
6816+ Consumed++;
6817+
6818+ OsSpinLockAcquire( OurQueue->QueueLock );
6819+
6820+ }
6821+
6822+ if (Consumed > FsaCommData.PeakFibsConsumed)
6823+ FsaCommData.PeakFibsConsumed = Consumed;
6824+
6825+ if (Consumed == 0)
6826+ FsaCommData.ZeroFibsConsumed++;
6827+
6828+ if (FsaCommData.HardInterruptModeration) {
6829+
6830+ //
6831+ // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6832+ // been put on the queue. This removes the race condition that exists between the
6833+ // last time we checked the queue, and when we re-enabled the interrupt.
6834+ //
6835+ // If there is something on the queue, then go handle it.
6836+ //
6837+
6838+ EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6839+
6840+ if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6841+
6842+ DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6843+
6844+ goto loop;
6845+
6846+ }
6847+ }
6848+
6849+#ifdef commdebug
6850+ FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6851+#endif
6852+
6853+ OsSpinLockRelease( OurQueue->QueueLock );
6854+
6855+}
6856+
6857+/*++
6858+
6859+Routine Description:
6860+
6861+ This DPC routine wiol be queued when the adapter interrupts us to let us know there
6862+ is a response on our high priority queue. We will pull off all QE there are and wake
6863+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6864+ on it.
6865+
6866+Arguments:
6867+
6868+ Dpc - Pointer to this routine.
6869+
6870+ OurQueue is a pointer to the queue structure we will operate on.
6871+
6872+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6873+ stuff in here.
6874+
6875+Return Value:
6876+ Nothing.
6877+
6878+--*/
6879+u_int
6880+HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6881+{}
6882+
6883+
6884+/*++
6885+
6886+Routine Description:
6887+
6888+ This DPC routine will be queued when the adapter interrupts us to let us know there
6889+ is a command on our high priority queue. We will pull off all QE there are and wake
6890+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6891+ on it.
6892+
6893+Arguments:
6894+
6895+ Dpc - Pointer to this routine.
6896+
6897+ OurQueue is a pointer to the queue structure we will operate on.
6898+
6899+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6900+ stuff in here.
6901+
6902+Return Value:
6903+ Nothing.
6904+
6905+--*/
6906+u_int
6907+HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6908+{}
6909+
6910+
6911+/*++
6912+
6913+Routine Description:
6914+
6915+ This DPC routine will be queued when the adapter interrupts us to let us know there
6916+ is a command on our normal priority queue. We will pull off all QE there are and wake
6917+ up all the waiters before exiting. We will take a spinlock out on the queue before operating
6918+ on it.
6919+
6920+Arguments:
6921+
6922+ Dpc - Pointer to this routine.
6923+
6924+ OurQueue is a pointer to the queue structure we will operate on.
6925+
6926+ MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6927+ stuff in here.
6928+
6929+Return Value:
6930+ Nothing.
6931+
6932+--*/
6933+u_int
6934+HostCommandNormDpc (IN PCOMM_QUE OurQueue)
6935+{
6936+ PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6937+ PQUEUE_ENTRY QueueEntry;
6938+
6939+ OsSpinLockAcquire( OurQueue->QueueLock );
6940+
6941+ //
6942+ // Keep pulling response QEs off the response queue and waking
6943+ // up the waiters until there are no more QEs. We then return
6944+ // back to the system.
6945+ //
6946+
6947+ while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6948+
6949+ PFIB Fib;
6950+
6951+ Fib = (PFIB)QueueEntry->FibAddress;
6952+
6953+
6954+ if (Adapter->AifThreadStarted) {
6955+
6956+
6957+// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
6958+
6959+
6960+ InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
6961+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
6962+ OsCv_signal(&OurQueue->CommandReady);
6963+
6964+
6965+
6966+ } else {
6967+
6968+
6969+
6970+ COMM_FIB_CONTEXT FibContext;
6971+
6972+
6973+
6974+ FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
6975+
6976+
6977+
6978+ OsSpinLockRelease( OurQueue->QueueLock );
6979+
6980+
6981+
6982+// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
6983+
6984+
6985+ RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6986+
6987+ FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6988+ FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6989+ FibContext.Fib = Fib;
6990+ FibContext.FibData = Fib->data;
6991+ FibContext.Adapter = Adapter;
6992+
6993+ //
6994+ // Set the status of this FIB
6995+ //
6996+
6997+ *(FSASTATUS *)Fib->data = ST_OK;
6998+
6999+ CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7000+
7001+
7002+
7003+ OsSpinLockAcquire( OurQueue->QueueLock );
7004+ }
7005+ }
7006+
7007+ OsSpinLockRelease( OurQueue->QueueLock );
7008+
7009+}
7010diff -urN linux/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7011--- linux/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 19:00:00 1969
7012+++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Thu Dec 21 13:14:30 2000
7013@@ -0,0 +1,57 @@
7014+/*++
7015+ * Adaptec aacraid device driver for Linux.
7016+ *
7017+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7018+ *
7019+ * This program is free software; you can redistribute it and/or modify
7020+ * it under the terms of the GNU General Public License as published by
7021+ * the Free Software Foundation; either version 2, or (at your option)
7022+ * any later version.
7023+ *
7024+ * This program is distributed in the hope that it will be useful,
7025+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7026+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7027+ * GNU General Public License for more details.
7028+ *
7029+ * You should have received a copy of the GNU General Public License
7030+ * along with this program; see the file COPYING. If not, write to
7031+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7032+ *
7033+ * Module Name:
7034+ *
7035+ * AacGenericTypes.h
7036+ *
7037+ * Abstract:
7038+ *
7039+ * The module defines the generic data types that all of the other header files
7040+ * depend upon.
7041+ --*/
7042+
7043+#ifndef _AAC_GENERIC_TYPES
7044+#define _AAC_GENERIC_TYPES
7045+
7046+static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7047+
7048+typedef char AAC_INT8, *PAAC_INT8;
7049+typedef short AAC_INT16, *PAAC_INT16;
7050+typedef int AAC_INT32, *PAAC_INT32;
7051+typedef long long AAC_INT64, *PAAC_INT64;
7052+
7053+typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7054+typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7055+typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7056+typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7057+
7058+typedef void AAC_VOID, *PAAC_VOID;
7059+
7060+//
7061+// this compiler uses 32 bit enum data types
7062+//
7063+
7064+#define AAC_32BIT_ENUMS 1
7065+#define FAILURE 1
7066+#define INTR_UNCLAIMED 1
7067+#define INTR_CLAIMED 0
7068+
7069+#endif // _AAC_GENERIC_TYPES
7070+
7071diff -urN linux/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7072--- linux/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 19:00:00 1969
7073+++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Thu Dec 21 13:14:30 2000
7074@@ -0,0 +1,300 @@
7075+/*++
7076+ * Adaptec aacraid device driver for Linux.
7077+ *
7078+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7079+ *
7080+ * This program is free software; you can redistribute it and/or modify
7081+ * it under the terms of the GNU General Public License as published by
7082+ * the Free Software Foundation; either version 2, or (at your option)
7083+ * any later version.
7084+ *
7085+ * This program is distributed in the hope that it will be useful,
7086+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7087+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7088+ * GNU General Public License for more details.
7089+ *
7090+ * You should have received a copy of the GNU General Public License
7091+ * along with this program; see the file COPYING. If not, write to
7092+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7093+ *
7094+ * Module Name:
7095+ *
7096+ * aac_unix_defs.h
7097+ *
7098+ * Abstract:
7099+ *
7100+ * Macro definition and typedefs
7101+ *
7102+ --*/
7103+
7104+#ifndef _AAC_UNIX_DEFS
7105+#define _AAC_UNIX_DEFS
7106+
7107+static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7108+
7109+#define AAC_MAX_ADAPTERS 64
7110+
7111+#ifndef TRUE
7112+#define TRUE 1
7113+#define FALSE 0
7114+#endif
7115+
7116+#define PAGE_SIZE 4096
7117+
7118+typedef void VOID;
7119+typedef VOID *PVOID;
7120+
7121+typedef char CHAR, *PCHAR;
7122+typedef unsigned char UCHAR, *PUCHAR;
7123+typedef short SHORT, *PSHORT;
7124+typedef short CSHORT, *PCSHORT;
7125+typedef unsigned short USHORT, *PUSHORT;
7126+typedef unsigned long ULONG, *PULONG;
7127+typedef long LONG, *PLONG;
7128+
7129+typedef unsigned long BOOLEAN;
7130+
7131+typedef unsigned long AAC_STATUS, *PNT_STATUS;
7132+
7133+typedef struct {
7134+ unsigned long LowPart;
7135+ unsigned long HighPart;
7136+} LARGE_INTEGER;
7137+
7138+typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7139+
7140+
7141+typedef struct _AFA_IOCTL_CMD {
7142+ int cmd;
7143+ intptr_t arg;
7144+ int flag;
7145+ cred_t *cred_p;
7146+ int *rval_p;
7147+} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7148+
7149+
7150+//
7151+// Singly linked list structure. Can be used as either a list head, or
7152+// as link words.
7153+//
7154+
7155+typedef struct _SINGLE_LIST_ENTRY {
7156+ struct _SINGLE_LIST_ENTRY *Next;
7157+} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7158+
7159+
7160+//
7161+// Calculate the address of the base of the structure given its type, and an
7162+// address of a field within the structure.
7163+//
7164+
7165+#define CONTAINING_RECORD(address, type, field) ((type *)( \
7166+ (PCHAR)(address) - \
7167+ (PCHAR)(&((type *)0)->field)))
7168+
7169+typedef PVOID PMDL;
7170+typedef PVOID PDEVICE_OBJECT;
7171+typedef PVOID PADAPTER_OBJECT;
7172+typedef ULONG KIRQL;
7173+typedef PVOID HANDLE;
7174+typedef PVOID KDPC, *PKDPC;
7175+typedef PVOID PFILE_OBJECT;
7176+typedef PVOID PIRP;
7177+typedef PVOID PDRIVER_OBJECT;
7178+typedef ULONG KTIMER;
7179+
7180+
7181+#define STATUS_SUCCESS 0x00000000
7182+#define STATUS_PENDING 0x40000001
7183+#define STATUS_IO_TIMEOUT 0xc0000001
7184+#define STATUS_UNSUCCESSFUL 0xc0000002
7185+#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7186+#define STATUS_BUFFER_OVERFLOW 0xc0000003
7187+
7188+
7189+#define OUT
7190+
7191+
7192+
7193+typedef u_int
7194+(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7195+
7196+//
7197+// Zone Allocation
7198+//
7199+
7200+typedef struct _ZONE_SEGMENT_HEADER {
7201+ SINGLE_LIST_ENTRY SegmentList;
7202+ PVOID Reserved;
7203+} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7204+
7205+typedef struct _ZONE_HEADER {
7206+ SINGLE_LIST_ENTRY FreeList;
7207+ SINGLE_LIST_ENTRY SegmentList;
7208+ ULONG BlockSize;
7209+ ULONG TotalSegmentSize;
7210+} ZONE_HEADER, *PZONE_HEADER;
7211+
7212+
7213+//++
7214+//
7215+// PVOID
7216+// ExAllocateFromZone(
7217+// IN PZONE_HEADER Zone
7218+// )
7219+//
7220+// Routine Description:
7221+//
7222+// This routine removes an entry from the zone and returns a pointer to it.
7223+//
7224+// Arguments:
7225+//
7226+// Zone - Pointer to the zone header controlling the storage from which the
7227+// entry is to be allocated.
7228+//
7229+// Return Value:
7230+//
7231+// The function value is a pointer to the storage allocated from the zone.
7232+//
7233+//--
7234+
7235+#define ExAllocateFromZone(Zone) \
7236+ (PVOID)((Zone)->FreeList.Next); \
7237+ if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7238+
7239+//++
7240+//
7241+// PVOID
7242+// ExFreeToZone(
7243+// IN PZONE_HEADER Zone,
7244+// IN PVOID Block
7245+// )
7246+//
7247+// Routine Description:
7248+//
7249+// This routine places the specified block of storage back onto the free
7250+// list in the specified zone.
7251+//
7252+// Arguments:
7253+//
7254+// Zone - Pointer to the zone header controlling the storage to which the
7255+// entry is to be inserted.
7256+//
7257+// Block - Pointer to the block of storage to be freed back to the zone.
7258+//
7259+// Return Value:
7260+//
7261+// Pointer to previous block of storage that was at the head of the free
7262+// list. NULL implies the zone went from no available free blocks to
7263+// at least one free block.
7264+//
7265+//--
7266+
7267+#define ExFreeToZone(Zone,Block) \
7268+ ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7269+ (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7270+ ((PSINGLE_LIST_ENTRY)(Block))->Next \
7271+ )
7272+
7273+//++
7274+//
7275+// BOOLEAN
7276+// ExIsFullZone(
7277+// IN PZONE_HEADER Zone
7278+// )
7279+//
7280+// Routine Description:
7281+//
7282+// This routine determines if the specified zone is full or not. A zone
7283+// is considered full if the free list is empty.
7284+//
7285+// Arguments:
7286+//
7287+// Zone - Pointer to the zone header to be tested.
7288+//
7289+// Return Value:
7290+//
7291+// TRUE if the zone is full and FALSE otherwise.
7292+//
7293+//--
7294+
7295+#define ExIsFullZone(Zone) \
7296+ ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7297+
7298+
7299+#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7300+#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7301+
7302+//
7303+// Doubly-linked list manipulation routines. Implemented as macros
7304+// but logically these are procedures.
7305+//
7306+
7307+//
7308+// VOID
7309+// InitializeListHead(
7310+// PLIST_ENTRY ListHead
7311+// );
7312+//
7313+
7314+#define InitializeListHead(ListHead) (\
7315+ (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7316+
7317+//
7318+// BOOLEAN
7319+// IsListEmpty(
7320+// PLIST_ENTRY ListHead
7321+// );
7322+//
7323+
7324+#define IsListEmpty(ListHead) \
7325+ ((ListHead)->Flink == (ListHead))
7326+
7327+//
7328+// PLIST_ENTRY
7329+// RemoveHeadList(
7330+// PLIST_ENTRY ListHead
7331+// );
7332+//
7333+
7334+#define RemoveHeadList(ListHead) \
7335+ (ListHead)->Flink;\
7336+ {RemoveEntryList((ListHead)->Flink)}
7337+
7338+
7339+//
7340+// VOID
7341+// RemoveEntryList(
7342+// PLIST_ENTRY Entry
7343+// );
7344+//
7345+
7346+#define RemoveEntryList(Entry) {\
7347+ PLIST_ENTRY _EX_Blink;\
7348+ PLIST_ENTRY _EX_Flink;\
7349+ _EX_Flink = (Entry)->Flink;\
7350+ _EX_Blink = (Entry)->Blink;\
7351+ _EX_Blink->Flink = _EX_Flink;\
7352+ _EX_Flink->Blink = _EX_Blink;\
7353+ }
7354+
7355+//
7356+// VOID
7357+// InsertTailList(
7358+// PLIST_ENTRY ListHead,
7359+// PLIST_ENTRY Entry
7360+// );
7361+//
7362+
7363+#define InsertTailList(ListHead,Entry) {\
7364+ PLIST_ENTRY _EX_Blink;\
7365+ PLIST_ENTRY _EX_ListHead;\
7366+ _EX_ListHead = (ListHead);\
7367+ _EX_Blink = _EX_ListHead->Blink;\
7368+ (Entry)->Flink = _EX_ListHead;\
7369+ (Entry)->Blink = _EX_Blink;\
7370+ _EX_Blink->Flink = (Entry);\
7371+ _EX_ListHead->Blink = (Entry);\
7372+ }
7373+
7374+#endif /* AAC_UNIX_DEFS */
7375diff -urN linux/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7376--- linux/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 19:00:00 1969
7377+++ linux/drivers/scsi/aacraid/include/adapter.h Thu Dec 21 13:14:30 2000
7378@@ -0,0 +1,164 @@
7379+/*++
7380+ * Adaptec aacraid device driver for Linux.
7381+ *
7382+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7383+ *
7384+ * This program is free software; you can redistribute it and/or modify
7385+ * it under the terms of the GNU General Public License as published by
7386+ * the Free Software Foundation; either version 2, or (at your option)
7387+ * any later version.
7388+ *
7389+ * This program is distributed in the hope that it will be useful,
7390+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7391+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7392+ * GNU General Public License for more details.
7393+ *
7394+ * You should have received a copy of the GNU General Public License
7395+ * along with this program; see the file COPYING. If not, write to
7396+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7397+ *
7398+ * Module Name:
7399+ *
7400+ * Adapter.h
7401+ *
7402+ * Abstract:
7403+ * The module contains the definitions for a comm layer view of the adapter.
7404+ *
7405+ *
7406+ *
7407+ --*/
7408+
7409+#ifndef _ADAPTER_
7410+#define _ADAPTER_
7411+
7412+static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7413+
7414+typedef struct _GET_ADAPTER_FIB_CONTEXT {
7415+
7416+ NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7417+ NODE_BYTE_SIZE NodeByteSize;
7418+ PFILE_OBJECT FileObject; // used for cleanup
7419+ LIST_ENTRY NextContext; // used to link context's into a linked list
7420+ OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7421+ BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7422+ ULONG FibCount; // total number of FIBs on FibList
7423+ LIST_ENTRY FibList;
7424+} GET_ADAPTER_FIB_CONTEXT;
7425+typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7426+
7427+
7428+typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7429+
7430+ struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7431+ ULONG FibContextSegmentSize;
7432+ PVOID FibContextSegment;
7433+ ULONG ExtendSize;
7434+ MAPFIB_CONTEXT MapFibContext;
7435+
7436+} FIB_CONTEXT_ZONE_SEGMENT;
7437+typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7438+
7439+typedef struct _AFA_COMM_ADAPTER {
7440+
7441+ struct _AFA_COMM_ADAPTER *NextAdapter;
7442+
7443+ //
7444+ // The following fields are used to allocate FIB context structures
7445+ // using the zone allocator, and other fixed sized structures from a
7446+ // small cache. The mutex protects access to the zone/lists
7447+ //
7448+
7449+ ZONE_HEADER FibContextZone;
7450+ OS_SPINLOCK *FibContextZoneSpinLock;
7451+ int FibContextZoneExtendSize;
7452+
7453+ PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7454+
7455+ PVOID FibContextTimedOutList;
7456+
7457+ PFIB SyncFib;
7458+ ULONG SyncFibPhysicalAddress;
7459+
7460+ PCOMM_REGION CommRegion;
7461+
7462+ OS_SPINLOCK_COOKIE SpinLockCookie;
7463+
7464+ //
7465+ // The user API will use an IOCTL to register itself to receive FIBs
7466+ // from the adapter. The following list is used to keep track of all
7467+ // the threads that have requested these FIBs. The mutex is used to
7468+ // synchronize access to all data associated with the adapter fibs.
7469+ //
7470+ LIST_ENTRY AdapterFibContextList;
7471+ OS_CVLOCK *AdapterFibMutex;
7472+
7473+ //
7474+ // The following holds which FileObject is allow to send configuration
7475+ // commands to the adapter that would modify the configuration.
7476+ //
7477+ // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7478+ // ioctls.
7479+ //
7480+ PFILE_OBJECT AdapterConfigFileObject;
7481+
7482+ //
7483+ // The following is really here because of the simulator
7484+ //
7485+ BOOLEAN InterruptsBelowDpc;
7486+
7487+ //
7488+ // The following is the device specific extension.
7489+ //
7490+ PVOID AdapterExtension;
7491+ PFSAPORT_FUNCS AdapterFuncs;
7492+ void *Dip;
7493+
7494+ //
7495+ // The following are user variables that are specific to the mini port.
7496+ //
7497+ PFSA_USER_VAR AdapterUserVars;
7498+ ULONG AdapterUserVarsSize;
7499+
7500+ //
7501+ // The following is the number of the individual adapter..i.e. \Device\Afa0
7502+ //
7503+ LONG AdapterNumber;
7504+
7505+ AFACOMM_FUNCS CommFuncs;
7506+
7507+ PAFA_CLASS_DRIVER ClassDriverList;
7508+
7509+ BOOLEAN AifThreadStarted;
7510+
7511+} AFA_COMM_ADAPTER;
7512+
7513+typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7514+
7515+
7516+#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7517+ Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7518+
7519+#define FsaFreeAdapterCommArea(Adapter) \
7520+ Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7521+
7522+
7523+#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7524+ Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7525+
7526+#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7527+ Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7528+
7529+#define InterruptAdapter(Adapter) \
7530+ Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7531+
7532+#define NotifyAdapter(Adapter, AdapterEvent) \
7533+ Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7534+
7535+#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7536+ Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7537+
7538+#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7539+ Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7540+
7541+
7542+#endif // _ADAPTER_
7543diff -urN linux/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7544--- linux/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 19:00:00 1969
7545+++ linux/drivers/scsi/aacraid/include/afacomm.h Thu Dec 21 13:14:30 2000
7546@@ -0,0 +1,191 @@
7547+/*++
7548+ * Adaptec aacraid device driver for Linux.
7549+ *
7550+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7551+ *
7552+ * This program is free software; you can redistribute it and/or modify
7553+ * it under the terms of the GNU General Public License as published by
7554+ * the Free Software Foundation; either version 2, or (at your option)
7555+ * any later version.
7556+ *
7557+ * This program is distributed in the hope that it will be useful,
7558+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7559+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7560+ * GNU General Public License for more details.
7561+ *
7562+ * You should have received a copy of the GNU General Public License
7563+ * along with this program; see the file COPYING. If not, write to
7564+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7565+ *
7566+ * Module Name:
7567+ * AfaComm.h
7568+ *
7569+ * Abstract:
7570+ * This module defines all of the external interfaces to the AFA comm layer.
7571+ *
7572+ *
7573+ *
7574+ --*/
7575+#ifndef _AFACOMM_
7576+#define _AFACOMM_
7577+
7578+static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7579+
7580+#include "fsaport.h"
7581+
7582+typedef void *PFIB_CONTEXT;
7583+
7584+typedef VOID
7585+(*PFIB_CALLBACK)(
7586+ PVOID FibCallbackContext,
7587+ PFIB_CONTEXT FibContext,
7588+ AAC_STATUS Status
7589+ );
7590+
7591+
7592+typedef PFIB_CONTEXT
7593+(*PAFA_COMM_ALLOCATE_FIB) (
7594+ IN PVOID AdapterExtension
7595+ );
7596+
7597+typedef VOID
7598+(*PAFA_COMM_FREE_FIB) (
7599+ IN PFIB_CONTEXT FibContext
7600+ );
7601+
7602+
7603+typedef AAC_STATUS
7604+(*PAFA_COMM_DEALLOCATE_FIB) (
7605+ IN PFIB_CONTEXT FibContext
7606+ );
7607+
7608+
7609+typedef VOID
7610+(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7611+ IN PFIB_CONTEXT FibContext
7612+ );
7613+
7614+typedef AAC_STATUS
7615+(*PAFA_COMM_INITIALIZE_FIB) (
7616+ IN PFIB_CONTEXT FibContext
7617+ );
7618+
7619+typedef PVOID
7620+(*PAFA_COMM_GET_FIB_DATA) (
7621+ IN PFIB_CONTEXT FibContext
7622+ );
7623+
7624+typedef AAC_STATUS
7625+(*PAFA_COMM_SEND_FIB) (
7626+ IN FIB_COMMAND Command,
7627+ IN PFIB_CONTEXT FibContext,
7628+ IN ULONG Size,
7629+ IN COMM_PRIORITIES Priority,
7630+ IN BOOLEAN Wait,
7631+ IN PVOID WaitOn,
7632+ IN BOOLEAN ResponseExpected,
7633+ IN PFIB_CALLBACK FibCallback,
7634+ IN PVOID FibCallbackContext
7635+ );
7636+
7637+typedef AAC_STATUS
7638+(*PAFA_COMM_COMPLETE_FIB) (
7639+ IN PFIB_CONTEXT FibContext
7640+ );
7641+
7642+typedef AAC_STATUS
7643+(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7644+ IN PFIB_CONTEXT FibContext,
7645+ IN USHORT Size
7646+ );
7647+
7648+typedef BOOLEAN
7649+(*PAFA_COMM_SEND_SYNCH_FIB) (
7650+ PVOID AdapterExtension,
7651+ FIB_COMMAND Command,
7652+ PVOID Data,
7653+ USHORT Size,
7654+ PVOID Response,
7655+ USHORT *ResponseSize
7656+ );
7657+
7658+
7659+typedef struct _AFACOMM_FUNCS {
7660+ ULONG SizeOfAfaCommFuncs;
7661+ PAFA_COMM_ALLOCATE_FIB AllocateFib;
7662+ PAFA_COMM_FREE_FIB FreeFib;
7663+ PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7664+ PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7665+ PAFA_COMM_INITIALIZE_FIB InitializeFib;
7666+ PAFA_COMM_GET_FIB_DATA GetFibData;
7667+ PAFA_COMM_SEND_FIB SendFib;
7668+ PAFA_COMM_COMPLETE_FIB CompleteFib;
7669+ PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7670+ PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7671+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7672+ PFSA_BUILD_SGMAP BuildSgMap;
7673+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7674+} AFACOMM_FUNCS;
7675+typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7676+
7677+
7678+typedef AAC_STATUS
7679+(*PAFA_CLASS_OPEN_ADAPTER) (
7680+ IN PVOID Adapter
7681+ );
7682+
7683+
7684+typedef AAC_STATUS
7685+(*PAFA_CLASS_CLOSE_ADAPTER) (
7686+ IN PVOID Adapter
7687+ );
7688+
7689+
7690+typedef BOOLEAN
7691+(*PAFA_CLASS_DEV_CONTROL) (
7692+ IN PVOID Adapter,
7693+ IN PAFA_IOCTL_CMD IoctlCmdPtr,
7694+ OUT int * Status
7695+ );
7696+
7697+typedef BOOLEAN
7698+(*PAFA_CLASS_HANDLE_AIF) (
7699+ IN PVOID Adapter,
7700+ IN PFIB_CONTEXT FibContext
7701+ );
7702+
7703+
7704+typedef struct _AFA_NEW_CLASS_DRIVER {
7705+ PVOID ClassDriverExtension;
7706+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7707+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7708+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7709+ PAFA_CLASS_HANDLE_AIF HandleAif;
7710+ PFSA_USER_VAR UserVars;
7711+ ULONG NumUserVars;
7712+} AFA_NEW_CLASS_DRIVER;
7713+typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7714+
7715+
7716+typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7717+ PAFACOMM_FUNCS CommFuncs;
7718+ PVOID CommPortExtension;
7719+ PVOID MiniPortExtension;
7720+ OS_SPINLOCK_COOKIE SpinLockCookie;
7721+ void *Dip;
7722+} AFA_NEW_CLASS_DRIVER_RESPONSE;
7723+typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7724+
7725+
7726+typedef struct _AFA_CLASS_DRIVER {
7727+ struct _AFA_CLASS_DRIVER *Next;
7728+ PVOID ClassDriverExtension;
7729+ PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7730+ PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7731+ PAFA_CLASS_DEV_CONTROL DeviceControl;
7732+ PAFA_CLASS_HANDLE_AIF HandleAif;
7733+} AFA_CLASS_DRIVER;
7734+typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7735+
7736+
7737+#endif // _AFACOMM_
7738diff -urN linux/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7739--- linux/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 19:00:00 1969
7740+++ linux/drivers/scsi/aacraid/include/aifstruc.h Thu Dec 21 13:14:30 2000
7741@@ -0,0 +1,319 @@
7742+/*++
7743+ * Adaptec aacraid device driver for Linux.
7744+ *
7745+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7746+ *
7747+ * This program is free software; you can redistribute it and/or modify
7748+ * it under the terms of the GNU General Public License as published by
7749+ * the Free Software Foundation; either version 2, or (at your option)
7750+ * any later version.
7751+ *
7752+ * This program is distributed in the hope that it will be useful,
7753+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7754+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7755+ * GNU General Public License for more details.
7756+ *
7757+ * You should have received a copy of the GNU General Public License
7758+ * along with this program; see the file COPYING. If not, write to
7759+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7760+ *
7761+ * Module Name:
7762+ * Aifstruc.h
7763+ *
7764+ * Abstract:
7765+ * Define all shared data types relating to
7766+ * the set of features utilizing Adapter
7767+ * Initiated Fibs.
7768+ *
7769+ *
7770+ *
7771+ --*/
7772+#ifndef _AIFSTRUC_H
7773+#define _AIFSTRUC_H
7774+
7775+static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7776+
7777+#include <protocol.h>
7778+
7779+//
7780+// Progress report structure definitions
7781+//
7782+typedef enum {
7783+ AifJobStsSuccess = 1,
7784+ AifJobStsFinished,
7785+ AifJobStsAborted,
7786+ AifJobStsFailed,
7787+ AifJobStsLastReportMarker = 100, // All before mean last report
7788+ AifJobStsSuspended,
7789+ AifJobStsRunning
7790+} _E_AifJobStatus;
7791+
7792+#ifdef AAC_32BIT_ENUMS
7793+typedef _E_AifJobStatus AifJobStatus;
7794+#else
7795+typedef AAC_UINT32 AifJobStatus;
7796+#endif
7797+
7798+
7799+typedef enum {
7800+ AifJobScsiMin = 1, // Minimum value for Scsi operation
7801+ AifJobScsiZero, // SCSI device clear operation
7802+ AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7803+ AifJobScsiExercise, // SCSI device Exercise operation
7804+ AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7805+ // Add new SCSI task types above this line
7806+ AifJobScsiMax = 99, // Max Scsi value
7807+ AifJobCtrMin, // Min Ctr op value
7808+ AifJobCtrZero, // Container clear operation
7809+ AifJobCtrCopy, // Container copy operation
7810+ AifJobCtrCreateMirror, // Container Create Mirror operation
7811+ AifJobCtrMergeMirror, // Container Merge Mirror operation
7812+ AifJobCtrScrubMirror, // Container Scrub Mirror operation
7813+ AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7814+ AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7815+ AifJobCtrMorph, // Container morph operation
7816+ AifJobCtrPartCopy, // Container Partition copy operation
7817+ AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7818+ AifJobCtrCrazyCache, // crazy cache
7819+ // Add new container task types above this line
7820+ AifJobCtrMax = 199, // Max Ctr type operation
7821+ AifJobFsMin, // Min Fs type operation
7822+ AifJobFsCreate, // File System Create operation
7823+ AifJobFsVerify, // File System Verify operation
7824+ AifJobFsExtend, // File System Extend operation
7825+ // Add new file system task types above this line
7826+ AifJobFsMax = 299, // Max Fs type operation
7827+ // Add new API task types here
7828+ AifJobApiFormatNTFS, // Format a drive to NTFS
7829+ AifJobApiFormatFAT, // Format a drive to FAT
7830+ AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7831+ AifJobApiFormatFAT32, // Format a drive to FAT32
7832+ AifJobApiMax = 399, // Max API type operation
7833+ AifJobCtlContinuousCtrVerify, // Controller operation
7834+ AifJobCtlMax = 499 // Max Controller type operation
7835+
7836+} _E_AifJobType;
7837+
7838+#ifdef AAC_32BIT_ENUMS
7839+typedef _E_AifJobType AifJobType;
7840+#else
7841+typedef AAC_UINT32 AifJobType;
7842+#endif
7843+
7844+union SrcContainer {
7845+ AAC_UINT32 from;
7846+ AAC_UINT32 master;
7847+ AAC_UINT32 container;
7848+};
7849+
7850+union DstContainer {
7851+ AAC_UINT32 to;
7852+ AAC_UINT32 slave;
7853+ AAC_UINT32 container;
7854+};
7855+
7856+
7857+struct AifContainers {
7858+ union SrcContainer src;
7859+ union DstContainer dst;
7860+};
7861+
7862+union AifJobClient {
7863+
7864+ struct AifContainers container; // For Container nd file system progress ops;
7865+ AAC_INT32 scsi_dh; // For SCSI progress ops
7866+};
7867+
7868+struct AifJobDesc {
7869+ AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7870+ AifJobType type; // Operation that is being performed
7871+ union AifJobClient client; // Details
7872+};
7873+
7874+struct AifJobProgressReport {
7875+ struct AifJobDesc jd;
7876+ AifJobStatus status;
7877+ AAC_UINT32 finalTick;
7878+ AAC_UINT32 currentTick;
7879+ AAC_UINT32 jobSpecificData1;
7880+ AAC_UINT32 jobSpecificData2;
7881+};
7882+
7883+//
7884+// Notification of events structure definition starts here
7885+//
7886+typedef enum {
7887+ // General application notifies start here
7888+ AifEnGeneric = 1, // Generic notification
7889+ AifEnTaskComplete, // Task has completed
7890+ AifEnConfigChange, // Adapter configuration change occurred
7891+ AifEnContainerChange, // Adapter specific container configuration change
7892+ AifEnDeviceFailure, // SCSI device failed
7893+ AifEnMirrorFailover, // Mirror failover started
7894+ AifEnContainerEvent, // Significant container event
7895+ AifEnFileSystemChange, // File system changed
7896+ AifEnConfigPause, // Container pause event
7897+ AifEnConfigResume, // Container resume event
7898+ AifEnFailoverChange, // Failover space assignment changed
7899+ AifEnRAID5RebuildDone, // RAID5 rebuild finished
7900+ AifEnEnclosureManagement, // Enclosure management event
7901+ AifEnBatteryEvent, // Significant NV battery event
7902+ AifEnAddContainer, // A new container was created.
7903+ AifEnDeleteContainer, // A container was deleted.
7904+ AifEnSMARTEvent, // SMART Event
7905+ AifEnBatteryNeedsRecond, // The battery needs reconditioning
7906+ AifEnClusterEvent, // Some cluster event
7907+ AifEnDiskSetEvent, // A disk set event occured.
7908+ // Add general application notifies above this comment
7909+ AifDriverNotifyStart=199, // Notifies for host driver go here
7910+ // Host driver notifications start here
7911+ AifDenMorphComplete, // A morph operation completed
7912+ AifDenVolumeExtendComplete // A volume expand operation completed
7913+ // Add host driver notifications above this comment
7914+} _E_AifEventNotifyType;
7915+
7916+#ifdef AAC_32BIT_ENUMS
7917+typedef _E_AifEventNotifyType AifEventNotifyType;
7918+#else
7919+typedef AAC_UINT32 AifEventNotifyType;
7920+#endif
7921+
7922+struct AifEnsGeneric {
7923+ AAC_INT8 text[132]; // Generic text
7924+};
7925+
7926+struct AifEnsDeviceFailure {
7927+ AAC_INT32 deviceHandle; // SCSI device handle
7928+};
7929+
7930+struct AifEnsMirrorFailover {
7931+ AAC_UINT32 container; // Container with failed element
7932+ AAC_UINT32 failedSlice; // Old slice which failed
7933+ AAC_UINT32 creatingSlice; // New slice used for auto-create
7934+};
7935+
7936+struct AifEnsContainerChange {
7937+ AAC_UINT32 container[2]; // container that changed, -1 if no container
7938+};
7939+
7940+struct AifEnsContainerEvent {
7941+ AAC_UINT32 container; // container number
7942+ AAC_UINT32 eventType; // event type
7943+};
7944+
7945+struct AifEnsEnclosureEvent {
7946+ AAC_UINT32 empID; // enclosure management processor number
7947+ AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
7948+ AAC_UINT32 eventType; // event type
7949+};
7950+
7951+
7952+struct AifEnsBatteryEvent {
7953+ NVBATT_TRANSITION transition_type; // e.g. from low to ok
7954+ NVBATTSTATUS current_state; // current battery state
7955+ NVBATTSTATUS prior_state; // previous battery state
7956+};
7957+
7958+struct AifEnsDiskSetEvent {
7959+ AAC_UINT32 eventType;
7960+ AAC_UINT32 DsNum[2];
7961+ AAC_UINT32 CreatorId[2];
7962+};
7963+
7964+
7965+
7966+typedef enum _CLUSTER_AIF_EVENT {
7967+ CLUSTER_NULL_EVENT = 0,
7968+ CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
7969+ // (partner's agent may be up)
7970+ CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
7971+ // (partner has rebooted)
7972+} _E_CLUSTER_AIF_EVENT;
7973+
7974+#ifdef AAC_32BIT_ENUMS
7975+typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
7976+#else
7977+typedef AAC_UINT32 CLUSTER_AIF_EVENT;
7978+#endif
7979+
7980+struct AifEnsClusterEvent {
7981+ CLUSTER_AIF_EVENT eventType;
7982+};
7983+
7984+struct AifEventNotify {
7985+ AifEventNotifyType type;
7986+ union {
7987+ struct AifEnsGeneric EG;
7988+ struct AifEnsDeviceFailure EDF;
7989+ struct AifEnsMirrorFailover EMF;
7990+ struct AifEnsContainerChange ECC;
7991+ struct AifEnsContainerEvent ECE;
7992+ struct AifEnsEnclosureEvent EEE;
7993+ struct AifEnsBatteryEvent EBE;
7994+ struct AifEnsDiskSetEvent EDS;
7995+#ifdef BRIDGE
7996+ struct AifEnsSMARTEvent ES;
7997+#endif
7998+ struct AifEnsClusterEvent ECLE;
7999+ } data;
8000+};
8001+
8002+//
8003+// Generic API structure
8004+//
8005+#define AIF_API_REPORT_MAX_SIZE 64
8006+typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8007+
8008+
8009+
8010+//
8011+// For FIB communication, we need all of the following things
8012+// to send back to the user.
8013+//
8014+typedef enum {
8015+ AifCmdEventNotify = 1, // Notify of event
8016+ AifCmdJobProgress, // Progress report
8017+ AifCmdAPIReport, // Report from other user of API
8018+ AifCmdDriverNotify, // Notify host driver of event
8019+ AifReqJobList = 100, // Gets back complete job list
8020+ AifReqJobsForCtr, // Gets back jobs for specific container
8021+ AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8022+ AifReqJobReport, // Gets back a specific job report or list of them
8023+ AifReqTerminateJob, // Terminates job
8024+ AifReqSuspendJob, // Suspends a job
8025+ AifReqResumeJob, // Resumes a job
8026+ AifReqSendAPIReport, // API generic report requests
8027+ AifReqAPIJobStart, // Start a job from the API
8028+ AifReqAPIJobUpdate, // Update a job report from the API
8029+ AifReqAPIJobFinish // Finish a job from the API
8030+} _E_AIFCOMMAND;
8031+
8032+#ifdef AAC_32BIT_ENUMS
8033+typedef _E_AIFCOMMAND AIFCOMMAND;
8034+#else
8035+typedef AAC_UINT32 AIFCOMMAND;
8036+#endif
8037+
8038+
8039+
8040+//
8041+// Adapter Initiated FIB command structures. Start with the adapter
8042+// initiated FIBs that really come from the adapter, and get responded
8043+// to by the host.
8044+//
8045+typedef struct _AIFCOMMANDTOHOST {
8046+ AIFCOMMAND command; // Tell host what type of notify this is
8047+ AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8048+ union {
8049+ // First define data going to the adapter
8050+ struct AifEventNotify EN; // Event notify structure
8051+ struct AifJobProgressReport PR[1]; // Progress report
8052+ AifApiReport AR;
8053+ } data;
8054+} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8055+
8056+
8057+#endif // _AIFSTRUC_H
8058+
8059+
8060+
8061diff -urN linux/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8062--- linux/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 19:00:00 1969
8063+++ linux/drivers/scsi/aacraid/include/build_number.h Thu Dec 21 13:14:30 2000
8064@@ -0,0 +1,39 @@
8065+/*++
8066+ * Adaptec aacraid device driver for Linux.
8067+ *
8068+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8069+ *
8070+ * This program is free software; you can redistribute it and/or modify
8071+ * it under the terms of the GNU General Public License as published by
8072+ * the Free Software Foundation; either version 2, or (at your option)
8073+ * any later version.
8074+ *
8075+ * This program is distributed in the hope that it will be useful,
8076+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8077+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8078+ * GNU General Public License for more details.
8079+ *
8080+ * You should have received a copy of the GNU General Public License
8081+ * along with this program; see the file COPYING. If not, write to
8082+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8083+ *
8084+ * Module Name:
8085+ * build_number.h
8086+ *
8087+ * Abstract:
8088+ * DThis module contains the single location where the build number
8089+ * is kept.
8090+ *
8091+ *
8092+ *
8093+ --*/
8094+#ifndef _BUILD_NUMBER_H
8095+#define _BUILD_NUMBER_H
8096+
8097+static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8098+
8099+#define REV_BUILD_NUMBER 3911
8100+
8101+
8102+#endif // _BUILD_NUMBER_H
8103+
8104diff -urN linux/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8105--- linux/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 19:00:00 1969
8106+++ linux/drivers/scsi/aacraid/include/commdata.h Thu Dec 21 13:14:30 2000
8107@@ -0,0 +1,112 @@
8108+/*++
8109+ * Adaptec aacraid device driver for Linux.
8110+ *
8111+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8112+ *
8113+ * This program is free software; you can redistribute it and/or modify
8114+ * it under the terms of the GNU General Public License as published by
8115+ * the Free Software Foundation; either version 2, or (at your option)
8116+ * any later version.
8117+ *
8118+ * This program is distributed in the hope that it will be useful,
8119+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8120+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8121+ * GNU General Public License for more details.
8122+ *
8123+ * You should have received a copy of the GNU General Public License
8124+ * along with this program; see the file COPYING. If not, write to
8125+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8126+ *
8127+ * Module Name:
8128+ * commdata.h
8129+ *
8130+ * Abstract: Define the communication layer of the adapter
8131+ *
8132+ *
8133+ *
8134+ --*/
8135+#ifndef _COMMDATA_
8136+#define _COMMDATA_
8137+
8138+static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8139+
8140+typedef struct _FSA_COMM_DATA {
8141+
8142+ //
8143+ // A pointer to the Driver and Device object we were initialized with
8144+ //
8145+
8146+ PDRIVER_OBJECT DriverObject;
8147+ PDEVICE_OBJECT DeviceObject;
8148+
8149+ //
8150+ // A list of all adapters we have configured.
8151+ //
8152+
8153+ PAFA_COMM_ADAPTER AdapterList;
8154+ ULONG TotalAdapters;
8155+
8156+ //
8157+ // Adapter timeout support. This is the default timeout to wait for the
8158+ // adapter to respond(setup in initfs.c), and a boolean to indicate if
8159+ // we should timeout requests to the adapter or not.
8160+ //
8161+
8162+ LARGE_INTEGER QueueFreeTimeout;
8163+ LARGE_INTEGER AdapterTimeout;
8164+ BOOLEAN EnableAdapterTimeouts;
8165+
8166+ ULONG FibTimeoutIncrement;
8167+
8168+ ULONG FibsSent;
8169+ ULONG FibRecved;
8170+ ULONG NoResponseSent;
8171+ ULONG NoResponseRecved;
8172+ ULONG AsyncSent;
8173+ ULONG AsyncRecved;
8174+ ULONG NormalSent;
8175+ ULONG NormalRecved;
8176+
8177+ ULONG TimedOutFibs;
8178+
8179+ KDPC TimeoutDPC;
8180+ KTIMER TimeoutTimer;
8181+
8182+ //
8183+ // If this value is set to 1 then interrupt moderation will occur
8184+ // in the base commuication support.
8185+ //
8186+
8187+ ULONG EnableInterruptModeration;
8188+
8189+ int HardInterruptModeration;
8190+ int HardInterruptModeration1;
8191+ int PeakFibsConsumed;
8192+ int ZeroFibsConsumed;
8193+ int EnableFibTimeoutBreak;
8194+ ULONG FibTimeoutSeconds;
8195+
8196+ //
8197+ // The following holds all of the available user settable variables.
8198+ // This includes all for the comm layer as well as any from the class
8199+ // drivers as well.
8200+ //
8201+
8202+ FSA_USER_VAR *UserVars;
8203+ ULONG NumUserVars;
8204+
8205+
8206+ ULONG MeterFlag;
8207+
8208+#ifdef FIB_CHECKSUMS
8209+ int do_fib_checksums;
8210+#endif
8211+
8212+} FSA_COMM_DATA;
8213+typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8214+
8215+extern FSA_COMM_DATA FsaCommData;
8216+
8217+
8218+#endif // _COMMDATA_
8219+
8220diff -urN linux/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8221--- linux/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 19:00:00 1969
8222+++ linux/drivers/scsi/aacraid/include/commerr.h Thu Dec 21 13:14:30 2000
8223@@ -0,0 +1,125 @@
8224+/*++
8225+ * Adaptec aacraid device driver for Linux.
8226+ *
8227+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8228+ *
8229+ * This program is free software; you can redistribute it and/or modify
8230+ * it under the terms of the GNU General Public License as published by
8231+ * the Free Software Foundation; either version 2, or (at your option)
8232+ * any later version.
8233+ *
8234+ * This program is distributed in the hope that it will be useful,
8235+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8236+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8237+ * GNU General Public License for more details.
8238+ *
8239+ * You should have received a copy of the GNU General Public License
8240+ * along with this program; see the file COPYING. If not, write to
8241+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8242+ *
8243+ * Module Name:
8244+ * commerr.h
8245+ *
8246+ * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8247+ *
8248+ *
8249+ *
8250+ --*/
8251+
8252+#ifndef _FSAERR_
8253+#define _FSAERR_
8254+
8255+static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8256+
8257+//
8258+// Note: comments in the .mc file must use both ";" and "//".
8259+//
8260+// Status values are 32 bit values layed out as follows:
8261+//
8262+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8263+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8264+// +---+-+-------------------------+-------------------------------+
8265+// |Sev|C| Facility | Code |
8266+// +---+-+-------------------------+-------------------------------+
8267+//
8268+// where
8269+//
8270+// Sev - is the severity code
8271+//
8272+// 00 - Success
8273+// 01 - Informational
8274+// 10 - Warning
8275+// 11 - Error
8276+//
8277+// C - is the Customer code flag
8278+//
8279+// Facility - is the facility code
8280+//
8281+// Code - is the facility's status code
8282+//
8283+
8284+
8285+//
8286+// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8287+// called with a device, the name of the device will be inserted into
8288+// the message at %1. Otherwise, the place of %1 will be left empty.
8289+// In either case, the insertion strings from the driver's error log
8290+// entry starts at %2. In other words, the first insertion string goes
8291+// to %2, the second to %3 and so on.
8292+//
8293+
8294+//
8295+// Values are 32 bit values layed out as follows:
8296+//
8297+// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8298+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8299+// +---+-+-+-----------------------+-------------------------------+
8300+// |Sev|C|R| Facility | Code |
8301+// +---+-+-+-----------------------+-------------------------------+
8302+//
8303+// where
8304+//
8305+// Sev - is the severity code
8306+//
8307+// 00 - Success
8308+// 01 - Informational
8309+// 10 - Warning
8310+// 11 - Error
8311+//
8312+// C - is the Customer code flag
8313+//
8314+// R - is a reserved bit
8315+//
8316+// Facility - is the facility code
8317+//
8318+// Code - is the facility's status code
8319+//
8320+//
8321+// Define the facility codes
8322+//
8323+
8324+
8325+#define FACILITY_FSAFS_ERROR_CODE 0x7
8326+
8327+
8328+
8329+//
8330+// MessageId: FSAFS_FIB_INVALID
8331+//
8332+// MessageText:
8333+//
8334+// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8335+//
8336+#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8337+
8338+
8339+//
8340+// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8341+//
8342+// MessageText:
8343+//
8344+// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8345+//
8346+#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8347+
8348+#endif _FSAERR_
8349diff -urN linux/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8350--- linux/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 19:00:00 1969
8351+++ linux/drivers/scsi/aacraid/include/commfibcontext.h Thu Dec 21 13:14:30 2000
8352@@ -0,0 +1,98 @@
8353+/*++
8354+ * Adaptec aacraid device driver for Linux.
8355+ *
8356+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8357+ *
8358+ * This program is free software; you can redistribute it and/or modify
8359+ * it under the terms of the GNU General Public License as published by
8360+ * the Free Software Foundation; either version 2, or (at your option)
8361+ * any later version.
8362+ *
8363+ * This program is distributed in the hope that it will be useful,
8364+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8365+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8366+ * GNU General Public License for more details.
8367+ *
8368+ * You should have received a copy of the GNU General Public License
8369+ * along with this program; see the file COPYING. If not, write to
8370+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8371+ *
8372+ * Module Name:
8373+ * commfibcontext.h
8374+ *
8375+ * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8376+ *
8377+ *
8378+ *
8379+ --*/
8380+#ifndef _COMM_FIB_CONTEXT_
8381+#define _COMM_FIB_CONTEXT_
8382+
8383+static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8384+
8385+typedef struct _COMM_FIB_CONTEXT {
8386+
8387+ PVOID Next; // this is used by the zone allocation
8388+
8389+ //
8390+ // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8391+ //
8392+ // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8393+ // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8394+ // ITS SIZE.
8395+ //
8396+
8397+ NODE_TYPE_CODE NodeTypeCode;
8398+ NODE_BYTE_SIZE NodeByteSize;
8399+
8400+ //
8401+ // The Adapter that this I/O is destined for.
8402+ //
8403+
8404+ PAFA_COMM_ADAPTER Adapter;
8405+
8406+ PHYSICAL_ADDRESS LogicalFibAddress;
8407+
8408+ //
8409+ // This is the event the sendfib routine will wait on if the
8410+ // caller did not pass one and this is synch io.
8411+ //
8412+
8413+ OS_CV_T FsaEvent;
8414+ OS_CVLOCK *FsaEventMutex;
8415+
8416+ ULONG FibComplete; // gets set to 1 when fib is complete
8417+
8418+ PFIB_CALLBACK FibCallback;
8419+ PVOID FibCallbackContext;
8420+
8421+ ULONG Flags;
8422+
8423+
8424+#ifdef GATHER_FIB_TIMES
8425+ LARGE_INTEGER FibTimeStamp;
8426+ PFIB_TIMES FibTimesPtr;
8427+#endif
8428+
8429+ //
8430+ // The following is used to put this fib context onto the Outstanding I/O queue.
8431+ //
8432+
8433+ LIST_ENTRY QueueEntry;
8434+
8435+ //
8436+ // The following is used to timeout a fib to the adapter.
8437+ //
8438+
8439+ LARGE_INTEGER TimeoutValue;
8440+
8441+ PVOID FibData;
8442+
8443+ PFIB Fib;
8444+
8445+} COMM_FIB_CONTEXT;
8446+typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8447+
8448+#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8449+
8450+#endif /* _COMM_FIB_CONTEXT_ */
8451diff -urN linux/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8452--- linux/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 19:00:00 1969
8453+++ linux/drivers/scsi/aacraid/include/comprocs.h Thu Dec 21 13:14:30 2000
8454@@ -0,0 +1,93 @@
8455+/*++
8456+ * Adaptec aacraid device driver for Linux.
8457+ *
8458+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8459+ *
8460+ * This program is free software; you can redistribute it and/or modify
8461+ * it under the terms of the GNU General Public License as published by
8462+ * the Free Software Foundation; either version 2, or (at your option)
8463+ * any later version.
8464+ *
8465+ * This program is distributed in the hope that it will be useful,
8466+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8467+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8468+ * GNU General Public License for more details.
8469+ *
8470+ * You should have received a copy of the GNU General Public License
8471+ * along with this program; see the file COPYING. If not, write to
8472+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8473+ *
8474+ * Module Name:
8475+ * comprocs.h
8476+ *
8477+ * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8478+ *
8479+ *
8480+ *
8481+ --*/
8482+#ifndef _COMPROCS_
8483+#define _COMPROCS_
8484+
8485+static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8486+
8487+#include "osheaders.h"
8488+
8489+#include "AacGenericTypes.h"
8490+
8491+#include "aac_unix_defs.h"
8492+
8493+#include "nodetype.h"
8494+
8495+// #define GATHER_FIB_TIMES
8496+
8497+#include "fsatypes.h"
8498+
8499+#include "perfpack.h"
8500+
8501+#include "comstruc.h"
8502+
8503+//#include "unix_protocol.h"
8504+
8505+#include "fsact.h"
8506+
8507+#include "protocol.h"
8508+
8509+#include "fsaioctl.h"
8510+
8511+#undef GATHER_FIB_TIMES
8512+
8513+#include "aifstruc.h"
8514+
8515+#include "fsaport.h"
8516+#include "comsup.h"
8517+#include "afacomm.h"
8518+#include "adapter.h"
8519+
8520+#include "commfibcontext.h"
8521+#include "comproto.h"
8522+#include "commdata.h"
8523+#include "commerr.h"
8524+
8525+
8526+
8527+
8528+//
8529+// The following macro is used when sending and receiving FIBs. It is only used for
8530+// debugging.
8531+
8532+#if DBG
8533+#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8534+#else
8535+#define FIB_COUNTER_INCREMENT(Counter)
8536+#endif
8537+
8538+
8539+
8540+int
8541+AfaCommAdapterDeviceControl (
8542+ IN PVOID AdapterArg,
8543+ IN PAFA_IOCTL_CMD IoctlCmdPtr
8544+ );
8545+
8546+
8547+#endif // _COMPROCS_
8548diff -urN linux/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8549--- linux/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 19:00:00 1969
8550+++ linux/drivers/scsi/aacraid/include/comproto.h Thu Dec 21 13:14:30 2000
8551@@ -0,0 +1,170 @@
8552+/*++
8553+ * Adaptec aacraid device driver for Linux.
8554+ *
8555+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8556+ *
8557+ * This program is free software; you can redistribute it and/or modify
8558+ * it under the terms of the GNU General Public License as published by
8559+ * the Free Software Foundation; either version 2, or (at your option)
8560+ * any later version.
8561+ *
8562+ * This program is distributed in the hope that it will be useful,
8563+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8564+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8565+ * GNU General Public License for more details.
8566+ *
8567+ * You should have received a copy of the GNU General Public License
8568+ * along with this program; see the file COPYING. If not, write to
8569+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8570+ *
8571+ * Module Name:
8572+ * comproto.h
8573+ *
8574+ * Abstract: Global routines for the commuication interface that are device
8575+ * independant.
8576+ *
8577+ *
8578+ *
8579+ --*/
8580+#ifndef _COMM_PROTO
8581+#define _COMM_PROTO
8582+
8583+static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8584+
8585+//
8586+// define the routines we need so we can commuicate with the
8587+// fsa adapter
8588+//
8589+
8590+//
8591+// The following 4 dpc routines will support commuication from the adapter to the
8592+// host. There is one DPC routine to deal with each type of queue that supports
8593+// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8594+// These routines will simply pull off the QE and set an event. In the case of a
8595+// adapter to host command they will also put the FIB on a queue to be processed by
8596+// a FS thread running at passive level.
8597+//
8598+
8599+// Handle queue not full notification to the file system thread waiting for a queue entry
8600+
8601+u_int
8602+CommonNotFullDpc(
8603+ IN PCOMM_REGION CommRegion
8604+ );
8605+
8606+// Adapter to host normal priority responses
8607+
8608+u_int
8609+HostResponseNormalDpc(
8610+ IN PCOMM_QUE OurQueue
8611+ );
8612+
8613+// Adapter to host high priority responses
8614+u_int
8615+HostResponseHighDpc(
8616+ IN PCOMM_QUE OurQueue
8617+ );
8618+
8619+// Adapter to host high priority commands
8620+u_int
8621+HostCommandHighDpc(
8622+ IN PCOMM_QUE OurQueue
8623+ );
8624+
8625+
8626+// Adapter to host normal priority commands
8627+u_int
8628+HostCommandNormDpc(
8629+ IN PCOMM_QUE OurQueue
8630+ );
8631+
8632+
8633+
8634+BOOLEAN
8635+SendSynchFib(
8636+ PVOID Arg,
8637+ FIB_COMMAND Command,
8638+ PVOID Data,
8639+ USHORT Size,
8640+ PVOID Response,
8641+ USHORT *ResponseSize
8642+ );
8643+
8644+PFIB_CONTEXT
8645+AllocateFib (
8646+ IN PVOID Adapter
8647+ );
8648+
8649+VOID
8650+FreeFib (
8651+ IN PFIB_CONTEXT FibContext
8652+ );
8653+
8654+VOID
8655+FreeFibFromDpc(
8656+ IN PFIB_CONTEXT FibContext
8657+ );
8658+
8659+AAC_STATUS
8660+DeallocateFib(
8661+ IN PFIB_CONTEXT FibContext
8662+ );
8663+
8664+
8665+
8666+AAC_STATUS
8667+SendFib(
8668+ IN FIB_COMMAND Command,
8669+ IN PFIB_CONTEXT FibContext,
8670+ IN ULONG Size,
8671+ IN COMM_PRIORITIES Priority,
8672+ IN BOOLEAN Wait,
8673+ IN PVOID WaitOn,
8674+ IN BOOLEAN ResponseExpected,
8675+ IN PFIB_CALLBACK FibCallback,
8676+ IN PVOID FibCallbackContext
8677+ );
8678+
8679+AAC_STATUS
8680+CompleteFib(
8681+ IN PFIB_CONTEXT FibContext
8682+ );
8683+
8684+AAC_STATUS
8685+CompleteAdapterFib(
8686+ IN PFIB_CONTEXT FibContext,
8687+ IN USHORT Size
8688+ );
8689+
8690+AAC_STATUS
8691+InitializeFib(
8692+ IN PFIB_CONTEXT FibContext
8693+ );
8694+
8695+
8696+PVOID
8697+FsaGetFibData(
8698+ IN PFIB_CONTEXT FibContext
8699+ );
8700+
8701+
8702+
8703+AAC_STATUS
8704+AfaCommOpenAdapter (
8705+ IN PVOID AdapterArg
8706+ );
8707+
8708+AAC_STATUS
8709+AfaCommCloseAdapter (
8710+ IN PVOID AdapterArg
8711+ );
8712+
8713+
8714+VOID
8715+AfaCommInterruptHost(
8716+ PVOID Adapter,
8717+ ADAPTER_EVENT AdapterEvent
8718+ );
8719+
8720+
8721+#endif // _COMM_PROTO
8722diff -urN linux/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8723--- linux/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 19:00:00 1969
8724+++ linux/drivers/scsi/aacraid/include/comstruc.h Thu Dec 21 13:14:30 2000
8725@@ -0,0 +1,435 @@
8726+/*++
8727+ * Adaptec aacraid device driver for Linux.
8728+ *
8729+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8730+ *
8731+ * This program is free software; you can redistribute it and/or modify
8732+ * it under the terms of the GNU General Public License as published by
8733+ * the Free Software Foundation; either version 2, or (at your option)
8734+ * any later version.
8735+ *
8736+ * This program is distributed in the hope that it will be useful,
8737+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
8738+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8739+ * GNU General Public License for more details.
8740+ *
8741+ * You should have received a copy of the GNU General Public License
8742+ * along with this program; see the file COPYING. If not, write to
8743+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8744+ *
8745+ * Module Name:
8746+ * comstruc.h
8747+ *
8748+ * Abstract: This module defines the data structures that make up the communication
8749+ * region for the FSA filesystem. This region is how the host based code
8750+ * communicates both control and data to the adapter based code.
8751+ *
8752+ *
8753+ *
8754+ --*/
8755+#ifndef _COMM_STRUCT
8756+#define _COMM_STRUCT
8757+
8758+static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8759+
8760+//
8761+// Define all the constants needed for the communication interface
8762+//
8763+
8764+// Define how many queue entries each queue will have and the total number of
8765+// entries for the entire communication interface. Also define how many queues
8766+// we support.
8767+
8768+#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8769+#define HOST_HIGH_CMD_ENTRIES 4
8770+#define HOST_NORM_CMD_ENTRIES 8
8771+#define ADAP_HIGH_CMD_ENTRIES 4
8772+#define ADAP_NORM_CMD_ENTRIES 512
8773+#define HOST_HIGH_RESP_ENTRIES 4
8774+#define HOST_NORM_RESP_ENTRIES 512
8775+#define ADAP_HIGH_RESP_ENTRIES 4
8776+#define ADAP_NORM_RESP_ENTRIES 8
8777+
8778+#define TOTAL_QUEUE_ENTRIES \
8779+ (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8780+ HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8781+
8782+
8783+
8784+
8785+// Set the queues on a 16 byte alignment
8786+#define QUEUE_ALIGNMENT 16
8787+
8788+
8789+//
8790+// The queue headers define the Communication Region queues. These
8791+// are physically contiguous and accessible by both the adapter and the
8792+// host. Even though all queue headers are in the same contiguous block they will be
8793+// represented as individual units in the data structures.
8794+//
8795+
8796+typedef AAC_UINT32 QUEUE_INDEX;
8797+
8798+typedef QUEUE_INDEX *PQUEUE_INDEX;
8799+
8800+typedef struct _QUEUE_ENTRY {
8801+
8802+ AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8803+ AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8804+
8805+} QUEUE_ENTRY;
8806+
8807+typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8808+
8809+
8810+
8811+// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8812+// adjacently and in that order.
8813+//
8814+typedef struct _QUEUE_HEADERS {
8815+
8816+ PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8817+ PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8818+ PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8819+
8820+} QUEUE_HEADERS;
8821+typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8822+
8823+//
8824+// Define all the events which the adapter would like to notify
8825+// the host of.
8826+//
8827+typedef enum _ADAPTER_EVENT {
8828+ HostNormCmdQue = 1, // Change in host normal priority command queue
8829+ HostHighCmdQue, // Change in host high priority command queue
8830+ HostNormRespQue, // Change in host normal priority response queue
8831+ HostHighRespQue, // Change in host high priority response queue
8832+ AdapNormRespNotFull,
8833+ AdapHighRespNotFull,
8834+ AdapNormCmdNotFull,
8835+ AdapHighCmdNotFull,
8836+ SynchCommandComplete,
8837+ AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8838+
8839+} _E_ADAPTER_EVENT;
8840+
8841+#ifdef AAC_32BIT_ENUMS
8842+typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8843+#else
8844+typedef AAC_UINT32 ADAPTER_EVENT;
8845+#endif
8846+
8847+//
8848+// Define all the events the host wishes to notify the
8849+// adapter of.
8850+//
8851+typedef enum _HOST_2_ADAP_EVENT {
8852+ AdapNormCmdQue = 1,
8853+ AdapHighCmdQue,
8854+ AdapNormRespQue,
8855+ AdapHighRespQue,
8856+ HostShutdown,
8857+ HostPowerFail,
8858+ FatalCommError,
8859+ HostNormRespNotFull,
8860+ HostHighRespNotFull,
8861+ HostNormCmdNotFull,
8862+ HostHighCmdNotFull,
8863+ FastIo,
8864+ AdapPrintfDone
8865+} _E_HOST_2_ADAP_EVENT;
8866+
8867+#ifdef AAC_32BIT_ENUMS
8868+typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8869+#else
8870+typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8871+#endif
8872+
8873+//
8874+// Define all the queues that the adapter and host use to communicate
8875+//
8876+
8877+typedef enum _QUEUE_TYPES {
8878+ HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8879+ HostHighCmdQueue, // Adapter to host high priority command traffic
8880+ AdapNormRespQueue, // Host to adapter normal priority response traffic
8881+ AdapHighRespQueue, // Host to adapter high priority response traffic
8882+ AdapNormCmdQueue, // Host to adapter normal priority command traffic
8883+ AdapHighCmdQueue, // Host to adapter high priority command traffic
8884+ HostNormRespQueue, // Adapter to host normal priority response traffic
8885+ HostHighRespQueue // Adapter to host high priority response traffic
8886+} _E_QUEUE_TYPES;
8887+
8888+#ifdef AAC_32BIT_ENUMS
8889+typedef _E_QUEUE_TYPES QUEUE_TYPES;
8890+#else
8891+typedef AAC_UINT32 QUEUE_TYPES;
8892+#endif
8893+
8894+
8895+//
8896+// Assign type values to the FSA communication data structures
8897+//
8898+
8899+typedef enum _STRUCT_TYPES {
8900+ TFib = 1,
8901+ TQe,
8902+ TCtPerf
8903+} _E_STRUCT_TYPES;
8904+
8905+#ifdef AAC_32BIT_ENUMS
8906+typedef _E_STRUCT_TYPES STRUCT_TYPES;
8907+#else
8908+typedef AAC_UINT32 STRUCT_TYPES;
8909+#endif
8910+
8911+//
8912+// Define the priority levels the FSA communication routines support.
8913+//
8914+
8915+typedef enum _COMM_PRIORITIES {
8916+ FsaNormal = 1,
8917+ FsaHigh
8918+} _E_COMM_PRIORITIES;
8919+
8920+#ifdef AAC_32BIT_ENUMS
8921+typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
8922+#else
8923+typedef AAC_UINT32 COMM_PRIORITIES;
8924+#endif
8925+
8926+
8927+
8928+//
8929+// Define the LIST_ENTRY structure. This structure is used on the NT side to link
8930+// the FIBs together in a linked list. Since this structure gets compiled on the adapter
8931+// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
8932+// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
8933+// is already defined.
8934+#if !defined(_NTDEF_) && !defined(_WINNT_)
8935+typedef struct _LIST_ENTRY {
8936+ struct _LIST_ENTRY *Flink;
8937+ struct _LIST_ENTRY *Blink;
8938+} LIST_ENTRY;
8939+typedef LIST_ENTRY *PLIST_ENTRY;
8940+#endif
8941+
8942+
8943+//
8944+// Define the FIB. The FIB is the where all the requested data and
8945+// command information are put to the application on the FSA adapter.
8946+//
8947+
8948+typedef struct _FIB_HEADER {
8949+ AAC_UINT32 XferState; // Current transfer state for this CCB
8950+ AAC_UINT16 Command; // Routing information for the destination
8951+ AAC_UINT8 StructType; // Type FIB
8952+ AAC_UINT8 Flags; // Flags for FIB
8953+ AAC_UINT16 Size; // Size of this FIB in bytes
8954+ AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
8955+ AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
8956+ AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
8957+ AAC_UINT32 SenderData; // Place holder for the sender to store data
8958+#ifndef __midl
8959+ union {
8960+ struct {
8961+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
8962+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
8963+ } _s;
8964+ LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
8965+ } _u;
8966+#else // The MIDL compiler does not support unions without a discriminant.
8967+ struct { // Since nothing during the midl compile actually looks into this
8968+ struct { // structure, this shoudl be ok.
8969+ AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
8970+ AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
8971+ } _s;
8972+ } _u;
8973+#endif
8974+} FIB_HEADER;
8975+
8976+
8977+#define FibLinks _u._FibLinks
8978+
8979+
8980+#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
8981+
8982+
8983+typedef struct _FIB {
8984+
8985+#ifdef BRIDGE //rma
8986+ DLQUE link;
8987+#endif
8988+ FIB_HEADER Header;
8989+
8990+ AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
8991+
8992+} FIB;
8993+typedef FIB *PFIB;
8994+
8995+
8996+
8997+//
8998+// FIB commands
8999+//
9000+
9001+typedef enum _FIB_COMMANDS {
9002+ TestCommandResponse = 1,
9003+ TestAdapterCommand = 2,
9004+
9005+ // Lowlevel and comm commands
9006+
9007+ LastTestCommand = 100,
9008+ ReinitHostNormCommandQueue = 101,
9009+ ReinitHostHighCommandQueue = 102,
9010+ ReinitHostHighRespQueue = 103,
9011+ ReinitHostNormRespQueue = 104,
9012+ ReinitAdapNormCommandQueue = 105,
9013+ ReinitAdapHighCommandQueue = 107,
9014+ ReinitAdapHighRespQueue = 108,
9015+ ReinitAdapNormRespQueue = 109,
9016+ InterfaceShutdown = 110,
9017+ DmaCommandFib = 120,
9018+ StartProfile = 121,
9019+ TermProfile = 122,
9020+ SpeedTest = 123,
9021+ TakeABreakPt = 124,
9022+ RequestPerfData = 125,
9023+ SetInterruptDefTimer= 126,
9024+ SetInterruptDefCount= 127,
9025+ GetInterruptDefStatus= 128,
9026+ LastCommCommand = 129,
9027+
9028+ // Filesystem commands
9029+
9030+ NuFileSystem = 300,
9031+ UFS = 301,
9032+ HostFileSystem = 302,
9033+ LastFileSystemCommand = 303,
9034+
9035+ // Container Commands
9036+
9037+ ContainerCommand = 500,
9038+ ContainerCommand64 = 501,
9039+
9040+ // Cluster Commands
9041+
9042+ ClusterCommand = 550,
9043+
9044+ // Scsi Port commands (scsi passthrough)
9045+
9046+ ScsiPortCommand = 600,
9047+
9048+ // misc house keeping and generic adapter initiated commands
9049+
9050+ AifRequest = 700,
9051+ CheckRevision = 701,
9052+ FsaHostShutdown = 702,
9053+ RequestAdapterInfo = 703,
9054+ IsAdapterPaused = 704,
9055+ SendHostTime = 705,
9056+ LastMiscCommand = 706
9057+
9058+} _E_FIB_COMMANDS;
9059+
9060+
9061+
9062+typedef AAC_UINT16 FIB_COMMAND;
9063+
9064+//
9065+// Commands that will target the failover level on the FSA adapter
9066+//
9067+
9068+typedef enum _FIB_XFER_STATE {
9069+ HostOwned = (1<<0),
9070+ AdapterOwned = (1<<1),
9071+ FibInitialized = (1<<2),
9072+ FibEmpty = (1<<3),
9073+ AllocatedFromPool = (1<<4),
9074+ SentFromHost = (1<<5),
9075+ SentFromAdapter = (1<<6),
9076+ ResponseExpected = (1<<7),
9077+ NoResponseExpected = (1<<8),
9078+ AdapterProcessed = (1<<9),
9079+ HostProcessed = (1<<10),
9080+ HighPriority = (1<<11),
9081+ NormalPriority = (1<<12),
9082+ Async = (1<<13),
9083+ AsyncIo = (1<<13), // rpbfix: remove with new regime
9084+ PageFileIo = (1<<14), // rpbfix: remove with new regime
9085+ ShutdownRequest = (1<<15),
9086+ LazyWrite = (1<<16), // rpbfix: remove with new regime
9087+ AdapterMicroFib = (1<<17),
9088+ BIOSFibPath = (1<<18),
9089+ FastResponseCapable = (1<<19),
9090+ ApiFib = (1<<20) // Its an API Fib.
9091+
9092+} _E_FIB_XFER_STATE;
9093+
9094+
9095+typedef enum _FSA_ERRORS {
9096+ FSA_NORMAL = 0,
9097+ FSA_SUCCESS = 0,
9098+ FSA_PENDING = 0x01,
9099+ FSA_FATAL = 0x02,
9100+ FSA_INVALID_QUEUE = 0x03,
9101+ FSA_NOENTRIES = 0x04,
9102+ FSA_SENDFAILED = 0x05,
9103+ FSA_INVALID_QUEUE_PRIORITY = 0x06,
9104+ FSA_FIB_ALLOCATION_FAILED = 0x07,
9105+ FSA_FIB_DEALLOCATION_FAILED = 0x08
9106+
9107+} _E_FSA_ERRORS;
9108+
9109+
9110+//
9111+// The following defines needs to be updated any time there is an incompatible change made
9112+// to the ADAPTER_INIT_STRUCT structure.
9113+//
9114+#define ADAPTER_INIT_STRUCT_REVISION 3
9115+
9116+typedef struct _ADAPTER_INIT_STRUCT {
9117+ AAC_UINT32 InitStructRevision;
9118+ AAC_UINT32 MiniPortRevision;
9119+ AAC_UINT32 FilesystemRevision;
9120+ PAAC_VOID CommHeaderAddress;
9121+ PAAC_VOID FastIoCommAreaAddress;
9122+ PAAC_VOID AdapterFibsPhysicalAddress;
9123+ PAAC_VOID AdapterFibsVirtualAddress;
9124+ AAC_UINT32 AdapterFibsSize;
9125+ AAC_UINT32 AdapterFibAlign;
9126+ PAAC_VOID PrintfBufferAddress;
9127+ AAC_UINT32 PrintfBufferSize;
9128+ AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9129+ AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9130+} ADAPTER_INIT_STRUCT;
9131+typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9132+
9133+#ifdef AAC_32BIT_ENUMS
9134+typedef _E_FSA_ERRORS FSA_ERRORS;
9135+#else
9136+typedef AAC_UINT32 FSA_ERRORS;
9137+#endif
9138+
9139+typedef enum _LOG_LEVEL {
9140+ LOG_INIT = 10,
9141+ LOG_INFORMATIONAL = 20,
9142+ LOG_WARNING = 30,
9143+ LOG_LOW_ERROR = 40,
9144+ LOG_MEDIUM_ERROR = 50,
9145+ LOG_HIGH_ERROR = 60,
9146+ LOG_PANIC = 70,
9147+ LOG_DEBUG = 80,
9148+ LOG_WINDBG_PRINT = 90
9149+} _E_LOG_LEVEL;
9150+
9151+#ifdef AAC_32BIT_ENUMS
9152+typedef _E_LOG_LEVEL LOG_LEVEL;
9153+#else
9154+typedef AAC_UINT32 LOG_LEVEL;
9155+#endif
9156+
9157+
9158+#endif //_COMM_STRUCT
9159+
9160+
9161diff -urN linux/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9162--- linux/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 19:00:00 1969
9163+++ linux/drivers/scsi/aacraid/include/comsup.h Thu Dec 21 13:14:30 2000
9164@@ -0,0 +1,132 @@
9165+/*++
9166+ * Adaptec aacraid device driver for Linux.
9167+ *
9168+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9169+ *
9170+ * This program is free software; you can redistribute it and/or modify
9171+ * it under the terms of the GNU General Public License as published by
9172+ * the Free Software Foundation; either version 2, or (at your option)
9173+ * any later version.
9174+ *
9175+ * This program is distributed in the hope that it will be useful,
9176+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9177+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9178+ * GNU General Public License for more details.
9179+ *
9180+ * You should have received a copy of the GNU General Public License
9181+ * along with this program; see the file COPYING. If not, write to
9182+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9183+ *
9184+ * Module Name:
9185+ * comsup.h
9186+ *
9187+ * Abstract: This module defines the data structures that make up the
9188+ * commuication region for the FSA filesystem. This region is
9189+ * how the host based code commuicates both control and data
9190+ * to the adapter based code.
9191+ *
9192+ *
9193+ *
9194+ --*/
9195+#ifndef _COMM_SUP_DEF
9196+#define _COMM_SUP_DEF
9197+
9198+static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9199+
9200+//
9201+// The adapter interface specs all queues to be located in the same physically
9202+// contigous block. The host structure that defines the commuication queues will
9203+// assume they are each a seperate physically contigous memory region that will
9204+// support them all being one big contigous block.
9205+// There is a command and response queue for each level and direction of
9206+// commuication. These regions are accessed by both the host and adapter.
9207+//
9208+typedef struct _COMM_QUE {
9209+
9210+ PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9211+
9212+ PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9213+ QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9214+ ULONG QueueEntries; // Number of queue entries on this queue
9215+ OS_CV_T QueueFull; // Event to wait on if the queue is full
9216+ OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9217+ // This is only valid for adapter to host command queues.
9218+ OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9219+ KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9220+ ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9221+ // Only queues which the host will be the consumer will this field be valid
9222+ LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9223+ // only valid for command queues which receive entries from the adapter.
9224+ LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9225+ ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9226+
9227+ PVOID Adapter; // Back pointer to adapter structure
9228+
9229+} COMM_QUE;
9230+typedef COMM_QUE *PCOMM_QUE;
9231+
9232+
9233+typedef struct _COMM_REGION {
9234+
9235+ COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9236+ COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9237+
9238+ COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9239+ COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9240+
9241+ COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9242+ COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9243+
9244+ COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9245+ COMM_QUE AdapHighRespQue; // A response for high priority host responses
9246+
9247+ //
9248+ // The 2 threads below are the threads which handle command traffic from the
9249+ // the adapter. There is one for normal priority and one for high priority queues.
9250+ // These threads will wait on the commandready event for it's queue.
9251+ //
9252+
9253+ HANDLE NormCommandThread;
9254+ HANDLE HighCommandThread;
9255+
9256+ //
9257+ // This dpc routine will handle the setting the of not full event when the adapter
9258+ // lets us know the queue is not longer full via interrupt
9259+ //
9260+
9261+ KDPC QueueNotFullDpc;
9262+
9263+#ifdef API_THROTTLE
9264+ //
9265+ // Support for data I/O throttling to improve CLI performance
9266+ // while the system is under load.
9267+ // This is the throttling mechanism built into the COMM layer.
9268+ // Look in commsup.c, dpcsup.c and comminit.c for use.
9269+ //
9270+
9271+ int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9272+ int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9273+ LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9274+ LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9275+ BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9276+ KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9277+ KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9278+ KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9279+
9280+ unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9281+ unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9282+ unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9283+
9284+ unsigned int ThrottledFibs;
9285+ unsigned int ThrottleTimedoutFibs;
9286+ unsigned int ApiFibs;
9287+ unsigned int NonPassiveFibs;
9288+ unsigned int TotalFibs;
9289+ unsigned int FSInfoFibs;
9290+
9291+#endif // #ifdef API_THROTTLE
9292+
9293+} COMM_REGION;
9294+typedef COMM_REGION *PCOMM_REGION;
9295+
9296+#endif // _COMM_SUP
9297diff -urN linux/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9298--- linux/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 19:00:00 1969
9299+++ linux/drivers/scsi/aacraid/include/fsact.h Thu Dec 21 13:14:30 2000
9300@@ -0,0 +1,165 @@
9301+/*++
9302+ * Adaptec aacraid device driver for Linux.
9303+ *
9304+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9305+ *
9306+ * This program is free software; you can redistribute it and/or modify
9307+ * it under the terms of the GNU General Public License as published by
9308+ * the Free Software Foundation; either version 2, or (at your option)
9309+ * any later version.
9310+ *
9311+ * This program is distributed in the hope that it will be useful,
9312+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9314+ * GNU General Public License for more details.
9315+ *
9316+ * You should have received a copy of the GNU General Public License
9317+ * along with this program; see the file COPYING. If not, write to
9318+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9319+ *
9320+ * Module Name:
9321+ * fsact.h
9322+ *
9323+ * Abstract: Common container structures that are required to be
9324+ * known on both the host and adapter.
9325+ *
9326+ *
9327+ --*/
9328+#ifndef _FSACT_H_
9329+#define _FSACT_H_
9330+
9331+static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9332+
9333+//#include <comstruc.h>
9334+//#include <fsatypes.h>
9335+#include <protocol.h> // definitions for FSASTATUS
9336+
9337+
9338+/*
9339+ * Object-Server / Volume-Manager Dispatch Classes
9340+ */
9341+typedef enum _VM_COMMANDS {
9342+ VM_Null = 0,
9343+ VM_NameServe,
9344+ VM_ContainerConfig,
9345+ VM_Ioctl,
9346+ VM_FilesystemIoctl,
9347+ VM_CloseAll,
9348+ VM_CtBlockRead, // see protocol.h for BlockRead command layout
9349+ VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9350+ VM_SliceBlockRead, // raw access to configured "storage objects"
9351+ VM_SliceBlockWrite,
9352+ VM_DriveBlockRead, // raw access to physical devices
9353+ VM_DriveBlockWrite,
9354+ VM_EnclosureMgt, // enclosure management
9355+ VM_Unused, // used to be diskset management
9356+ VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9357+ VM_CtPerf, // performance test
9358+ VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9359+ VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9360+ VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9361+ MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9362+} _E_VMCOMMAND;
9363+
9364+#ifdef AAC_32BIT_ENUMS
9365+typedef _E_VMCOMMAND VMCOMMAND;
9366+#else
9367+typedef AAC_UINT32 VMCOMMAND;
9368+#endif
9369+
9370+
9371+
9372+//
9373+// Descriptive information (eg, vital stats)
9374+// that a content manager might report. The
9375+// FileArray filesystem component is one example
9376+// of a content manager. Raw mode might be
9377+// another.
9378+//
9379+
9380+struct FileSysInfo {
9381+/*
9382+ a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9383+ b) FSA usage (implemented by ObjType and ContentState fields)
9384+ c) Block size
9385+ d) Frag size
9386+ e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9387+ f) I-node density - (computed from other fields)
9388+*/
9389+ AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9390+ AAC_UINT32 fsBlockSize;
9391+ AAC_UINT32 fsFragSize;
9392+ AAC_UINT32 fsMaxExtendSize;
9393+ AAC_UINT32 fsSpaceUnits;
9394+ AAC_UINT32 fsMaxNumFiles;
9395+ AAC_UINT32 fsNumFreeFiles;
9396+ AAC_UINT32 fsInodeDensity;
9397+}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9398+
9399+union ContentManagerInfo {
9400+ struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9401+};
9402+
9403+//
9404+// Query for "mountable" objects, ie, objects that are typically
9405+// associated with a drive letter on the client (host) side.
9406+//
9407+
9408+typedef struct _MNTOBJ {
9409+
9410+ AAC_UINT32 ObjectId;
9411+ FSASTRING FileSystemName; // if applicable
9412+ ContainerCreationInfo CreateInfo; // if applicable
9413+ AAC_UINT32 Capacity;
9414+ FSAVOLTYPE VolType; // substrate structure
9415+ FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9416+ AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9417+
9418+ union ContentManagerInfo
9419+ ObjExtension; // Info specific to content manager (eg, filesystem)
9420+
9421+ AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9422+
9423+} MNTOBJ;
9424+
9425+
9426+#define FSCS_READONLY 0x0002 // possible result of broken mirror
9427+
9428+
9429+
9430+typedef struct _MNTINFO {
9431+
9432+ VMCOMMAND Command;
9433+ FTYPE MntType;
9434+ AAC_UINT32 MntCount;
9435+
9436+} MNTINFO;
9437+typedef MNTINFO *PMNTINFO;
9438+
9439+typedef struct _MNTINFORESPONSE {
9440+
9441+ FSASTATUS Status;
9442+ FTYPE MntType; // should be same as that requested
9443+ AAC_UINT32 MntRespCount;
9444+ MNTOBJ MntTable[1];
9445+
9446+} MNTINFORESPONSE;
9447+typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9448+
9449+
9450+//
9451+// The following command is sent to shut down each container.
9452+//
9453+
9454+typedef struct _CLOSECOMMAND {
9455+
9456+ VMCOMMAND Command;
9457+ AAC_UINT32 ContainerId;
9458+
9459+} CLOSECOMMAND;
9460+typedef CLOSECOMMAND *PCLOSECOMMAND;
9461+
9462+
9463+#endif /* _FSACT_H_ */
9464+
9465+
9466diff -urN linux/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9467--- linux/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 19:00:00 1969
9468+++ linux/drivers/scsi/aacraid/include/fsafs.h Thu Dec 21 13:14:30 2000
9469@@ -0,0 +1,78 @@
9470+/*++
9471+ * Adaptec aacraid device driver for Linux.
9472+ *
9473+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9474+ *
9475+ * This program is free software; you can redistribute it and/or modify
9476+ * it under the terms of the GNU General Public License as published by
9477+ * the Free Software Foundation; either version 2, or (at your option)
9478+ * any later version.
9479+ *
9480+ * This program is distributed in the hope that it will be useful,
9481+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9482+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9483+ * GNU General Public License for more details.
9484+ *
9485+ * You should have received a copy of the GNU General Public License
9486+ * along with this program; see the file COPYING. If not, write to
9487+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9488+ *
9489+ * Module Name:
9490+ * fsafs.h
9491+ *
9492+ * Abstract: Common file system structures that are required to be
9493+ * known on both the host and adapter
9494+ *
9495+ *
9496+ *
9497+ --*/
9498+
9499+#ifndef _FSAFS_H_
9500+#define _FSAFS_H_ 1
9501+
9502+static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9503+
9504+#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9505+
9506+/*
9507+ * Maximum number of filesystems.
9508+ */
9509+#define NFILESYS 24
9510+
9511+/*
9512+ * File identifier.
9513+ * These are unique and self validating within a filesystem
9514+ * on a single machine and can persist across reboots.
9515+ * The hint field may be volatile and is not guaranteed to persist
9516+ * across reboots but is used to speed up the FID to file object translation
9517+ * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9518+ * the file object (assuming a filesystem context, i.e. driveno).
9519+ */
9520+typedef struct {
9521+ AAC_UINT32 hint; // last used hint for fast reclaim
9522+ AAC_UINT32 f1; // opaque
9523+ AAC_UINT32 f2; // opaque
9524+ } fileid_t; /* intra-filesystem file ID type */
9525+
9526+
9527+/*
9528+ * Generic file handle
9529+ */
9530+struct fhandle {
9531+ fsid_t fh_fsid; /* File system id of mount point */
9532+ fileid_t fh_fid; /* File sys specific file id */
9533+};
9534+typedef struct fhandle fhandle_t;
9535+
9536+#define FIDSIZE sizeof(fhandle_t)
9537+
9538+typedef struct {
9539+ union {
9540+ AAC_INT8 fid_data[FIDSIZE];
9541+ struct fhandle fsafid;
9542+ } fidu;
9543+} FSAFID; /* FSA File ID type */
9544+
9545+
9546+#endif /* _FSAFS_H_ */
9547+
9548diff -urN linux/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9549--- linux/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 19:00:00 1969
9550+++ linux/drivers/scsi/aacraid/include/fsaioctl.h Thu Dec 21 13:14:30 2000
9551@@ -0,0 +1,159 @@
9552+/*++
9553+ * Adaptec aacraid device driver for Linux.
9554+ *
9555+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9556+ *
9557+ * This program is free software; you can redistribute it and/or modify
9558+ * it under the terms of the GNU General Public License as published by
9559+ * the Free Software Foundation; either version 2, or (at your option)
9560+ * any later version.
9561+ *
9562+ * This program is distributed in the hope that it will be useful,
9563+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9564+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9565+ * GNU General Public License for more details.
9566+ *
9567+ * You should have received a copy of the GNU General Public License
9568+ * along with this program; see the file COPYING. If not, write to
9569+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9570+ *
9571+ * Module Name:
9572+ * fsaioctl.h
9573+ *
9574+ * Abstract: Defines the interface structures between user mode applications
9575+ * and the fsa driver. This structures are used in
9576+ * DeviceIoControl() calls.
9577+ *
9578+ *
9579+ *
9580+ --*/
9581+#ifndef _FSAIOCTL_H_
9582+#define _FSAIOCTL_H_
9583+
9584+static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9585+
9586+#ifndef IOTRACEUSER
9587+
9588+#ifndef CTL_CODE
9589+
9590+
9591+#define FILE_DEVICE_CONTROLLER 0x00000004
9592+
9593+//
9594+// Macro definition for defining IOCTL and FSCTL function control codes. Note
9595+// that function codes 0-2047 are reserved for Microsoft Corporation, and
9596+// 2048-4095 are reserved for customers.
9597+//
9598+
9599+#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9600+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9601+)
9602+
9603+//
9604+// Define the method codes for how buffers are passed for I/O and FS controls
9605+//
9606+
9607+#define METHOD_BUFFERED 0
9608+
9609+
9610+#define METHOD_NEITHER 3
9611+
9612+//
9613+// Define the access check value for any access
9614+//
9615+//
9616+// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9617+// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9618+// constants *MUST* always be in sync.
9619+//
9620+#define FILE_ANY_ACCESS 0
9621+
9622+
9623+
9624+#endif
9625+
9626+
9627+
9628+typedef struct _UNIX_QUERY_DISK {
9629+ AAC_INT32 ContainerNumber;
9630+ AAC_INT32 Bus;
9631+ AAC_INT32 Target;
9632+ AAC_INT32 Lun;
9633+ AAC_BOOLEAN Valid;
9634+ AAC_BOOLEAN Locked;
9635+ AAC_BOOLEAN Deleted;
9636+ AAC_INT32 Instance;
9637+ AAC_INT8 diskDeviceName[10];
9638+ AAC_BOOLEAN UnMapped;
9639+} UNIX_QUERY_DISK;
9640+typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9641+
9642+
9643+typedef struct _DELETE_DISK {
9644+ AAC_UINT32 NtDiskNumber;
9645+ AAC_UINT32 ContainerNumber;
9646+} DELETE_DISK;
9647+typedef DELETE_DISK *PDELETE_DISK;
9648+
9649+
9650+#endif /*IOTRACEUSER*/
9651+
9652+#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9653+#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9654+
9655+
9656+#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9657+
9658+
9659+#define FSACTL_GET_VAR 0x93
9660+#define FSACTL_SET_VAR 0xa3
9661+#define FSACTL_GET_FIBTIMES 0xb3
9662+#define FSACTL_ZERO_FIBTIMES 0xc3
9663+
9664+
9665+#define FSACTL_DELETE_DISK 0x163
9666+#define FSACTL_QUERY_DISK 0x173
9667+
9668+
9669+// AfaComm perfmon ioctls
9670+#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9671+
9672+
9673+#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9674+
9675+
9676+typedef struct _GET_ADAPTER_FIB_IOCTL {
9677+ char *AdapterFibContext;
9678+ int Wait;
9679+ char *AifFib;
9680+} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9681+
9682+//
9683+// filesystem ioctls
9684+//
9685+#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9686+
9687+#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9688+
9689+#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9690+
9691+#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9692+
9693+#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9694+
9695+
9696+#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9697+
9698+
9699+#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9700+
9701+
9702+#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9703+
9704+
9705+#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9706+
9707+
9708+#endif // _FSAIOCTL_H_
9709+
9710+
9711diff -urN linux/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9712--- linux/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 19:00:00 1969
9713+++ linux/drivers/scsi/aacraid/include/fsaport.h Thu Dec 21 13:14:30 2000
9714@@ -0,0 +1,223 @@
9715+/*++
9716+ * Adaptec aacraid device driver for Linux.
9717+ *
9718+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9719+ *
9720+ * This program is free software; you can redistribute it and/or modify
9721+ * it under the terms of the GNU General Public License as published by
9722+ * the Free Software Foundation; either version 2, or (at your option)
9723+ * any later version.
9724+ *
9725+ * This program is distributed in the hope that it will be useful,
9726+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9727+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9728+ * GNU General Public License for more details.
9729+ *
9730+ * You should have received a copy of the GNU General Public License
9731+ * along with this program; see the file COPYING. If not, write to
9732+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9733+ *
9734+ * Module Name:
9735+ * fsaport.h
9736+ *
9737+ * Abstract: This module defines all of the globally used procedures in the FSA
9738+ * file system.
9739+ *
9740+ *
9741+ *
9742+ --*/
9743+#ifndef _FSAPORT_
9744+#define _FSAPORT_
9745+
9746+static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9747+
9748+//
9749+// The scatter/gather map context is the information we
9750+// we need to keep the map and transfer data to and from the
9751+// adapter.
9752+//
9753+
9754+typedef struct _SGMAP_CONTEXT {
9755+
9756+ caddr_t BaseAddress;
9757+ PVOID MapRegBase;
9758+ ULONG NumberMapRegs;
9759+ PSGMAP SgMapPtr;
9760+ ULONG ByteCount; // Used to check the Mdl length.
9761+ BOOLEAN WriteToDevice;
9762+
9763+ struct buf *bp;
9764+
9765+
9766+} SGMAP_CONTEXT;
9767+typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9768+
9769+typedef struct _MAPFIB_CONTEXT {
9770+ PMDL Mdl;
9771+ PVOID MapRegBase;
9772+ ULONG NumberMapRegs;
9773+ PVOID FibVirtualAddress;
9774+ ULONG Size;
9775+ PVOID FibPhysicalAddress;
9776+
9777+
9778+} MAPFIB_CONTEXT;
9779+typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9780+
9781+typedef BOOLEAN
9782+(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9783+ PVOID AdapterExtension,
9784+ IN OUT PVOID *BaseAddress,
9785+ IN ULONG Size,
9786+ IN ULONG Alignment
9787+ );
9788+
9789+typedef BOOLEAN
9790+(*PFSA_FREE_ADAPTER_COMM_AREA)(
9791+ PVOID AdapterExtension
9792+ );
9793+
9794+typedef VOID
9795+(*PFSA_FREE_DMA_RESOURCES)(
9796+ IN PVOID AdapterExtension,
9797+ IN PSGMAP_CONTEXT SgMapContext
9798+ );
9799+
9800+typedef BOOLEAN
9801+(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9802+ IN PVOID AdapterExtension,
9803+ IN PMAPFIB_CONTEXT MapFibContext
9804+ );
9805+
9806+typedef BOOLEAN
9807+(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9808+ IN PVOID AdapterExtension,
9809+ IN PMAPFIB_CONTEXT MapFibContext
9810+ );
9811+
9812+typedef VOID
9813+(*PFSA_INTERRUPT_ADAPTER)(
9814+ IN PVOID AdapterExtension
9815+ );
9816+
9817+typedef VOID
9818+(*PFSA_NOTIFY_ADAPTER)(
9819+ IN PVOID AdapterExtension,
9820+ IN HOST_2_ADAP_EVENT AdapterEvent
9821+ );
9822+
9823+typedef VOID
9824+(*PFSA_RESET_DEVICE)(
9825+ PVOID AdapterExtension
9826+ );
9827+
9828+typedef AAC_STATUS
9829+(*PFSA_BUILD_SGMAP)(
9830+ IN PVOID AdapterExtension,
9831+ IN PSGMAP_CONTEXT SgMapContext
9832+ );
9833+
9834+typedef PVOID
9835+(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9836+ IN PVOID AdapterExtension,
9837+ IN PVOID AdapterAddress
9838+ );
9839+
9840+typedef VOID
9841+(*PFSA_INTERRUPT_HOST)(
9842+ PVOID Adapter,
9843+ ADAPTER_EVENT AdapterEvent
9844+ );
9845+
9846+typedef VOID
9847+(*PFSA_ENABLE_INTERRUPT)(
9848+ PVOID Adapter,
9849+ ADAPTER_EVENT AdapterEvent,
9850+ BOOLEAN AtDeviceIrq
9851+ );
9852+
9853+
9854+typedef VOID
9855+(*PFSA_DISABLE_INTERRUPT)(
9856+ PVOID Adapter,
9857+ ADAPTER_EVENT AdapterEvent,
9858+ BOOLEAN AtDeviceIrq
9859+ );
9860+
9861+typedef AAC_STATUS
9862+(*PFSA_OPEN_ADAPTER) (
9863+ IN PVOID Adapter
9864+ );
9865+
9866+typedef int
9867+(*PFSA_DEVICE_CONTROL) (
9868+ IN PVOID Adapter,
9869+ IN PAFA_IOCTL_CMD IoctlCmdPtr
9870+ );
9871+
9872+typedef AAC_STATUS
9873+(*PFSA_CLOSE_ADAPTER) (
9874+ IN PVOID Adapter
9875+ );
9876+
9877+typedef BOOLEAN
9878+(*PFSA_SEND_SYNCH_FIB) (
9879+ IN PVOID Adapter,
9880+ IN ULONG FibPhysicalAddress
9881+ );
9882+
9883+typedef struct _FSAPORT_FUNCS {
9884+ ULONG SizeOfFsaPortFuncs;
9885+
9886+ PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9887+ PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9888+ PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9889+ PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9890+ PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9891+ PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9892+ PFSA_NOTIFY_ADAPTER NotifyAdapter;
9893+ PFSA_ENABLE_INTERRUPT EnableInterrupt;
9894+ PFSA_DISABLE_INTERRUPT DisableInterrupt;
9895+ PFSA_RESET_DEVICE ResetDevice;
9896+ PFSA_BUILD_SGMAP BuildSgMap;
9897+ PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9898+
9899+ PFSA_INTERRUPT_HOST InterruptHost;
9900+ PFSA_OPEN_ADAPTER OpenAdapter;
9901+ PFSA_DEVICE_CONTROL DeviceControl;
9902+ PFSA_CLOSE_ADAPTER CloseAdapter;
9903+
9904+ PFSA_SEND_SYNCH_FIB SendSynchFib;
9905+
9906+} FSAPORT_FUNCS;
9907+typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9908+
9909+typedef AAC_STATUS
9910+(*PFSA_SETVAR_CALLBACK) (
9911+ IN PVOID Adapter,
9912+ IN ULONG NewValue
9913+ );
9914+
9915+typedef struct _FSA_USER_VAR {
9916+ char Name[32];
9917+ ULONG *Address;
9918+ PFSA_SETVAR_CALLBACK SetVarCallback;
9919+} FSA_USER_VAR;
9920+
9921+typedef FSA_USER_VAR *PFSA_USER_VAR;
9922+
9923+typedef struct _FSA_NEW_ADAPTER {
9924+ PVOID AdapterExtension;
9925+ PFSAPORT_FUNCS AdapterFuncs;
9926+ PVOID Adapter;
9927+ BOOLEAN AdapterInterruptsBelowDpc;
9928+ PFSA_USER_VAR AdapterUserVars;
9929+ ULONG AdapterUserVarsSize;
9930+ void *Dip;
9931+} FSA_NEW_ADAPTER;
9932+typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
9933+
9934+#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9935+#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9936+
9937+#endif
9938diff -urN linux/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
9939--- linux/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 19:00:00 1969
9940+++ linux/drivers/scsi/aacraid/include/fsatypes.h Thu Dec 21 13:14:30 2000
9941@@ -0,0 +1,214 @@
9942+/*++
9943+ * Adaptec aacraid device driver for Linux.
9944+ *
9945+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9946+ *
9947+ * This program is free software; you can redistribute it and/or modify
9948+ * it under the terms of the GNU General Public License as published by
9949+ * the Free Software Foundation; either version 2, or (at your option)
9950+ * any later version.
9951+ *
9952+ * This program is distributed in the hope that it will be useful,
9953+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9954+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9955+ * GNU General Public License for more details.
9956+ *
9957+ * You should have received a copy of the GNU General Public License
9958+ * along with this program; see the file COPYING. If not, write to
9959+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9960+ *
9961+ * Module Name:
9962+ * fsatypes.h
9963+ *
9964+ * Abstract: Define all shared data types here, ie, those
9965+ * types shared among several components, such
9966+ * as host (driver + apps), adapter, and BIOS.
9967+ *
9968+ *
9969+ --*/
9970+#ifndef _FSATYPES_H
9971+#define _FSATYPES_H
9972+
9973+static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
9974+
9975+typedef AAC_UINT32 AAC_BOOLEAN;
9976+
9977+//
9978+// Define a 64-bit address structure for use on
9979+// a 32-bit processor architecture.
9980+//
9981+typedef struct {
9982+ AAC_UINT32 lo32;
9983+ AAC_UINT32 hi32;
9984+} AAC_UINT64S, *PAAC_UINT64S;
9985+
9986+
9987+
9988+//
9989+// Container Types
9990+//
9991+typedef struct {
9992+ AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
9993+ // know what it looks like. Note, BIOS sees this
9994+ // definition and it must be coded in such a way
9995+ // that it appears to be 64 bits. ints are 16 bits
9996+ // in BIOS land; fortunately, longs are 32 bits.
9997+} SerialNumberT;
9998+
9999+
10000+
10001+//
10002+// ***********************
10003+// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10004+// ***********************
10005+// drivers for CT_NONE to CT_PASSTHRU
10006+//
10007+typedef enum _FSAVOLTYPE {
10008+ CT_NONE = 0,
10009+ CT_VOLUME,
10010+ CT_MIRROR,
10011+ CT_STRIPE,
10012+ CT_RAID5,
10013+ CT_SSRW,
10014+ CT_SSRO,
10015+ CT_MORPH,
10016+ CT_PASSTHRU,
10017+ CT_RAID4,
10018+ CT_RAID10, // stripe of mirror
10019+ CT_RAID00, // stripe of stripe
10020+ CT_VOLUME_OF_MIRRORS, // volume of mirror
10021+ CT_PSEUDO_RAID3, // really raid4
10022+
10023+ CT_LAST_VOLUME_TYPE
10024+
10025+} _E_FSAVOLTYPE;
10026+
10027+#ifdef AAC_32BIT_ENUMS
10028+typedef _E_FSAVOLTYPE FSAVOLTYPE;
10029+#else
10030+typedef AAC_UINT32 FSAVOLTYPE;
10031+#endif
10032+
10033+
10034+//
10035+// Types of objects addressable in some fashion by the client.
10036+// This is a superset of those objects handled just by the filesystem
10037+// and includes "raw" objects that an administrator would use to
10038+// configure containers and filesystems.
10039+//
10040+typedef enum _FTYPE {
10041+ FT_REG = 1, // regular file
10042+ FT_DIR, // directory
10043+ FT_BLK, // "block" device - reserved
10044+ FT_CHR, // "character special" device - reserved
10045+ FT_LNK, // symbolic link
10046+ FT_SOCK, // socket
10047+ FT_FIFO, // fifo
10048+ FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10049+ FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10050+ FT_SLICE, // virtual disk - raw volume - slice
10051+ FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10052+ FT_VOLUME, // Container - Volume Set
10053+ FT_STRIPE, // Container - Stripe Set
10054+ FT_MIRROR, // Container - Mirror Set
10055+ FT_RAID5, // Container - Raid 5 Set
10056+ FT_DATABASE // Storage object with "foreign" content manager
10057+} _E_FTYPE;
10058+
10059+#ifdef AAC_32BIT_ENUMS
10060+typedef _E_FTYPE FTYPE;
10061+#else
10062+typedef AAC_UINT32 FTYPE;
10063+#endif
10064+
10065+
10066+
10067+//
10068+// Host side memory scatter gather list
10069+// Used by the adapter for read, write, and readdirplus operations
10070+//
10071+typedef PAAC_UINT8 HOSTADDRESS;
10072+
10073+typedef struct _SGENTRY {
10074+ HOSTADDRESS SgAddress; /* 32-bit Base address. */
10075+ AAC_UINT32 SgByteCount; /* Length. */
10076+} SGENTRY;
10077+typedef SGENTRY *PSGENTRY;
10078+
10079+
10080+
10081+//
10082+// SGMAP
10083+//
10084+// This is the SGMAP structure for all commands that use
10085+// 32-bit addressing.
10086+//
10087+// Note that the upper 16 bits of SgCount are used as flags.
10088+// Only the lower 16 bits of SgCount are actually used as the
10089+// SG element count.
10090+//
10091+typedef struct _SGMAP {
10092+ AAC_UINT32 SgCount;
10093+ SGENTRY SgEntry[1];
10094+} SGMAP;
10095+typedef SGMAP *PSGMAP;
10096+
10097+
10098+
10099+//
10100+// SGMAP64
10101+//
10102+// This is the SGMAP structure for 64-bit container commands.
10103+//
10104+typedef struct _SGMAP64 {
10105+ AAC_UINT8 SgCount;
10106+ AAC_UINT8 SgSectorsPerPage;
10107+ AAC_UINT16 SgByteOffset; // For the first page
10108+ AAC_UINT64S SgEntry[1]; // Must be last entry
10109+} SGMAP64;
10110+typedef SGMAP64 *PSGMAP64;
10111+
10112+
10113+
10114+
10115+//
10116+// attempt at common time structure across host and adapter
10117+//
10118+typedef struct __TIME_T {
10119+
10120+ AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10121+ AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10122+
10123+} TIME_T;
10124+typedef TIME_T *PTIME_T;
10125+
10126+#ifndef _TIME_T
10127+#define timespec __TIME_T
10128+#define ts_sec tv_sec
10129+#define ts_nsec tv_usec
10130+#endif
10131+
10132+
10133+
10134+
10135+typedef struct _ContainerCreationInfo
10136+{
10137+
10138+ AAC_UINT8 ViaBuildNumber; // e.g., 588
10139+ AAC_UINT8 MicroSecond; // e.g., 588
10140+ AAC_UINT8 Via; // e.g., 1 = FSU,
10141+ // 2 = API,
10142+ AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10143+ AAC_UINT32 Date; //
10144+ // unsigned Month :4; // 1 - 12
10145+ // unsigned Day :6; // 1 - 32
10146+ // unsigned Hour :6; // 0 - 23
10147+ // unsigned Minute :6; // 0 - 60
10148+ // unsigned Second :6; // 0 - 60
10149+ SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10150+} ContainerCreationInfo;
10151+
10152+
10153+#endif // _FSATYPES_H
10154+
10155+
10156diff -urN linux/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10157--- linux/drivers/scsi/aacraid/include/linit.h Wed Dec 31 19:00:00 1969
10158+++ linux/drivers/scsi/aacraid/include/linit.h Thu Dec 21 13:14:30 2000
10159@@ -0,0 +1,106 @@
10160+/*++
10161+ * Adaptec aacraid device driver for Linux.
10162+ *
10163+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10164+ *
10165+ * This program is free software; you can redistribute it and/or modify
10166+ * it under the terms of the GNU General Public License as published by
10167+ * the Free Software Foundation; either version 2, or (at your option)
10168+ * any later version.
10169+ *
10170+ * This program is distributed in the hope that it will be useful,
10171+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10172+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10173+ * GNU General Public License for more details.
10174+ *
10175+ * You should have received a copy of the GNU General Public License
10176+ * along with this program; see the file COPYING. If not, write to
10177+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10178+ *
10179+ * Module Name:
10180+ * linit.h
10181+ *
10182+ * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10183+ *
10184+ --*/
10185+/*------------------------------------------------------------------------------
10186+ * I N C L U D E S
10187+ *----------------------------------------------------------------------------*/
10188+
10189+#ifndef _LINIT_H_
10190+#define _LINIT_H_
10191+
10192+static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10193+
10194+#include <linux/config.h>
10195+
10196+/*------------------------------------------------------------------------------
10197+ * D E F I N E S
10198+ *----------------------------------------------------------------------------*/
10199+/* Define the AAC SCSI Host Template structure. */
10200+#define AAC_HOST_TEMPLATE_ENTRY \
10201+ { name: "AAC", /* Driver Name */ \
10202+ proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10203+ detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10204+ release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10205+ info: AAC_DriverInfo, /* Driver Info Function */ \
10206+ ioctl: AAC_Ioctl, /* ioctl Interface */ \
10207+ command: AAC_Command, /* unqueued command */ \
10208+ queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10209+ abort: AAC_AbortCommand, /* Abort Command Function */ \
10210+ reset: AAC_ResetCommand, /* Reset Command Function */ \
10211+ bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10212+ can_queue: 1, /* Default initial value */ \
10213+ this_id: 0, /* Default initial value */ \
10214+ sg_tablesize: 0, /* Default initial value */ \
10215+ cmd_per_lun: 0, /* Default initial value */ \
10216+ present: 0, /* Default initial value */ \
10217+ unchecked_isa_dma: 0, /* Default Initial Value */ \
10218+ use_new_eh_code: 0, /* Default initial value */ \
10219+ eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10220+ eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10221+ eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10222+ eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10223+ eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10224+ use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10225+ }
10226+
10227+
10228+/*------------------------------------------------------------------------------
10229+ * T Y P E D E F S / S T R U C T S
10230+ *----------------------------------------------------------------------------*/
10231+typedef struct AAC_BIOS_DiskParameters
10232+{
10233+ int heads;
10234+ int sectors;
10235+ int cylinders;
10236+} AAC_BIOS_DiskParameters_T;
10237+
10238+
10239+/*------------------------------------------------------------------------------
10240+ * P R O G R A M G L O B A L S
10241+ *----------------------------------------------------------------------------*/
10242+
10243+const char *AAC_DriverInfo( struct Scsi_Host * );
10244+
10245+
10246+/*------------------------------------------------------------------------------
10247+ * F U N C T I O N P R O T O T Y P E S
10248+ *----------------------------------------------------------------------------*/
10249+/* Define prototypes for the AAC Driver Interface Functions. */
10250+int AAC_DetectHostAdapter( Scsi_Host_Template * );
10251+int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10252+int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10253+int AAC_Command( Scsi_Cmnd * );
10254+int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10255+int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10256+int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10257+int AAC_Ioctl( Scsi_Device *, int, void * );
10258+
10259+
10260+void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10261+
10262+
10263+int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10264+
10265+#endif /* _LINIT_H_ */
10266diff -urN linux/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10267--- linux/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 19:00:00 1969
10268+++ linux/drivers/scsi/aacraid/include/monkerapi.h Thu Dec 21 13:14:30 2000
10269@@ -0,0 +1,98 @@
10270+/*++
10271+ * Adaptec aacraid device driver for Linux.
10272+ *
10273+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10274+ *
10275+ * This program is free software; you can redistribute it and/or modify
10276+ * it under the terms of the GNU General Public License as published by
10277+ * the Free Software Foundation; either version 2, or (at your option)
10278+ * any later version.
10279+ *
10280+ * This program is distributed in the hope that it will be useful,
10281+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10282+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10283+ * GNU General Public License for more details.
10284+ *
10285+ * You should have received a copy of the GNU General Public License
10286+ * along with this program; see the file COPYING. If not, write to
10287+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10288+ *
10289+ * Module Name:
10290+ * monkerapi.h
10291+ *
10292+ * Abstract: This module contains the definitions used by the Host Adapter
10293+ * Communications interface.
10294+ * This is the interface used for by host programs and the Adapter
10295+ * to communicate via synchronous commands via a shared set of registers
10296+ * on a platform (typically doorbells and mailboxes).
10297+ *
10298+ --*/
10299+//**********************************************************************
10300+//
10301+// Monitor / Kernel API
10302+//
10303+// 03/24/1998 Bob Peret Initial creation
10304+//
10305+//**********************************************************************
10306+
10307+#ifndef MONKER_H
10308+#define MONKER_H
10309+
10310+static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10311+
10312+#define BREAKPOINT_REQUEST 0x00000004
10313+#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10314+
10315+
10316+#define SEND_SYNCHRONOUS_FIB 0x0000000c
10317+
10318+
10319+
10320+//
10321+// Adapter Status Register
10322+//
10323+// Phase Staus mailbox is 32bits:
10324+// <31:16> = Phase Status
10325+// <15:0> = Phase
10326+//
10327+// The adapter reports is present state through the phase. Only
10328+// a single phase should be ever be set. Each phase can have multiple
10329+// phase status bits to provide more detailed information about the
10330+// state of the board. Care should be taken to ensure that any phase status
10331+// bits that are set when changing the phase are also valid for the new phase
10332+// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10333+// for properly maintining the phase status mailbox when it is running.
10334+
10335+//
10336+// MONKER_API Phases
10337+//
10338+// Phases are bit oriented. It is NOT valid
10339+// to have multiple bits set
10340+//
10341+
10342+
10343+#define SELF_TEST_FAILED 0x00000004
10344+
10345+
10346+#define KERNEL_UP_AND_RUNNING 0x00000080
10347+#define KERNEL_PANIC 0x00000100
10348+
10349+
10350+
10351+//
10352+// Doorbell bit defines
10353+//
10354+
10355+
10356+#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10357+
10358+
10359+#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10360+#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10361+#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10362+#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10363+#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10364+
10365+
10366+#endif // MONKER_H
10367+
10368diff -urN linux/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10369--- linux/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 19:00:00 1969
10370+++ linux/drivers/scsi/aacraid/include/nodetype.h Thu Dec 21 13:14:30 2000
10371@@ -0,0 +1,67 @@
10372+/*++
10373+ * Adaptec aacraid device driver for Linux.
10374+ *
10375+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10376+ *
10377+ * This program is free software; you can redistribute it and/or modify
10378+ * it under the terms of the GNU General Public License as published by
10379+ * the Free Software Foundation; either version 2, or (at your option)
10380+ * any later version.
10381+ *
10382+ * This program is distributed in the hope that it will be useful,
10383+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10384+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10385+ * GNU General Public License for more details.
10386+ *
10387+ * You should have received a copy of the GNU General Public License
10388+ * along with this program; see the file COPYING. If not, write to
10389+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10390+ *
10391+ * Module Name:
10392+ * nodetype.h
10393+ *
10394+ * Abstract: This module defines all of the node type codes used in this development
10395+ * shell. Every major data structure in the file system is assigned a node
10396+ * type code that is. This code is the first CSHORT in the structure and is
10397+ * followed by a CSHORT containing the size, in bytes, of the structure.
10398+ *
10399+ --*/
10400+#ifndef _NODETYPE_
10401+#define _NODETYPE_
10402+
10403+static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10404+
10405+typedef CSHORT NODE_TYPE_CODE;
10406+
10407+
10408+#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10409+#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10410+
10411+
10412+typedef CSHORT NODE_BYTE_SIZE;
10413+
10414+
10415+//
10416+// The following definitions are used to generate meaningful blue bugcheck
10417+// screens. On a bugcheck the file system can output 4 ulongs of useful
10418+// information. The first ulong will have encoded in it a source file id
10419+// (in the high word) and the line number of the bugcheck (in the low word).
10420+// The other values can be whatever the caller of the bugcheck routine deems
10421+// necessary.
10422+//
10423+// Each individual file that calls bugcheck needs to have defined at the
10424+// start of the file a constant called BugCheckFileId with one of the
10425+// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10426+// the system.
10427+//
10428+
10429+
10430+#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10431+#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10432+
10433+
10434+#define FsaBugCheck(A,B,C) { cmn_err( CE_PANIC, "aacdisk: module %x, line %x, 0x%x, 0x%x, 0x%x ", BugCheckFileId, __LINE__, A, B, C); }
10435+
10436+
10437+#endif // _NODETYPE_
10438+
10439diff -urN linux/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10440--- linux/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 19:00:00 1969
10441+++ linux/drivers/scsi/aacraid/include/nvramioctl.h Thu Dec 21 13:14:30 2000
10442@@ -0,0 +1,112 @@
10443+/*++
10444+ * Adaptec aacraid device driver for Linux.
10445+ *
10446+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10447+ *
10448+ * This program is free software; you can redistribute it and/or modify
10449+ * it under the terms of the GNU General Public License as published by
10450+ * the Free Software Foundation; either version 2, or (at your option)
10451+ * any later version.
10452+ *
10453+ * This program is distributed in the hope that it will be useful,
10454+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10455+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10456+ * GNU General Public License for more details.
10457+ *
10458+ * You should have received a copy of the GNU General Public License
10459+ * along with this program; see the file COPYING. If not, write to
10460+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10461+ *
10462+ * Module Name:
10463+ * nvramioctl.h
10464+ *
10465+ * Abstract: This file defines the data structures related to querying
10466+ * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10467+ *
10468+ --*/
10469+#ifndef _NVRAMIOCTL_H_
10470+#define _NVRAMIOCTL_H_ 1
10471+
10472+static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10473+
10474+/*
10475+ * NVRAM/Write Cache subsystem states
10476+ */
10477+typedef enum _NVSTATUS {
10478+ NVSTATUS_DISABLED = 0, // present, clean, not being used
10479+ NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10480+ NVSTATUS_ERROR, // present, dirty, contains dirty data
10481+ // for bad/missing device
10482+ NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10483+ // for bad/missing device
10484+ NVSTATUS_UNKNOWN // present?????
10485+} _E_NVSTATUS;
10486+
10487+#ifdef AAC_32BIT_ENUMS
10488+typedef _E_NVSTATUS NVSTATUS;
10489+#else
10490+typedef AAC_UINT32 NVSTATUS;
10491+#endif
10492+
10493+/*
10494+ * NVRAM/Write Cache subsystem battery component states
10495+ *
10496+ */
10497+//NB: this enum should be identical to battery_status in nvram.h
10498+// or else collapsed into one enum someday
10499+typedef enum _NVBATTSTATUS {
10500+ NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10501+ NVBATTSTATUS_LOW, // battery is low on power
10502+ NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10503+ NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10504+} _E_NVBATTSTATUS;
10505+
10506+#ifdef AAC_32BIT_ENUMS
10507+typedef _E_NVBATTSTATUS NVBATTSTATUS;
10508+#else
10509+typedef AAC_UINT32 NVBATTSTATUS;
10510+#endif
10511+
10512+/*
10513+ * battery transition type
10514+ */
10515+typedef enum _NVBATT_TRANSITION {
10516+ NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10517+ NVBATT_TRANSITION_LOW, // battery is now low on power
10518+ NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10519+} _E_NVBATT_TRANSITION;
10520+
10521+#ifdef AAC_32BIT_ENUMS
10522+typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10523+#else
10524+typedef AAC_UINT32 NVBATT_TRANSITION;
10525+#endif
10526+
10527+/*
10528+ * NVRAM Info structure returned for NVRAM_GetInfo call
10529+ */
10530+typedef struct _NVRAMDEVINFO {
10531+ AAC_UINT32 NV_Enabled; /* write caching enabled */
10532+ AAC_UINT32 NV_Error; /* device in error state */
10533+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10534+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10535+} NVRAMDEVINFO, *PNVRAMDEVINFO;
10536+
10537+typedef struct _NVRAMINFO {
10538+ NVSTATUS NV_Status; /* nvram subsystem status */
10539+ NVBATTSTATUS NV_BattStatus; /* battery status */
10540+ AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10541+ AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10542+ AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10543+ AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10544+ AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10545+ AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10546+ AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10547+ NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10548+ AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10549+ AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10550+} NVRAMINFO, *PNVRAMINFO;
10551+
10552+#endif /* !_NVRAMIOCTL_H_ */
10553+
10554+
10555diff -urN linux/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10556--- linux/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 19:00:00 1969
10557+++ linux/drivers/scsi/aacraid/include/osheaders.h Thu Dec 21 13:14:30 2000
10558@@ -0,0 +1,150 @@
10559+/*++
10560+ * Adaptec aacraid device driver for Linux.
10561+ *
10562+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10563+ *
10564+ * This program is free software; you can redistribute it and/or modify
10565+ * it under the terms of the GNU General Public License as published by
10566+ * the Free Software Foundation; either version 2, or (at your option)
10567+ * any later version.
10568+ *
10569+ * This program is distributed in the hope that it will be useful,
10570+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10571+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10572+ * GNU General Public License for more details.
10573+ *
10574+ * You should have received a copy of the GNU General Public License
10575+ * along with this program; see the file COPYING. If not, write to
10576+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10577+ *
10578+ * Module Name:
10579+ * osheaders.h
10580+ *
10581+ * Abstract: Holds all of the header file includes for a particular O/S flavor.
10582+ *
10583+ --*/
10584+#ifndef _OSHEADERS_H_
10585+#define _OSHEADERS_H_
10586+
10587+static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10588+
10589+#include <linux/autoconf.h> // retrieve the kernel configuration info
10590+#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10591+#define MODVERSIONS // force it on
10592+#endif
10593+
10594+#include <linux/version.h>
10595+
10596+#if defined( MODVERSIONS ) && defined( MODULE )
10597+#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10598+#ifdef __SMP__
10599+#include <linux/modversions-smp.h>
10600+#elif defined( BOOT_DRIVER )
10601+#include <linux/modversions-BOOT.h>
10602+#else
10603+#include <linux/modversions-up.h>
10604+#endif // ifdef __SMP__
10605+#else
10606+#include <linux/modversions.h>
10607+#endif
10608+#endif
10609+
10610+
10611+#include <linux/kernel.h>
10612+#include <linux/config.h>
10613+#include <linux/init.h>
10614+#include <linux/types.h>
10615+#include <linux/blk.h>
10616+#include <linux/blkdev.h>
10617+#include <linux/delay.h>
10618+#include <linux/ioport.h>
10619+#include <linux/mm.h>
10620+#include <linux/sched.h>
10621+#include <linux/stat.h>
10622+#include <linux/pci.h>
10623+#include <linux/interrupt.h>
10624+#include <asm/dma.h>
10625+#include <asm/io.h>
10626+#include <linux/spinlock.h>
10627+#include <asm/system.h>
10628+#include <asm/bitops.h>
10629+#include <asm/uaccess.h>
10630+#include <linux/wait.h>
10631+#include <linux/malloc.h>
10632+#include <linux/tqueue.h>
10633+/* bmb fix
10634+#include <linux/tasks.h>
10635+*/
10636+#include <ostypes.h>
10637+#include "scsi.h"
10638+#include "hosts.h"
10639+
10640+#ifndef intptr_t
10641+#define intptr_t void *
10642+#endif
10643+
10644+#ifndef cred_t
10645+#define cred_t void
10646+#endif
10647+
10648+#ifndef paddr32_t
10649+#define paddr32_t unsigned
10650+#endif
10651+
10652+#ifndef bzero
10653+#define bzero(b,len) memset(b,0,len)
10654+#endif
10655+
10656+#ifndef bcopy
10657+#define bcopy(src,dst,len) memcpy(dst,src,len )
10658+#endif
10659+
10660+#ifndef DEVICE_NR
10661+#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10662+#endif
10663+
10664+typedef unsigned uint_t;
10665+
10666+typedef enum
10667+{
10668+ CE_PANIC = 0,
10669+ CE_WARN,
10670+ CE_NOTE,
10671+ CE_CONT,
10672+ CE_DEBUG,
10673+ CE_DEBUG2,
10674+ CE_TAIL
10675+} CE_ENUM_T;
10676+
10677+#define CMN_ERR_LEVEL CE_NOTE
10678+
10679+#ifndef IN
10680+#define IN
10681+#endif
10682+
10683+// usage of READ & WRITE as a typedefs in protocol.h
10684+// conflicts with <linux/fs.h> definition.
10685+#ifdef READ
10686+#undef READ
10687+#endif
10688+
10689+#ifdef WRITE
10690+#undef WRITE
10691+#endif
10692+
10693+typedef struct aac_options
10694+{
10695+ int message_level;
10696+ int reverse_scan;
10697+} aac_options_t;
10698+
10699+#endif // _OSHEADERS_H_
10700+
10701+
10702+
10703+
10704+
10705+
10706+
10707+
10708+
10709diff -urN linux/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10710--- linux/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 19:00:00 1969
10711+++ linux/drivers/scsi/aacraid/include/ostypes.h Thu Dec 21 13:14:30 2000
10712@@ -0,0 +1,149 @@
10713+/*++
10714+ * Adaptec aacraid device driver for Linux.
10715+ *
10716+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10717+ *
10718+ * This program is free software; you can redistribute it and/or modify
10719+ * it under the terms of the GNU General Public License as published by
10720+ * the Free Software Foundation; either version 2, or (at your option)
10721+ * any later version.
10722+ *
10723+ * This program is distributed in the hope that it will be useful,
10724+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10725+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10726+ * GNU General Public License for more details.
10727+ *
10728+ * You should have received a copy of the GNU General Public License
10729+ * along with this program; see the file COPYING. If not, write to
10730+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10731+ *
10732+ * Module Name:
10733+ * ostypes.h
10734+ *
10735+ * Abstract: Holds all of the O/S specific types.
10736+ *
10737+ --*/
10738+/*------------------------------------------------------------------------------
10739+ * D E F I N E S
10740+ *----------------------------------------------------------------------------*/
10741+#ifndef _OSTYPES_H_
10742+#define _OSTYPES_H_
10743+
10744+static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10745+
10746+#include <linux/types.h>
10747+
10748+#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10749+#define MAXIMUM_NUM_ADAPTERS 8
10750+
10751+#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10752+
10753+#define Os_remove_softintr OsSoftInterruptRemove
10754+#define OsPrintf printk
10755+#define FsaCommPrint
10756+
10757+// the return values for copy_from_user & copy_to_user is the
10758+// number of bytes not transferred. Thus if an internal error
10759+// occurs, the return value is greater than zero.
10760+#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10761+#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10762+
10763+#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10764+#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10765+
10766+/*------------------------------------------------------------------------------
10767+ * S T R U C T S / T Y P E D E F S
10768+ *----------------------------------------------------------------------------*/
10769+typedef struct OS_MUTEX
10770+{
10771+ unsigned long lock_var;
10772+ wait_queue_head_t wq;
10773+ unsigned owner;
10774+} OS_MUTEX;
10775+
10776+typedef struct OS_SPINLOCK
10777+{
10778+ spinlock_t spin_lock;
10779+ unsigned cpu_lock_count[NR_CPUS];
10780+ long cpu_flag;
10781+ long lockout_count;
10782+} OS_SPINLOCK;
10783+
10784+#ifdef CVLOCK_USE_SPINLOCK
10785+ typedef OS_SPINLOCK OS_CVLOCK;
10786+#else
10787+ typedef OS_MUTEX OS_CVLOCK;
10788+#endif
10789+
10790+typedef size_t OS_SIZE_T;
10791+
10792+typedef struct OS_CV_T
10793+{
10794+ unsigned long lock_var;
10795+ unsigned long type;
10796+ wait_queue_head_t wq;
10797+} OS_CV_T;
10798+
10799+struct fsa_scsi_hba {
10800+ void *CommonExtension;
10801+ unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10802+ unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10803+ unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10804+ unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10805+ unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10806+ unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10807+ long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10808+};
10809+
10810+typedef struct fsa_scsi_hba fsadev_t;
10811+
10812+typedef struct OsKI
10813+{
10814+ struct Scsi_Host *scsi_host_ptr;
10815+ void * dip; // #REVISIT#
10816+ fsadev_t fsa_dev;
10817+ int thread_pid;
10818+ int MiniPortIndex;
10819+} OsKI_t;
10820+
10821+#define dev_info_t fsadev_t
10822+
10823+typedef int OS_SPINLOCK_COOKIE;
10824+
10825+typedef unsigned int OS_STATUS;
10826+
10827+typedef struct tq_struct OS_SOFTINTR;
10828+
10829+typedef OS_SOFTINTR *ddi_softintr_t;
10830+
10831+
10832+
10833+//-----------------------------------------------------------------------------
10834+// Conditional variable functions
10835+
10836+void OsCv_init (
10837+ OS_CV_T *cv_ptr );
10838+
10839+
10840+//-----------------------------------------------------------------------------
10841+// Printing functions
10842+void printk_err(int flag, char *fmt, ...);
10843+
10844+#define cmn_err printk_err
10845+
10846+
10847+//
10848+// just ignore these solaris ddi functions in the code
10849+//
10850+#define DDI_SUCCESS 0
10851+
10852+#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10853+
10854+//#REVIEW#
10855+#define ddi_remove_softintr(A) 0
10856+#define ddi_get_soft_iblock_cookie(A, B, C) 0
10857+
10858+#define ASSERT(expr) ((void) 0)
10859+#define drv_usecwait udelay
10860+
10861+#endif // _OSTYPES_H_
10862diff -urN linux/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10863--- linux/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 19:00:00 1969
10864+++ linux/drivers/scsi/aacraid/include/pcisup.h Thu Dec 21 13:14:30 2000
10865@@ -0,0 +1,97 @@
10866+/*++
10867+ * Adaptec aacraid device driver for Linux.
10868+ *
10869+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10870+ *
10871+ * This program is free software; you can redistribute it and/or modify
10872+ * it under the terms of the GNU General Public License as published by
10873+ * the Free Software Foundation; either version 2, or (at your option)
10874+ * any later version.
10875+ *
10876+ * This program is distributed in the hope that it will be useful,
10877+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10878+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10879+ * GNU General Public License for more details.
10880+ *
10881+ * You should have received a copy of the GNU General Public License
10882+ * along with this program; see the file COPYING. If not, write to
10883+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10884+ *
10885+ * Module Name:
10886+ * pcisup.h
10887+ *
10888+ * Abstract: This module defines functions that are defined in PciSup.c
10889+ *
10890+ --*/
10891+#ifndef _PCISUP_
10892+#define _PCISUP_
10893+
10894+static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10895+
10896+
10897+/*
10898+ * define which interrupt handler needs to be installed
10899+ */
10900+
10901+#define SaISR 1
10902+#define RxISR 2
10903+
10904+typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10905+ ULONG AdapterNumber; // Which FSA# this miniport is
10906+
10907+ ULONG PciBusNumber; // Which PCI bus we are located on
10908+ ULONG PciSlotNumber; // Whiat PCI slot we are in
10909+
10910+ PVOID Adapter; // Back pointer to Fsa adapter object
10911+ ULONG AdapterIndex; // Index into PlxAdapterTypes array
10912+ PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10913+
10914+ FSAPORT_FUNCS AdapterFuncs;
10915+ ULONG FilesystemRevision; // Main driver's revision number
10916+
10917+
10918+ PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
10919+ PVOID PhysicalInitStruct; // Holds physical address of the init struct
10920+
10921+
10922+ PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
10923+
10924+ BOOLEAN AdapterPrintfsToScreen;
10925+ BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
10926+
10927+ void * MiniPort;
10928+
10929+ caddr_t CommAddress; // Base address of Comm area
10930+ paddr32_t CommPhysAddr; // Physical Address of Comm area
10931+ size_t CommSize;
10932+
10933+ OsKI_t OsDep; // OS dependent kernel interfaces
10934+
10935+
10936+} PCI_MINIPORT_COMMON_EXTENSION;
10937+
10938+typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
10939+
10940+typedef int
10941+(*PFSA_MINIPORT_INIT) (
10942+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
10943+ IN ULONG AdapterNumber,
10944+ IN ULONG PciBus,
10945+ IN ULONG PciSlot
10946+ );
10947+
10948+typedef struct _FSA_MINIPORT {
10949+ USHORT VendorId;
10950+ USHORT DeviceId;
10951+ USHORT SubVendorId;
10952+ USHORT SubSystemId;
10953+ PCHAR DevicePrefix;
10954+ PFSA_MINIPORT_INIT InitRoutine;
10955+ PCHAR DeviceName;
10956+ PCHAR Vendor;
10957+ PCHAR Model;
10958+} FSA_MINIPORT;
10959+typedef FSA_MINIPORT *PFSA_MINIPORT;
10960+
10961+
10962+#endif // _PCISUP_
10963diff -urN linux/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
10964--- linux/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 19:00:00 1969
10965+++ linux/drivers/scsi/aacraid/include/perfpack.h Thu Dec 21 13:14:30 2000
10966@@ -0,0 +1,110 @@
10967+/*++
10968+ * Adaptec aacraid device driver for Linux.
10969+ *
10970+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10971+ *
10972+ * This program is free software; you can redistribute it and/or modify
10973+ * it under the terms of the GNU General Public License as published by
10974+ * the Free Software Foundation; either version 2, or (at your option)
10975+ * any later version.
10976+ *
10977+ * This program is distributed in the hope that it will be useful,
10978+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10979+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10980+ * GNU General Public License for more details.
10981+ *
10982+ * You should have received a copy of the GNU General Public License
10983+ * along with this program; see the file COPYING. If not, write to
10984+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10985+ *
10986+ * Module Name:
10987+ * perfpack.h
10988+ *
10989+ * Abstract: This file defines the layout of the performance data that is passed
10990+ * back from the FSA filesystem driver.
10991+ *
10992+ *
10993+ --*/
10994+
10995+#ifndef _FSA_PERFPACK_H_
10996+#define _FSA_PERFPACK_H_ 1
10997+
10998+static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
10999+
11000+//#define FSA_DO_PERF 1 /* enable the engineering counters */
11001+
11002+#ifdef FSA_DO_PERF
11003+//
11004+// engineering counters
11005+//
11006+typedef struct _FSA_PERF_DATA {
11007+ ULONG FibsSent;
11008+ ULONG ReadDirs;
11009+ ULONG GetAttrs;
11010+ ULONG SetAttrs;
11011+ ULONG Lookups;
11012+ ULONG ReadFibs;
11013+ ULONG WriteFibs;
11014+ ULONG CreateFibs;
11015+ ULONG MakeDirs;
11016+ ULONG RemoveFibs;
11017+ ULONG RemoveDirs;
11018+ ULONG RenameFibs;
11019+ ULONG ReadDirPlus;
11020+ ULONG FsStat;
11021+ ULONG WriteBytes;
11022+ ULONG ReadBytes;
11023+// NT FSA entry points
11024+ ULONG FsaFsdCreateCount;
11025+ ULONG FsaFsdCloseCount;
11026+ ULONG FsaFsdReadCount;
11027+ ULONG FsaFsdWriteCount;
11028+ ULONG FsaFsdQueryInformationCount;
11029+
11030+ struct _FsaFsdSetInfomation{
11031+ ULONG FsaSetAllocationInfoCount;
11032+ ULONG FsaSetBasicInfoCount;
11033+ ULONG FsaSetDispositionInfoCount;
11034+ ULONG FsaSetEndOfFileInfoCount;
11035+ ULONG FsaSetPositionInfoCount;
11036+ ULONG FsaSetRenameInfoCount;
11037+ ULONG FsaClearArchiveBitCount;
11038+ };
11039+
11040+ ULONG FsaFsdFlushBuffersCount;
11041+ ULONG FsaFsdQueryVolumeInfoCount;
11042+ ULONG FsaFsdSetVolumeInfoCount;
11043+ ULONG FsaFsdCleanupCount;
11044+ ULONG FsaFsdDirectoryControlCount;
11045+ ULONG FsaFsdFileSystemControlCount;
11046+ ULONG FsaFsdLockControlCount;
11047+ ULONG FsaFsdDeviceControlCount;
11048+ ULONG FsaFsdShutdownCount;
11049+ ULONG FsaFsdQuerySecurityInfo;
11050+ ULONG FsaFsdSetSecurityInfo;
11051+ ULONG FastIoCheckIfPossibleCount;
11052+ ULONG FastIoReadCount;
11053+ ULONG FastIoWriteCount;
11054+ ULONG FastIoQueryBasicInfoCount;
11055+ ULONG FastIoQueryStandardInfoCount;
11056+ ULONG FastIoLockCount;
11057+ ULONG FastIoUnlockSingleCount;
11058+ ULONG FastIoUnlockAllCount;
11059+ ULONG FastIoUnlockAllByKeyCount;
11060+ ULONG FastIoDeviceControlCount;
11061+ } FSA_PERF_DATA;
11062+
11063+typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11064+
11065+
11066+#else /* FSA_DO_PERF */
11067+
11068+//
11069+// engineering performance counters are disabled
11070+//
11071+#define FSA_DO_PERF_INC(Counter) /* */
11072+#define FSA_DO_FSP_PERF_INC(Counter) /* */
11073+
11074+#endif /* FSA_DO_PERF */
11075+
11076+#endif // _FSA_PERFPACK_H_
11077diff -urN linux/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11078--- linux/drivers/scsi/aacraid/include/port.h Wed Dec 31 19:00:00 1969
11079+++ linux/drivers/scsi/aacraid/include/port.h Thu Dec 21 13:14:30 2000
11080@@ -0,0 +1,87 @@
11081+/*++
11082+ * Adaptec aacraid device driver for Linux.
11083+ *
11084+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11085+ *
11086+ * This program is free software; you can redistribute it and/or modify
11087+ * it under the terms of the GNU General Public License as published by
11088+ * the Free Software Foundation; either version 2, or (at your option)
11089+ * any later version.
11090+ *
11091+ * This program is distributed in the hope that it will be useful,
11092+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11093+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11094+ * GNU General Public License for more details.
11095+ *
11096+ * You should have received a copy of the GNU General Public License
11097+ * along with this program; see the file COPYING. If not, write to
11098+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11099+ *
11100+ * Module Name:
11101+ * port.h
11102+ *
11103+ * Abstract: This module defines functions and structures that are in common among all miniports
11104+ *
11105+ *
11106+ --*/
11107+
11108+#ifndef _PORT_
11109+#define _PORT_
11110+
11111+static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11112+
11113+#ifdef DBG
11114+#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11115+extern int AfaPortPrinting;
11116+#else
11117+#define AfaPortPrint
11118+#endif DBG
11119+
11120+extern int AfaPortPrinting;
11121+
11122+
11123+BOOLEAN
11124+AfaPortAllocateAdapterCommArea(
11125+ IN PVOID Arg1,
11126+ IN OUT PVOID *CommHeaderAddress,
11127+ IN ULONG CommAreaSize,
11128+ IN ULONG CommAreaAlignment
11129+ );
11130+
11131+
11132+BOOLEAN
11133+AfaPortFreeAdapterCommArea(
11134+ IN PVOID Arg1
11135+ );
11136+
11137+
11138+AAC_STATUS
11139+AfaPortBuildSgMap(
11140+ PVOID Arg1,
11141+ IN PSGMAP_CONTEXT SgMapContext
11142+ );
11143+
11144+
11145+VOID
11146+AfaPortFreeDmaResources(
11147+ PVOID Arg1,
11148+ IN PSGMAP_CONTEXT SgMapContext
11149+ );
11150+
11151+
11152+BOOLEAN
11153+AfaPortAllocateAndMapFibSpace(
11154+ PVOID Arg1,
11155+ IN PMAPFIB_CONTEXT MapFibContext
11156+ );
11157+
11158+
11159+BOOLEAN
11160+AfaPortUnmapAndFreeFibSpace(
11161+ PVOID Arg1,
11162+ IN PMAPFIB_CONTEXT MapFibContext
11163+ );
11164+
11165+
11166+#endif // _PORT_
11167+
11168diff -urN linux/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11169--- linux/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 19:00:00 1969
11170+++ linux/drivers/scsi/aacraid/include/protocol.h Thu Dec 21 13:14:30 2000
11171@@ -0,0 +1,249 @@
11172+/*++
11173+ * Adaptec aacraid device driver for Linux.
11174+ *
11175+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11176+ *
11177+ * This program is free software; you can redistribute it and/or modify
11178+ * it under the terms of the GNU General Public License as published by
11179+ * the Free Software Foundation; either version 2, or (at your option)
11180+ * any later version.
11181+ *
11182+ * This program is distributed in the hope that it will be useful,
11183+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11184+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11185+ * GNU General Public License for more details.
11186+ *
11187+ * You should have received a copy of the GNU General Public License
11188+ * along with this program; see the file COPYING. If not, write to
11189+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11190+ *
11191+ * Module Name:
11192+ * protocol.h
11193+ *
11194+ * Abstract: Defines the commands and command data which enables the nt
11195+ * filesystem driver to be the client of the fsa adapter
11196+ * filesystem. This protocol is largely modeled after the NFS
11197+ * V3 protocol with modifications allowed due to the unique
11198+ * client/server model FSA works under.
11199+ *
11200+ *
11201+ *
11202+ --*/
11203+
11204+#ifndef _PROTOCOL_H_
11205+#define _PROTOCOL_H_
11206+
11207+static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11208+
11209+#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11210+#include <nvramioctl.h> // for NVRAMINFO definition
11211+
11212+// #define MDL_READ_WRITE
11213+
11214+//
11215+// Define the command values
11216+//
11217+typedef enum _FSA_COMMANDS {
11218+ Null = 0,
11219+ GetAttributes,
11220+ SetAttributes,
11221+ Lookup,
11222+ ReadLink,
11223+ Read,
11224+ Write,
11225+ Create,
11226+ MakeDirectory,
11227+ SymbolicLink,
11228+ MakeNode,
11229+ Removex,
11230+ RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11231+ Rename,
11232+ Link,
11233+ ReadDirectory,
11234+ ReadDirectoryPlus,
11235+ FileSystemStatus,
11236+ FileSystemInfo,
11237+ PathConfigure,
11238+ Commit,
11239+ Mount,
11240+ UnMount,
11241+ Newfs,
11242+ FsCheck,
11243+ FsSync,
11244+ SimReadWrite,
11245+ SetFileSystemStatus,
11246+ BlockRead,
11247+ BlockWrite,
11248+ NvramIoctl,
11249+ FsSyncWait,
11250+ ClearArchiveBit,
11251+#ifdef MDL_READ_WRITE
11252+ MdlReadComplete,
11253+ MdlWriteComplete,
11254+ MdlRead, // these are used solely for stats, Mdl really controlled by
11255+ MdlWrite, // flags field in Fib.
11256+#endif
11257+ SetAcl,
11258+ GetAcl,
11259+ AssignAcl,
11260+ FaultInsertion, // Fault Insertion Command
11261+ CrazyCache, // crazycache
11262+ MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11263+} _E_FSACOMMAND;
11264+
11265+#ifdef AAC_32BIT_ENUMS
11266+typedef _E_FSACOMMAND FSACOMMAND;
11267+#else
11268+typedef AAC_UINT32 FSACOMMAND;
11269+#endif
11270+
11271+
11272+
11273+//
11274+// Define the status returns
11275+//
11276+// See include\comm\errno.h for adapter kernel errno's
11277+typedef enum _FSASTATUS {
11278+ ST_OK = 0,
11279+ ST_PERM = 1,
11280+ ST_NOENT = 2,
11281+ ST_IO = 5,
11282+ ST_NXIO = 6,
11283+ ST_E2BIG = 7,
11284+ ST_ACCES = 13,
11285+ ST_EXIST = 17,
11286+ ST_XDEV = 18,
11287+ ST_NODEV = 19,
11288+ ST_NOTDIR = 20,
11289+ ST_ISDIR = 21,
11290+ ST_INVAL = 22,
11291+ ST_FBIG = 27,
11292+ ST_NOSPC = 28,
11293+ ST_ROFS = 30,
11294+ ST_MLINK = 31,
11295+ ST_WOULDBLOCK = 35,
11296+ ST_NAMETOOLONG = 63,
11297+ ST_NOTEMPTY = 66,
11298+ ST_DQUOT = 69,
11299+ ST_STALE = 70,
11300+ ST_REMOTE = 71,
11301+ ST_BADHANDLE = 10001,
11302+ ST_NOT_SYNC = 10002,
11303+ ST_BAD_COOKIE = 10003,
11304+ ST_NOTSUPP = 10004,
11305+ ST_TOOSMALL = 10005,
11306+ ST_SERVERFAULT = 10006,
11307+ ST_BADTYPE = 10007,
11308+ ST_JUKEBOX = 10008,
11309+ ST_NOTMOUNTED = 10009,
11310+ ST_MAINTMODE = 10010,
11311+ ST_STALEACL = 10011
11312+} _E_FSASTATUS;
11313+
11314+#ifdef AAC_32BIT_ENUMS
11315+typedef _E_FSASTATUS FSASTATUS;
11316+#else
11317+typedef AAC_UINT32 FSASTATUS;
11318+#endif
11319+
11320+//
11321+// On writes how does the client want the data written.
11322+//
11323+
11324+typedef enum _CACHELEVEL {
11325+ CSTABLE = 1,
11326+ CUNSTABLE
11327+} _E_CACHELEVEL;
11328+
11329+#ifdef AAC_32BIT_ENUMS
11330+typedef _E_CACHELEVEL CACHELEVEL;
11331+#else
11332+typedef AAC_UINT32 CACHELEVEL;
11333+#endif
11334+
11335+//
11336+// Lets the client know at which level the data was commited on a write request
11337+//
11338+
11339+typedef enum _COMMITLEVEL {
11340+ CMFILE_SYNCH_NVRAM = 1,
11341+ CMDATA_SYNCH_NVRAM,
11342+ CMFILE_SYNCH,
11343+ CMDATA_SYNCH,
11344+ CMUNSTABLE
11345+} _E_COMMITLEVEL;
11346+
11347+#ifdef AAC_32BIT_ENUMS
11348+typedef _E_COMMITLEVEL COMMITLEVEL;
11349+#else
11350+typedef AAC_UINT32 COMMITLEVEL;
11351+#endif
11352+
11353+
11354+
11355+//
11356+// The following are all the different commands or FIBs which can be sent to the
11357+// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11358+// but others outside that subset are allowed to return not implemented. The client is then
11359+// responsible for dealing with the fact it is not implemented.
11360+//
11361+typedef AAC_INT8 FSASTRING[16];
11362+
11363+
11364+typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11365+
11366+
11367+
11368+//
11369+// BlockRead
11370+//
11371+
11372+typedef struct _BLOCKREAD { // variable size struct
11373+
11374+ FSACOMMAND Command;
11375+ AAC_UINT32 ContainerId;
11376+ BYTECOUNT BlockNumber;
11377+ BYTECOUNT ByteCount;
11378+ SGMAP SgMap; // Must be last in struct because it is variable
11379+
11380+} BLOCKREAD;
11381+typedef BLOCKREAD *PBLOCKREAD;
11382+
11383+typedef struct _BLOCKREADRESPONSE {
11384+
11385+ FSASTATUS Status;
11386+ BYTECOUNT ByteCount;
11387+
11388+} BLOCKREADRESPONSE;
11389+typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11390+
11391+//
11392+// BlockWrite
11393+//
11394+
11395+typedef struct _BLOCKWRITE { // variable size struct
11396+
11397+ FSACOMMAND Command;
11398+ AAC_UINT32 ContainerId;
11399+ BYTECOUNT BlockNumber;
11400+ BYTECOUNT ByteCount;
11401+ CACHELEVEL Stable;
11402+ SGMAP SgMap; // Must be last in struct because it is variable
11403+
11404+} BLOCKWRITE;
11405+typedef BLOCKWRITE *PBLOCKWRITE;
11406+
11407+
11408+typedef struct _BLOCKWRITERESPONSE {
11409+
11410+ FSASTATUS Status;
11411+ BYTECOUNT ByteCount;
11412+ COMMITLEVEL Committed;
11413+
11414+} BLOCKWRITERESPONSE;
11415+typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11416+
11417+
11418+
11419+#endif // _PROTOCOL_H_
11420+
11421diff -urN linux/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11422--- linux/drivers/scsi/aacraid/include/revision.h Wed Dec 31 19:00:00 1969
11423+++ linux/drivers/scsi/aacraid/include/revision.h Thu Dec 21 13:14:30 2000
11424@@ -0,0 +1,350 @@
11425+/*++
11426+ * Adaptec aacraid device driver for Linux.
11427+ *
11428+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11429+ *
11430+ * This program is free software; you can redistribute it and/or modify
11431+ * it under the terms of the GNU General Public License as published by
11432+ * the Free Software Foundation; either version 2, or (at your option)
11433+ * any later version.
11434+ *
11435+ * This program is distributed in the hope that it will be useful,
11436+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11437+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11438+ * GNU General Public License for more details.
11439+ *
11440+ * You should have received a copy of the GNU General Public License
11441+ * along with this program; see the file COPYING. If not, write to
11442+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11443+ *
11444+ * Module Name:
11445+ * revision.h
11446+ *
11447+ * Abstract: This module contains all of the revision information for
11448+ * the FSA product, as well as the support routines for
11449+ * checking module compatibility.
11450+ *
11451+ * Before editing anything in this module, make sure that
11452+ * you read the comments. Some lines are changed automatically
11453+ * as part of the build, and should never be changed by hand.
11454+ *
11455+ * Routines (all inlines):
11456+ *
11457+ * RevGetBuildNumber - Retrieve current build number
11458+ * RevGetExternalRev - Retrieve revision for external use
11459+ * RevGetFullRevision - Retrieve full revision structure
11460+ *
11461+ * RevCheckCompatibility - Checks compatibility base on internal table
11462+ *
11463+ * RevCheckCompatibilityFullInfo - Check for static component
11464+ * RevGetCompInfoTableSize - Get size for static component table
11465+ * RevGetCompInfoTable - Get actual table to place on static component
11466+ * RevGetBuildNumberFromInfo - Get build number for static component.
11467+ *
11468+ *
11469+ *
11470+ --*/
11471+
11472+#ifndef _REVISION_H
11473+#define _REVISION_H
11474+
11475+static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11476+
11477+#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11478+
11479+typedef int REV_BOOL;
11480+
11481+#define REV_TRUE 1
11482+#define REV_FALSE 0
11483+
11484+//
11485+// Define Revision Levels for this product
11486+//
11487+// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11488+// automatically by the build.
11489+//
11490+// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11491+//
11492+// IMPORTANT: Don't access these revisions directly. They can be
11493+// accessed via, the RevGetXxxxx rouines.
11494+//
11495+
11496+
11497+#define REV_AS_LONGWORD \
11498+ ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11499+
11500+
11501+
11502+#ifndef BIOS
11503+
11504+//
11505+// Enumerate the types of product levels we can have
11506+//
11507+enum {
11508+ RevType_Devo=1, // Development mode, testing all of latest
11509+ RevType_Alpha, // Alpha - Internal field test
11510+ RevType_Beta, // Beta - External field test
11511+ RevType_Release // Release - Retail version
11512+};
11513+
11514+//
11515+// Define the basic structure for all revision information. Note
11516+// that the ordering of the components is such that they should
11517+// always increase. dash will be updated the most, then the version
11518+// type, then minor and major.
11519+//
11520+typedef struct {
11521+ union {
11522+ struct {
11523+ unsigned char dash; // Dash version number
11524+ unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11525+ unsigned char minor;// Minor version minor
11526+ unsigned char major;// Major version number
11527+ } comp; // Components to external viewed rev number
11528+ unsigned long ul; // External revision as single 32-bit value
11529+ } external; // External revision number (union)
11530+ unsigned long buildNumber; // Automatically generated build number
11531+} FsaRevision;
11532+
11533+
11534+//
11535+// Define simple routines to get basic revision information. The
11536+// definitions should never be accessed directly. These routines
11537+// are meant to be used to access all relevant information no matter
11538+// how simple.
11539+//
11540+static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11541+
11542+static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11543+
11544+
11545+//
11546+// Enumerate different components that may have to check
11547+// compatibility. This list of components can be changed
11548+// at any time.
11549+//
11550+// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11551+// incompatibilities between component rev checking will
11552+// cause wrong checking results.
11553+//
11554+typedef enum {
11555+ RevApplication = 1, // Any user End application
11556+ RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11557+ RevNetService, // Network Service Revision (under API)
11558+ RevApi, // ADAPTEC User mode API
11559+ RevFileSysDriver, // FSA File System Driver
11560+ RevMiniportDriver, // FSA File System Miniport Driver
11561+ RevAdapterSW, // Adapter Software (or NT Simulator)
11562+ RevMonitor, // Monitor for adapter hardware (MON960 for now)
11563+ RevRemoteApi // The remote API.
11564+ // ALWAYS ADD NEW COMPONENTS HERE - AT END
11565+} RevComponent;
11566+
11567+//
11568+// Define a structure so that we can create a compatibility table.
11569+//
11570+typedef struct {
11571+ RevComponent A,B;
11572+ unsigned long BuildNumOfB_RequiredByA;
11573+ unsigned long BuildNumOfA_RequiredByB;
11574+} RevCompareElement;
11575+
11576+//
11577+// Now, define the table. This table should only be included once,
11578+// in one program. If it is linked from 2 modules, there will likely
11579+// be a multiply defined symbol error from the linker.
11580+//
11581+// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11582+// allow access to the revision information table without a redefinition
11583+// of the tables.
11584+//
11585+extern const int RevCompareTableLength;
11586+
11587+extern const RevCompareElement RevCompareTable[];
11588+
11589+/********************************************************************\
11590+* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11591+*
11592+* The following routine is used to check compatibility between
11593+* the calling component and a component that has some dependencies
11594+* on it. If this routine returns REV_FALSE, it is expected that the caller
11595+* will send an appropriate incompatibility message and stop.
11596+*
11597+* This routine is only meant to check for compatibility in the
11598+* absolute sense. If code wishes to execute a different path based
11599+* on the CompB_BuildNumber, then this routine is not useful. The
11600+* routine RevGetBuildNumber can be used to get the calling module's
11601+* current build number for a comparison check.
11602+*
11603+* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11604+* if the components are definitely not compatible, or there is an
11605+* error when trying to figure it out. To be more specific:
11606+*
11607+* 1) REV_TRUE if component B is newer than calling component. (In this
11608+* case, the revision check done by component B with respect to
11609+* this component will give the real compatibility information.
11610+* It is the only one with the knowledge, since this component
11611+* could not look into the future.)
11612+* 2) REV_TRUE if calling component is more recent and table shows okay
11613+* 3) REV_FALSE if calling component more recent and table show not okay
11614+* 4) REV_FALSE if calling component is more recent and table entry to
11615+* check does not exist.
11616+*
11617+* Note that the CompB_BuildNumber must be attained by the calling
11618+* routine through some mechanism done by the caller.
11619+*
11620+* Input:
11621+*
11622+* callerComp - Name of component making this call
11623+* compB - Name of component to check compatibility with
11624+* compB_BuildNumber - Build number to component B
11625+*
11626+* Output:
11627+*
11628+* None
11629+*
11630+* Return Value:
11631+*
11632+* REV_TRUE - Component compatibility is possible, continue as usual. compB
11633+* must give true compatibility information.
11634+* REV_FALSE - Incompatible components, notify and end
11635+*
11636+\********************************************************************/
11637+static inline REV_BOOL RevCheckCompatibility(
11638+ RevComponent callerComp,
11639+ RevComponent compB,
11640+ unsigned long compB_BuildNumber)
11641+{
11642+ int i;
11643+ unsigned long RevForB;
11644+
11645+ //
11646+ // Compatibility check is possible, so we should continue. When
11647+ // compB makes this call in its own component, it will get the
11648+ // true compatibility information, since only it can know.
11649+ //
11650+ if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11651+
11652+ //
11653+ // Go through rev table. When the components are found in the
11654+ // same table entry, return the approprate number.
11655+ //
11656+ for (i=0; i<RevCompareTableLength; i++) {
11657+ if (RevCompareTable[i].A == callerComp) {
11658+ if (RevCompareTable[i].B == compB) {
11659+ RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11660+ return (compB_BuildNumber >= RevForB);
11661+ }
11662+ } else if (RevCompareTable[i].B == callerComp) {
11663+ if (RevCompareTable[i].A == compB) {
11664+ RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11665+ return (compB_BuildNumber >= RevForB);
11666+ }
11667+ }
11668+ }
11669+
11670+ //
11671+ // Uh oh! No relevant table entry was found (this should never
11672+ // happen).
11673+ //
11674+ return REV_FALSE;
11675+}
11676+
11677+
11678+//
11679+// Now create a structure that can be used by a FIB to check
11680+// compatibility.
11681+//
11682+typedef struct _RevCheck {
11683+ RevComponent callingComponent;
11684+ FsaRevision callingRevision;
11685+} RevCheck;
11686+
11687+typedef struct _RevCheckResp {
11688+ REV_BOOL possiblyCompatible;
11689+ FsaRevision adapterSWRevision;
11690+} RevCheckResp;
11691+
11692+#endif /* bios */
11693+#endif /* _REVISION_H */
11694+
11695+//
11696+// The following allows for inclusion of revision.h in other h
11697+// files. when you include this file in another h file, simply
11698+// define REV_REFERENCE_ONLY. This will be undefined later, so that
11699+// the single C file inclusion in the module will be used to
11700+// implement the global structures.
11701+//
11702+#ifndef REV_REFERENCE_ONLY
11703+#ifndef _REVISION_H_GLOBAL
11704+#define _REVISION_H_GLOBAL
11705+
11706+
11707+
11708+//
11709+// The following array is the table of compatibility. This table
11710+// can be modified in two ways:
11711+//
11712+// 1) A component which has an incompatible change done to
11713+// it, can get a new build number.
11714+//
11715+// 2) A new component can be added, requiring more entries
11716+// to be place into this table.
11717+//
11718+//
11719+// In case (1), you must change the revision number in the appropriate
11720+// column, based on which component absolutely requires an upgrade.
11721+//
11722+// Example: A new FIB used by the API, in build number 105
11723+// {RevApi, RevAdapterSW, 100, 100}
11724+// ---> would be changed to <---
11725+// {RevApi, RevAdapterSW, 105, 100}
11726+//
11727+// Example: A structure is changed for a FIB that only the API uses
11728+// {RevApi, RevAdapterSW, 100, 100}
11729+// ---> would be changed to <---
11730+// {RevApi, RevAdapterSW, 105, 105}
11731+//
11732+//
11733+// In case (2), the less common case, the enumerated list of
11734+// components must be changed to include the new component. Then
11735+// entries need to be placed into this table.
11736+//
11737+// Since the revisions must be communicated between the two
11738+// components, it is likely that you would need to put in the
11739+// current build number for both columns. That is the recommended
11740+// way to start revision test.
11741+//
11742+const RevCompareElement RevCompareTable[] = {
11743+ // Component A Component B MinBForA MinAForB
11744+ // ----------- ----------- -------- --------
11745+ {RevApplication, RevApi, 2120, 2120 },
11746+ {RevDkiCli, RevApi, 2120, 2120 },
11747+ {RevDkiCli, RevFileSysDriver, 257, 257 },
11748+ {RevDkiCli, RevMiniportDriver, 257, 257 },
11749+ {RevDkiCli, RevAdapterSW, 257, 257 },
11750+ {RevApi, RevFileSysDriver, 2120, 2120 },
11751+ {RevApi, RevMiniportDriver, 2120, 2120 },
11752+ {RevApi, RevAdapterSW, 2120, 2120 },
11753+ {RevApi, RevNetService, 2120, 2120 },
11754+ {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11755+ {RevFileSysDriver, RevAdapterSW, 257, 257 },
11756+ {RevMiniportDriver, RevAdapterSW, 257, 257 },
11757+ {RevMiniportDriver, RevMonitor, 100, 100 },
11758+ {RevApi, RevNetService, 2120, 2120 },
11759+ {RevApi, RevRemoteApi, 2120, 2120 },
11760+ {RevNetService, RevRemoteApi, 2120, 2120 }
11761+};
11762+
11763+const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11764+
11765+#endif /* _REVISION_H_GLOBAL */
11766+#endif /* REV_REFERENCE_ONLY */
11767+#undef REV_REFERENCE_ONLY
11768+
11769+
11770+
11771+
11772+
11773+
11774+
11775diff -urN linux/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11776--- linux/drivers/scsi/aacraid/include/rx.h Wed Dec 31 19:00:00 1969
11777+++ linux/drivers/scsi/aacraid/include/rx.h Thu Dec 21 13:14:30 2000
11778@@ -0,0 +1,81 @@
11779+/*++
11780+ * Adaptec aacraid device driver for Linux.
11781+ *
11782+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11783+ *
11784+ * This program is free software; you can redistribute it and/or modify
11785+ * it under the terms of the GNU General Public License as published by
11786+ * the Free Software Foundation; either version 2, or (at your option)
11787+ * any later version.
11788+ *
11789+ * This program is distributed in the hope that it will be useful,
11790+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11791+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11792+ * GNU General Public License for more details.
11793+ *
11794+ * You should have received a copy of the GNU General Public License
11795+ * along with this program; see the file COPYING. If not, write to
11796+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11797+ *
11798+ * Module Name:
11799+ * rx.h
11800+ *
11801+ * Abstract: Prototypes and data structures unique to the Rx based controller board.
11802+ *
11803+ *
11804+ --*/
11805+
11806+static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11807+
11808+typedef struct _Rx_ADAPTER_EXTENSION {
11809+
11810+ //
11811+ // The following must be first.
11812+ //
11813+ PPCI_MINIPORT_COMMON_EXTENSION Common;
11814+ struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11815+ USHORT LocalMaskInterruptControl;
11816+ PRx_DEVICE_REGISTERS Device;
11817+
11818+} Rx_ADAPTER_EXTENSION;
11819+
11820+
11821+typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11822+
11823+
11824+
11825+#ifdef LINUX
11826+/*
11827+ *
11828+ */
11829+
11830+#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11831+
11832+
11833+
11834+#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11835+#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11836+
11837+
11838+#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11839+
11840+#endif /* LINUX */
11841+
11842+
11843+VOID
11844+RxInterruptAdapter(
11845+ PVOID Arg1
11846+ );
11847+
11848+VOID
11849+RxNotifyAdapter(
11850+ PVOID Arg1,
11851+ IN HOST_2_ADAP_EVENT AdapterEvent
11852+ );
11853+
11854+VOID
11855+RxResetDevice(
11856+ PVOID Arg1
11857+ );
11858+
11859+
11860diff -urN linux/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11861--- linux/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 19:00:00 1969
11862+++ linux/drivers/scsi/aacraid/include/rxcommon.h Thu Dec 21 13:14:30 2000
11863@@ -0,0 +1,105 @@
11864+/*++
11865+ * Adaptec aacraid device driver for Linux.
11866+ *
11867+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11868+ *
11869+ * This program is free software; you can redistribute it and/or modify
11870+ * it under the terms of the GNU General Public License as published by
11871+ * the Free Software Foundation; either version 2, or (at your option)
11872+ * any later version.
11873+ *
11874+ * This program is distributed in the hope that it will be useful,
11875+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11876+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11877+ * GNU General Public License for more details.
11878+ *
11879+ * You should have received a copy of the GNU General Public License
11880+ * along with this program; see the file COPYING. If not, write to
11881+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11882+ *
11883+ * Module Name:
11884+ * rxcommon.h
11885+ *
11886+ * Abstract: Structures and defines for the i960 Rx chip.
11887+ *
11888+ *
11889+ --*/
11890+
11891+#ifndef _Rx_COMMON_H_
11892+#define _Rx_COMMON_H_
11893+
11894+static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11895+
11896+//
11897+// Rx Message Unit Registers
11898+//
11899+
11900+typedef volatile struct _StructRxMURegisters {
11901+ // Local | PCI* | Name
11902+ // | |
11903+ unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11904+ unsigned reserved0; // 1304h | 04h | Reserved
11905+ unsigned AWR; // 1308h | 08h | APIC Window Register
11906+ unsigned reserved1; // 130Ch | 0Ch | Reserved
11907+ unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11908+ unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11909+ unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11910+ unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11911+ unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11912+ unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11913+ unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11914+ unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11915+ // * Must access trhough ATU Inbound Translation Window
11916+
11917+}Rx_MU_CONFIG;
11918+typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11919+
11920+typedef volatile struct _Rx_Inbound {
11921+
11922+ unsigned Mailbox[8];
11923+
11924+}Rx_Inbound;
11925+
11926+typedef Rx_Inbound *PRx_Inbound;
11927+
11928+#define InboundMailbox0 IndexRegs.Mailbox[0]
11929+#define InboundMailbox1 IndexRegs.Mailbox[1]
11930+#define InboundMailbox2 IndexRegs.Mailbox[2]
11931+#define InboundMailbox3 IndexRegs.Mailbox[3]
11932+#define InboundMailbox4 IndexRegs.Mailbox[4]
11933+
11934+
11935+
11936+#define INBOUNDDOORBELL_0 0x00000001
11937+#define INBOUNDDOORBELL_1 0x00000002
11938+#define INBOUNDDOORBELL_2 0x00000004
11939+#define INBOUNDDOORBELL_3 0x00000008
11940+#define INBOUNDDOORBELL_4 0x00000010
11941+#define INBOUNDDOORBELL_5 0x00000020
11942+#define INBOUNDDOORBELL_6 0x00000040
11943+
11944+
11945+#define OUTBOUNDDOORBELL_0 0x00000001
11946+#define OUTBOUNDDOORBELL_1 0x00000002
11947+#define OUTBOUNDDOORBELL_2 0x00000004
11948+#define OUTBOUNDDOORBELL_3 0x00000008
11949+#define OUTBOUNDDOORBELL_4 0x00000010
11950+
11951+
11952+#define InboundDoorbellReg MUnit.IDR
11953+
11954+#define OutboundDoorbellReg MUnit.ODR
11955+
11956+
11957+typedef struct _Rx_DEVICE_REGISTERS {
11958+ Rx_MU_CONFIG MUnit; // 1300h - 1334h
11959+ unsigned reserved1[6]; // 1338h - 134ch
11960+ Rx_Inbound IndexRegs;
11961+} Rx_DEVICE_REGISTERS;
11962+
11963+typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
11964+
11965+
11966+#endif // _Rx_COMMON_H_
11967+
11968+
11969diff -urN linux/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
11970--- linux/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 19:00:00 1969
11971+++ linux/drivers/scsi/aacraid/include/sap1.h Thu Dec 21 13:14:30 2000
11972@@ -0,0 +1,85 @@
11973+/*++
11974+ * Adaptec aacraid device driver for Linux.
11975+ *
11976+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11977+ *
11978+ * This program is free software; you can redistribute it and/or modify
11979+ * it under the terms of the GNU General Public License as published by
11980+ * the Free Software Foundation; either version 2, or (at your option)
11981+ * any later version.
11982+ *
11983+ * This program is distributed in the hope that it will be useful,
11984+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11985+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11986+ * GNU General Public License for more details.
11987+ *
11988+ * You should have received a copy of the GNU General Public License
11989+ * along with this program; see the file COPYING. If not, write to
11990+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11991+ *
11992+ * Module Name:
11993+ * sap1.h
11994+ *
11995+ * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
11996+ *
11997+ *
11998+ --*/
11999+#ifndef _SAP1_H_
12000+#define _SAP1_H_
12001+
12002+static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12003+
12004+#define Sa_MINIPORT_REVISION 1
12005+
12006+typedef struct _Sa_ADAPTER_EXTENSION {
12007+
12008+ //
12009+ // The following must be first.
12010+ //
12011+ PPCI_MINIPORT_COMMON_EXTENSION Common;
12012+ struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12013+ USHORT LocalMaskInterruptControl;
12014+ PSa_DEVICE_REGISTERS Device;
12015+
12016+} Sa_ADAPTER_EXTENSION;
12017+
12018+typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12019+
12020+
12021+
12022+#ifdef LINUX
12023+/*
12024+ *
12025+ */
12026+
12027+
12028+#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12029+#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12030+
12031+
12032+#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12033+#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12034+
12035+#endif /* LINUX */
12036+
12037+
12038+VOID
12039+SaInterruptAdapter(
12040+ PVOID Arg1
12041+ );
12042+
12043+VOID
12044+SaNotifyAdapter(
12045+ PVOID Arg1,
12046+ IN HOST_2_ADAP_EVENT AdapterEvent
12047+ );
12048+
12049+VOID
12050+SaResetDevice(
12051+ PVOID Arg1
12052+ );
12053+
12054+
12055+#endif /* _SAP1_H_ */
12056+
12057+
12058diff -urN linux/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12059--- linux/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 19:00:00 1969
12060+++ linux/drivers/scsi/aacraid/include/sap1common.h Thu Dec 21 13:14:30 2000
12061@@ -0,0 +1,111 @@
12062+/*++
12063+ * Adaptec aacraid device driver for Linux.
12064+ *
12065+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12066+ *
12067+ * This program is free software; you can redistribute it and/or modify
12068+ * it under the terms of the GNU General Public License as published by
12069+ * the Free Software Foundation; either version 2, or (at your option)
12070+ * any later version.
12071+ *
12072+ * This program is distributed in the hope that it will be useful,
12073+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12074+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12075+ * GNU General Public License for more details.
12076+ *
12077+ * You should have received a copy of the GNU General Public License
12078+ * along with this program; see the file COPYING. If not, write to
12079+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12080+ *
12081+ * Module Name:
12082+ * sap1common.h
12083+ *
12084+ * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12085+ *
12086+ --*/
12087+
12088+#ifndef _Sa_COMMON_H_
12089+#define _Sa_COMMON_H_
12090+
12091+static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12092+
12093+//
12094+// SaP1 Message Unit Registers
12095+//
12096+
12097+typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12098+ // Offset | Name
12099+ unsigned reserved[10]; // 00h-27h | Reserved
12100+ unsigned char LUT_Offset; // 28h | Looup Table Offset
12101+ unsigned char reserved1[3]; // 29h-2bh | Reserved
12102+ unsigned LUT_Data; // 2ch | Looup Table Data
12103+ unsigned reserved2[26]; // 30h-97h | Reserved
12104+ unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12105+ unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12106+ unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12107+ unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12108+ unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12109+ unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12110+ unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12111+ unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12112+ unsigned MAILBOX0; // a8h | Scratchpad 0
12113+ unsigned MAILBOX1; // ach | Scratchpad 1
12114+ unsigned MAILBOX2; // b0h | Scratchpad 2
12115+ unsigned MAILBOX3; // b4h | Scratchpad 3
12116+ unsigned MAILBOX4; // b8h | Scratchpad 4
12117+ unsigned MAILBOX5; // bch | Scratchpad 5
12118+ unsigned MAILBOX6; // c0h | Scratchpad 6
12119+ unsigned MAILBOX7; // c4h | Scratchpad 7
12120+
12121+ unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12122+ unsigned ROM_Control_Addr; // cch | Rom Control and Address
12123+
12124+ unsigned reserved3[12]; // d0h-ffh | reserved
12125+ unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12126+
12127+ //
12128+ // TO DO
12129+ // need to add DMA, I2O, UART, etc registers form 80h to 364h
12130+ //
12131+
12132+}Sa_Drawbridge_CSR;
12133+
12134+typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12135+
12136+
12137+#define Mailbox0 SaDbCSR.MAILBOX0
12138+#define Mailbox1 SaDbCSR.MAILBOX1
12139+#define Mailbox2 SaDbCSR.MAILBOX2
12140+#define Mailbox3 SaDbCSR.MAILBOX3
12141+#define Mailbox4 SaDbCSR.MAILBOX4
12142+
12143+
12144+#define Mailbox7 SaDbCSR.MAILBOX7
12145+
12146+#define DoorbellReg_p SaDbCSR.PRISETIRQ
12147+#define DoorbellReg_s SaDbCSR.SECSETIRQ
12148+#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12149+
12150+
12151+#define DOORBELL_0 0x00000001
12152+#define DOORBELL_1 0x00000002
12153+#define DOORBELL_2 0x00000004
12154+#define DOORBELL_3 0x00000008
12155+#define DOORBELL_4 0x00000010
12156+#define DOORBELL_5 0x00000020
12157+#define DOORBELL_6 0x00000040
12158+
12159+
12160+#define PrintfReady DOORBELL_5
12161+#define PrintfDone DOORBELL_5
12162+
12163+typedef struct _Sa_DEVICE_REGISTERS {
12164+ Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12165+} Sa_DEVICE_REGISTERS;
12166+
12167+typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12168+
12169+
12170+#endif // _Sa_COMMON_H_
12171+
12172+
12173diff -urN linux/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12174--- linux/drivers/scsi/aacraid/include/version.h Wed Dec 31 19:00:00 1969
12175+++ linux/drivers/scsi/aacraid/include/version.h Thu Dec 21 13:14:30 2000
12176@@ -0,0 +1,40 @@
12177+/*++
12178+ * Adaptec aacraid device driver for Linux.
12179+ *
12180+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12181+ *
12182+ * This program is free software; you can redistribute it and/or modify
12183+ * it under the terms of the GNU General Public License as published by
12184+ * the Free Software Foundation; either version 2, or (at your option)
12185+ * any later version.
12186+ *
12187+ * This program is distributed in the hope that it will be useful,
12188+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12189+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12190+ * GNU General Public License for more details.
12191+ *
12192+ * You should have received a copy of the GNU General Public License
12193+ * along with this program; see the file COPYING. If not, write to
12194+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12195+ *
12196+ * Module Name:
12197+ * version.h
12198+ *
12199+ * Abstract: Keeps track of build number for development purposes.
12200+ *
12201+ --*/
12202+#ifndef _VERSION_H_
12203+#define _VERSION_H_
12204+
12205+static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12206+
12207+#include "build_number.h"
12208+
12209+#define REV_MAJOR 2
12210+#define REV_MINOR 1
12211+#define REV_TYPE RevType_Release
12212+#define REV_DASH 5
12213+
12214+#define FSA_VERSION_STRING "2.1.5.3857\0"
12215+
12216+#endif /* _VERSION_H_ */
12217diff -urN linux/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12218--- linux/drivers/scsi/aacraid/linit.c Wed Dec 31 19:00:00 1969
12219+++ linux/drivers/scsi/aacraid/linit.c Thu Dec 21 14:21:32 2000
12220@@ -0,0 +1,1060 @@
12221+/*++
12222+ * Adaptec aacraid device driver for Linux.
12223+ *
12224+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12225+ *
12226+ * This program is free software; you can redistribute it and/or modify
12227+ * it under the terms of the GNU General Public License as published by
12228+ * the Free Software Foundation; either version 2, or (at your option)
12229+ * any later version.
12230+ *
12231+ * This program is distributed in the hope that it will be useful,
12232+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12233+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12234+ * GNU General Public License for more details.
12235+ *
12236+ * You should have received a copy of the GNU General Public License
12237+ * along with this program; see the file COPYING. If not, write to
12238+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12239+ *
12240+ * Module Name:
12241+ * linit.c
12242+ *
12243+ * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12244+ *
12245+ * Provides the following driver entry points:
12246+ * AAC_DetectHostAdapter()
12247+ * AAC_ReleaseHostAdapter()
12248+ * AAC_QueueCommand()
12249+ * AAC_ResetCommand()
12250+ * AAC_BIOSDiskParameters()
12251+ *
12252+ --*/
12253+
12254+static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12255+
12256+/*------------------------------------------------------------------------------
12257+ * D E F I N E S
12258+ *----------------------------------------------------------------------------*/
12259+#define AAC_DRIVER_VERSION "0.1.1"
12260+#define AAC_DRIVER_BUILD_DATE __DATE__
12261+#define MAX_DRIVER_QUEUE_DEPTH 500
12262+
12263+/*------------------------------------------------------------------------------
12264+ * I N C L U D E S
12265+ *----------------------------------------------------------------------------*/
12266+#include "osheaders.h"
12267+
12268+#include "AacGenericTypes.h"
12269+
12270+#ifdef MODULE
12271+#include <linux/module.h>
12272+#endif
12273+#include "sd.h"
12274+#include "linit.h"
12275+#include "aac_unix_defs.h"
12276+#include "fsatypes.h"
12277+#include "comstruc.h"
12278+#include "fsaport.h"
12279+#include "pcisup.h"
12280+#include "port.h"
12281+#include "afacomm.h"
12282+#include "nodetype.h"
12283+#include "comsup.h"
12284+#include "adapter.h"
12285+
12286+/*------------------------------------------------------------------------------
12287+ * G L O B A L S
12288+ *----------------------------------------------------------------------------*/
12289+extern FSA_MINIPORT MiniPorts[];
12290+extern int CommPrinting;
12291+extern char DescriptionString[];
12292+extern char devicestr[];
12293+
12294+/*------------------------------------------------------------------------------
12295+ * M O D U L E G L O B A L S
12296+ *----------------------------------------------------------------------------*/
12297+aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12298+
12299+char g_DriverName[] = { "aacraid" };
12300+#define module_options aacraid_options
12301+static char * aacraid_options = NULL;
12302+
12303+PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12304+unsigned g_HostAdapterCount = 0;
12305+unsigned g_chardev_major = 0;
12306+
12307+int g_single_command_done = FALSE;
12308+
12309+/*------------------------------------------------------------------------------
12310+ * F U N C T I O N P R O T O T Y P E S
12311+ *----------------------------------------------------------------------------*/
12312+int AacHba_Ioctl(
12313+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12314+ int cmd,
12315+ void * arg );
12316+
12317+int AacHba_ProbeContainers(
12318+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12319+
12320+int AacHba_DoScsiCmd(
12321+ Scsi_Cmnd *scsi_cmnd_ptr,
12322+ int wait );
12323+
12324+void AacHba_DetachAdapter(
12325+ IN PVOID AdapterArg );
12326+
12327+int AacHba_ClassDriverInit(
12328+ PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12329+
12330+void AacHba_AbortScsiCommand(
12331+ Scsi_Cmnd *scsi_cmnd_ptr );
12332+
12333+
12334+/*------------------------------------------------------------------------------
12335+ * L O C A L F U N C T I O N P R O T O T Y P E S
12336+ *----------------------------------------------------------------------------*/
12337+static int parse_keyword(
12338+ char ** str_ptr,
12339+ char * keyword );
12340+
12341+static void AAC_ParseDriverOptions(
12342+ char * cmnd_line_options_str );
12343+
12344+static void AAC_AnnounceDriver( void );
12345+
12346+int AAC_ChardevIoctl(
12347+ struct inode * inode_ptr,
12348+ struct file * file_ptr,
12349+ unsigned int cmd,
12350+ unsigned long arg );
12351+
12352+int AAC_ChardevOpen(
12353+ struct inode * inode_ptr,
12354+ struct file * file_ptr );
12355+
12356+int AAC_ChardevRelease(
12357+ struct inode * inode_ptr,
12358+ struct file * file_ptr );
12359+
12360+struct file_operations AAC_fops = {
12361+ NULL, // module name
12362+ NULL, // lseek
12363+ NULL, // read
12364+ NULL, // write
12365+ NULL, // readdir
12366+ NULL, // poll
12367+ AAC_ChardevIoctl, // ioctl
12368+ NULL, // mmap
12369+ AAC_ChardevOpen, // open
12370+ NULL, // flush
12371+ AAC_ChardevRelease, // release
12372+ NULL, // fsync
12373+ NULL, // fasync
12374+ NULL, // check media change
12375+ NULL, // revalidate
12376+ NULL // lock
12377+};
12378+
12379+/*------------------------------------------------------------------------------
12380+ * F U N C T I O N S
12381+ *----------------------------------------------------------------------------*/
12382+/*------------------------------------------------------------------------------
12383+ AAC_AnnounceDriver()
12384+
12385+ Announce the driver name, version and date.
12386+ *----------------------------------------------------------------------------*/
12387+static void AAC_AnnounceDriver( void ){
12388+ printk("<1>%s, %s\n",
12389+ "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12390+ schedule();
12391+}
12392+
12393+
12394+/*------------------------------------------------------------------------------
12395+ AAC_DetectHostAdapter()
12396+
12397+ Probe for AAC Host Adapters initialize, register, and report the
12398+ configuration of each AAC Host Adapter found.
12399+
12400+ Preconditions:
12401+ Postconditions:
12402+ - Returns the number of adapters successfully initialized and
12403+ registered.
12404+ - Initialize all data necessary for this particular SCSI driver.
12405+ Notes:
12406+ The detect routine must not call any of the mid level functions
12407+ to queue commands because things are not guaranteed to be set
12408+ up yet. The detect routine can send commands to the host adapter
12409+ as long as the program control will not be passed to scsi.c in
12410+ the processing of the command. Note especially that
12411+ scsi_malloc/scsi_free must not be called.
12412+ *----------------------------------------------------------------------------*/
12413+int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12414+{
12415+ int index;
12416+ int ContainerId;
12417+ uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12418+ struct Scsi_Host *host_ptr;
12419+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12420+ struct pci_dev *dev = NULL;
12421+ extern int NumMiniPorts;
12422+ fsadev_t *fsa_dev_ptr;
12423+ char *DeviceName;
12424+
12425+ struct pci_dev *devp;
12426+
12427+ int first_index, last_index, increment;
12428+
12429+ CommPrinting = TRUE;
12430+
12431+#ifdef MODULE
12432+ EXPORT_NO_SYMBOLS;
12433+#endif
12434+
12435+ AAC_AnnounceDriver();
12436+
12437+ /* setting up the proc directory structure */
12438+ HostTemplate->proc_name = "aacraid";
12439+
12440+ if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12441+
12442+ // NumMiniPorts & MiniPorts[] defined in aacid.c
12443+ if (g_options.reverse_scan == 0) {
12444+ first_index = 0;
12445+ last_index = NumMiniPorts;
12446+ increment = 1;
12447+ } else {
12448+ first_index = NumMiniPorts -1;
12449+ last_index = -1;
12450+ increment = -1;
12451+ }
12452+
12453+ for( index = first_index; index != last_index; index += increment )
12454+ {
12455+ device_id = MiniPorts[index].DeviceId;
12456+ vendor_id = MiniPorts[index].VendorId;
12457+ DeviceName = MiniPorts[index].DeviceName;
12458+ cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12459+ DeviceName, vendor_id, device_id,
12460+ MiniPorts[index].SubVendorId,
12461+ MiniPorts[index].SubSystemId);
12462+
12463+
12464+ // pci_find_device traverses the pci_devices linked list for devices
12465+ // with matching vendor and device ids.
12466+
12467+ dev = NULL; // start from beginning of list
12468+ while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12469+ {
12470+ if (pci_enable_device(dev)) continue;
12471+
12472+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12473+ cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12474+ break;
12475+ }
12476+ if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12477+ cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12478+ break;
12479+ }
12480+
12481+ cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12482+ if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12483+ ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12484+ continue;
12485+ }
12486+
12487+
12488+ printk("<1>%s device detected\n", DeviceName );
12489+ cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12490+
12491+ // Increment the host adapter count
12492+ g_HostAdapterCount++;
12493+
12494+ // scsi_register() allocates memory for a Scsi_Hosts structure and
12495+ // links it into the linked list of host adapters. This linked list
12496+ // contains the data for all possible <supported> scsi hosts.
12497+ // This is similar to the Scsi_Host_Template, except that we have
12498+ // one entry for each actual physical host adapter on the system,
12499+ // stored as a linked list. If there are two AAC boards, then we
12500+ // will need to make two Scsi_Host entries, but there will be only
12501+ // one Scsi_Host_Template entry. The second argument to scsi_register()
12502+ // specifies the size of the extra memory we want to hold any device
12503+ // specific information.
12504+ host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12505+
12506+ // These three parameters can be used to allow for wide SCSI
12507+ // and for host adapters that support multiple buses.
12508+ host_ptr->max_id = 17;
12509+ host_ptr->max_lun = 8;
12510+ host_ptr->max_channel = 1;
12511+
12512+
12513+ host_ptr->irq = dev->irq; // Adapter IRQ number
12514+ /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12515+ host_ptr->base = ( char * )(dev->resource[0].start);
12516+
12517+ cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12518+ cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12519+
12520+ // The unique_id field is a unique identifier that must be assigned
12521+ // so that we have some way of identifying each host adapter properly
12522+ // and uniquely. For hosts that do not support more than one card in the
12523+ // system, this does not need to be set. It is initialized to zero in
12524+ // scsi_register(). This is the value returned from OsGetDeviceInstance().
12525+
12526+ host_ptr->unique_id = g_HostAdapterCount - 1;
12527+ host_ptr->this_id = 16; // SCSI Id for the adapter itself
12528+
12529+ // Set the maximum number of simultaneous commands supported by the driver.
12530+ host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12531+
12532+ // Define the maximum number of scatter/gather elements supported by
12533+ // the driver.
12534+
12535+ host_ptr->sg_tablesize = 16;
12536+ host_ptr->cmd_per_lun = 1; // untagged queue depth
12537+
12538+ // This function is called after the device list has been built to find
12539+ // tagged queueing depth supported for each device.
12540+
12541+ host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12542+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12543+
12544+ // attach a pointer back to Scsi_Host
12545+ CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12546+ CommonExtensionPtr->OsDep.MiniPortIndex = index;
12547+
12548+ // Initialize the ordinal number of the device to -1
12549+ fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12550+ for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12551+ fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12552+
12553+ // Call initialization routine
12554+ cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12555+ if( ( *MiniPorts[index].InitRoutine )
12556+ ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12557+ {
12558+ // device initialization failed
12559+ cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12560+ scsi_unregister( host_ptr );
12561+ g_HostAdapterCount--;
12562+ } /* end if */
12563+ else
12564+ {
12565+ cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12566+ AacHba_ClassDriverInit( CommonExtensionPtr );
12567+ cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12568+ AacHba_ProbeContainers( CommonExtensionPtr );
12569+ g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12570+
12571+ } /* end else */
12572+
12573+ } /* end while */
12574+
12575+ } /* end for */
12576+
12577+ if( g_HostAdapterCount ){
12578+ if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12579+ cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12580+ }
12581+
12582+ HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12583+
12584+ return( g_HostAdapterCount );
12585+}
12586+
12587+
12588+/*------------------------------------------------------------------------------
12589+ AAC_ReleaseHostAdapter()
12590+
12591+ Release all resources previously acquired to support a specific Host
12592+ Adapter and unregister the AAC Host Adapter.
12593+ *----------------------------------------------------------------------------*/
12594+int AAC_ReleaseHostAdapter(
12595+ struct Scsi_Host *host_ptr )
12596+/*----------------------------------------------------------------------------*/
12597+{
12598+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12599+
12600+ cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12601+
12602+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12603+
12604+ // kill any threads we started
12605+ kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12606+
12607+ // Call the comm layer to detach from this adapter
12608+ AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12609+
12610+ // remove interrupt binding
12611+ OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12612+
12613+ SaDetachDevice( CommonExtensionPtr );
12614+
12615+ // unregister adapter
12616+ scsi_unregister( host_ptr );
12617+
12618+ if( g_chardev_major )
12619+ {
12620+ unregister_chrdev( g_chardev_major, devicestr );
12621+ g_chardev_major = 0;
12622+ }
12623+
12624+ return( 0 ); // #REVISIT# return code
12625+}
12626+
12627+
12628+/*------------------------------------------------------------------------------
12629+ AAC_QueueCommand()
12630+
12631+ Queues a command for execution by the associated Host Adapter.
12632+ *----------------------------------------------------------------------------*/
12633+int AAC_QueueCommand(
12634+ Scsi_Cmnd *scsi_cmnd_ptr,
12635+ void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12636+/*----------------------------------------------------------------------------*/
12637+{
12638+ scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12639+
12640+ // AacHba_DoScsiCmd() handles command processing, setting the
12641+ // result code and calling completion routine.
12642+ #ifdef SYNC_FIB
12643+ if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 ) ) // called with wait = TRUE
12644+ #else
12645+ if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 ) ) // called with wait = FALSE
12646+ #endif
12647+ cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12648+ return 0;
12649+}
12650+
12651+
12652+/*------------------------------------------------------------------------------
12653+ AAC_Done()
12654+
12655+ Callback function for a non-queued command.
12656+
12657+ Postconditions
12658+ Sets g_single_command done to TRUE
12659+ *----------------------------------------------------------------------------*/
12660+void AAC_Done(
12661+ Scsi_Cmnd * scsi_cmnd_ptr )
12662+/*----------------------------------------------------------------------------*/
12663+{
12664+ g_single_command_done = TRUE;
12665+}
12666+
12667+
12668+/*------------------------------------------------------------------------------
12669+ AAC_Command()
12670+
12671+ Accepts a single command for execution by the associated Host Adapter.
12672+
12673+ Postconditions
12674+ Returns an int where:
12675+ Byte 0 = SCSI status code
12676+ Byte 1 = SCSI 1 byte message
12677+ Byte 2 = host error return
12678+ Byte 3 = mid level error return
12679+ *----------------------------------------------------------------------------*/
12680+int AAC_Command(
12681+ Scsi_Cmnd *scsi_cmnd_ptr )
12682+/*----------------------------------------------------------------------------*/
12683+{
12684+ scsi_cmnd_ptr->scsi_done = AAC_Done;
12685+
12686+ cmn_err( CE_DEBUG, "AAC_Command" );
12687+
12688+ // AacHba_DoScsiCmd() handles command processing, setting the
12689+ // result code and calling completion routine.
12690+ g_single_command_done = FALSE;
12691+
12692+ AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12693+ while( !g_single_command_done );
12694+ return( scsi_cmnd_ptr->result );
12695+}
12696+
12697+
12698+/*------------------------------------------------------------------------------
12699+ AAC_AbortCommand()
12700+
12701+ Abort command if possible.
12702+ *----------------------------------------------------------------------------*/
12703+int AAC_AbortCommand(
12704+ Scsi_Cmnd *scsi_cmnd_ptr )
12705+/*----------------------------------------------------------------------------*/
12706+{
12707+ int target = scsi_cmnd_ptr->target;
12708+ int hba = scsi_cmnd_ptr->host->unique_id;
12709+ int result = 0;
12710+ u_short interrupt_status;
12711+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12712+ char *DeviceName;
12713+
12714+ cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12715+ AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12716+
12717+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12718+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12719+
12720+ /*
12721+ cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12722+ "command already completed", DeviceName, hba, target);
12723+ result = SCSI_ABORT_NOT_RUNNING;
12724+
12725+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12726+ "no command found\n", DeviceName, hba, target);
12727+ result = SCSI_ABORT_NOT_RUNNING;
12728+
12729+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12730+ "command reset\n", DeviceName, hba, target);
12731+ result = SCSI_ABORT_PENDING;
12732+
12733+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12734+ "abort tag not supported\n", DeviceName, hba, target);
12735+ result = SCSI_ABORT_SNOOZE;
12736+
12737+ cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12738+ DeviceName, hba, target);
12739+ result = SCSI_ABORT_PENDING;
12740+
12741+ cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12742+ DeviceName, hba, target);
12743+ result = SCSI_ABORT_BUSY;
12744+
12745+ cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12746+ DeviceName, hba, target);
12747+ result = SCSI_ABORT_SUCCESS;
12748+ */
12749+
12750+ // Abort not supported yet
12751+ result = SCSI_ABORT_BUSY;
12752+ return result;
12753+}
12754+
12755+
12756+/*------------------------------------------------------------------------------
12757+ AAC_ResetCommand()
12758+
12759+ Reset command handling.
12760+ *----------------------------------------------------------------------------*/
12761+int AAC_ResetCommand(
12762+ struct scsi_cmnd *scsi_cmnd_ptr,
12763+ unsigned int reset_flags )
12764+/*----------------------------------------------------------------------------*/
12765+{
12766+ int target = scsi_cmnd_ptr->target;
12767+ int hba = scsi_cmnd_ptr->host->unique_id;
12768+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12769+ char *DeviceName;
12770+
12771+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12772+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12773+
12774+ cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12775+
12776+ return SCSI_RESET_PUNT;
12777+}
12778+
12779+
12780+/*------------------------------------------------------------------------------
12781+ AAC_DriverInfo()
12782+
12783+ Returns the host adapter name
12784+ *----------------------------------------------------------------------------*/
12785+const char *AAC_DriverInfo(
12786+ struct Scsi_Host *host_ptr )
12787+/*----------------------------------------------------------------------------*/
12788+{
12789+ PCI_MINIPORT_COMMON_EXTENSION *cep;
12790+ char *DeviceName;
12791+
12792+ cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12793+ DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12794+
12795+ cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12796+ return (DeviceName);
12797+}
12798+
12799+
12800+/*------------------------------------------------------------------------------
12801+ AAC_BIOSDiskParameters()
12802+
12803+ Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12804+ The default disk geometry is 64 heads, 32 sectors, and the appropriate
12805+ number of cylinders so as not to exceed drive capacity. In order for
12806+ disks equal to or larger than 1 GB to be addressable by the BIOS
12807+ without exceeding the BIOS limitation of 1024 cylinders, Extended
12808+ Translation should be enabled. With Extended Translation enabled,
12809+ drives between 1 GB inclusive and 2 GB exclusive are given a disk
12810+ geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12811+ are given a disk geometry of 255 heads and 63 sectors. However, if
12812+ the BIOS detects that the Extended Translation setting does not match
12813+ the geometry in the partition table, then the translation inferred
12814+ from the partition table will be used by the BIOS, and a warning may
12815+ be displayed.
12816+ *----------------------------------------------------------------------------*/
12817+int AAC_BIOSDiskParameters(
12818+ Scsi_Disk *scsi_disk_ptr,
12819+ kdev_t device,
12820+ int *parameter_ptr )
12821+/*----------------------------------------------------------------------------*/
12822+{
12823+ AAC_BIOS_DiskParameters_T *disk_parameters =
12824+ ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12825+ struct buffer_head * buffer_head_ptr;
12826+
12827+ cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12828+
12829+ // Assuming extended translation is enabled - #REVISIT#
12830+ if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12831+ {
12832+ if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12833+ {
12834+ disk_parameters->heads = 255;
12835+ disk_parameters->sectors = 63;
12836+ }
12837+ else
12838+ {
12839+ disk_parameters->heads = 128;
12840+ disk_parameters->sectors = 32;
12841+ }
12842+ }
12843+ else
12844+ {
12845+ disk_parameters->heads = 64;
12846+ disk_parameters->sectors = 32;
12847+ }
12848+
12849+ disk_parameters->cylinders = scsi_disk_ptr->capacity
12850+ /( disk_parameters->heads * disk_parameters->sectors );
12851+
12852+ // Read the first 1024 bytes from the disk device
12853+ buffer_head_ptr = bread(
12854+ MKDEV( MAJOR( device ),
12855+ MINOR( device ) & ~0x0F ),
12856+ 0, 1024 );
12857+
12858+ if( buffer_head_ptr == NULL )
12859+ return( 0 );
12860+ /*
12861+ If the boot sector partition table is valid, search for a partition
12862+ table entry whose end_head matches one of the standard geometry
12863+ translations ( 64/32, 128/32, 255/63 ).
12864+ */
12865+ if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12866+ {
12867+ struct partition *first_partition_entry =
12868+ ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12869+ struct partition *partition_entry = first_partition_entry;
12870+ int saved_cylinders = disk_parameters->cylinders;
12871+ int partition_number;
12872+ unsigned char partition_entry_end_head, partition_entry_end_sector;
12873+
12874+ for( partition_number = 0; partition_number < 4; partition_number++ )
12875+ {
12876+ partition_entry_end_head = partition_entry->end_head;
12877+ partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12878+
12879+ if( partition_entry_end_head == ( 64 - 1 ) )
12880+ {
12881+ disk_parameters->heads = 64;
12882+ disk_parameters->sectors = 32;
12883+ break;
12884+ }
12885+ else if( partition_entry_end_head == ( 128 - 1 ) )
12886+ {
12887+ disk_parameters->heads = 128;
12888+ disk_parameters->sectors = 32;
12889+ break;
12890+ }
12891+ else if( partition_entry_end_head == ( 255 - 1 ) )
12892+ {
12893+ disk_parameters->heads = 255;
12894+ disk_parameters->sectors = 63;
12895+ break;
12896+ }
12897+ partition_entry++;
12898+ }
12899+
12900+ if( partition_number == 4 )
12901+ {
12902+ partition_entry_end_head = first_partition_entry->end_head;
12903+ partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12904+ }
12905+
12906+ disk_parameters->cylinders = scsi_disk_ptr->capacity
12907+ /( disk_parameters->heads * disk_parameters->sectors );
12908+
12909+ if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
12910+ {
12911+ if( disk_parameters->cylinders != saved_cylinders )
12912+ cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12913+ disk_parameters->heads, disk_parameters->sectors, partition_number );
12914+ }
12915+ else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
12916+ {
12917+ cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
12918+ partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
12919+ cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
12920+ disk_parameters->heads, disk_parameters->sectors );
12921+ }
12922+ }
12923+
12924+ brelse( buffer_head_ptr );
12925+
12926+ return( 0 );
12927+}
12928+
12929+
12930+/*------------------------------------------------------------------------------
12931+ AAC_SelectQueueDepths()
12932+
12933+ Selects queue depths for each target device based on the host adapter's
12934+ total capacity and the queue depth supported by the target device.
12935+ A queue depth of one automatically disables tagged queueing.
12936+ *----------------------------------------------------------------------------*/
12937+void AAC_SelectQueueDepths(
12938+ struct Scsi_Host * host_ptr,
12939+ Scsi_Device * scsi_device_ptr )
12940+/*----------------------------------------------------------------------------*/
12941+{
12942+ Scsi_Device * device_ptr;
12943+
12944+ cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
12945+ cmn_err( CE_DEBUG, "Device # Q Depth Online" );
12946+ cmn_err( CE_DEBUG, "---------------------------" );
12947+ for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
12948+ if( device_ptr->host == host_ptr )
12949+ {
12950+ device_ptr->queue_depth = 10;
12951+ cmn_err( CE_DEBUG, " %2d %d %d",
12952+ device_ptr->id, device_ptr->queue_depth, device_ptr->online );
12953+ }
12954+}
12955+
12956+
12957+/*------------------------------------------------------------------------------
12958+ AAC_SearchBiosSignature()
12959+
12960+ Locate adapter signature in BIOS
12961+ *----------------------------------------------------------------------------*/
12962+int AAC_SearchBiosSignature( void )
12963+/*----------------------------------------------------------------------------*/
12964+{
12965+ unsigned base;
12966+ unsigned namep;
12967+ int index;
12968+ int val;
12969+ char name_buf[32];
12970+ int result = FALSE;
12971+
12972+ for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
12973+ {
12974+ val = readb( base );
12975+ if( val != 0x55 )
12976+ continue;
12977+
12978+ result = TRUE;
12979+ namep = base + 0x1e;
12980+ memcpy_fromio( name_buf, namep, 32 );
12981+ name_buf[31] = '\0';
12982+ }
12983+ return( result );
12984+}
12985+
12986+
12987+/*------------------------------------------------------------------------------
12988+ AAC_Ioctl()
12989+
12990+ Handle SCSI ioctls
12991+ *----------------------------------------------------------------------------*/
12992+int AAC_Ioctl(
12993+ Scsi_Device * scsi_dev_ptr,
12994+ int cmd,
12995+ void * arg )
12996+/*----------------------------------------------------------------------------*/
12997+{
12998+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12999+
13000+ cmn_err( CE_DEBUG, "AAC_Ioctl" );
13001+ CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13002+ return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13003+}
13004+
13005+
13006+
13007+/*------------------------------------------------------------------------------
13008+ AAC_ChardevOpen()
13009+
13010+ Handle character device open
13011+
13012+ Preconditions:
13013+ Postconditions:
13014+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13015+ *----------------------------------------------------------------------------*/
13016+int AAC_ChardevOpen(
13017+ struct inode * inode_ptr,
13018+ struct file * file_ptr )
13019+/*----------------------------------------------------------------------------*/
13020+{
13021+ unsigned minor_number;
13022+
13023+ cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13024+
13025+ // check device permissions in file_ptr->f_mode ??
13026+
13027+ // extract & check the minor number
13028+ minor_number = MINOR( inode_ptr->i_rdev );
13029+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13030+ {
13031+ cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13032+ return( -ENODEV );
13033+ }
13034+
13035+#ifdef MODULE
13036+ MOD_INC_USE_COUNT;
13037+#endif
13038+
13039+ return( 0 );
13040+}
13041+
13042+
13043+/*------------------------------------------------------------------------------
13044+ AAC_ChardevRelease()
13045+
13046+ Handle character device release.
13047+
13048+ Preconditions:
13049+ Postconditions:
13050+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13051+ *----------------------------------------------------------------------------*/
13052+int AAC_ChardevRelease(
13053+ struct inode * inode_ptr,
13054+ struct file * file_ptr )
13055+/*----------------------------------------------------------------------------*/
13056+{
13057+ cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13058+
13059+#ifdef MODULE
13060+ MOD_DEC_USE_COUNT;
13061+#endif
13062+
13063+ return( 0 );
13064+}
13065+
13066+
13067+/*------------------------------------------------------------------------------
13068+ AAC_ChardevIoctl()
13069+
13070+ Handle character device interface ioctls
13071+
13072+ Preconditions:
13073+ Postconditions:
13074+ Returns 0 if successful, -ENODEV or -EINVAL otherwise
13075+ *----------------------------------------------------------------------------*/
13076+int AAC_ChardevIoctl(
13077+ struct inode * inode_ptr,
13078+ struct file * file_ptr,
13079+ unsigned int cmd,
13080+ unsigned long arg )
13081+{
13082+ unsigned minor_number;
13083+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13084+
13085+ cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13086+
13087+ // check device permissions in file_ptr->f_mode ??
13088+
13089+ // extract & check the minor number
13090+ minor_number = MINOR( inode_ptr->i_rdev );
13091+ if( minor_number > ( g_HostAdapterCount - 1 ) )
13092+ {
13093+ cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13094+ return( -ENODEV );
13095+ }
13096+
13097+ // get device pointer
13098+ CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13099+
13100+ // dispatch ioctl - AacHba_Ioctl() returns zero on success
13101+ if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13102+ return( -EINVAL );
13103+
13104+ return( 0 );
13105+}
13106+
13107+
13108+/*------------------------------------------------------------------------------
13109+ parse_keyword()
13110+
13111+ Look for the keyword in str_ptr
13112+
13113+ Preconditions:
13114+ Postconditions:
13115+ If keyword found
13116+ - return true and update the pointer str_ptr.
13117+ otherwise
13118+ - return false
13119+ *----------------------------------------------------------------------------*/
13120+static int parse_keyword(
13121+ char ** str_ptr,
13122+ char * keyword )
13123+/*----------------------------------------------------------------------------*/
13124+{
13125+ char * ptr = *str_ptr;
13126+
13127+ while( *keyword != '\0' )
13128+ {
13129+ char string_char = *ptr++;
13130+ char keyword_char = *keyword++;
13131+
13132+ if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13133+ string_char += 'a' - 'Z';
13134+ if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13135+ keyword_char += 'a' - 'Z';
13136+ if( string_char != keyword_char )
13137+ return FALSE;
13138+ }
13139+ *str_ptr = ptr;
13140+ return TRUE;
13141+}
13142+
13143+
13144+/*------------------------------------------------------------------------------
13145+ AAC_ParseDriverOptions()
13146+
13147+ For modules the usage is:
13148+ insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13149+ *----------------------------------------------------------------------------*/
13150+static void AAC_ParseDriverOptions(
13151+ char * cmnd_line_options_str )
13152+/*----------------------------------------------------------------------------*/
13153+{
13154+ int message_level;
13155+ int reverse_scan;
13156+ char *cp;
13157+ char *endp;
13158+
13159+ cp = cmnd_line_options_str;
13160+
13161+ cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13162+
13163+ while( *cp ) {
13164+ if( parse_keyword( &cp, "message_level:" ) ) {
13165+ message_level = simple_strtoul( cp, 0, 0 );
13166+ if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13167+ g_options.message_level = message_level;
13168+ cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13169+ }
13170+ else {
13171+ cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13172+ }
13173+ } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13174+ reverse_scan = simple_strtoul( cp, 0, 0 );
13175+ if (reverse_scan) {
13176+ g_options.reverse_scan = 1;
13177+ cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13178+ }
13179+ }
13180+ else {
13181+ cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13182+ }
13183+
13184+ /*
13185+ * skip to next option, accept " ", ";", and "," as delimiters
13186+ */
13187+ while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13188+ cp++;
13189+
13190+ if (*cp) /* skip over the delimiter */
13191+ cp++;
13192+ }
13193+
13194+}
13195+
13196+
13197+/*------------------------------------------------------------------------------
13198+ Include Module support if requested.
13199+
13200+ To use the low level SCSI driver support using the linux kernel loadable
13201+ module interface we should initialize the global variable driver_interface
13202+ (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13203+ This should also be wrapped in a #ifdef MODULE/#endif
13204+ *----------------------------------------------------------------------------*/
13205+#ifdef MODULE
13206+
13207+/*
13208+ The Loadable Kernel Module Installation Facility may pass us
13209+ a pointer to a driver specific options string to be parsed,
13210+ we assign this to options string.
13211+*/
13212+MODULE_PARM( module_options, "s" );
13213+
13214+Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13215+
13216+#include "scsi_module.c"
13217+
13218+#else
13219+Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13220+
13221+#include "scsi_module.c"
13222+#endif
13223+
13224+/*********************************************************************
13225+ AAC_ProcDirectoryInfo()
13226+
13227+ Implement /proc/scsi/<drivername>/<n>.
13228+ Used to export driver statistics and other infos to the world outside
13229+ the kernel using the proc file system. Also provides an interface to
13230+ feed the driver with information.
13231+
13232+ Postconditions
13233+ For reads
13234+ - if offset > 0 return 0
13235+ - if offset == 0 write data to proc_buffer and set the start_ptr to
13236+ beginning of proc_buffer, return the number of characters written.
13237+ For writes
13238+ - writes currently not supported, return 0
13239+************************************************************/
13240+int AAC_ProcDirectoryInfo(
13241+ char *proc_buffer, // read/write buffer
13242+ char **start_ptr, // start of valid data in the buffer
13243+ off_t offset, // offset from the beginning of the imaginary file
13244+ int bytes_available, // bytes available
13245+ int host_no, // SCSI host number
13246+ int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13247+{
13248+ int length = 0;
13249+ cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13250+
13251+ if( ( write ) || ( offset > 0 ) )
13252+ return( 0 );
13253+
13254+ *start_ptr = proc_buffer;
13255+
13256+ return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13257+}
13258+
13259+void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13260+{
13261+ void *BaseAddress;
13262+ ULONG PhysAddress;
13263+ int size;
13264+ int npages;
13265+ int i;
13266+
13267+ AFA_COMM_ADAPTER *Adapter;
13268+ Adapter = CommonExtension->Adapter;
13269+
13270+
13271+ // Allocate 1 fib for synch fibs
13272+ // Allocate 1 page.
13273+ BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13274+ bzero(BaseAddress, PAGE_SIZE);
13275+ PhysAddress = virt_to_phys (BaseAddress);
13276+ Adapter->SyncFib = BaseAddress;
13277+ Adapter->SyncFibPhysicalAddress = PhysAddress;
13278+ cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13279+
13280+}
13281diff -urN linux/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13282--- linux/drivers/scsi/aacraid/osddi.c Wed Dec 31 19:00:00 1969
13283+++ linux/drivers/scsi/aacraid/osddi.c Thu Dec 21 13:14:30 2000
13284@@ -0,0 +1,512 @@
13285+/*++
13286+ * Adaptec aacraid device driver for Linux.
13287+ *
13288+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13289+ *
13290+ * This program is free software; you can redistribute it and/or modify
13291+ * it under the terms of the GNU General Public License as published by
13292+ * the Free Software Foundation; either version 2, or (at your option)
13293+ * any later version.
13294+ *
13295+ * This program is distributed in the hope that it will be useful,
13296+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13297+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13298+ * GNU General Public License for more details.
13299+ *
13300+ * You should have received a copy of the GNU General Public License
13301+ * along with this program; see the file COPYING. If not, write to
13302+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13303+ *
13304+ * Module Name:
13305+ * osddi.c
13306+ *
13307+ * Abstract: This file contains all the proceedures which use LINUX specific Device
13308+ * Driver Interfaces.
13309+ *
13310+ --*/
13311+
13312+static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13313+
13314+#include "osheaders.h"
13315+
13316+#include <linux/smp_lock.h>
13317+
13318+#ifdef fsid_t
13319+#undef fsid_t
13320+#endif
13321+#include "AacGenericTypes.h"
13322+#include "aac_unix_defs.h"
13323+#include "comstruc.h"
13324+#include "monkerapi.h"
13325+#include "protocol.h"
13326+#include "fsafs.h"
13327+
13328+#include "sap1common.h"
13329+#include "fsaport.h"
13330+#include "pcisup.h"
13331+#include "sap1.h"
13332+#include "nodetype.h"
13333+#include "comsup.h"
13334+#include "afacomm.h"
13335+#include "adapter.h"
13336+
13337+
13338+void AacSaPciIsr(
13339+ int irq,
13340+ void * irq_data,
13341+ struct pt_regs *regs);
13342+
13343+void AacRxPciIsr(
13344+ int irq,
13345+ void * irq_data,
13346+ struct pt_regs *regs);
13347+
13348+unsigned SaPciIsr (
13349+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13350+
13351+unsigned RxPciIsr (
13352+ IN PSa_ADAPTER_EXTENSION AdapterExtension );
13353+
13354+
13355+/*----------------------------------------------------------------------------*/
13356+VOID AfaCommInterruptHost(
13357+ PVOID AdapterArg,
13358+ ADAPTER_EVENT AdapterEvent )
13359+/*----------------------------------------------------------------------------*/
13360+{
13361+ PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13362+ PCOMM_REGION CommRegion = Adapter->CommRegion;
13363+
13364+ switch (AdapterEvent) {
13365+
13366+ case HostNormRespQue:
13367+ OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13368+
13369+ // #REVIEW# - what do we do with this
13370+ // if (FsaCommData.HardInterruptModeration)
13371+ // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13372+
13373+ break;
13374+
13375+ case AdapNormCmdNotFull:
13376+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13377+ break;
13378+
13379+ case HostNormCmdQue:
13380+ OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13381+ break;
13382+
13383+ case AdapNormRespNotFull:
13384+ OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13385+ break;
13386+
13387+ // #REVIEW# - what do we do with these
13388+ case HostHighCmdQue:
13389+ case HostHighRespQue:
13390+ case AdapHighCmdNotFull:
13391+ case AdapHighRespNotFull:
13392+ case SynchCommandComplete:
13393+ case AdapInternalError:
13394+ break;
13395+ }
13396+}
13397+
13398+
13399+// get the device name associated with this instance of the device
13400+/*----------------------------------------------------------------------------*/
13401+char *OsGetDeviceName(
13402+ void *AdapterExtension )
13403+/*----------------------------------------------------------------------------*/
13404+{
13405+ return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13406+ OsDep.scsi_host_ptr->hostt->name );
13407+}
13408+
13409+
13410+/*----------------------------------------------------------------------------*/
13411+int OsGetDeviceInstance(
13412+ void *AdapterExtension )
13413+/*----------------------------------------------------------------------------*/
13414+{
13415+ return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13416+ OsDep.scsi_host_ptr->unique_id );
13417+}
13418+
13419+
13420+/*------------------------------------------------------------------------------
13421+ OsMapDeviceRegisters()
13422+
13423+ Postconditions:
13424+ Return zero on success non-zero otherwise.
13425+ *----------------------------------------------------------------------------*/
13426+int OsMapDeviceRegisters(
13427+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13428+/*----------------------------------------------------------------------------*/
13429+{
13430+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13431+
13432+ CommonExtension = AdapterExtension->Common;
13433+
13434+ if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13435+ ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13436+ {
13437+ cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13438+ return( 0 );
13439+ }
13440+ else
13441+ {
13442+ cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13443+ return( 1 );
13444+ }
13445+}
13446+
13447+
13448+/*------------------------------------------------------------------------------
13449+ OsUnMapDeviceRegisters()
13450+
13451+ Postconditions:
13452+ *----------------------------------------------------------------------------*/
13453+void OsUnMapDeviceRegisters(
13454+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13455+/*----------------------------------------------------------------------------*/
13456+{
13457+ iounmap( ( void * )AdapterExtension->Device );
13458+}
13459+
13460+
13461+/*----------------------------------------------------------------------------*/
13462+int OsAttachInterrupt(
13463+ Sa_ADAPTER_EXTENSION *AdapterExtension ,
13464+ int WhichIsr )
13465+/*----------------------------------------------------------------------------*/
13466+{
13467+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13468+ void *irq_data;
13469+ void (*Isr)();
13470+
13471+ CommonExtension = AdapterExtension->Common;
13472+ irq_data = ( void * )AdapterExtension;
13473+
13474+ switch (WhichIsr) {
13475+ case SaISR:
13476+ Isr = AacSaPciIsr;
13477+ break;
13478+ case RxISR:
13479+ Isr = AacRxPciIsr;
13480+ break;
13481+ default:
13482+ cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13483+ return( FAILURE );
13484+ break;
13485+ }
13486+
13487+
13488+ if ( OsRegisterInterrupt (
13489+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13490+ Isr, // handler function
13491+ irq_data )
13492+ )
13493+ {
13494+ cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13495+ CommonExtension->OsDep.scsi_host_ptr->irq );
13496+ return( FAILURE );
13497+ }
13498+
13499+ return ( 0 );
13500+}
13501+
13502+
13503+/*----------------------------------------------------------------------------*/
13504+void AacSaPciIsr(
13505+ int irq,
13506+ void * irq_data,
13507+ struct pt_regs *regs)
13508+/*----------------------------------------------------------------------------*/
13509+{
13510+ // call the actual interrupt handler
13511+ SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13512+}
13513+
13514+/*----------------------------------------------------------------------------*/
13515+void AacRxPciIsr(
13516+ int irq,
13517+ void * irq_data,
13518+ struct pt_regs *regs)
13519+/*----------------------------------------------------------------------------*/
13520+{
13521+ // call the actual interrupt handler
13522+ RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13523+}
13524+
13525+
13526+/*----------------------------------------------------------------------------*/
13527+void OsDetachInterrupt(
13528+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13529+/*----------------------------------------------------------------------------*/
13530+{
13531+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13532+ void *irq_data;
13533+
13534+ CommonExtension = AdapterExtension->Common;
13535+ irq_data = ( void * )AdapterExtension;
13536+
13537+ OsUnregisterInterrupt (
13538+ CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13539+ irq_data );
13540+}
13541+
13542+
13543+/*----------------------------------------------------------------------------*/
13544+int OsAttachDMA(
13545+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13546+/*----------------------------------------------------------------------------*/
13547+{
13548+ return( 0 );
13549+}
13550+
13551+/*----------------------------------------------------------------------------*/
13552+int OsAttachHBA(
13553+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13554+/*----------------------------------------------------------------------------*/
13555+{
13556+ return( 0 );
13557+}
13558+
13559+/*----------------------------------------------------------------------------*/
13560+void OsDetachDevice(
13561+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13562+/*----------------------------------------------------------------------------*/
13563+{
13564+ OsUnMapDeviceRegisters( AdapterExtension );
13565+ return( 0 );
13566+}
13567+
13568+/*----------------------------------------------------------------------------*/
13569+ULONG *OsAllocCommPhysMem(
13570+ Sa_ADAPTER_EXTENSION *AdapterExtension,
13571+ ULONG size,
13572+ ULONG **virt_addr_pptr,
13573+ ULONG *phys_addr_ptr )
13574+/*----------------------------------------------------------------------------*/
13575+{
13576+ if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13577+ {
13578+ *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13579+ if( !*phys_addr_ptr )
13580+ {
13581+ cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13582+ }
13583+
13584+ return( *virt_addr_pptr );
13585+ }
13586+ else
13587+ return( NULL );
13588+}
13589+
13590+OsAifKernelThread(
13591+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13592+{
13593+
13594+ struct fs_struct *fs;
13595+ int i;
13596+ struct task_struct *tsk;
13597+
13598+ tsk = current;
13599+
13600+
13601+ /*
13602+ * set up the name that will appear in 'ps'
13603+ * stored in task_struct.comm[16].
13604+ */
13605+
13606+ sprintf(tsk->comm, "AIFd");
13607+
13608+
13609+ // use_init_fs_context(); only exists in 2.2.13 onward.
13610+
13611+#ifdef __SMP__
13612+ lock_kernel();
13613+#endif
13614+
13615+ /*
13616+ * we were started as a result of loading the module.
13617+ * free all of user space pages
13618+ */
13619+
13620+ exit_mm(tsk);
13621+
13622+ exit_files(tsk);
13623+
13624+ exit_fs(tsk);
13625+
13626+ fs = init_task.fs;
13627+ tsk->fs = fs;
13628+
13629+ tsk->session = 1;
13630+ tsk->pgrp = 1;
13631+
13632+ if (fs)
13633+ atomic_inc(&fs->count);
13634+
13635+#ifdef __SMP__
13636+ unlock_kernel();
13637+#endif
13638+
13639+
13640+
13641+
13642+ NormCommandThread(AdapterExtension);
13643+ /* NOT REACHED */
13644+}
13645+
13646+/*----------------------------------------------------------------------------*/
13647+void OsStartKernelThreads(
13648+ Sa_ADAPTER_EXTENSION *AdapterExtension )
13649+/*----------------------------------------------------------------------------*/
13650+{
13651+ PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13652+ AFA_COMM_ADAPTER *Adapter;
13653+ extern void NormCommandThread(void *Adapter);
13654+
13655+ CommonExtension = AdapterExtension->Common;
13656+ Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13657+
13658+ //
13659+ // Start thread which will handle interrupts for this adapter
13660+ //
13661+ //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13662+
13663+ //
13664+ // Start thread which will handle AdapterInititatedFibs from this adapter
13665+ //
13666+ CommonExtension->OsDep.thread_pid =
13667+ kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13668+// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13669+}
13670+
13671+/*----------------------------------------------------------------------------*/
13672+BOOLEAN AfaPortAllocateAndMapFibSpace(
13673+ PVOID Arg1,
13674+ IN PMAPFIB_CONTEXT MapFibContext )
13675+/*----------------------------------------------------------------------------*/
13676+{
13677+ PVOID BaseAddress;
13678+ ULONG PhysAddress;
13679+
13680+ if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13681+ {
13682+ cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13683+ return( FALSE );
13684+ }
13685+
13686+ PhysAddress = OsVirtToPhys( BaseAddress );
13687+
13688+ MapFibContext->FibVirtualAddress = BaseAddress;
13689+ MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13690+
13691+ return (TRUE);
13692+}
13693+
13694+/*----------------------------------------------------------------------------*/
13695+BOOLEAN AfaPortUnmapAndFreeFibSpace(
13696+ PVOID Arg1,
13697+ IN PMAPFIB_CONTEXT MapFibContext )
13698+/*----------------------------------------------------------------------------*/
13699+{
13700+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13701+
13702+ OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13703+
13704+ return (TRUE);
13705+}
13706+
13707+/*----------------------------------------------------------------------------*/
13708+BOOLEAN AfaPortFreeAdapterCommArea(
13709+ IN PVOID Arg1 )
13710+/*----------------------------------------------------------------------------*/
13711+{
13712+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13713+
13714+ OsFreeMemory( CommonExtension->CommAddress, 0 );
13715+
13716+ return (TRUE);
13717+}
13718+
13719+
13720+/* ================================================================================ */
13721+/*
13722+ * Not sure if the functions below here ever get called in the current code
13723+ * These probably should be a different file.
13724+ */
13725+/*
13726+ddi_dma_attr_t AfaPortDmaAttributes = {
13727+ //rpbfix : we may want something different for I/O
13728+ DMA_ATTR_V0,
13729+ 0,
13730+ 0xffffffff,
13731+ 0x0000ffff,
13732+ 1,
13733+ 1,
13734+ 1,
13735+ 0x0000ffff,
13736+ 0x0000ffff,
13737+ 17,
13738+ 512,
13739+ 0
13740+};
13741+*/
13742+
13743+AAC_STATUS
13744+AfaPortBuildSgMap(
13745+ PVOID Arg1,
13746+ IN PSGMAP_CONTEXT SgMapContext
13747+ )
13748+
13749+/*++
13750+
13751+Routine Description:
13752+
13753+ This routine build a scatter gather map using the information
13754+ in the SgMapContext.
13755+
13756+Arguments:
13757+
13758+ AdapterExtension - Pointer to adapter extension structure.
13759+ SgMapContext - Pointer to the SgMapContext for the request.
13760+
13761+
13762+Return Value:
13763+
13764+ AAC_STATUS
13765+--*/
13766+{
13767+ printk( "<1>AfaPortBuildSgMap: unimplemented function called" );
13768+ return (STATUS_UNSUCCESSFUL);
13769+}
13770+
13771+VOID
13772+AfaPortFreeDmaResources(
13773+ PVOID Arg1,
13774+ IN PSGMAP_CONTEXT SgMapContext
13775+ )
13776+
13777+/*++
13778+
13779+Routine Description:
13780+
13781+ Given a pointer to the IRP context will free all reserved DMA resources allocated for
13782+ the completed IO operation.
13783+
13784+Arguments:
13785+
13786+ Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13787+ Context - Pointer to the Irp Context we use to store the dma mapping information
13788+ we need to do and complete the IO.
13789+
13790+Return Value:
13791+
13792+ Nothing
13793+
13794+--*/
13795+{
13796+}
13797diff -urN linux/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13798--- linux/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 19:00:00 1969
13799+++ linux/drivers/scsi/aacraid/osfuncs.c Thu Dec 21 13:14:30 2000
13800@@ -0,0 +1,596 @@
13801+/*++
13802+ * Adaptec aacraid device driver for Linux.
13803+ *
13804+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13805+ *
13806+ * This program is free software; you can redistribute it and/or modify
13807+ * it under the terms of the GNU General Public License as published by
13808+ * the Free Software Foundation; either version 2, or (at your option)
13809+ * any later version.
13810+ *
13811+ * This program is distributed in the hope that it will be useful,
13812+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13813+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13814+ * GNU General Public License for more details.
13815+ *
13816+ * You should have received a copy of the GNU General Public License
13817+ * along with this program; see the file COPYING. If not, write to
13818+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13819+ *
13820+ * Module Name:
13821+ * osfuncs.c
13822+ *
13823+ * Abstract: Holds all of the O/S specific interface functions.
13824+ *
13825+ --*/
13826+
13827+static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13828+
13829+#include "osheaders.h"
13830+
13831+//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13832+
13833+extern aac_options_t g_options;
13834+
13835+OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13836+wait_queue_t * g_wait_queue_ptr = NULL;
13837+wait_queue_t g_wait;
13838+
13839+void OsTimeoutHandler(
13840+ struct semaphore * sem );
13841+
13842+int * OsIdleTask( void * data );
13843+
13844+//-----------------------------------------------------------------------------
13845+// Memory Allocation functions
13846+
13847+/*----------------------------------------------------------------------------*/
13848+void * OsAllocMemory(
13849+ OS_SIZE_T Size,
13850+ unsigned int Flags )
13851+/*----------------------------------------------------------------------------*/
13852+{
13853+ void *mem_ptr;
13854+
13855+ if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13856+ cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13857+ return( mem_ptr );
13858+}
13859+
13860+
13861+/*----------------------------------------------------------------------------*/
13862+void OsFreeMemory(
13863+ void * Buffer,
13864+ OS_SIZE_T Size )
13865+/*----------------------------------------------------------------------------*/
13866+{
13867+ kfree( Buffer );
13868+}
13869+
13870+
13871+/*----------------------------------------------------------------------------*/
13872+int OsRegisterInterrupt(
13873+ unsigned int irq, // interrupt number
13874+ void ( *handler )( int, void*, struct pt_regs * ), // handler function
13875+ void *irq_data ) // argument to handler function
13876+/*----------------------------------------------------------------------------*/
13877+{
13878+ return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13879+}
13880+
13881+
13882+/*----------------------------------------------------------------------------*/
13883+void OsUnregisterInterrupt(
13884+ unsigned int irq, // interrupt number
13885+ void *irq_data)
13886+/*----------------------------------------------------------------------------*/
13887+{
13888+ free_irq (
13889+ irq, // interrupt number
13890+ irq_data );
13891+}
13892+
13893+
13894+/*----------------------------------------------------------------------------*/
13895+unsigned long OsVirtToPhys(
13896+ void * virtual_address )
13897+/*----------------------------------------------------------------------------*/
13898+{
13899+ return( virt_to_phys( virtual_address ) );
13900+}
13901+
13902+
13903+//-----------------------------------------------------------------------------
13904+// MUTEX functions
13905+
13906+/*----------------------------------------------------------------------------*/
13907+OS_STATUS OsMutexInit(
13908+ OS_MUTEX *Mutex,
13909+ OS_SPINLOCK_COOKIE Cookie )
13910+/*----------------------------------------------------------------------------*/
13911+{
13912+ Mutex->lock_var = 0;
13913+ // bzero (&Mutex->wq, sizeof (Mutex->wq));
13914+ init_waitqueue_head (&Mutex->wq);
13915+ return ( 0 );
13916+}
13917+
13918+
13919+/*----------------------------------------------------------------------------*/
13920+void OsMutexDestroy(
13921+ OS_MUTEX *Mutex )
13922+/*----------------------------------------------------------------------------*/
13923+{
13924+}
13925+
13926+
13927+/*----------------------------------------------------------------------------*/
13928+void OsMutexAcquire(
13929+ OS_MUTEX *Mutex )
13930+/*----------------------------------------------------------------------------*/
13931+{
13932+ // wait_queue_t wait = { current, NULL };
13933+ unsigned long time_stamp;
13934+
13935+ DECLARE_WAITQUEUE (wait, current);
13936+
13937+ time_stamp = jiffies;
13938+
13939+ if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13940+ {
13941+ if( in_interrupt() )
13942+ panic( "OsMutexAcquire going to sleep at interrupt time\n" );
13943+ current->state = TASK_INTERRUPTIBLE;
13944+ add_wait_queue( &( Mutex->wq ), &wait );
13945+ while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13946+ schedule();
13947+ remove_wait_queue( &( Mutex->wq ), &wait );
13948+ }
13949+
13950+ if( ( jiffies - 1 ) > time_stamp )
13951+ cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
13952+ Mutex, jiffies - time_stamp );
13953+}
13954+
13955+
13956+/*----------------------------------------------------------------------------*/
13957+void OsMutexRelease(
13958+ OS_MUTEX *Mutex )
13959+/*----------------------------------------------------------------------------*/
13960+{
13961+ if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
13962+ cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
13963+ wake_up_interruptible( &( Mutex->wq ) );
13964+}
13965+
13966+// see man hierarchy(D5)
13967+#define FSA_LOCK 1
13968+
13969+//-----------------------------------------------------------------------------
13970+// Spinlock functions
13971+
13972+/*----------------------------------------------------------------------------*/
13973+OS_SPINLOCK * OsSpinLockAlloc( void )
13974+/*----------------------------------------------------------------------------*/
13975+{
13976+ OS_SPINLOCK *SpinLock;
13977+ int i;
13978+
13979+
13980+ SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
13981+
13982+ if (SpinLock == NULL)
13983+ cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
13984+
13985+ SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
13986+ for( i = 0; i < NR_CPUS; i++ )
13987+ SpinLock->cpu_lock_count[ i ] = 0;
13988+ return( SpinLock );
13989+}
13990+
13991+
13992+/*----------------------------------------------------------------------------*/
13993+OS_STATUS OsSpinLockInit(
13994+ OS_SPINLOCK *SpinLock,
13995+ OS_SPINLOCK_COOKIE Cookie )
13996+/*----------------------------------------------------------------------------*/
13997+{
13998+ return( 0 );
13999+}
14000+
14001+
14002+/*----------------------------------------------------------------------------*/
14003+void OsSpinLockDestroy(
14004+ OS_SPINLOCK *SpinLock )
14005+/*----------------------------------------------------------------------------*/
14006+{
14007+ kfree( SpinLock );
14008+ SpinLock = NULL;
14009+}
14010+
14011+
14012+/*----------------------------------------------------------------------------*/
14013+void OsSpinLockAcquire(
14014+ OS_SPINLOCK *SpinLock )
14015+/*----------------------------------------------------------------------------*/
14016+{
14017+ unsigned cpu_id, i;
14018+
14019+
14020+ if( SpinLock )
14021+ {
14022+ cpu_id = smp_processor_id();
14023+ if( SpinLock->cpu_lock_count[ cpu_id ] ){
14024+ cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14025+ cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14026+ }
14027+
14028+ spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14029+ SpinLock->cpu_lock_count[ cpu_id ]++;
14030+
14031+ } else {
14032+ cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14033+ }
14034+}
14035+
14036+
14037+/*----------------------------------------------------------------------------*/
14038+void OsSpinLockRelease(
14039+ OS_SPINLOCK *SpinLock )
14040+/*----------------------------------------------------------------------------*/
14041+{
14042+ if( SpinLock )
14043+ {
14044+ SpinLock->cpu_lock_count[ smp_processor_id() ]--;
14045+ spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14046+ }
14047+ else
14048+ cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14049+}
14050+
14051+
14052+/*----------------------------------------------------------------------------*/
14053+int OsSpinLockOwned(
14054+ OS_SPINLOCK *SpinLock )
14055+/*----------------------------------------------------------------------------*/
14056+{
14057+#ifdef __SMP__
14058+ if( SpinLock->spin_lock.lock != 0 )
14059+ return( 1 );
14060+ else
14061+#endif
14062+ return( 0 );
14063+}
14064+
14065+
14066+//-----------------------------------------------------------------------------
14067+// CvLock functions
14068+
14069+/*----------------------------------------------------------------------------*/
14070+OS_CVLOCK *OsCvLockAlloc( void )
14071+{
14072+ OS_CVLOCK *cv_lock;
14073+
14074+
14075+#ifdef CVLOCK_USE_SPINLOCK
14076+ cv_lock = OsSpinLockAlloc();
14077+#else
14078+ cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14079+ cv_lock->wq = NULL;
14080+ cv_lock->lock_var = 0;
14081+#endif
14082+
14083+ return( cv_lock );
14084+}
14085+
14086+
14087+/*----------------------------------------------------------------------------*/
14088+OS_STATUS OsCvLockInit(
14089+ OS_CVLOCK *cv_lock,
14090+ OS_SPINLOCK_COOKIE Cookie )
14091+/*----------------------------------------------------------------------------*/
14092+{
14093+ return ( 0 );
14094+}
14095+
14096+
14097+/*----------------------------------------------------------------------------*/
14098+void OsCvLockDestroy(
14099+ OS_CVLOCK *cv_lock )
14100+/*----------------------------------------------------------------------------*/
14101+{
14102+ if( cv_lock )
14103+ kfree( cv_lock );
14104+ cv_lock = NULL;
14105+}
14106+
14107+
14108+/*----------------------------------------------------------------------------*/
14109+void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14110+{
14111+#ifdef CVLOCK_USE_SPINLOCK
14112+ OsSpinLockAcquire( cv_lock );
14113+#else
14114+ OsMutexAcquire( cv_lock );
14115+#endif
14116+}
14117+
14118+
14119+/*----------------------------------------------------------------------------*/
14120+void OsCvLockRelease(
14121+ OS_CVLOCK *cv_lock )
14122+/*----------------------------------------------------------------------------*/
14123+{
14124+#ifdef CVLOCK_USE_SPINLOCK
14125+ OsSpinLockRelease( cv_lock );
14126+#else
14127+ OsMutexRelease( cv_lock );
14128+#endif
14129+}
14130+
14131+
14132+/*----------------------------------------------------------------------------*/
14133+int OsCvLockOwned(
14134+ OS_CVLOCK *cv_lock )
14135+/*----------------------------------------------------------------------------*/
14136+{
14137+ return( 1 );
14138+}
14139+
14140+
14141+//-----------------------------------------------------------------------------
14142+// Conditional variable functions
14143+
14144+/*----------------------------------------------------------------------------*/
14145+void OsCv_init (
14146+ OS_CV_T *cv_ptr )
14147+/*----------------------------------------------------------------------------*/
14148+{
14149+ cv_ptr->lock_var = 1;
14150+ init_waitqueue_head (&cv_ptr->wq);
14151+}
14152+
14153+
14154+/*----------------------------------------------------------------------------*/
14155+void OsCv_destroy(
14156+ OS_CV_T *cv_ptr )
14157+/*----------------------------------------------------------------------------*/
14158+{
14159+}
14160+
14161+
14162+/*______________________________________________________________________________
14163+ -
14164+ -
14165+ -----------------------------------------------------------------------------*/
14166+OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14167+{
14168+ unsigned long flags;
14169+
14170+ DECLARE_WAITQUEUE (wait, current);
14171+
14172+ if( in_interrupt() )
14173+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14174+
14175+ cv_ptr->type = TASK_UNINTERRUPTIBLE;
14176+ current->state = TASK_UNINTERRUPTIBLE;
14177+
14178+ add_wait_queue( &cv_ptr->wq, &wait );
14179+
14180+ OsCvLockRelease( cv_lock_ptr );
14181+ schedule();
14182+
14183+ while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14184+ {
14185+ if( in_interrupt() )
14186+ panic( "OsCv_wait going to sleep at interrupt time\n" );
14187+ schedule();
14188+ }
14189+
14190+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14191+
14192+ OsCvLockAcquire( cv_lock_ptr );
14193+}
14194+
14195+
14196+/*----------------------------------------------------------------------------*/
14197+int OsCv_wait_sig(
14198+ OS_CV_T *cv_ptr,
14199+ OS_CVLOCK *cv_lock_ptr )
14200+/*----------------------------------------------------------------------------*/
14201+{
14202+ unsigned long flags;
14203+ int signal_state = 1;
14204+
14205+ DECLARE_WAITQUEUE (wait, current);
14206+
14207+ if( in_interrupt() )
14208+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14209+
14210+ cv_ptr->type = TASK_INTERRUPTIBLE;
14211+ current->state = TASK_INTERRUPTIBLE;
14212+
14213+ add_wait_queue( &( cv_ptr->wq ), &wait );
14214+
14215+ OsCvLockRelease( cv_lock_ptr );
14216+ schedule();
14217+
14218+ while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14219+ ( !signal_pending( current ) ) )
14220+ {
14221+ if( in_interrupt() )
14222+ panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14223+ schedule();
14224+ }
14225+
14226+ if( signal_pending( current ) )
14227+ signal_state = 0;
14228+
14229+ remove_wait_queue( &( cv_ptr->wq ), &wait );
14230+
14231+ OsCvLockAcquire( cv_lock_ptr );
14232+ return( signal_state );
14233+}
14234+
14235+
14236+/*----------------------------------------------------------------------------*/
14237+void OsCv_signal(
14238+ OS_CV_T *cv_ptr )
14239+/*----------------------------------------------------------------------------*/
14240+{
14241+
14242+ clear_bit( 0, &( cv_ptr->lock_var ) );
14243+ if( cv_ptr->type == TASK_INTERRUPTIBLE )
14244+ wake_up_interruptible( &( cv_ptr->wq ) );
14245+ else{
14246+ wake_up( &( cv_ptr->wq ) );
14247+ }
14248+}
14249+
14250+
14251+// return time in seconds
14252+/*----------------------------------------------------------------------------*/
14253+unsigned long OsGetSeconds( void )
14254+/*----------------------------------------------------------------------------*/
14255+{
14256+ return( jiffies/HZ );
14257+}
14258+
14259+
14260+//-----------------------------------------------------------------------------
14261+// Deferred procedure call functions
14262+
14263+// create a soft interrupt object
14264+/*----------------------------------------------------------------------------*/
14265+int OsSoftInterruptAdd(
14266+ OS_SOFTINTR **ptr,
14267+ void * handler,
14268+ void * data )
14269+/*----------------------------------------------------------------------------*/
14270+{
14271+ OS_SOFTINTR *tmp_ptr;
14272+
14273+ if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14274+ return( -1 );
14275+ tmp_ptr->routine = handler;
14276+ tmp_ptr->data = data;
14277+ tmp_ptr->sync = 0;
14278+
14279+ *ptr = tmp_ptr;
14280+
14281+ return( 0 );
14282+}
14283+
14284+/*
14285+ Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14286+*/
14287+/*----------------------------------------------------------------------------*/
14288+int * OsIdleTask( void * data )
14289+/*----------------------------------------------------------------------------*/
14290+{
14291+ DECLARE_WAITQUEUE (wait, current);
14292+
14293+ while( 1 )
14294+ {
14295+ current->state = TASK_INTERRUPTIBLE;
14296+ add_wait_queue( &g_wait_queue_ptr, &wait );
14297+ schedule();
14298+ remove_wait_queue( &g_wait_queue_ptr, &wait );
14299+ wait.task = current;
14300+ wait.task_list.next = NULL;
14301+ }
14302+ return( NULL );
14303+}
14304+
14305+
14306+// dispatch a soft interrupt
14307+/*----------------------------------------------------------------------------*/
14308+void OsSoftInterruptTrigger(
14309+ OS_SOFTINTR *soft_intr_ptr )
14310+/*----------------------------------------------------------------------------*/
14311+{
14312+ // call the completion routine directly
14313+ soft_intr_ptr->routine( soft_intr_ptr->data );
14314+}
14315+
14316+
14317+// delete a soft interrupt object
14318+/*----------------------------------------------------------------------------*/
14319+void OsSoftInterruptRemove(
14320+ OS_SOFTINTR *arg )
14321+/*----------------------------------------------------------------------------*/
14322+{
14323+ if( arg )
14324+ kfree( arg );
14325+ arg = NULL;
14326+}
14327+
14328+
14329+/*----------------------------------------------------------------------------*/
14330+void OsSleep(
14331+ unsigned time ) // in seconds
14332+/*----------------------------------------------------------------------------*/
14333+{
14334+ struct semaphore sem;
14335+ struct timer_list timer_var;
14336+
14337+ init_MUTEX_LOCKED (&sem);
14338+
14339+ // if( in_interrupt() )
14340+ // panic( "OsSleep going to sleep at interrupt time\n" );
14341+
14342+ init_timer( &timer_var );
14343+ timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14344+ timer_var.data = ( unsigned long )&sem;
14345+ timer_var.expires = jiffies + time * HZ;
14346+
14347+ add_timer( &timer_var );
14348+ down( &sem );
14349+
14350+ del_timer( &timer_var );
14351+}
14352+
14353+
14354+/*----------------------------------------------------------------------------*/
14355+void OsTimeoutHandler(
14356+ struct semaphore * sem )
14357+/*----------------------------------------------------------------------------*/
14358+{
14359+ if( sem != NULL )
14360+ up( sem );
14361+}
14362+
14363+
14364+/*----------------------------------------------------------------------------*/
14365+void printk_err(
14366+ int flag,
14367+ char *fmt,
14368+ ...)
14369+/*----------------------------------------------------------------------------*/
14370+{
14371+ char buf[256];
14372+ va_list ap;
14373+
14374+ va_start(ap, fmt);
14375+ (void) vsprintf(buf, fmt, ap);
14376+ va_end(ap);
14377+
14378+ if( flag <= g_options.message_level )
14379+ printk("<1>%s\n", buf);
14380+}
14381+
14382+/* void aac_show_tasks (struct list_head *our_tasks){ */
14383+
14384+/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14385+
14386+/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14387+/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14388+/* else */
14389+/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14390+
14391+/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14392+/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14393+/* else */
14394+/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14395+
14396+/* } */
14397diff -urN linux/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14398--- linux/drivers/scsi/aacraid/ossup.c Wed Dec 31 19:00:00 1969
14399+++ linux/drivers/scsi/aacraid/ossup.c Thu Dec 21 13:14:30 2000
14400@@ -0,0 +1,199 @@
14401+/*++
14402+ * Adaptec aacraid device driver for Linux.
14403+ *
14404+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14405+ *
14406+ * This program is free software; you can redistribute it and/or modify
14407+ * it under the terms of the GNU General Public License as published by
14408+ * the Free Software Foundation; either version 2, or (at your option)
14409+ * any later version.
14410+ *
14411+ * This program is distributed in the hope that it will be useful,
14412+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14413+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14414+ * GNU General Public License for more details.
14415+ *
14416+ * You should have received a copy of the GNU General Public License
14417+ * along with this program; see the file COPYING. If not, write to
14418+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14419+ *
14420+ * Module Name:
14421+ * ossup.c
14422+ *
14423+ *
14424+ *
14425+ --*/
14426+
14427+static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14428+
14429+#include "osheaders.h"
14430+
14431+#include "aac_unix_defs.h"
14432+
14433+
14434+AAC_STATUS
14435+ExInitializeZone(
14436+ IN PZONE_HEADER Zone,
14437+ IN ULONG BlockSize,
14438+ IN PVOID InitialSegment,
14439+ IN ULONG InitialSegmentSize
14440+ )
14441+
14442+/*++
14443+
14444+Routine Description:
14445+
14446+ This function initializes a zone header. Once successfully
14447+ initialized, blocks can be allocated and freed from the zone, and
14448+ the zone can be extended.
14449+
14450+Arguments:
14451+
14452+ Zone - Supplies the address of a zone header to be initialized.
14453+
14454+ BlockSize - Supplies the block size of the allocatable unit within
14455+ the zone. The size must be larger that the size of the
14456+ initial segment, and must be 64-bit aligned.
14457+
14458+ InitialSegment - Supplies the address of a segment of storage. The
14459+ first ZONE_SEGMENT_HEADER-sized portion of the segment
14460+ is used by the zone allocator. The remainder of
14461+ the segment is carved up into fixed size
14462+ (BlockSize) blocks and is made available for
14463+ allocation and deallocation from the zone. The
14464+ address of the segment must be aligned on a 64-bit
14465+ boundary.
14466+
14467+ InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14468+
14469+Return Value:
14470+
14471+ STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14472+ 64-bit boundaries, or BlockSize was larger than
14473+ the initial segment size.
14474+
14475+ STATUS_SUCCESS - The zone was successfully initialized.
14476+
14477+--*/
14478+
14479+{
14480+ ULONG i;
14481+ PCHAR p;
14482+
14483+
14484+ Zone->BlockSize = BlockSize;
14485+
14486+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14487+ ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14488+ ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14489+
14490+ Zone->FreeList.Next = NULL;
14491+
14492+ p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14493+
14494+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14495+ i <= InitialSegmentSize - BlockSize;
14496+ i += BlockSize
14497+ ) {
14498+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14499+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14500+ p += BlockSize;
14501+ }
14502+ Zone->TotalSegmentSize = i;
14503+
14504+#if 0
14505+ DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14506+ Zone, InitialSegment, InitialSegmentSize,
14507+ BlockSize, p
14508+ );
14509+#endif
14510+
14511+ return STATUS_SUCCESS;
14512+}
14513+
14514+AAC_STATUS
14515+ExExtendZone(
14516+ IN PZONE_HEADER Zone,
14517+ IN PVOID Segment,
14518+ IN ULONG SegmentSize
14519+ )
14520+
14521+/*++
14522+
14523+Routine Description:
14524+
14525+ This function extends a zone by adding another segment's worth of
14526+ blocks to the zone.
14527+
14528+Arguments:
14529+
14530+ Zone - Supplies the address of a zone header to be extended.
14531+
14532+ Segment - Supplies the address of a segment of storage. The first
14533+ ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14534+ zone allocator. The remainder of the segment is carved up
14535+ into fixed-size (BlockSize) blocks and is added to the
14536+ zone. The address of the segment must be aligned on a 64-
14537+ bit boundary.
14538+
14539+ SegmentSize - Supplies the size in bytes of Segment.
14540+
14541+Return Value:
14542+
14543+ STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14544+ 64-bit boundaries, or BlockSize was larger than
14545+ the segment size.
14546+
14547+ STATUS_SUCCESS - The zone was successfully extended.
14548+
14549+--*/
14550+
14551+{
14552+ ULONG i;
14553+ PCHAR p;
14554+
14555+
14556+ ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14557+ Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14558+
14559+ p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14560+
14561+ for (i = sizeof(ZONE_SEGMENT_HEADER);
14562+ i <= SegmentSize - Zone->BlockSize;
14563+ i += Zone->BlockSize
14564+ ) {
14565+
14566+ ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14567+ Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14568+ p += Zone->BlockSize;
14569+ }
14570+ Zone->TotalSegmentSize += i;
14571+
14572+#if 0
14573+ DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14574+ Zone, Segment, SegmentSize, Zone->BlockSize, p
14575+ );
14576+#endif
14577+
14578+ return STATUS_SUCCESS;
14579+}
14580+
14581+DbgPrint()
14582+{
14583+}
14584+
14585+/* Function: InqStrCopy()
14586+ *
14587+ * Arguments: [2] pointer to char
14588+ *
14589+ * Purpose: Copy a String from one location to another
14590+ * without copying \0
14591+ */
14592+void
14593+InqStrCopy(char *a, char *b)
14594+{
14595+
14596+ while(*a != (char)0)
14597+ *b++ = *a++;
14598+}
14599+
14600diff -urN linux/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14601--- linux/drivers/scsi/aacraid/port.c Wed Dec 31 19:00:00 1969
14602+++ linux/drivers/scsi/aacraid/port.c Thu Dec 21 13:14:30 2000
14603@@ -0,0 +1,287 @@
14604+/*++
14605+ * Adaptec aacraid device driver for Linux.
14606+ *
14607+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14608+ *
14609+ * This program is free software; you can redistribute it and/or modify
14610+ * it under the terms of the GNU General Public License as published by
14611+ * the Free Software Foundation; either version 2, or (at your option)
14612+ * any later version.
14613+ *
14614+ * This program is distributed in the hope that it will be useful,
14615+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14617+ * GNU General Public License for more details.
14618+ *
14619+ * You should have received a copy of the GNU General Public License
14620+ * along with this program; see the file COPYING. If not, write to
14621+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14622+ *
14623+ * Module Name:
14624+ * port.c
14625+ *
14626+ * Abstract: All support routines for FSA communication which are miniport specific.
14627+ *
14628+ --*/
14629+
14630+static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14631+
14632+#include "osheaders.h"
14633+
14634+
14635+#include "AacGenericTypes.h"
14636+
14637+#include "aac_unix_defs.h"
14638+
14639+#include "fsatypes.h"
14640+#include "comstruc.h"
14641+#include "protocol.h"
14642+
14643+#include "fsaport.h"
14644+#include "fsaioctl.h"
14645+
14646+#include "pcisup.h"
14647+#include "port.h"
14648+
14649+int AfaPortPrinting = 1;
14650+
14651+extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14652+extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14653+extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14654+extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14655+
14656+
14657+
14658+VOID
14659+AfaPortLogError(
14660+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14661+ IN AAC_STATUS ErrorCode,
14662+ IN PUCHAR StringBuffer,
14663+ IN ULONG StringLength
14664+ )
14665+/*++
14666+
14667+Routine Description:
14668+
14669+ Does all of the work to log an error log entry
14670+Arguments:
14671+
14672+ CommonExtension - Pointer to the adapter that caused the error.
14673+
14674+ ErrorCode - Which error is being logged.
14675+
14676+ StringBuffer - Pointer to optional String for error log entry.
14677+
14678+ StringLength - Length of StringBuffer.
14679+
14680+Return Value:
14681+
14682+ Nothing
14683+
14684+--*/
14685+
14686+{
14687+
14688+}
14689+
14690+BOOLEAN
14691+AfaPortGetNextAdapterNumber(
14692+ IN PDRIVER_OBJECT DriverObject,
14693+ OUT PDEVICE_OBJECT *FsaDeviceObject,
14694+ OUT PFILE_OBJECT *FileObject,
14695+ OUT PULONG AdapterNumber
14696+ )
14697+{
14698+}
14699+BOOLEAN
14700+AfaPortAllocateAdapterCommArea(
14701+ IN PVOID Arg1,
14702+ IN OUT PVOID *CommHeaderAddress,
14703+ IN ULONG CommAreaSize,
14704+ IN ULONG CommAreaAlignment
14705+ )
14706+{
14707+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14708+ PVOID BaseAddress;
14709+ PHYSICAL_ADDRESS PhysicalBaseAddress;
14710+ ULONG TotalSize, BytesToAlign;
14711+ size_t RealLength;
14712+ uint_t Count;
14713+// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14714+// ULONG AdapterFibsSize = PAGE_SIZE;
14715+ ULONG AdapterFibsSize = 4096;
14716+ ULONG PrintfBufferSize = 256;
14717+ PADAPTER_INIT_STRUCT InitStruct;
14718+ extern int MiniPortRevision;
14719+ ULONG PhysAddress;
14720+
14721+// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14722+// SizeOfFastIoComm + PrintfBufferSize;
14723+ TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14724+ PrintfBufferSize;
14725+
14726+
14727+ OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14728+
14729+ CommonExtension->CommAddress = BaseAddress;
14730+ CommonExtension->CommPhysAddr = PhysAddress;
14731+ CommonExtension->CommSize = TotalSize;
14732+
14733+ PhysicalBaseAddress.HighPart = 0;
14734+ PhysicalBaseAddress.LowPart = PhysAddress;
14735+
14736+ CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14737+ CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14738+
14739+ InitStruct = CommonExtension->InitStruct;
14740+
14741+ InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14742+ InitStruct->MiniPortRevision = MiniPortRevision;
14743+ InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14744+
14745+ //
14746+ // Adapter Fibs are the first thing allocated so that they start page aligned
14747+ //
14748+ InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14749+ InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14750+ InitStruct->AdapterFibsSize = AdapterFibsSize;
14751+ InitStruct->AdapterFibAlign = sizeof(FIB);
14752+
14753+ //
14754+ // Increment the base address by the amount already used
14755+ //
14756+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14757+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14758+
14759+ //
14760+ // Align the beginning of Headers to CommAreaAlignment
14761+ //
14762+ BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14763+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14764+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14765+
14766+ //
14767+ // Fill in addresses of the Comm Area Headers and Queues
14768+ //
14769+ *CommHeaderAddress = BaseAddress;
14770+ InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14771+
14772+ //
14773+ // Increment the base address by the size of the CommArea
14774+ //
14775+ BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14776+ PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14777+
14778+
14779+ //
14780+ // Place the Printf buffer area after the Fast I/O comm area.
14781+ //
14782+ CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14783+ InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14784+ InitStruct->PrintfBufferSize = PrintfBufferSize;
14785+ bzero (BaseAddress, PrintfBufferSize);
14786+
14787+ AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14788+ TotalSize, InitStruct->AdapterFibsVirtualAddress,
14789+ (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14790+
14791+ AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14792+
14793+ return (TRUE);
14794+}
14795+
14796+AAC_STATUS
14797+AfaPortCreate (
14798+ IN PDEVICE_OBJECT DeviceObject,
14799+ IN PIRP Irp
14800+ )
14801+/*++
14802+
14803+Routine Description:
14804+
14805+ The routine will get called each time a user issues a CreateFile on the DeviceObject
14806+ for the adapter.
14807+
14808+ The main purpose of this routine is to set up any data structures that may be needed
14809+ to handle any requests made on this DeviceObject.
14810+
14811+Arguments:
14812+
14813+ DeviceObject - Pointer to device object representing adapter
14814+
14815+ Irp - Pointer to Irp that caused this open
14816+
14817+
14818+Return Value:
14819+
14820+ Status value returned from File system driver AdapterOpen
14821+
14822+--*/
14823+
14824+{
14825+}
14826+
14827+AAC_STATUS
14828+AfaPortClose (
14829+ IN PDEVICE_OBJECT DeviceObject,
14830+ IN PIRP Irp
14831+ )
14832+/*++
14833+
14834+Routine Description:
14835+
14836+ This routine will get called each time a user issues a CloseHandle on the DeviceObject
14837+ for the adapter.
14838+
14839+ The main purpose of this routine is to cleanup any data structures that have been set up
14840+ while this FileObject has been opened.
14841+
14842+Arguments:
14843+
14844+ DeviceObject - Pointer to device object representing adapter
14845+
14846+ Irp - Pointer to Irp that caused this close
14847+
14848+Return Value:
14849+
14850+ Status value returned from File system driver AdapterClose
14851+
14852+--*/
14853+
14854+{
14855+
14856+}
14857+
14858+AAC_STATUS
14859+AfaPortDeviceControl (
14860+ IN PDEVICE_OBJECT DeviceObject,
14861+ IN PIRP Irp
14862+ )
14863+{
14864+
14865+}
14866+
14867+ULONG
14868+AfaPortGetMaxPhysicalPage(
14869+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14870+ )
14871+/*++
14872+
14873+Routine Description:
14874+
14875+ This routine determines the max physical page in host memory.
14876+
14877+Arguments:
14878+
14879+ AdapterExtension
14880+
14881+Return Value:
14882+
14883+ Max physical page in host memory.
14884+
14885+--*/
14886+{
14887+
14888+}
14889+
14890+
14891diff -urN linux/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14892--- linux/drivers/scsi/aacraid/rx.c Wed Dec 31 19:00:00 1969
14893+++ linux/drivers/scsi/aacraid/rx.c Thu Dec 21 13:14:30 2000
14894@@ -0,0 +1,917 @@
14895+/*++
14896+ * Adaptec aacraid device driver for Linux.
14897+ *
14898+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14899+ *
14900+ * This program is free software; you can redistribute it and/or modify
14901+ * it under the terms of the GNU General Public License as published by
14902+ * the Free Software Foundation; either version 2, or (at your option)
14903+ * any later version.
14904+ *
14905+ * This program is distributed in the hope that it will be useful,
14906+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14907+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14908+ * GNU General Public License for more details.
14909+ *
14910+ * You should have received a copy of the GNU General Public License
14911+ * along with this program; see the file COPYING. If not, write to
14912+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14913+ *
14914+ * Module Name:
14915+ * rx.c
14916+ *
14917+ * Abstract: Hardware miniport for Drawbridge specific hardware functions.
14918+ *
14919+ --*/
14920+
14921+static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
14922+
14923+#include "osheaders.h"
14924+
14925+
14926+#include "AacGenericTypes.h"
14927+
14928+#include "aac_unix_defs.h"
14929+
14930+#include "fsatypes.h"
14931+#include "comstruc.h"
14932+#include "fsact.h"
14933+#include "protocol.h"
14934+
14935+#define DEFINE_PCI_IDS
14936+#include "rxcommon.h"
14937+#include "monkerapi.h"
14938+
14939+#include "fsaport.h"
14940+#include "fsaioctl.h"
14941+
14942+#include "pcisup.h"
14943+#include "rx.h"
14944+
14945+#include "port.h"
14946+
14947+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
14948+
14949+// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
14950+
14951+#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
14952+
14953+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
14954+
14955+
14956+//
14957+// The list of all the Rx adapter structures
14958+//
14959+
14960+PRx_ADAPTER_EXTENSION RxAdapterList;
14961+
14962+int
14963+RxInitDevice(
14964+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14965+ IN ULONG AdapterNumber,
14966+ IN ULONG PciBus,
14967+ IN ULONG PciSlot
14968+);
14969+
14970+BOOLEAN
14971+RxSendSynchFib(
14972+ PVOID Arg1,
14973+ ULONG FibPhysicalAddress
14974+ );
14975+
14976+FSA_USER_VAR RxUserVars[] = {
14977+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
14978+};
14979+
14980+
14981+//
14982+// Declare private use routines for this modual
14983+//
14984+
14985+u_int
14986+RxPciIsr (
14987+ IN PRx_ADAPTER_EXTENSION AdapterExtension
14988+ )
14989+
14990+/*++
14991+
14992+Routine Description:
14993+
14994+ The Isr routine for fsa Rx based adapter boards.
14995+
14996+Arguments:
14997+
14998+
14999+Return Value:
15000+
15001+ TRUE - if the interrupt was handled by this isr
15002+ FALSE - if the interrupt was not handled by this isr
15003+
15004+--*/
15005+
15006+{
15007+ ULONG DoorbellBits;
15008+ UCHAR InterruptStatus, Mask;
15009+ u_int OurInterrupt = INTR_UNCLAIMED;
15010+
15011+ //cmn_err(CE_WARN, "RxPciIsr entered\n");
15012+
15013+ InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15014+
15015+ //
15016+ // Read mask and invert because drawbridge is reversed.
15017+ //
15018+ // This allows us to only service interrupts that have been enabled.
15019+ //
15020+
15021+ Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15022+
15023+ // Check to see if this is our interrupt. If it isn't just return FALSE.
15024+
15025+
15026+ if (InterruptStatus & Mask) {
15027+
15028+ DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15029+
15030+ OurInterrupt = INTR_CLAIMED;
15031+
15032+ if (DoorbellBits & DoorBellPrintfReady) {
15033+
15034+ ULONG Length, Level;
15035+ unsigned char *cp;
15036+
15037+ cp = AdapterExtension->Common->PrintfBufferAddress;
15038+
15039+ //
15040+ // The size of the Printfbuffer is set in port.c
15041+ // There is no variable or define for it
15042+ //
15043+ if (Length > 255)
15044+ Length = 255;
15045+
15046+ if (cp[Length] != 0) {
15047+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15048+ cp[Length] = 0;
15049+ }
15050+
15051+ if (Level == LOG_HIGH_ERROR)
15052+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15053+ else
15054+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15055+
15056+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15057+
15058+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15059+
15060+ Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15061+
15062+
15063+ } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15064+
15065+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15066+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15067+
15068+ } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15069+
15070+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15071+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15072+
15073+ } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15074+
15075+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15076+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15077+
15078+ } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15079+
15080+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15081+ Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15082+
15083+ }
15084+
15085+ }
15086+ return(OurInterrupt);
15087+}
15088+
15089+VOID
15090+RxEnableInterrupt(
15091+ PVOID Arg1,
15092+ ADAPTER_EVENT AdapterEvent,
15093+ BOOLEAN AtDeviceIrq
15094+ )
15095+/*++
15096+
15097+Routine Description:
15098+
15099+ This routine will enable the corresponding adapter event to cause an interrupt on
15100+ the host.
15101+
15102+Arguments:
15103+
15104+ AdapterExtension - Which adapter to enable.
15105+
15106+ AdapterEvent - Which adapter event.
15107+
15108+ AtDeviceIrq - Whether the system is in DEVICE irql
15109+
15110+Return Value:
15111+
15112+ Nothing.
15113+
15114+--*/
15115+{
15116+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15117+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15118+
15119+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15120+ switch (AdapterEvent) {
15121+
15122+ case HostNormCmdQue:
15123+
15124+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15125+
15126+ break;
15127+
15128+ case HostNormRespQue:
15129+
15130+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15131+
15132+ break;
15133+
15134+ case AdapNormCmdNotFull:
15135+
15136+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15137+
15138+ break;
15139+
15140+ case AdapNormRespNotFull:
15141+
15142+ AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15143+
15144+ break;
15145+
15146+ }
15147+
15148+}
15149+
15150+VOID
15151+RxDisableInterrupt(
15152+ PVOID Arg1,
15153+ ADAPTER_EVENT AdapterEvent,
15154+ BOOLEAN AtDeviceIrq
15155+ )
15156+/*++
15157+
15158+Routine Description:
15159+
15160+ This routine will disable the corresponding adapter event to cause an interrupt on
15161+ the host.
15162+
15163+Arguments:
15164+
15165+ AdapterExtension - Which adapter to enable.
15166+
15167+ AdapterEvent - Which adapter event.
15168+
15169+ AtDeviceIrq - Whether the system is in DEVICE irql
15170+
15171+Return Value:
15172+
15173+ Nothing.
15174+
15175+--*/
15176+{
15177+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15178+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15179+
15180+ //cmn_err(CE_WARN, "RxEnableInterrupt");
15181+
15182+ switch (AdapterEvent) {
15183+
15184+
15185+ case HostNormCmdQue:
15186+
15187+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15188+
15189+ break;
15190+
15191+ case HostNormRespQue:
15192+
15193+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15194+
15195+ break;
15196+
15197+ case AdapNormCmdNotFull:
15198+
15199+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15200+
15201+ break;
15202+
15203+
15204+ case AdapNormRespNotFull:
15205+
15206+ AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15207+
15208+ break;
15209+
15210+ }
15211+
15212+}
15213+
15214+
15215+
15216+RxDetachDevice(
15217+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15218+ )
15219+{
15220+ PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15221+
15222+ //
15223+ // Free the register mapping.
15224+ //
15225+
15226+ OsDetachDevice( AdapterExtension);
15227+
15228+ OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15229+
15230+}
15231+
15232+int
15233+RxInitDevice(
15234+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15235+ IN ULONG AdapterNumber,
15236+ IN ULONG PciBus,
15237+ IN ULONG PciSlot
15238+)
15239+
15240+/*++
15241+
15242+Routine Description:
15243+
15244+ Scans the PCI bus looking for the Rx card. When found all resources for the
15245+ device will be allocated and the interrupt vectors and csrs will be allocated and
15246+ mapped.
15247+
15248+ The device_interface in the commregion will be allocated and linked to the comm region.
15249+
15250+Arguments:
15251+
15252+
15253+Return Value:
15254+
15255+ TRUE - if the device was setup with not problems
15256+ FALSE - if the device could not be mapped and init successfully
15257+
15258+--*/
15259+
15260+{
15261+ AAC_STATUS Status;
15262+ PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15263+ FSA_NEW_ADAPTER NewAdapter;
15264+ ULONG StartTime, EndTime, WaitTime;
15265+ ULONG InitStatus;
15266+ int instance;
15267+ int nIntrs;
15268+ char * name;
15269+
15270+ AfaPortPrint("In init device.\n");
15271+
15272+ //cmn_err(CE_WARN, "In RxInitDevice");
15273+
15274+// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15275+ CommonExtension->AdapterNumber = AdapterNumber;
15276+
15277+
15278+ CommonExtension->PciBusNumber = PciBus;
15279+ CommonExtension->PciSlotNumber = PciSlot;
15280+
15281+
15282+ AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15283+ AdapterExtension->Common = CommonExtension;
15284+ CommonExtension->MiniPort = AdapterExtension;
15285+
15286+ instance = OsGetDeviceInstance(AdapterExtension);
15287+ name = OsGetDeviceName(AdapterExtension);
15288+ //
15289+ // Map in the registers from the adapter, register space 0 is config space,
15290+ // register space 1 is the memery space.
15291+ //
15292+
15293+ if (OsMapDeviceRegisters(AdapterExtension)) {
15294+
15295+ cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15296+ OsGetDeviceName(AdapterExtension), instance);
15297+ return(FAILURE);
15298+ }
15299+
15300+ //
15301+ // Check to see if the board failed any self tests.
15302+ //
15303+
15304+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15305+
15306+ cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15307+ OsGetDeviceName(AdapterExtension), instance);
15308+ return(FAILURE);
15309+
15310+ }
15311+ //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15312+ // OsGetDeviceName(AdapterExtension), instance);
15313+
15314+ //
15315+ // Check to see if the board panic'd while booting.
15316+ //
15317+
15318+ if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15319+
15320+ cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15321+ OsGetDeviceName(AdapterExtension), instance);
15322+ return(FAILURE);
15323+
15324+ }
15325+
15326+ StartTime = OsGetSeconds();
15327+ WaitTime = 0;
15328+
15329+
15330+ //
15331+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
15332+ //
15333+
15334+ while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15335+
15336+ EndTime = OsGetSeconds();
15337+
15338+ WaitTime = EndTime - StartTime;
15339+
15340+ if ( WaitTime > (3 * 10) ) {
15341+
15342+ InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15343+
15344+ cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15345+ OsGetDeviceName(AdapterExtension), instance, InitStatus);
15346+ return(FAILURE);
15347+
15348+ }
15349+ }
15350+
15351+ if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15352+ cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15353+ return(FAILURE);
15354+ }
15355+
15356+
15357+ if (OsAttachDMA(AdapterExtension)) {
15358+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15359+ return(FAILURE);
15360+ }
15361+
15362+ //
15363+ // Fill in the function dispatch table.
15364+ //
15365+
15366+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15367+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15368+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15369+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15370+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15371+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15372+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15373+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15374+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15375+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15376+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15377+ AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15378+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15379+
15380+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15381+
15382+ NewAdapter.AdapterExtension = CommonExtension;
15383+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15384+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15385+ NewAdapter.AdapterUserVars = RxUserVars;
15386+ NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15387+
15388+ NewAdapter.Dip = CommonExtension->OsDep.dip;
15389+
15390+
15391+ if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15392+
15393+ cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15394+ return (FAILURE);
15395+ }
15396+
15397+
15398+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15399+
15400+ if (AdapterExtension->Common->Adapter == NULL) {
15401+
15402+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15403+ cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15404+
15405+
15406+ return (FAILURE);
15407+ }
15408+
15409+
15410+ //
15411+ // Start any kernel threads needed
15412+ //
15413+ OsStartKernelThreads(AdapterExtension);
15414+
15415+ //
15416+ // Tell the adapter that all is configure, and it can start accepting requests
15417+ //
15418+
15419+ RxStartAdapter(AdapterExtension);
15420+
15421+
15422+#ifdef AACDISK
15423+#endif
15424+
15425+
15426+ //
15427+ // Put this adapter into the list of Rx adapters
15428+ //
15429+
15430+ AdapterExtension->Next = RxAdapterList;
15431+ RxAdapterList = AdapterExtension;
15432+
15433+ AdapterExtension->Common->AdapterConfigured = TRUE;
15434+
15435+
15436+#ifdef AACDISK
15437+ //
15438+ // Call the disk layer to initialize itself.
15439+ //
15440+
15441+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15442+#endif
15443+
15444+
15445+init_done:
15446+
15447+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15448+
15449+
15450+
15451+ OsAttachHBA(AdapterExtension);
15452+
15453+ return(0);
15454+}
15455+
15456+VOID
15457+RxStartAdapter(
15458+ PRx_ADAPTER_EXTENSION AdapterExtension
15459+ )
15460+{
15461+ ULONG ReturnStatus;
15462+ LARGE_INTEGER HostTime;
15463+ ULONG ElapsedSeconds;
15464+ PADAPTER_INIT_STRUCT InitStruct;
15465+
15466+ //cmn_err(CE_WARN, "RxStartAdapter");
15467+ //
15468+ // Fill in the remaining pieces of the InitStruct.
15469+ //
15470+
15471+ InitStruct = AdapterExtension->Common->InitStruct;
15472+
15473+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15474+
15475+ ElapsedSeconds = OsGetSeconds();
15476+
15477+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
15478+
15479+ //
15480+ // Tell the adapter we are back and up and running so it will scan its command
15481+ // queues and enable our interrupts
15482+ //
15483+
15484+ AdapterExtension->LocalMaskInterruptControl =
15485+ (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15486+
15487+ //
15488+ // First clear out all interrupts. Then enable the one's that we can handle.
15489+ //
15490+
15491+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15492+ Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15493+// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15494+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15495+
15496+ RxSendSynchCommand(AdapterExtension,
15497+ INIT_STRUCT_BASE_ADDRESS,
15498+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15499+ 0,
15500+ 0,
15501+ 0,
15502+ &ReturnStatus);
15503+
15504+}
15505+
15506+
15507+VOID
15508+RxResetDevice(
15509+ PVOID Arg1
15510+ )
15511+
15512+{
15513+}
15514+
15515+VOID
15516+RxInterruptAdapter(
15517+ PVOID Arg1
15518+ )
15519+/*++
15520+
15521+Routine Description:
15522+
15523+ The will cause the adapter to take a break point.
15524+
15525+Arguments:
15526+
15527+ None
15528+
15529+Return Value:
15530+
15531+ Nothing
15532+
15533+--*/
15534+{
15535+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15536+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15537+
15538+ ULONG ReturnStatus;
15539+
15540+ RxSendSynchCommand(AdapterExtension,
15541+ BREAKPOINT_REQUEST,
15542+ 0,
15543+ 0,
15544+ 0,
15545+ 0,
15546+ &ReturnStatus);
15547+
15548+}
15549+
15550+VOID
15551+RxNotifyAdapter(
15552+ PVOID Arg1,
15553+ IN HOST_2_ADAP_EVENT AdapterEvent
15554+ )
15555+/*++
15556+
15557+Routine Description:
15558+
15559+ Will read the adapter CSRs to find the reason the adapter has
15560+ interrupted us.
15561+
15562+Arguments:
15563+
15564+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15565+
15566+Return Value:
15567+
15568+ Nothing
15569+
15570+--*/
15571+{
15572+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15573+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15574+ ULONG ReturnStatus;
15575+
15576+ //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15577+
15578+ switch (AdapterEvent) {
15579+ case AdapNormCmdQue:
15580+
15581+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15582+ break;
15583+
15584+ case HostNormRespNotFull:
15585+
15586+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15587+ break;
15588+
15589+ case AdapNormRespQue:
15590+
15591+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15592+ break;
15593+
15594+ case HostNormCmdNotFull:
15595+
15596+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15597+ break;
15598+
15599+ case HostShutdown:
15600+
15601+// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15602+
15603+ break;
15604+
15605+ case FastIo:
15606+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15607+ break;
15608+
15609+ case AdapPrintfDone:
15610+ Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15611+ break;
15612+
15613+ default:
15614+
15615+ RxBugCheck(0,0,0);
15616+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15617+ break;
15618+ }
15619+}
15620+
15621+AAC_STATUS
15622+RxSendSynchCommand(
15623+ PVOID Arg1,
15624+ ULONG Command,
15625+ ULONG Parameter1,
15626+ ULONG Parameter2,
15627+ ULONG Parameter3,
15628+ ULONG Parameter4,
15629+ PULONG ReturnStatus
15630+ )
15631+/*++
15632+
15633+Routine Description:
15634+
15635+ This routine will send a synchronous comamnd to the adapter and wait for its
15636+ completion.
15637+
15638+Arguments:
15639+
15640+ AdapterExtension - Pointer to adapter extension structure.
15641+ Command - Which command to send
15642+ Parameter1 - 4 - Parameters for command
15643+ ReturnStatus - return status from adapter after completion of command
15644+
15645+
15646+Return Value:
15647+
15648+ AAC_STATUS
15649+
15650+--*/
15651+{
15652+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15653+ ULONG StartTime,EndTime,WaitTime;
15654+ BOOLEAN CommandSucceeded;
15655+
15656+ //cmn_err(CE_WARN, "RxSendSyncCommand");
15657+ //
15658+ // Write the Command into Mailbox 0
15659+ //
15660+
15661+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15662+
15663+ //
15664+ // Write the parameters into Mailboxes 1 - 4
15665+ //
15666+
15667+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15668+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15669+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15670+ Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15671+
15672+ //
15673+ // Clear the synch command doorbell to start on a clean slate.
15674+ //
15675+
15676+ Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15677+
15678+ //
15679+ // disable doorbell interrupts
15680+ //
15681+
15682+ Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15683+ Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15684+
15685+ //
15686+ // force the completion of the mask register write before issuing the interrupt.
15687+ //
15688+
15689+ Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15690+
15691+ //
15692+ // Signal that there is a new synch command
15693+ //
15694+
15695+ Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15696+
15697+ CommandSucceeded = FALSE;
15698+
15699+ StartTime = OsGetSeconds();
15700+ WaitTime = 0;
15701+
15702+ while (WaitTime < 30) { // wait up to 30 seconds
15703+
15704+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15705+
15706+ //
15707+ // Mon110 will set doorbell0 bit when it has completed the command.
15708+ //
15709+
15710+ if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15711+
15712+ //
15713+ // clear the doorbell.
15714+ //
15715+
15716+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15717+
15718+ CommandSucceeded = TRUE;
15719+ break;
15720+ }
15721+
15722+ EndTime = OsGetSeconds();
15723+ WaitTime = EndTime - StartTime;
15724+
15725+ }
15726+
15727+ if (CommandSucceeded != TRUE) {
15728+
15729+ //
15730+ // restore interrupt mask even though we timed out
15731+ //
15732+
15733+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15734+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15735+
15736+ return (STATUS_IO_TIMEOUT);
15737+
15738+ }
15739+
15740+ //
15741+ // Pull the synch status from Mailbox 0.
15742+ //
15743+
15744+ *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15745+
15746+ //
15747+ // Clear the synch command doorbell.
15748+ //
15749+
15750+ Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15751+
15752+ //
15753+ // restore interrupt mask
15754+ //
15755+
15756+ Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15757+ Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15758+
15759+ //
15760+ // Return SUCCESS
15761+ //
15762+
15763+ return (STATUS_SUCCESS);
15764+
15765+}
15766+
15767+BOOLEAN
15768+RxSendSynchFib(
15769+ PVOID Arg1,
15770+ ULONG FibPhysicalAddress
15771+ )
15772+/*++
15773+
15774+Routine Description:
15775+
15776+ This routine will send a synchronous fib to the adapter and wait for its
15777+ completion.
15778+
15779+Arguments:
15780+
15781+ AdapterExtension - Pointer to adapter extension structure.
15782+ FibPhysicalAddress - Physical address of fib to send.
15783+
15784+
15785+Return Value:
15786+
15787+ BOOLEAN
15788+
15789+--*/
15790+{
15791+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15792+ PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15793+ ULONG returnStatus;
15794+
15795+ if (RxSendSynchCommand( AdapterExtension,
15796+ SEND_SYNCHRONOUS_FIB,
15797+ FibPhysicalAddress,
15798+ 0,
15799+ 0,
15800+ 0,
15801+ &returnStatus ) != STATUS_SUCCESS ) {
15802+
15803+ return (FALSE);
15804+
15805+ }
15806+
15807+ return (TRUE);
15808+
15809+}
15810+
15811+
15812diff -urN linux/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15813--- linux/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 19:00:00 1969
15814+++ linux/drivers/scsi/aacraid/sap1sup.c Thu Dec 21 13:14:30 2000
15815@@ -0,0 +1,859 @@
15816+/*++
15817+ * Adaptec aacraid device driver for Linux.
15818+ *
15819+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15820+ *
15821+ * This program is free software; you can redistribute it and/or modify
15822+ * it under the terms of the GNU General Public License as published by
15823+ * the Free Software Foundation; either version 2, or (at your option)
15824+ * any later version.
15825+ *
15826+ * This program is distributed in the hope that it will be useful,
15827+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15828+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15829+ * GNU General Public License for more details.
15830+ *
15831+ * You should have received a copy of the GNU General Public License
15832+ * along with this program; see the file COPYING. If not, write to
15833+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15834+ *
15835+ * Module Name:
15836+ * sap1sup.c
15837+ *
15838+ * Abstract: Drawbridge specific support functions
15839+ *
15840+ --*/
15841+
15842+static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15843+
15844+#include "osheaders.h"
15845+
15846+
15847+#include "AacGenericTypes.h"
15848+
15849+#include "aac_unix_defs.h"
15850+
15851+#include "fsatypes.h"
15852+#include "comstruc.h"
15853+#include "fsact.h"
15854+#include "protocol.h"
15855+
15856+#define DEFINE_PCI_IDS
15857+#include "sap1common.h"
15858+#include "monkerapi.h"
15859+
15860+#include "fsaport.h"
15861+#include "fsaioctl.h"
15862+
15863+
15864+#include "pcisup.h"
15865+#include "sap1.h"
15866+
15867+#include "port.h"
15868+
15869+#include "nodetype.h"
15870+#include "comsup.h"
15871+#include "afacomm.h"
15872+#include "adapter.h"
15873+
15874+#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15875+
15876+// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15877+
15878+#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15879+
15880+#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15881+
15882+int MiniPortRevision = Sa_MINIPORT_REVISION;
15883+
15884+
15885+//
15886+// The list of all the Sa adapter structures
15887+//
15888+
15889+PSa_ADAPTER_EXTENSION SaAdapterList;
15890+
15891+int
15892+SaInitDevice(
15893+ IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15894+ IN ULONG AdapterNumber,
15895+ IN ULONG PciBus,
15896+ IN ULONG PciSlot
15897+);
15898+
15899+BOOLEAN
15900+SaSendSynchFib(
15901+ PVOID Arg1,
15902+ ULONG FibPhysicalAddress
15903+ );
15904+
15905+FSA_USER_VAR SaUserVars[] = {
15906+ { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15907+};
15908+
15909+
15910+//
15911+// Declare private use routines for this modual
15912+//
15913+
15914+
15915+/*++
15916+
15917+Routine Description:
15918+
15919+ The Isr routine for fsa Sa based adapter boards.
15920+
15921+Arguments:
15922+
15923+
15924+Return Value:
15925+
15926+ TRUE - if the interrupt was handled by this isr
15927+ FALSE - if the interrupt was not handled by this isr
15928+
15929+--*/
15930+u_int
15931+SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
15932+{
15933+ USHORT InterruptStatus, Mask;
15934+ u_int OurInterrupt = INTR_UNCLAIMED;
15935+
15936+ InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
15937+
15938+ //
15939+ // Read mask and invert because drawbridge is reversed.
15940+ //
15941+ // This allows us to only service interrupts that have been enabled.
15942+ //
15943+
15944+ Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
15945+
15946+ // Check to see if this is our interrupt. If it isn't just return FALSE.
15947+
15948+
15949+ if (InterruptStatus & Mask) {
15950+
15951+ OurInterrupt = INTR_CLAIMED;
15952+
15953+ if (InterruptStatus & PrintfReady) {
15954+
15955+ ULONG Length, Level;
15956+ unsigned char *cp;
15957+
15958+ cp = AdapterExtension->Common->PrintfBufferAddress;
15959+
15960+ //
15961+ // The size of the Printbuffer is set in port.c
15962+ // There is no variable or define for it
15963+ //
15964+ if (Length > 255)
15965+ Length = 255;
15966+
15967+ if (cp[Length] != 0) {
15968+ // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15969+ cp[Length] = 0;
15970+ }
15971+
15972+ if (Level == LOG_HIGH_ERROR)
15973+ cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15974+ else
15975+ cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15976+
15977+ bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15978+
15979+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
15980+
15981+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
15982+
15983+ } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
15984+
15985+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15986+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
15987+
15988+ } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
15989+
15990+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15991+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
15992+
15993+ } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
15994+
15995+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15996+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
15997+
15998+ } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
15999+
16000+ AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16001+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16002+
16003+ }
16004+
16005+ }
16006+ return(OurInterrupt);
16007+}
16008+
16009+
16010+/*++
16011+
16012+Routine Description:
16013+
16014+ This routine will enable the corresponding adapter event to cause an interrupt on
16015+ the host.
16016+
16017+Arguments:
16018+
16019+ AdapterExtension - Which adapter to enable.
16020+
16021+ AdapterEvent - Which adapter event.
16022+
16023+ AtDeviceIrq - Whether the system is in DEVICE irql
16024+
16025+Return Value:
16026+
16027+ Nothing.
16028+
16029+--*/
16030+VOID
16031+SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16032+{
16033+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16034+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16035+
16036+ switch (AdapterEvent) {
16037+
16038+ case HostNormCmdQue:
16039+
16040+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16041+
16042+ break;
16043+
16044+ case HostNormRespQue:
16045+
16046+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16047+
16048+ break;
16049+
16050+ case AdapNormCmdNotFull:
16051+
16052+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16053+
16054+ break;
16055+
16056+ case AdapNormRespNotFull:
16057+
16058+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16059+
16060+ break;
16061+
16062+ }
16063+
16064+}
16065+
16066+
16067+
16068+/*++
16069+
16070+Routine Description:
16071+
16072+ This routine will disable the corresponding adapter event to cause an interrupt on
16073+ the host.
16074+
16075+Arguments:
16076+
16077+ AdapterExtension - Which adapter to enable.
16078+
16079+ AdapterEvent - Which adapter event.
16080+
16081+ AtDeviceIrq - Whether the system is in DEVICE irql
16082+
16083+Return Value:
16084+
16085+ Nothing.
16086+
16087+--*/
16088+VOID
16089+SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16090+{
16091+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16092+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16093+
16094+ switch (AdapterEvent) {
16095+
16096+
16097+ case HostNormCmdQue:
16098+
16099+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16100+
16101+ break;
16102+
16103+ case HostNormRespQue:
16104+
16105+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16106+
16107+ break;
16108+
16109+ case AdapNormCmdNotFull:
16110+
16111+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16112+
16113+ break;
16114+
16115+
16116+ case AdapNormRespNotFull:
16117+
16118+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16119+
16120+ break;
16121+
16122+ }
16123+
16124+}
16125+
16126+
16127+SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16128+{
16129+ PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16130+
16131+ //
16132+ // Free the register mapping.
16133+ //
16134+
16135+ OsDetachDevice(AdapterExtension);
16136+
16137+ OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16138+
16139+}
16140+
16141+
16142+/*++
16143+
16144+Routine Description:
16145+
16146+ Scans the PCI bus looking for the Sa card. When found all resources for the
16147+ device will be allocated and the interrupt vectors and csrs will be allocated and
16148+ mapped.
16149+
16150+ The device_interface in the commregion will be allocated and linked to the comm region.
16151+
16152+Arguments:
16153+
16154+
16155+Return Value:
16156+
16157+ TRUE - if the device was setup with not problems
16158+ FALSE - if the device could not be mapped and init successfully
16159+
16160+--*/
16161+int
16162+SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16163+ IN ULONG AdapterNumber, IN ULONG PciBus,
16164+ IN ULONG PciSlot)
16165+{
16166+ AAC_STATUS Status;
16167+ PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16168+ FSA_NEW_ADAPTER NewAdapter;
16169+ ULONG StartTime, EndTime, WaitTime;
16170+ ULONG InitStatus;
16171+ int instance;
16172+ char *name;
16173+
16174+ AfaPortPrint("In init device.\n");
16175+
16176+ CommonExtension->AdapterNumber = AdapterNumber;
16177+
16178+ CommonExtension->PciBusNumber = PciBus;
16179+ CommonExtension->PciSlotNumber = PciSlot;
16180+
16181+ AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16182+ AdapterExtension->Common = CommonExtension;
16183+ CommonExtension->MiniPort = AdapterExtension;
16184+
16185+ instance = OsGetDeviceInstance(AdapterExtension);
16186+ name = OsGetDeviceName(AdapterExtension);
16187+
16188+ //
16189+ // Map in the registers from the adapter, register space 0 is config space,
16190+ // register space 1 is the memery space.
16191+ //
16192+
16193+ if (OsMapDeviceRegisters(AdapterExtension)){
16194+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16195+ return(FAILURE);
16196+ }
16197+
16198+
16199+ //
16200+ // Check to see if the board failed any self tests.
16201+ //
16202+
16203+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16204+
16205+ cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16206+ name, instance);
16207+ return(FAILURE);
16208+ }
16209+
16210+ //
16211+ // Check to see if the board panic'd while booting.
16212+ //
16213+
16214+ if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16215+
16216+ cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16217+ name, instance);
16218+ return(FAILURE);
16219+ }
16220+
16221+
16222+ StartTime = OsGetSeconds();
16223+ WaitTime = 0;
16224+
16225+
16226+ //
16227+ // Wait for the adapter to be up and running. Wait up until 3 minutes.
16228+ //
16229+
16230+ while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16231+
16232+ EndTime = OsGetSeconds();
16233+
16234+ WaitTime = EndTime - StartTime;
16235+
16236+ if ( WaitTime > (3 * 60) ) {
16237+
16238+ InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16239+
16240+ cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16241+ name, instance, InitStatus);
16242+ return(FAILURE);
16243+
16244+ }
16245+ }
16246+
16247+ if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16248+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16249+ return(FAILURE);
16250+ }
16251+
16252+ if (OsAttachDMA(AdapterExtension)) {
16253+ cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16254+ return(FAILURE);
16255+ }
16256+
16257+
16258+ //
16259+ // Fill in the function dispatch table.
16260+ //
16261+
16262+ AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16263+ AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16264+ AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16265+ AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16266+ AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16267+ AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16268+ AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16269+ AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16270+ AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16271+ AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16272+ AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16273+ AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16274+ AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16275+
16276+ AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16277+
16278+ NewAdapter.AdapterExtension = CommonExtension;
16279+ NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16280+ NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16281+ NewAdapter.AdapterUserVars = SaUserVars;
16282+ NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16283+
16284+ NewAdapter.Dip = CommonExtension->OsDep.dip;
16285+
16286+
16287+ if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16288+ cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16289+ return (FAILURE);
16290+ };
16291+
16292+
16293+ AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16294+
16295+ if (AdapterExtension->Common->Adapter == NULL) {
16296+
16297+ AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16298+ cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16299+
16300+ return (FAILURE);
16301+ }
16302+
16303+
16304+ //
16305+ // Start any kernel threads needed
16306+ OsStartKernelThreads(AdapterExtension);
16307+
16308+ //
16309+ // Tell the adapter that all is configure, and it can start accepting requests
16310+ //
16311+
16312+ SaStartAdapter(AdapterExtension);
16313+
16314+
16315+
16316+ //
16317+ // Put this adapter into the list of Sa adapters
16318+ //
16319+
16320+ AdapterExtension->Next = SaAdapterList;
16321+ SaAdapterList = AdapterExtension;
16322+
16323+ AdapterExtension->Common->AdapterConfigured = TRUE;
16324+
16325+
16326+#ifdef AACDISK
16327+ //
16328+ // Call the disk layer to initialize itself.
16329+ //
16330+
16331+ AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16332+#endif
16333+
16334+
16335+init_done:
16336+
16337+ AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16338+
16339+ OsAttachHBA(AdapterExtension);
16340+
16341+ return (0);
16342+
16343+init_error:
16344+
16345+ return (FAILURE);
16346+}
16347+
16348+
16349+
16350+VOID
16351+SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16352+{
16353+ ULONG ReturnStatus;
16354+ LARGE_INTEGER HostTime;
16355+ ULONG ElapsedSeconds;
16356+ PADAPTER_INIT_STRUCT InitStruct;
16357+
16358+ //
16359+ // Fill in the remaining pieces of the InitStruct.
16360+ //
16361+
16362+ InitStruct = AdapterExtension->Common->InitStruct;
16363+
16364+ InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16365+
16366+ ElapsedSeconds = OsGetSeconds();
16367+
16368+ InitStruct->HostElapsedSeconds = ElapsedSeconds;
16369+
16370+ //
16371+ // Tell the adapter we are back and up and running so it will scan its command
16372+ // queues and enable our interrupts
16373+ //
16374+
16375+ AdapterExtension->LocalMaskInterruptControl =
16376+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16377+
16378+
16379+ //
16380+ // First clear out all interrupts. Then enable the one's that we can handle.
16381+ //
16382+
16383+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16384+ Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16385+ (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16386+
16387+ SaSendSynchCommand(AdapterExtension,
16388+ INIT_STRUCT_BASE_ADDRESS,
16389+ (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16390+ 0,
16391+ 0,
16392+ 0,
16393+ &ReturnStatus);
16394+
16395+}
16396+
16397+
16398+VOID
16399+SaResetDevice (PVOID Arg1){
16400+
16401+}
16402+
16403+
16404+/*++
16405+
16406+Routine Description:
16407+
16408+ The will cause the adapter to take a break point.
16409+
16410+Arguments:
16411+
16412+ None
16413+
16414+Return Value:
16415+
16416+ Nothing
16417+
16418+--*/
16419+VOID
16420+SaInterruptAdapter (PVOID Arg1)
16421+{
16422+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16423+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16424+
16425+ ULONG ReturnStatus;
16426+
16427+ SaSendSynchCommand(AdapterExtension,
16428+ BREAKPOINT_REQUEST,
16429+ 0,
16430+ 0,
16431+ 0,
16432+ 0,
16433+ &ReturnStatus);
16434+
16435+}
16436+
16437+
16438+/*++
16439+
16440+Routine Description:
16441+
16442+ Will read the adapter CSRs to find the reason the adapter has
16443+ interrupted us.
16444+
16445+Arguments:
16446+
16447+ AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16448+
16449+Return Value:
16450+
16451+ Nothing
16452+
16453+--*/
16454+VOID
16455+SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16456+{
16457+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16458+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16459+ ULONG ReturnStatus;
16460+
16461+ switch (AdapterEvent) {
16462+ case AdapNormCmdQue:
16463+
16464+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16465+ break;
16466+
16467+ case HostNormRespNotFull:
16468+
16469+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16470+ break;
16471+
16472+ case AdapNormRespQue:
16473+
16474+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16475+ break;
16476+
16477+ case HostNormCmdNotFull:
16478+
16479+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16480+ break;
16481+
16482+ case HostShutdown:
16483+
16484+// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16485+
16486+ break;
16487+
16488+ case FastIo:
16489+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16490+ break;
16491+
16492+ case AdapPrintfDone:
16493+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16494+ break;
16495+
16496+ default:
16497+
16498+ SaBugCheck(0,0,0);
16499+ AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16500+ break;
16501+ }
16502+}
16503+
16504+
16505+/*++
16506+
16507+Routine Description:
16508+
16509+ This routine will send a synchronous comamnd to the adapter and wait for its
16510+ completion.
16511+
16512+Arguments:
16513+
16514+ AdapterExtension - Pointer to adapter extension structure.
16515+ Command - Which command to send
16516+ Parameter1 - 4 - Parameters for command
16517+ ReturnStatus - return status from adapter after completion of command
16518+
16519+
16520+Return Value:
16521+
16522+ AAC_STATUS
16523+
16524+--*/
16525+AAC_STATUS
16526+SaSendSynchCommand(
16527+ PVOID Arg1,
16528+ ULONG Command,
16529+ ULONG Parameter1,
16530+ ULONG Parameter2,
16531+ ULONG Parameter3,
16532+ ULONG Parameter4,
16533+ PULONG ReturnStatus
16534+ )
16535+{
16536+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16537+ ULONG StartTime,EndTime,WaitTime;
16538+ BOOLEAN CommandSucceeded;
16539+
16540+ //
16541+ // Write the Command into Mailbox 0
16542+ //
16543+
16544+ Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16545+
16546+ //
16547+ // Write the parameters into Mailboxes 1 - 4
16548+ //
16549+
16550+ Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16551+ Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16552+ Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16553+ Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16554+
16555+ //
16556+ // Clear the synch command doorbell to start on a clean slate.
16557+ //
16558+
16559+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16560+
16561+ //
16562+ // Signal that there is a new synch command
16563+ //
16564+
16565+ Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16566+
16567+ CommandSucceeded = FALSE;
16568+
16569+ StartTime = OsGetSeconds();
16570+ WaitTime = 0;
16571+
16572+ while (WaitTime < 30) { // wait up to 30 seconds
16573+
16574+ drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16575+
16576+ //
16577+ // Mon110 will set doorbell0 bit when it has completed the command.
16578+ //
16579+
16580+ if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16581+
16582+ CommandSucceeded = TRUE;
16583+ break;
16584+ }
16585+
16586+ EndTime = OsGetSeconds();
16587+ WaitTime = EndTime - StartTime;
16588+
16589+ }
16590+
16591+ if (CommandSucceeded != TRUE) {
16592+
16593+ return (STATUS_IO_TIMEOUT);
16594+
16595+ }
16596+
16597+ //
16598+ // Clear the synch command doorbell.
16599+ //
16600+
16601+ Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16602+
16603+ //
16604+ // Pull the synch status from Mailbox 0.
16605+ //
16606+
16607+ *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16608+
16609+ //
16610+ // Return SUCCESS
16611+ //
16612+
16613+ return (STATUS_SUCCESS);
16614+
16615+}
16616+
16617+
16618+/*++
16619+
16620+Routine Description:
16621+
16622+ This routine will send a synchronous fib to the adapter and wait for its
16623+ completion.
16624+
16625+Arguments:
16626+
16627+ AdapterExtension - Pointer to adapter extension structure.
16628+ FibPhysicalAddress - Physical address of fib to send.
16629+
16630+
16631+Return Value:
16632+
16633+ BOOLEAN
16634+
16635+--*/
16636+BOOLEAN
16637+SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16638+{
16639+ PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16640+ PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16641+ ULONG returnStatus;
16642+
16643+ if (SaSendSynchCommand( AdapterExtension,
16644+ SEND_SYNCHRONOUS_FIB,
16645+ FibPhysicalAddress,
16646+ 0,
16647+ 0,
16648+ 0,
16649+ &returnStatus ) != STATUS_SUCCESS ) {
16650+
16651+ return (FALSE);
16652+
16653+ }
16654+
16655+ return (TRUE);
16656+
16657+}
16658+
16659+BOOLEAN
16660+WriteFlash(
16661+ PVOID AdapterExtension,
16662+ ULONG *MappedBuffer)
16663+{
16664+ return (FALSE);
16665+}
16666+
16667+BOOLEAN
16668+ReadFlash(
16669+ PVOID AdapterExtension,
16670+ ULONG *MappedBuffer)
16671+{
16672+ return (FALSE);
16673+}
16674+
This page took 2.123601 seconds and 4 git commands to generate.