1 diff -burN linux-2.4.9/MAINTAINERS linux/MAINTAINERS
2 --- linux-2.4.9/MAINTAINERS Thu Aug 16 13:40:30 2001
3 +++ linux/MAINTAINERS Thu Aug 16 13:41:30 2001
5 W: http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
8 +AACRAID SCSI RAID DRIVER
9 +P: Adaptec OEM Raid Solutions
10 +M: linux-aacraid-devel@dell.com
11 +L: linux-aacraid-devel@dell.com
12 +L: linux-aacraid-announce@dell.com
13 +W: http://domsch.com/linux
18 M: andrew.grover@intel.com
19 diff -burN linux-2.4.9/arch/i386/defconfig linux/arch/i386/defconfig
20 --- linux-2.4.9/arch/i386/defconfig Thu Aug 16 13:40:30 2001
21 +++ linux/arch/i386/defconfig Thu Aug 16 13:41:30 2001
23 # CONFIG_SCSI_AHA152X is not set
24 # CONFIG_SCSI_AHA1542 is not set
25 # CONFIG_SCSI_AHA1740 is not set
26 +# CONFIG_SCSI_AACRAID is not set
27 # CONFIG_SCSI_AIC7XXX is not set
28 # CONFIG_SCSI_AIC7XXX_OLD is not set
29 # CONFIG_SCSI_ADVANSYS is not set
30 diff -burN linux-2.4.9/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31 --- linux-2.4.9/drivers/scsi/Config.in Thu Aug 16 13:40:11 2001
32 +++ linux/drivers/scsi/Config.in Thu Aug 16 13:41:30 2001
34 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
35 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
36 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
37 +dep_tristate 'Adaptec AACRAID support' CONFIG_SCSI_AACRAID $CONFIG_SCSI
38 source drivers/scsi/aic7xxx/Config.in
39 if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
40 dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
41 diff -burN linux-2.4.9/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42 --- linux-2.4.9/drivers/scsi/Makefile Thu Aug 16 13:40:11 2001
43 +++ linux/drivers/scsi/Makefile Thu Aug 16 13:41:30 2001
45 obj-$(CONFIG_SCSI_AHA152X) += aha152x.o
46 obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
47 obj-$(CONFIG_SCSI_AHA1740) += aha1740.o
48 +obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
49 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
50 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx_drv.o
53 sim710_u.h: sim710_d.h
61 53c700_d.h: 53c700.scr script_asm.pl
62 $(PERL) -s script_asm.pl -ncr7x0_family < 53c700.scr
63 diff -burN linux-2.4.9/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
64 --- linux-2.4.9/drivers/scsi/aacraid/ChangeLog Wed Dec 31 18:00:00 1969
65 +++ linux/drivers/scsi/aacraid/ChangeLog Thu Aug 16 18:18:10 2001
67 +2001-08-16 Matt Domsch <Matt_Domsch@dell.com>
68 +* renamed aacraid_pciid to perc_pciid for future Dell controllers
69 +* added rx_pciid and sa_pciid options for future Adaptec controllers
70 +* applied changes from Adaptec (new PCI ID, some cleanups)
71 +* released patch against 2.4.8
72 +* released patch against 2.4.9
74 +2001-08-11 Matt Domsch <Matt_Domsch@dell.com>
75 +* applied pciid patch to allow passing a new PCI ID to the module at insmod
76 +* removed all #ifdef CONFIG_SMP and #ifdef MODULE stuff
77 +* released patch against 2.4.7
78 +* released patch against 2.4.8
80 +2001-07-21 Matt Domsch <Matt_Domsch@dell.com>
81 +* changed __SMP__ to CONFIG_SMP everywhere (really this time)
82 +* Applied read capacity patch
83 +* released patch against 2.4.6
84 +* released patch against 2.4.7
86 +2001-07-04 Matt Domsch <Matt_Domsch@dell.com>
87 +* Started with linux-2.4.5-aacraid-043001.patch
88 +* Applied Chris Pascoe's SMP fix patch
89 +* Released patch against 2.4.6
92 +2001-04-30 Matt Domsch <Matt_Domsch@dell.com>
93 +* Started with linux-2.4.3-aacraid-030101.patch
94 +* Applied against 2.4.4.
95 +* Added scsi_set_pci_device() call in linit.c
97 diff -burN linux-2.4.9/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
98 --- linux-2.4.9/drivers/scsi/aacraid/Makefile Wed Dec 31 18:00:00 1969
99 +++ linux/drivers/scsi/aacraid/Makefile Thu Aug 16 13:41:30 2001
102 +# Makefile aacraid Raid Controller
105 +###############################################################################
106 +### SOURCE FILES DEFINES
107 +###############################################################################
125 + ./include/AacGenericTypes.h \
126 + ./include/aac_unix_defs.h \
127 + ./include/adapter.h \
128 + ./include/afacomm.h \
129 + ./include/aifstruc.h \
130 + ./include/build_number.h \
131 + ./include/commdata.h \
132 + ./include/commerr.h \
133 + ./include/commfibcontext.h \
134 + ./include/comprocs.h \
135 + ./include/comproto.h \
136 + ./include/comstruc.h \
137 + ./include/comsup.h \
138 + ./include/fsact.h \
139 + ./include/fsafs.h \
140 + ./include/fsaioctl.h \
141 + ./include/fsaport.h \
142 + ./include/fsatypes.h \
143 + ./include/linit.h \
144 + ./include/monkerapi.h \
145 + ./include/nodetype.h \
146 + ./include/nvramioctl.h \
147 + ./include/osheaders.h \
148 + ./include/ostypes.h \
149 + ./include/pcisup.h \
150 + ./include/perfpack.h \
152 + ./include/protocol.h \
153 + ./include/revision.h \
154 + ./include/rxcommon.h \
156 + ./include/sap1common.h \
158 + ./include/version.h
164 +###############################################################################
165 +### OBJECT FILES DEFINES
166 +###############################################################################
183 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
185 +###############################################################################
187 +###############################################################################
189 +# Remember that we're doing a chdir one level lower, so we need an extra ../
192 + -I../../../include -I..
194 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
198 + -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
202 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
204 +###############################################################################
205 +### DO GENERAL STUFF
206 +###############################################################################
209 +.SUFFIXES: .c .o .h .a
211 +all: source ${TARGET_OFILES} aacraid.o
213 +source: ${ALL_SOURCE}
218 +###############################################################################
220 +###############################################################################
222 +aacraid.o: source ${TARGET_OFILES}
223 + ld -r -o $@ $(TARGET_OFILES)
224 + cp -r aacraid.o ../
226 +###############################################################################
228 +###############################################################################
231 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
233 +aachba.o: ./aachba.c
234 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
237 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
239 +osfuncs.o: ./osfuncs.c
240 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
242 +commctrl.o: ./commctrl.c
243 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
245 +comminit.o: ./comminit.c
246 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
248 +commsup.o: ./commsup.c
249 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
251 +dpcsup.o: ./dpcsup.c
252 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
255 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
258 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
261 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
264 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
266 +sap1sup.o: ./sap1sup.c
267 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
270 diff -burN linux-2.4.9/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
271 --- linux-2.4.9/drivers/scsi/aacraid/README Wed Dec 31 18:00:00 1969
272 +++ linux/drivers/scsi/aacraid/README Thu Aug 16 13:41:30 2001
274 + AACRAID Driver for Linux
277 +-------------------------
278 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
279 +OEM based RAID controllers.
281 +It is important to note the amount of test time the 2.4.x driver
282 +received. Though not a great deal has changed between 2.2 and 2.4
283 +for this version, it has not recevied a great deal of test time.
285 +A new driver version is in the works and that version will be
286 +submitted to the standard distribution kernel. The previous
287 +2.2 version was submitted but rejected due to the large
288 +amount of code reduncdancy and NTisms. This driver was
289 +initially ported from NT to Solaris and then to Linux.
291 +The new version is being written on Unix for Unix and
292 +should be much easier to read and a great deal cleaner.
294 +Supported Cards/Chipsets
295 +-------------------------
296 + Dell Computer Corporation PERC 2 Quad Channel
297 + Dell Computer Corporation PERC 2/Si
298 + Dell Computer Corporation PERC 3/Si
299 + Dell Computer Corporation PERC 3/Di
302 +Not Supported Devices
303 +-------------------------
304 + Any and All Adaptec branded raid controllers.
307 +-------------------------
308 + Adaptec Unix OEM Product Group
311 +-------------------------
312 +please see http://domsch.com/linux for information
313 +on mailing lists. There is both a development and
314 +an announcment list. Due to the overwhelming amount
315 +of mail I receive about this driver, I can not
316 +answer questions individually and requests should
317 +be directed to the list server. Thanks.
319 +Modified by Brian Boerner February 2001
320 diff -burN linux-2.4.9/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
321 --- linux-2.4.9/drivers/scsi/aacraid/aachba.c Wed Dec 31 18:00:00 1969
322 +++ linux/drivers/scsi/aacraid/aachba.c Thu Aug 16 13:41:30 2001
325 + * Adaptec aacraid device driver for Linux.
327 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
329 + * This program is free software; you can redistribute it and/or modify
330 + * it under the terms of the GNU General Public License as published by
331 + * the Free Software Foundation; either version 2, or (at your option)
332 + * any later version.
334 + * This program is distributed in the hope that it will be useful,
335 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
336 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
337 + * GNU General Public License for more details.
339 + * You should have received a copy of the GNU General Public License
340 + * along with this program; see the file COPYING. If not, write to
341 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
346 + * Abstract: driver...
350 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
352 +/*------------------------------------------------------------------------------
354 + *----------------------------------------------------------------------------*/
355 +#include "osheaders.h"
356 +#include "AacGenericTypes.h"
357 +#include "aac_unix_defs.h"
358 +#include "comstruc.h"
359 +#include "monkerapi.h"
360 +#include "protocol.h"
363 +#include "fsaioctl.h"
365 +#include "sap1common.h"
366 +#include "fsaport.h"
369 +#include "nodetype.h"
371 +#include "afacomm.h"
372 +#include "adapter.h"
374 +/*------------------------------------------------------------------------------
376 + *----------------------------------------------------------------------------*/
378 +#define SS_TEST 0x00 /* Test unit ready */
379 +#define SS_REZERO 0x01 /* Rezero unit */
380 +#define SS_REQSEN 0x03 /* Request Sense */
381 +#define SS_REASGN 0x07 /* Reassign blocks */
382 +#define SS_READ 0x08 /* Read 6 */
383 +#define SS_WRITE 0x0A /* Write 6 */
384 +#define SS_INQUIR 0x12 /* inquiry */
385 +#define SS_ST_SP 0x1B /* Start/Stop unit */
386 +#define SS_LOCK 0x1E /* prevent/allow medium removal */
387 +#define SS_RESERV 0x16 /* Reserve */
388 +#define SS_RELES 0x17 /* Release */
389 +#define SS_MODESEN 0x1A /* Mode Sense 6 */
390 +#define SS_RDCAP 0x25 /* Read Capacity */
391 +#define SM_READ 0x28 /* Read 10 */
392 +#define SM_WRITE 0x2A /* Write 10 */
393 +#define SS_SEEK 0x2B /* Seek */
395 +/* values for inqd_pdt: Peripheral device type in plain English */
396 +#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
397 +#define INQD_PDT_PROC 0x03 /* Processor device */
398 +#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
399 +#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
400 +#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
401 +#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
403 +#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
404 +#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
406 +#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
407 +#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
408 +#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
410 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
412 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
414 +// ------------------------------------------------------
417 +#define SENKEY_NO_SENSE 0x00 //
418 +#define SENKEY_UNDEFINED 0x01 //
419 +#define SENKEY_NOT_READY 0x02 //
420 +#define SENKEY_MEDIUM_ERR 0x03 //
421 +#define SENKEY_HW_ERR 0x04 //
422 +#define SENKEY_ILLEGAL 0x05 //
423 +#define SENKEY_ATTENTION 0x06 //
424 +#define SENKEY_PROTECTED 0x07 //
425 +#define SENKEY_BLANK 0x08 //
426 +#define SENKEY_V_UNIQUE 0x09 //
427 +#define SENKEY_CPY_ABORT 0x0A //
428 +#define SENKEY_ABORT 0x0B //
429 +#define SENKEY_EQUAL 0x0C //
430 +#define SENKEY_VOL_OVERFLOW 0x0D //
431 +#define SENKEY_MISCOMP 0x0E //
432 +#define SENKEY_RESERVED 0x0F //
434 +// ------------------------------------------------------
437 +#define SENCODE_NO_SENSE 0x00
438 +#define SENCODE_END_OF_DATA 0x00
439 +#define SENCODE_BECOMING_READY 0x04
440 +#define SENCODE_INIT_CMD_REQUIRED 0x04
441 +#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
442 +#define SENCODE_INVALID_COMMAND 0x20
443 +#define SENCODE_LBA_OUT_OF_RANGE 0x21
444 +#define SENCODE_INVALID_CDB_FIELD 0x24
445 +#define SENCODE_LUN_NOT_SUPPORTED 0x25
446 +#define SENCODE_INVALID_PARAM_FIELD 0x26
447 +#define SENCODE_PARAM_NOT_SUPPORTED 0x26
448 +#define SENCODE_PARAM_VALUE_INVALID 0x26
449 +#define SENCODE_RESET_OCCURRED 0x29
450 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
451 +#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
452 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
453 +#define SENCODE_DIAGNOSTIC_FAILURE 0x40
454 +#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
455 +#define SENCODE_INVALID_MESSAGE_ERROR 0x49
456 +#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
457 +#define SENCODE_OVERLAPPED_COMMAND 0x4E
459 +// ------------------------------------------------------
460 +// Additional sense codes
462 +#define ASENCODE_NO_SENSE 0x00
463 +#define ASENCODE_END_OF_DATA 0x05
464 +#define ASENCODE_BECOMING_READY 0x01
465 +#define ASENCODE_INIT_CMD_REQUIRED 0x02
466 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
467 +#define ASENCODE_INVALID_COMMAND 0x00
468 +#define ASENCODE_LBA_OUT_OF_RANGE 0x00
469 +#define ASENCODE_INVALID_CDB_FIELD 0x00
470 +#define ASENCODE_LUN_NOT_SUPPORTED 0x00
471 +#define ASENCODE_INVALID_PARAM_FIELD 0x00
472 +#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
473 +#define ASENCODE_PARAM_VALUE_INVALID 0x02
474 +#define ASENCODE_RESET_OCCURRED 0x00
475 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
476 +#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
477 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
478 +#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
479 +#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
480 +#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
481 +#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
482 +#define ASENCODE_OVERLAPPED_COMMAND 0x00
484 +#define BYTE0( x ) ( unsigned char )( x )
485 +#define BYTE1( x ) ( unsigned char )( x >> 8 )
486 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
487 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
489 +/*------------------------------------------------------------------------------
490 + * S T R U C T S / T Y P E D E F S
491 + *----------------------------------------------------------------------------*/
492 +/* SCSI inquiry data */
493 +struct inquiry_data {
494 + unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
495 + unchar inqd_dtq; /* RMB | Device Type Qualifier */
496 + unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
497 + unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
498 + unchar inqd_len; /* Additional length (n-4) */
499 + unchar inqd_pad1[2]; /* Reserved - must be zero */
500 + unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
501 + unchar inqd_vid[8]; /* Vendor ID */
502 + unchar inqd_pid[16]; /* Product ID */
503 + unchar inqd_prl[4]; /* Product Revision Level */
507 + unchar error_code; // 70h (current errors), 71h(deferred errors)
508 + unchar valid:1; // A valid bit of one indicates that the information
509 + // field contains valid information as defined in the
510 + // SCSI-2 Standard.
512 + unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
515 + unchar sense_key:4; // Sense Key
517 + unchar ILI:1; // Incorrect Length Indicator
518 + unchar EOM:1; // End Of Medium - reserved for random access devices
519 + unchar filemark:1; // Filemark - reserved for random access devices
521 + unchar information[4]; // for direct-access devices, contains the unsigned
522 + // logical block address or residue associated with
524 + unchar add_sense_len; // number of additional sense bytes to follow this field
525 + unchar cmnd_info[4]; // not used
526 + unchar ASC; // Additional Sense Code
527 + unchar ASCQ; // Additional Sense Code Qualifier
528 + unchar FRUC; // Field Replaceable Unit Code - not used
530 + unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
532 + unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
533 + // the bit_ptr field has valid value
534 + unchar reserved2:2;
535 + unchar CD:1; // command data bit: 1- illegal parameter in CDB.
536 + // 0- illegal parameter in data.
539 + unchar field_ptr[2]; // byte of the CDB or parameter data in error
542 +/*------------------------------------------------------------------------------
544 + *----------------------------------------------------------------------------*/
545 +/*------------------------------------------------------------------------------
546 + * M O D U L E G L O B A L S
547 + *----------------------------------------------------------------------------*/
548 +static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
549 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
551 +/*------------------------------------------------------------------------------
552 + * F U N C T I O N P R O T O T Y P E S
553 + *----------------------------------------------------------------------------*/
554 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
555 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
556 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
557 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
558 + PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
560 +void AacHba_CompleteScsi(
561 + Scsi_Cmnd *scsi_cmnd_ptr );
563 +void AacHba_CompleteScsiNoLock(
564 + Scsi_Cmnd *scsi_cmnd_ptr );
566 +static void AacHba_ReadCallback(
568 + PFIB_CONTEXT FibContext,
571 +static void AacHba_WriteCallback(
573 + PFIB_CONTEXT FibContext,
576 +int AacHba_DoScsiRead(
577 + Scsi_Cmnd *scsi_cmnd_ptr,
581 +int AacHba_DoScsiWrite(
582 + Scsi_Cmnd *scsi_cmnd_ptr,
586 +int AacHba_QueryDisk(
587 + PVOID AdapterArg, // CommonExtensionPtr
588 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
590 +int AacHba_ForceDeleteDisk(
591 + PVOID AdapterArg, // CommonExtensionPtr
592 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
594 +int AacHba_DeleteDisk(
596 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
598 +void AacHba_DetachAdapter(
599 + IN PVOID AdapterArg );
601 +BOOLEAN AacCommDetachAdapter(
602 + IN PAFA_COMM_ADAPTER Adapter );
604 +void AacHba_SetSenseData(
608 + unchar a_sense_code,
609 + unchar incorrect_length,
610 + unchar bit_pointer,
611 + unsigned field_pointer,
612 + unsigned long residue );
614 +static void get_sd_devname(
618 +// Keep these here for the time being - #REVIEW#
620 +AfaCommAdapterDeviceControl (
621 + IN PVOID AdapterArg,
622 + IN PAFA_IOCTL_CMD IoctlCmdPtr
626 +AfaCommRegisterNewClassDriver(
627 + IN PAFA_COMM_ADAPTER Adapter,
628 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
629 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
633 +SetInqDataStr (int, void *, int);
634 +/*------------------------------------------------------------------------------
635 + * F U N C T I O N S
636 + *----------------------------------------------------------------------------*/
638 +/*------------------------------------------------------------------------------
639 + AacHba_ClassDriverInit()
641 + Setup 'core' class driver to answer ioctl's
642 + *----------------------------------------------------------------------------*/
643 +int AacHba_ClassDriverInit(
644 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
645 +/*----------------------------------------------------------------------------*/
647 + AFA_NEW_CLASS_DRIVER NewClassDriver;
648 + AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
649 + PAFA_COMM_ADAPTER Adapter;
651 + Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
653 + RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
655 + // ClassDriverExtension is the first argument passed to class driver functions below
656 + NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
658 + NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
659 + NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
660 + NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
661 + NewClassDriver.HandleAif = AacHba_HandleAif;
662 + AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
668 +/*------------------------------------------------------------------------------
669 + AacHba_ProbeContainers()
671 + Make a list of all containers in the system.
672 +------------------------------------------------------------------------------*/
673 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
675 + fsadev_t *fsa_dev_ptr;
678 + PMNTINFORESPONSE DiskInfoResponse;
679 + PFIB_CONTEXT FibContext;
680 + AFA_COMM_ADAPTER *Adapter;
686 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
687 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
688 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
690 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
692 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
693 + return( STATUS_UNSUCCESSFUL );
696 + for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
698 + Adapter->CommFuncs.InitializeFib( FibContext );
700 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
702 + DiskInfo->Command = VM_NameServe;
703 + DiskInfo->MntCount = Index;
704 + DiskInfo->MntType = FT_FILESYS;
706 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
717 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
721 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
724 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
725 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
729 + fsa_dev_ptr->ContainerValid[Index] = TRUE;
730 + fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
731 + fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
733 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
734 + fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
737 + Adapter->CommFuncs.CompleteFib( FibContext );
739 + // If there are no more containers, then stop asking.
740 + if ((Index + 1) >= DiskInfoResponse->MntRespCount)
744 + Adapter->CommFuncs.FreeFib( FibContext );
746 + g_fsa_dev_array[instance] = fsa_dev_ptr;
751 +/*------------------------------------------------------------------------------
752 + AacHba_ProbeContainer()
754 + Probe a single container.
755 + *----------------------------------------------------------------------------*/
756 +int AacHba_ProbeContainer(
757 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
759 +/*----------------------------------------------------------------------------*/
761 + fsadev_t *fsa_dev_ptr;
764 + PMNTINFORESPONSE DiskInfoResponse;
765 + PFIB_CONTEXT FibContext;
766 + AFA_COMM_ADAPTER *Adapter;
769 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
770 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
771 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
773 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
775 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
776 + return( STATUS_UNSUCCESSFUL );
779 + Adapter->CommFuncs.InitializeFib( FibContext );
781 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
783 + DiskInfo->Command = VM_NameServe;
784 + DiskInfo->MntCount = ContainerId;
785 + DiskInfo->MntType = FT_FILESYS;
787 + Status = Adapter->CommFuncs.SendFib (ContainerCommand,
798 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
799 + Adapter->CommFuncs.CompleteFib( FibContext );
800 + Adapter->CommFuncs.FreeFib( FibContext );
804 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
807 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
808 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
811 + fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
812 + fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
813 + fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
814 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
815 + fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
818 + Adapter->CommFuncs.CompleteFib( FibContext );
819 + Adapter->CommFuncs.FreeFib( FibContext );
825 +/*------------------------------------------------------------------------------
826 + AacHba_CompleteScsi()
828 + Call SCSI completion routine after acquiring io_request_lock
832 + *----------------------------------------------------------------------------*/
833 +void AacHba_CompleteScsi(
834 + Scsi_Cmnd *scsi_cmnd_ptr )
836 + unsigned long cpu_flags;
838 + spin_lock_irqsave( &io_request_lock, cpu_flags );
839 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
840 + spin_unlock_irqrestore( &io_request_lock, cpu_flags );
844 +/*------------------------------------------------------------------------------
845 + AacHba_CompleteScsiNoLock()
847 + Call SCSI completion routine
851 + *----------------------------------------------------------------------------*/
852 +void AacHba_CompleteScsiNoLock(
853 + Scsi_Cmnd *scsi_cmnd_ptr )
855 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
858 +/*------------------------------------------------------------------------------
861 + Process SCSI command
865 + Returns 0 on success, -1 on failure
866 + *----------------------------------------------------------------------------*/
867 +int AacHba_DoScsiCmd(
868 + Scsi_Cmnd *scsi_cmnd_ptr,
871 + int ContainerId = 0;
872 + fsadev_t *fsa_dev_ptr;
873 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
876 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
877 + MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
879 + fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
881 + // If the bus, target or lun is out of range, return fail
882 + // Test does not apply to ID 16, the pseudo id for the controller itself.
883 + if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
885 + if( ( scsi_cmnd_ptr->channel > 0 ) ||
886 + ( scsi_cmnd_ptr->target > 15 ) ||
887 + ( scsi_cmnd_ptr->lun > 7 ) )
889 + cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
890 + scsi_cmnd_ptr->channel,
891 + scsi_cmnd_ptr->target,
892 + scsi_cmnd_ptr->lun );
893 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
895 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
900 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
903 + // If the target container doesn't exist, it may have been newly created
904 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
906 + switch( scsi_cmnd_ptr->cmnd[0] )
911 + spin_unlock_irq( &io_request_lock );
912 + AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
913 + spin_lock_irq( &io_request_lock );
919 + // If the target container still doesn't exist, return failure
920 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
923 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
924 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
929 + else // the command is for the controller itself
930 + if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
931 + ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
933 + cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
934 + scsi_cmnd_ptr->cmnd[0] );
936 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
938 + AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
939 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
942 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
947 + // Handle commands here that don't really require going out to the adapter
948 + switch ( scsi_cmnd_ptr->cmnd[0] )
952 + struct inquiry_data *inq_data_ptr;
954 + cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
955 + inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
956 + bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
958 + inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
960 + inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
961 + // that the medium is removable
962 + inq_data_ptr->inqd_rdf = 2; // A response data format value of
963 + // two indicates that the data shall
964 + // be in the format specified in SCSI-2
965 + inq_data_ptr->inqd_len = 31;
967 + // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
968 + SetInqDataStr( MiniPortIndex,
969 + (void *)(inq_data_ptr->inqd_vid),
970 + fsa_dev_ptr->ContainerType[ContainerId]);
972 + if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
973 + inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
975 + inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
977 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
978 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
988 + cmn_err( CE_DEBUG, "READ CAPACITY command" );
989 + capacity = fsa_dev_ptr->ContainerSize[ContainerId] - 1;
990 + cp = scsi_cmnd_ptr->request_buffer;
991 + cp[0] = ( capacity >> 24 ) & 0xff;
992 + cp[1] = ( capacity >> 16 ) & 0xff;
993 + cp[2] = ( capacity >> 8 ) & 0xff;
994 + cp[3] = ( capacity >> 0 ) & 0xff;
1000 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1001 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1010 + cmn_err( CE_DEBUG, "MODE SENSE command" );
1011 + mode_buf = scsi_cmnd_ptr->request_buffer;
1012 + mode_buf[0] = 0; // Mode data length (MSB)
1013 + mode_buf[1] = 6; // Mode data length (LSB)
1014 + mode_buf[2] = 0; // Medium type - default
1015 + mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
1016 + mode_buf[4] = 0; // reserved
1017 + mode_buf[5] = 0; // reserved
1018 + mode_buf[6] = 0; // Block descriptor length (MSB)
1019 + mode_buf[7] = 0; // Block descriptor length (LSB)
1021 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1022 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1028 + // These commands are all No-Ops
1030 + cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1031 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1032 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1036 + cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1038 + memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1039 + sizeof( struct sense_data ) );
1040 + bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1042 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1043 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1047 + cmn_err(CE_DEBUG, "LOCK command");
1049 + if( scsi_cmnd_ptr->cmnd[4] )
1050 + fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1052 + fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1054 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1055 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1059 + cmn_err( CE_DEBUG, "RESERVE command" );
1060 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1061 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1065 + cmn_err( CE_DEBUG, "RELEASE command" );
1066 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1067 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1071 + cmn_err( CE_DEBUG, "REZERO command" );
1072 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1073 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1077 + cmn_err( CE_DEBUG, "REASSIGN command" );
1078 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1079 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1083 + cmn_err( CE_DEBUG, "SEEK command" );
1084 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1085 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1089 + cmn_err( CE_DEBUG, "START/STOP command" );
1090 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1091 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1095 + switch ( scsi_cmnd_ptr->cmnd[0] )
1099 + // Hack to keep track of ordinal number of the device that corresponds
1100 + // to a container. Needed to convert containers to /dev/sd device names
1101 + fsa_dev_ptr->ContainerDevNo[ContainerId] =
1102 + DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1104 + return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1110 + return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1114 + // Unhandled commands
1116 + cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1117 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1119 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1120 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1123 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1128 +/*------------------------------------------------------------------------------
1129 + AacHba_DoScsiRead()
1131 + Handles SCSI READ requests
1135 + Returns 0 on success, -1 on failure
1136 + *----------------------------------------------------------------------------*/
1137 +int AacHba_DoScsiRead(
1138 + Scsi_Cmnd *scsi_cmnd_ptr,
1141 +/*----------------------------------------------------------------------------*/
1145 + u_long byte_count;
1148 + PBLOCKREAD BlockReadDisk;
1149 + PBLOCKREADRESPONSE BlockReadResponse;
1151 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1152 + AFA_COMM_ADAPTER *Adapter;
1153 + PFIB_CONTEXT cmd_fibcontext;
1155 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1156 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1158 + // Get block address and transfer length
1159 + if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1161 + cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1163 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1164 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1165 + scsi_cmnd_ptr->cmnd[3];
1166 + count = scsi_cmnd_ptr->cmnd[4];
1173 + cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1175 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1176 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1178 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1180 + cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1182 + //-------------------------------------------------------------------------
1183 + // Alocate and initialize a Fib
1184 + // Setup BlockRead command
1185 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1187 + cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1188 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1189 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1193 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1195 + BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1196 + BlockReadDisk->Command = VM_CtBlockRead;
1197 + BlockReadDisk->ContainerId = ContainerId;
1198 + BlockReadDisk->BlockNumber = lba;
1199 + BlockReadDisk->ByteCount = count * 512;
1200 + BlockReadDisk->SgMap.SgCount = 1;
1202 + if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1204 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1205 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1207 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1208 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1214 + //-------------------------------------------------------------------------
1215 + // Build Scatter/Gather list
1217 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1219 + struct scatterlist *scatterlist_ptr;
1222 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1225 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1227 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1228 + ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1229 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1230 + scatterlist_ptr[segment].length;
1232 +#ifdef DEBUG_SGBUFFER
1233 + memset( scatterlist_ptr[segment].address, 0xa5,
1234 + scatterlist_ptr[segment].length );
1237 + byte_count += scatterlist_ptr[segment].length;
1239 + if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1241 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1242 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1244 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1245 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1251 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1253 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1254 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1257 + BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1259 + if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1261 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1262 + MAX_DRIVER_SG_SEGMENT_COUNT );
1263 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1267 + else // one piece of contiguous phys mem
1269 + BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1270 + ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1271 + BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1273 + byte_count = scsi_cmnd_ptr->request_bufflen;
1275 + if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1277 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1278 + cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1279 + cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1280 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1282 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1283 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1290 + if( byte_count != BlockReadDisk->ByteCount )
1291 + cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1293 + //-------------------------------------------------------------------------
1294 + // Now send the Fib to the adapter
1296 + FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1300 + // This path shouldn't ever get executed with the current driver
1301 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1311 + BlockReadResponse = ( PBLOCKREADRESPONSE )
1312 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1314 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1315 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1317 + if( BlockReadResponse->Status != ST_OK )
1319 + cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1320 + BlockReadResponse->Status );
1321 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1323 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1324 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1327 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1331 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1333 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1338 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1345 + ( PFIB_CALLBACK )AacHba_ReadCallback,
1346 + ( void *)scsi_cmnd_ptr );
1348 + // Check that the command queued to the controller
1349 + if (Status != STATUS_PENDING) {
1350 + cmn_err( CE_WARN, "AacHba_DoScsiRead: SendFib failed with status: %d\n",
1353 + // For some reason, the Fib didn't queue, return QUEUE_FULL
1354 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1358 + // don't call done func here
1363 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1365 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1366 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1372 +/*------------------------------------------------------------------------------
1373 + AacHba_DoScsiWrite()
1375 + Handles SCSI WRITE requests
1379 + Returns 0 on success, -1 on failure
1380 + *----------------------------------------------------------------------------*/
1381 +int AacHba_DoScsiWrite(
1382 + Scsi_Cmnd *scsi_cmnd_ptr,
1385 +/*----------------------------------------------------------------------------*/
1389 + u_long byte_count;
1392 + PBLOCKWRITE BlockWriteDisk;
1393 + PBLOCKWRITERESPONSE BlockWriteResponse;
1395 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1396 + AFA_COMM_ADAPTER *Adapter;
1397 + PFIB_CONTEXT cmd_fibcontext;
1399 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1400 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1402 + // Get block address and transfer length
1403 + if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1405 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1406 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1407 + scsi_cmnd_ptr->cmnd[3];
1408 + count = scsi_cmnd_ptr->cmnd[4];
1415 + cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1417 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1418 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1420 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1423 + cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1425 + //-------------------------------------------------------------------------
1426 + // Alocate and initialize a Fib
1427 + // Setup BlockWrite command
1428 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1430 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1431 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1432 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1436 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1438 + BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1439 + BlockWriteDisk->Command = VM_CtBlockWrite;
1440 + BlockWriteDisk->ContainerId = ContainerId;
1441 + BlockWriteDisk->BlockNumber = lba;
1442 + BlockWriteDisk->ByteCount = count * 512;
1443 + BlockWriteDisk->SgMap.SgCount = 1;
1446 + if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1448 + struct scatterlist *scatterlist_ptr;
1450 + scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1452 + cmn_err( CE_WARN, "\n");
1453 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request is larger than 64K");
1454 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1455 +/* cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1456 +/* cmn_err( CE_WARN, "Dump SG Element Size..."); */
1457 +/* for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) */
1459 +/* cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1461 +/* cmn_err (CE_WARN, "\n"); */
1463 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1465 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1466 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1472 + //-------------------------------------------------------------------------
1473 + // Build Scatter/Gather list
1475 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1477 + struct scatterlist *scatterlist_ptr;
1480 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1483 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1485 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1486 + ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1487 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1488 + scatterlist_ptr[segment].length;
1490 + byte_count += scatterlist_ptr[segment].length;
1492 + if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1494 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1495 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1497 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1498 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1505 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1507 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1508 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1511 + BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1513 + if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1515 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1516 + MAX_DRIVER_SG_SEGMENT_COUNT );
1517 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1521 + else // one piece of contiguous phys mem
1523 + BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1524 + ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1525 + BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1527 + byte_count = scsi_cmnd_ptr->request_bufflen;
1529 + if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1531 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1533 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1534 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1535 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1542 + if( byte_count != BlockWriteDisk->ByteCount )
1543 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1545 + //-------------------------------------------------------------------------
1546 + // Now send the Fib to the adapter
1548 + FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1552 + // This path shouldn't ever get executed with the current driver
1553 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1563 + BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1564 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1566 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1567 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1569 + if( BlockWriteResponse->Status != ST_OK )
1571 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1572 + BlockWriteResponse->Status );
1573 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1574 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1575 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1577 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1581 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1583 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1588 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1595 + ( PFIB_CALLBACK )AacHba_WriteCallback,
1596 + ( void * )scsi_cmnd_ptr );
1598 + // Check that the command queued to the controller
1599 + if (Status != STATUS_PENDING) {
1600 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: SendFib failed with status: %d\n",
1603 + // For some reason, the Fib didn't queue, return QUEUE_FULL
1604 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1608 + // don't call done func here - it should be called by the WriteCallback
1613 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1615 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1616 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1622 +/*------------------------------------------------------------------------------
1623 + AacHba_ReadCallback()
1624 + *----------------------------------------------------------------------------*/
1625 +void AacHba_ReadCallback(
1627 + PFIB_CONTEXT FibContext,
1629 +/*----------------------------------------------------------------------------*/
1631 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1632 + AFA_COMM_ADAPTER *Adapter;
1633 + BLOCKREADRESPONSE *BlockReadResponse;
1634 + Scsi_Cmnd * scsi_cmnd_ptr;
1638 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1640 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1641 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1643 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1645 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1646 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1647 + scsi_cmnd_ptr->cmnd[3];
1648 + cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1650 + if( FibContext == 0 )
1652 + cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1653 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1654 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1658 + BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1660 + if ( BlockReadResponse->Status == ST_OK )
1661 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1664 + cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1665 + BlockReadResponse->Status );
1666 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1667 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1668 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1672 +#ifdef DEBUG_SGBUFFER
1673 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1675 + struct scatterlist *scatterlist_ptr;
1676 + int i, segment, count;
1679 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1681 + for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1684 + ptr = scatterlist_ptr[segment].address;
1685 + for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1687 + if( *( ptr++ ) == 0xa5 )
1690 + if( count == scatterlist_ptr[segment].length )
1691 + cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1697 + Adapter->CommFuncs.CompleteFib( FibContext );
1698 + Adapter->CommFuncs.FreeFib( FibContext );
1700 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1703 +/*------------------------------------------------------------------------------
1704 + AacHba_WriteCallback()
1705 + *----------------------------------------------------------------------------*/
1706 +void AacHba_WriteCallback(
1708 + PFIB_CONTEXT FibContext,
1710 +/*----------------------------------------------------------------------------*/
1712 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1713 + AFA_COMM_ADAPTER *Adapter;
1714 + BLOCKWRITERESPONSE *BlockWriteResponse;
1715 + Scsi_Cmnd *scsi_cmnd_ptr;
1719 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1721 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1722 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1724 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1726 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1727 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1728 + scsi_cmnd_ptr->cmnd[3];
1729 + cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1730 + if( FibContext == 0 )
1732 + cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1733 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1734 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1738 + BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1739 + if (BlockWriteResponse->Status == ST_OK)
1740 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1743 + cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1744 + BlockWriteResponse->Status );
1745 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1746 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1747 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1751 + Adapter->CommFuncs.CompleteFib( FibContext );
1752 + Adapter->CommFuncs.FreeFib( FibContext );
1754 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1758 +/*------------------------------------------------------------------------------
1761 + Handle IOCTL requests
1765 + *----------------------------------------------------------------------------*/
1767 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1770 +/*----------------------------------------------------------------------------*/
1772 + Sa_ADAPTER_EXTENSION *AdapterExtension;
1773 + AFA_IOCTL_CMD IoctlCmd;
1776 + AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1778 + cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1781 + case FSACTL_SENDFIB:
1782 + cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1785 + case FSACTL_AIF_THREAD:
1786 + cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1789 + case FSACTL_NULL_IO_TEST:
1790 + cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1793 + case FSACTL_SIM_IO_TEST:
1794 + cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1797 + case FSACTL_GET_FIBTIMES:
1798 + cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1801 + case FSACTL_ZERO_FIBTIMES:
1802 + cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1805 + case FSACTL_GET_VAR:
1806 + cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1809 + case FSACTL_SET_VAR:
1810 + cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1813 + case FSACTL_OPEN_ADAPTER_CONFIG:
1814 + cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1817 + case FSACTL_CLOSE_ADAPTER_CONFIG:
1818 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1821 + case FSACTL_QUERY_ADAPTER_CONFIG:
1822 + cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1825 + case FSACTL_OPEN_GET_ADAPTER_FIB:
1826 + cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1829 + case FSACTL_GET_NEXT_ADAPTER_FIB:
1830 + cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1833 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
1834 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1837 + case FSACTL_MINIPORT_REV_CHECK:
1838 + cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1841 + case FSACTL_OPENCLS_COMM_PERF_DATA:
1842 + cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1845 + case FSACTL_GET_COMM_PERF_DATA:
1846 + cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1849 + case FSACTL_QUERY_DISK:
1850 + cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1853 + case FSACTL_DELETE_DISK:
1854 + cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1858 + cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1861 + IoctlCmd.cmd = cmd;
1862 + IoctlCmd.arg = ( intptr_t )arg;
1863 + IoctlCmd.flag = 0;
1864 + IoctlCmd.cred_p = 0;
1865 + IoctlCmd.rval_p = 0;
1867 + status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1868 + cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1873 +/*------------------------------------------------------------------------------
1874 + AacHba_AdapterDeviceControl()
1878 + Returns TRUE if ioctl handled, FALSE otherwise
1879 + *ReturnStatus set to completion status
1880 + *----------------------------------------------------------------------------*/
1881 +BOOLEAN AacHba_AdapterDeviceControl (
1882 + PVOID AdapterArg, // CommonExtensionPtr
1883 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
1884 + OUT int * ReturnStatus )
1885 +/*----------------------------------------------------------------------------*/
1887 + BOOLEAN Handled = TRUE; // start out handling it.
1888 + int Status = EFAULT;
1890 + switch( IoctlCmdPtr->cmd )
1892 + case FSACTL_QUERY_DISK:
1893 + Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1896 + case FSACTL_DELETE_DISK:
1897 + Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1900 + case FSACTL_FORCE_DELETE_DISK:
1901 + Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1905 + if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1914 + *ReturnStatus = Status;
1916 + return( Handled );
1920 +/*------------------------------------------------------------------------------
1921 + AacHba_QueryDisk()
1926 + -EFAULT = Bad address
1927 + -EINVAL = Bad container number
1928 + *----------------------------------------------------------------------------*/
1929 +int AacHba_QueryDisk(
1930 + PVOID AdapterArg, // CommonExtensionPtr
1931 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
1932 +/*----------------------------------------------------------------------------*/
1934 + UNIX_QUERY_DISK QueryDisk;
1935 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1936 + fsadev_t *fsa_dev_ptr;
1938 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1939 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1941 + if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1942 + return( -EFAULT );
1944 + if (QueryDisk.ContainerNumber == -1)
1945 + QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1947 + if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1949 + if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1950 + return( -EINVAL );
1952 + QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1953 + QueryDisk.Bus = 0;
1954 + QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1955 + QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1958 + return( -EINVAL );
1960 + QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1961 + QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1962 + QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1964 + if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1965 + QueryDisk.UnMapped = TRUE;
1967 + QueryDisk.UnMapped = FALSE;
1969 + get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1970 + QueryDisk.diskDeviceName );
1972 + if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1973 + return( -EFAULT );
1979 +/*------------------------------------------------------------------------------
1981 + *----------------------------------------------------------------------------*/
1982 +static void get_sd_devname(
1985 +/*----------------------------------------------------------------------------*/
1989 + sprintf(buffer, "%s", "");
1993 + if( disknum < 26 )
1994 + sprintf(buffer, "sd%c", 'a' + disknum);
1996 + unsigned int min1;
1997 + unsigned int min2;
1999 + * For larger numbers of disks, we need to go to a new
2002 + min1 = disknum / 26;
2003 + min2 = disknum % 26;
2004 + sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
2009 +/*------------------------------------------------------------------------------
2010 + AacHba_ForceDeleteDisk()
2015 + -EFAULT = Bad address
2016 + -EINVAL = Bad container number
2017 + *----------------------------------------------------------------------------*/
2018 +int AacHba_ForceDeleteDisk(
2019 + PVOID AdapterArg, // CommonExtensionPtr
2020 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
2021 +/*----------------------------------------------------------------------------*/
2023 + DELETE_DISK DeleteDisk;
2024 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2025 + fsadev_t *fsa_dev_ptr;
2027 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2028 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2030 + if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2031 + return( -EFAULT );
2033 + if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2034 + return( -EINVAL );
2036 + // Mark this container as being deleted.
2037 + fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
2039 + // Mark the container as no longer valid
2040 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2046 +/*------------------------------------------------------------------------------
2047 + AacHba_DeleteDisk()
2052 + -EFAULT = Bad address
2053 + -EINVAL = Bad container number
2054 + -EBUSY = Device locked
2055 + *----------------------------------------------------------------------------*/
2056 +int AacHba_DeleteDisk(
2058 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
2059 +/*----------------------------------------------------------------------------*/
2061 + DELETE_DISK DeleteDisk;
2062 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2063 + fsadev_t *fsa_dev_ptr;
2065 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2066 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2068 + if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2069 + return( -EFAULT );
2071 + if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2072 + return( -EINVAL );
2074 + // If the container is locked, it can not be deleted by the API.
2075 + if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2079 + // Mark the container as no longer being valid.
2080 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2081 + fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2087 +/*------------------------------------------------------------------------------
2088 + AacHba_OpenAdapter()
2089 + *----------------------------------------------------------------------------*/
2090 +AAC_STATUS AacHba_OpenAdapter(
2091 + IN PVOID AdapterArg )
2092 +/*----------------------------------------------------------------------------*/
2094 + return( STATUS_SUCCESS );
2098 +/*------------------------------------------------------------------------------
2099 + AacHba_CloseAdapter()
2100 + *----------------------------------------------------------------------------*/
2101 +AAC_STATUS AacHba_CloseAdapter(
2102 + IN PVOID AdapterArg )
2103 +/*----------------------------------------------------------------------------*/
2105 + return( STATUS_SUCCESS );
2109 +/*------------------------------------------------------------------------------
2110 + AacHba_DetachAdapter()
2111 + *----------------------------------------------------------------------------*/
2112 +void AacHba_DetachAdapter(
2113 + IN PVOID AdapterArg )
2114 +/*----------------------------------------------------------------------------*/
2116 + AacCommDetachAdapter( AdapterArg );
2120 +/*------------------------------------------------------------------------------
2121 + AacHba_AbortScsiCommand()
2122 + *----------------------------------------------------------------------------*/
2123 +void AacHba_AbortScsiCommand(
2124 + Scsi_Cmnd *scsi_cmnd_ptr )
2125 +/*----------------------------------------------------------------------------*/
2127 + u_short interrupt_status;
2128 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2130 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2131 + interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2133 + cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2135 + if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2136 + cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2139 + if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2140 + cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2143 + if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2144 + cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2147 + if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2148 + cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2154 +/*------------------------------------------------------------------------------
2155 + AacHba_HandleAif()
2156 + *----------------------------------------------------------------------------*/
2157 +BOOLEAN AacHba_HandleAif(
2158 + IN PVOID AdapterArg,
2159 + IN PFIB_CONTEXT FibContext )
2160 +/*----------------------------------------------------------------------------*/
2166 +/*------------------------------------------------------------------------------
2167 + AacHba_SetSenseData()
2168 + Fill in the sense data.
2171 + *----------------------------------------------------------------------------*/
2172 +void AacHba_SetSenseData(
2175 + unchar sense_code,
2176 + unchar a_sense_code,
2177 + unchar incorrect_length,
2178 + unchar bit_pointer,
2179 + unsigned field_pointer,
2180 + unsigned long residue )
2181 +/*----------------------------------------------------------------------------*/
2183 + sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2184 + sense_buf[1] = 0; // Segment number, always zero
2186 + if( incorrect_length )
2188 + sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2189 + sense_buf[3] = BYTE3(residue);
2190 + sense_buf[4] = BYTE2(residue);
2191 + sense_buf[5] = BYTE1(residue);
2192 + sense_buf[6] = BYTE0(residue);
2195 + sense_buf[2] = sense_key; // Sense key
2197 + if( sense_key == SENKEY_ILLEGAL )
2198 + sense_buf[7] = 10; // Additional sense length
2200 + sense_buf[7] = 6; // Additional sense length
2202 + sense_buf[12] = sense_code; // Additional sense code
2203 + sense_buf[13] = a_sense_code; // Additional sense code qualifier
2204 + if( sense_key == SENKEY_ILLEGAL )
2206 + sense_buf[15] = 0;
2208 + if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2209 + sense_buf[15] = 0x80; // Std sense key specific field
2210 + // Illegal parameter is in the parameter block
2212 + if( sense_code == SENCODE_INVALID_CDB_FIELD )
2213 + sense_buf[15] = 0xc0; // Std sense key specific field
2214 + // Illegal parameter is in the CDB block
2215 + sense_buf[15] |= bit_pointer;
2216 + sense_buf[16] = field_pointer >> 8; // MSB
2217 + sense_buf[17] = field_pointer; // LSB
2221 diff -burN linux-2.4.9/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2222 --- linux-2.4.9/drivers/scsi/aacraid/aacid.c Wed Dec 31 18:00:00 1969
2223 +++ linux/drivers/scsi/aacraid/aacid.c Thu Aug 16 18:10:23 2001
2226 + * Adaptec aacraid device driver for Linux.
2228 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2230 + * This program is free software; you can redistribute it and/or modify
2231 + * it under the terms of the GNU General Public License as published by
2232 + * the Free Software Foundation; either version 2, or (at your option)
2233 + * any later version.
2235 + * This program is distributed in the hope that it will be useful,
2236 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2237 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2238 + * GNU General Public License for more details.
2240 + * You should have received a copy of the GNU General Public License
2241 + * along with this program; see the file COPYING. If not, write to
2242 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2247 + * Abstract: Data structures for controller specific info.
2251 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2253 +#include "osheaders.h"
2255 +#include "AacGenericTypes.h"
2257 +#include "aac_unix_defs.h"
2259 +#include "fsatypes.h"
2260 +#include "comstruc.h"
2261 +#include "fsaport.h"
2262 +#include "pcisup.h"
2264 +#include "version.h"
2267 +/* Function Prototypes */
2268 +void InqStrCopy(char *a, char *b); /* ossup.c */
2270 +/* Device name used to register and unregister
2271 + the device in linit.c */
2272 +char devicestr[]="aac";
2274 +char *container_types[] = {
2293 +/* Local Structure to set SCSI inquiry data strings */
2294 +typedef struct _INQSTR {
2295 + char vid[8]; /* Vendor ID */
2296 + char pid[16]; /* Product ID */
2297 + char prl[4]; /* Product Revision Level */
2298 +} INQSTR, *INQSTRP;
2300 +FSA_MINIPORT MiniPorts[];
2302 +/* Function: SetInqDataStr
2304 + * Arguments: [1] pointer to void [1] int
2306 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2307 + * and revision level. Allows strings to be set in platform dependant
2308 + * files instead of in OS dependant driver source.
2312 + int MiniPortIndex,
2316 + INQSTRP InqStrPtr;
2320 + mp = &MiniPorts[MiniPortIndex];
2322 + InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2324 + InqStrCopy (mp->Vendor, InqStrPtr->vid);
2325 + InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2327 + findit = InqStrPtr->pid;
2329 + for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2332 + if (tindex < (sizeof(container_types)/sizeof(char *))){
2333 + InqStrCopy (container_types[tindex], findit);
2335 + InqStrCopy ("0001", InqStrPtr->prl);
2340 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2341 + IN ULONG AdapterNumber,
2348 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2349 + IN ULONG AdapterNumber,
2356 + * Because of the way Linux names scsi devices, the order in this table has
2357 + * become important. Check for on-board Raid first, add-in cards second.
2360 +FSA_MINIPORT MiniPorts[] = {
2361 + { 0x0000, 0x0000, 0x0000, 0x0000, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell unknown - uses perc_pciid */
2362 + { 0x0000, 0x0000, 0x0000, 0x0000, "aac", RxInitDevice, "aacraid", "ADAPTEC ", "AACRAID " }, /* unknown - uses rx_pciid */
2363 + { 0x0000, 0x0000, 0x0000, 0x0000, "aac", SaInitDevice, "aacraid", "ADAPTEC ", "AACRAID " }, /* unknown - uses sa_pciid */
2364 + { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 2/Si */
2365 + { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2366 + { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2367 + { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2368 + { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2369 + { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2370 + { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2371 + { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel" */
2372 + { 0x1011, 0x0046, 0x9005, 0x0365, "aac", SaInitDevice, "aacraid", "ADAPTEC ", "Adaptec 5400S " }, /* Adaptec 5400S */
2373 + { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2377 +#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2379 +int NumMiniPorts = NUM_MINIPORTS;
2381 +char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2382 diff -burN linux-2.4.9/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2383 --- linux-2.4.9/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2384 +++ linux/drivers/scsi/aacraid/commctrl.c Thu Aug 16 13:41:30 2001
2387 + * Adaptec aacraid device driver for Linux.
2389 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2391 + * This program is free software; you can redistribute it and/or modify
2392 + * it under the terms of the GNU General Public License as published by
2393 + * the Free Software Foundation; either version 2, or (at your option)
2394 + * any later version.
2396 + * This program is distributed in the hope that it will be useful,
2397 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2398 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2399 + * GNU General Public License for more details.
2401 + * You should have received a copy of the GNU General Public License
2402 + * along with this program; see the file COPYING. If not, write to
2403 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2408 + * Abstract: Contains all routines for control of the AFA comm layer
2412 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2414 +#include "comprocs.h"
2415 +#include "osheaders.h"
2416 +#include "ostypes.h"
2422 +typedef BOOLEAN BOOL;
2423 +#define inline /* _inline */
2425 +#include <revision.h>
2427 +FsaCtlCheckRevision(
2428 + IN PAFA_COMM_ADAPTER Adapter,
2429 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2433 +Routine Description:
2435 + This routine validates the revision of the caller with the current revision
2436 + of the filesystem.
2440 + Adapter - Supplies which adapter is being processed.
2442 + Irp - Supplies the Irp being processed.
2444 + IrpContext - Supplies the IrpContext.
2453 + RevCheck APIRevCheck;
2454 + RevCheckResp APIRevCheckResp;
2455 + RevComponent APICallingComponent;
2456 + ULONG APIBuildNumber;
2458 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2462 + APICallingComponent = APIRevCheck.callingComponent;
2463 + APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2465 + APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2467 + APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2468 + APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2470 + if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2479 +AfaCommAdapterDeviceControl(
2480 + IN PVOID AdapterArg,
2481 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2484 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2485 + int Status = ENOTTY;
2486 +// PIO_STACK_LOCATION IrpSp;
2487 + PAFA_CLASS_DRIVER ClassDriver;
2490 + // First loop through all of the class drivers to give them a chance to handle
2491 + // the Device control first.
2494 + ClassDriver = Adapter->ClassDriverList;
2496 + while (ClassDriver) {
2498 + if (ClassDriver->DeviceControl) {
2500 + if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2507 + ClassDriver = ClassDriver->Next;
2510 + switch (IoctlCmdPtr->cmd) {
2513 + case FSACTL_SENDFIB:
2515 + Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2518 + case FSACTL_AIF_THREAD:
2520 + Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2524 + case FSACTL_OPEN_GET_ADAPTER_FIB:
2526 + Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2529 + case FSACTL_GET_NEXT_ADAPTER_FIB:
2531 + Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2534 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
2536 + Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2539 + case FSACTL_MINIPORT_REV_CHECK:
2541 + Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2557 +AfaCommRegisterNewClassDriver(
2558 + IN PAFA_COMM_ADAPTER Adapter,
2559 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2560 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2564 +Routine Description:
2566 + This routine registers a new class driver for the comm layer.
2568 + It will return a pointer to the communication functions for the class driver
2573 + Adapter - Supplies which adapter is being processed.
2575 + Irp - Supplies the Irp being processed.
2579 + STATUS_SUCCESS - Everything OK.
2583 + AAC_STATUS Status;
2584 + PAFA_CLASS_DRIVER ClassDriver;
2587 + ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2589 + if (ClassDriver == NULL) {
2591 + Status = STATUS_INSUFFICIENT_RESOURCES;
2597 + // If the class driver has sent in user Vars, then copy them into the global
2601 + if (NewClassDriver->NumUserVars) {
2603 + PFSA_USER_VAR NewUserVars;
2605 + NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2606 + NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2609 + // First copy the existing into the new area.
2612 + RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2615 + // Next copy the new vars passed in from class driver.
2618 + RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2619 + NewClassDriver->UserVars,
2620 + NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2623 + // Free up the old user vars.
2626 + OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2629 + // Point the global to the new area.
2632 + FsaCommData.UserVars = NewUserVars;
2635 + // Update the total count.
2638 + FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2642 + ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2643 + ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2644 + ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2645 + ClassDriver->HandleAif = NewClassDriver->HandleAif;
2646 + ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2648 + ClassDriver->Next = Adapter->ClassDriverList;
2649 + Adapter->ClassDriverList = ClassDriver;
2652 + // Now return the information needed by the class driver to communicate to us.
2655 + NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2656 + NewClassDriverResponse->CommPortExtension = Adapter;
2657 + NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2658 + NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2659 + NewClassDriverResponse->Dip = Adapter->Dip;
2661 + return (STATUS_SUCCESS);
2668 + IN PAFA_COMM_ADAPTER Adapter,
2669 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2673 +Routine Description:
2675 + This routine sends a fib to the adapter on behalf of a user level
2680 + Adapter - Supplies which adapter is being processed.
2682 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2686 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2688 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2690 + STATUS_SUCCESS - Everything OK.
2695 +// PMDL DmaMdl = NULL;
2696 + PCOMM_FIB_CONTEXT FibContext;
2697 + PSGMAP_CONTEXT SgMapContext;
2698 + SGMAP_CONTEXT _SgMapContext;
2699 + QUEUE_TYPES WhichQueue;
2700 + PVOID UsersAddress;
2701 + AAC_STATUS Status;
2703 + FibContext = AllocateFib( Adapter );
2705 + KFib = FibContext->Fib;
2708 + // First copy in the header so that we can check the size field.
2711 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2712 + FreeFib( FibContext );
2718 + // Since we copy based on the fib header size, make sure that we
2719 + // will not overrun the buffer when we copy the memory. Return
2720 + // an error if we would.
2723 + if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2724 + FreeFib( FibContext );
2730 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2731 + FreeFib( FibContext );
2736 + WhichQueue = AdapNormCmdQueue;
2739 + if (KFib->Header.Command == TakeABreakPt) {
2741 + InterruptAdapter(Adapter);
2744 + // Since we didn't really send a fib, zero out the state to allow
2745 + // cleanup code not to assert.
2748 + KFib->Header.XferState = 0;
2753 + if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2754 + TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2755 + FsaCommPrint("User SendFib failed!.\n");
2758 + FreeFib( FibContext );
2762 + if (CompleteFib(FibContext) != FSA_SUCCESS) {
2763 + FsaCommPrint("User Complete FIB failed.\n");
2765 + FreeFib( FibContext );
2774 + // Make sure that the size returned by the adapter (which includes
2775 + // the header) is less than or equal to the size of a fib, so we
2776 + // don't corrupt application data. Then copy that size to the user
2777 + // buffer. (Don't try to add the header information again, since it
2778 + // was already included by the adapter.)
2780 + ASSERT(KFib->Header.Size <= sizeof(FIB));
2782 + if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2783 + FreeFib( FibContext );
2788 + FreeFib( FibContext );
2795 +AfaCommCtlAifThread(
2796 + IN PAFA_COMM_ADAPTER Adapter,
2797 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2801 +Routine Description:
2803 + This routine will act as the AIF thread for this adapter.
2807 + Adapter - Supplies which adapter is being processed.
2809 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2813 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2815 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2817 + STATUS_SUCCESS - Everything OK.
2821 + return (NormCommandThread(Adapter));
2826 +#ifdef GATHER_FIB_TIMES
2828 +AfaCommGetFibTimes(
2829 + IN PAFA_COMM_ADAPTER Adapter,
2834 +Routine Description:
2836 + This routine returns the gathered fibtimes to the user.
2840 + Adapter - Supplies which adapter is being processed.
2842 + Irp - Supplies the Irp being processed.
2846 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2848 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2850 + STATUS_SUCCESS - Everything OK.
2854 + PALL_FIB_TIMES AllFibTimes;
2855 + PLARGE_INTEGER FreqPtr;
2856 + PIO_STACK_LOCATION IrpSp;
2859 + // Get a pointer to the current Irp stack location
2862 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2864 + FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2866 + *FreqPtr = Adapter->FibTimesFrequency;
2868 + AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2870 + RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2872 + Irp->IoStatus.Information = 0;
2874 + return (STATUS_SUCCESS);
2879 +AfaCommZeroFibTimes(
2880 + IN PAFA_COMM_ADAPTER Adapter,
2885 +Routine Description:
2887 + This routine zero's the FibTimes structure within the adapter structure.
2891 + Adapter - Supplies which adapter is being processed.
2893 + Irp - Supplies the Irp being processed.
2897 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2899 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2901 + STATUS_SUCCESS - Everything OK.
2905 + PFIB_TIMES FibTimesPtr;
2907 + PIO_STACK_LOCATION IrpSp;
2910 + // Get a pointer to the current Irp stack location
2913 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2916 + // Initialize the Fib timing data structures
2918 + RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2920 + for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2922 + FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2924 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2925 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2926 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2927 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2929 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2931 + FibTimesPtr = &Adapter->FibTimes->Read[i];
2933 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2934 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2935 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2936 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2938 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2940 + FibTimesPtr = &Adapter->FibTimes->Write[i];
2942 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2943 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2944 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2945 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2948 + FibTimesPtr = &Adapter->FibTimes->Other;
2950 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2951 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2952 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2953 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2955 + Irp->IoStatus.Information = 0;
2957 + return (STATUS_SUCCESS);
2960 +#endif // GATHER_FIB_TIMES
2964 +FsaCtlOpenGetAdapterFib(
2965 + IN PAFA_COMM_ADAPTER Adapter,
2966 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2970 +Routine Description:
2972 + This routine will get the next Fib, if available, from the AdapterFibContext
2973 + passed in from the user.
2977 + Adapter - Supplies which adapter is being processed.
2979 + Irp - Supplies the Irp being processed.
2983 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2985 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2987 + STATUS_SUCCESS - Everything OK.
2991 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2993 +// PKEVENT eventObject = (PKEVENT) NULL;
2997 + // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
3000 + AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
3002 + if (AdapterFibContext == NULL) {
3008 + AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
3009 + AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
3013 + // Initialize the conditional variable use to wait for the next AIF.
3016 + OsCv_init( &AdapterFibContext->UserEvent);
3019 + // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
3022 + AdapterFibContext->WaitingForFib = FALSE;
3025 + // Initialize the FibList and set the count of fibs on the list to 0.
3028 + AdapterFibContext->FibCount = 0;
3029 + InitializeListHead(&AdapterFibContext->FibList);
3032 + // Overload FileObject with a time stamp.
3034 + AdapterFibContext->FileObject = (void *)OsGetSeconds();
3037 + // Now add this context onto the adapter's AdapterFibContext list.
3040 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3042 + InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
3044 + OsCvLockRelease(Adapter->AdapterFibMutex);
3046 + if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
3047 + IoctlCmdPtr->flag )) {
3063 +FsaCtlGetNextAdapterFib(
3064 + IN PAFA_COMM_ADAPTER Adapter,
3065 + IN PAFA_IOCTL_CMD IoctlCmdPtr
3069 +Routine Description:
3071 + This routine will get the next Fib, if available, from the AdapterFibContext
3072 + passed in from the user.
3076 + Adapter - Supplies which adapter is being processed.
3078 + Irp - Supplies the Irp being processed.
3082 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3084 + STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3086 + STATUS_SUCCESS - Everything OK.
3090 + GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3091 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3094 + PLIST_ENTRY Entry;
3097 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3098 + sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3103 + // Extract the AdapterFibContext from the Input parameters.
3106 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3109 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3111 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3112 + // this is a valid address
3115 + Entry = Adapter->AdapterFibContextList.Flink;
3117 + while ( Entry != &Adapter->AdapterFibContextList ) {
3118 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3119 + if ( AdapterFibContext == aifcp ) { // We found a winner
3123 + Entry = Entry->Flink;
3126 + if ( found == 0 ) {
3127 + return ( EINVAL );;
3130 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3131 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3133 + return ( EINVAL );
3137 + Status = STATUS_SUCCESS;
3139 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3142 + // If there are no fibs to send back, then either wait or return EAGAIN
3146 + if (!IsListEmpty(&AdapterFibContext->FibList)) {
3148 + PLIST_ENTRY Entry;
3151 + // Pull the next fib from the FibList
3153 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3155 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3157 + AdapterFibContext->FibCount--;
3159 + if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3161 + OsCvLockRelease( Adapter->AdapterFibMutex );
3162 + OsFreeMemory( Fib, sizeof(Fib) );
3168 + // Free the space occupied by this copy of the fib.
3171 + OsFreeMemory(Fib, sizeof(FIB));
3176 + // Overload FileObject with a time stamp
3178 + AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3182 + if (AdapterFibIoctl.Wait) {
3184 + if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3200 + OsCvLockRelease( Adapter->AdapterFibMutex );
3206 +FsaCtlCloseGetAdapterFib(
3207 + IN PAFA_COMM_ADAPTER Adapter,
3208 + IN PAFA_IOCTL_CMD IoctlCmdPtr
3212 +Routine Description:
3214 + This routine will close down the AdapterFibContext passed in from the user.
3218 + Adapter - Supplies which adapter is being processed.
3220 + Irp - Supplies the Irp being processed.
3224 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3226 + STATUS_SUCCESS - Everything OK.
3230 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3231 + AAC_STATUS Status;
3233 + PLIST_ENTRY Entry;
3237 + // Extract the AdapterFibContext from the Input parameters
3240 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3242 + if (AdapterFibContext == 0) {
3243 + cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3248 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3250 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3251 + // this is a valid address
3254 + Entry = Adapter->AdapterFibContextList.Flink;
3256 + while ( Entry != &Adapter->AdapterFibContextList ) {
3257 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3258 + if ( AdapterFibContext == aifcp ) { // We found a winner
3262 + Entry = Entry->Flink;
3265 + if ( found == 0 ) {
3266 + return ( 0 ); // Already Gone
3269 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3270 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3276 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3278 + Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3280 + OsCvLockRelease(Adapter->AdapterFibMutex);
3286 +FsaCloseAdapterFibContext(
3287 + IN PAFA_COMM_ADAPTER Adapter,
3288 + IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3295 + // First free any FIBs that have not been consumed yet.
3298 + while (!IsListEmpty(&AdapterFibContext->FibList)) {
3300 + PLIST_ENTRY Entry;
3303 + // Pull the next fib from the FibList
3306 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3308 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3310 + AdapterFibContext->FibCount--;
3313 + // Free the space occupied by this copy of the fib.
3316 + OsFreeMemory(Fib, sizeof(FIB));
3320 + // Remove the Context from the AdapterFibContext List
3323 + RemoveEntryList(&AdapterFibContext->NextContext);
3325 + OsCv_destroy( &AdapterFibContext->UserEvent );
3328 + // Invalidate context
3331 + AdapterFibContext->NodeTypeCode = 0;
3334 + // Free the space occupied by the Context
3337 + OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3339 + Status = STATUS_SUCCESS;
3346 +AfaCommOpenAdapter(
3351 +Routine Description:
3353 + The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3356 + The main purpose of this routine is to set up any data structures that may be needed
3357 + to handle any requests made on this DeviceObject.
3361 + Adapter - Pointer to which adapter miniport was opened.
3371 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3372 + AAC_STATUS Status = STATUS_SUCCESS;
3373 + PAFA_CLASS_DRIVER ClassDriver;
3375 + ClassDriver = Adapter->ClassDriverList;
3377 + while (ClassDriver) {
3379 + if (ClassDriver->OpenAdapter) {
3381 + Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3383 + if (Status != STATUS_SUCCESS)
3387 + ClassDriver = ClassDriver->Next;
3390 + return ( Status );
3394 +AfaCommCloseAdapter(
3399 +Routine Description:
3401 + This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3404 + The main purpose of this routine is to cleanup any data structures that have been set up
3405 + while this FileObject has been opened.
3407 + This routine loops through all of the AdapterFibContext structures to determine if any need
3408 + to be deleted for this FileObject.
3412 + Adapter - Pointer to adapter miniport
3414 + Irp - Pointer to Irp that caused this close
3418 + Status value returned from File system driver AdapterClose
3422 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3423 + PLIST_ENTRY Entry, NextEntry;
3424 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3425 + AAC_STATUS Status = STATUS_SUCCESS;
3426 + PAFA_CLASS_DRIVER ClassDriver;
3428 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3430 + Entry = Adapter->AdapterFibContextList.Flink;
3433 + // Loop through all of the AdapterFibContext, looking for any that
3434 + // were created with the FileObject that is being closed.
3436 + while (Entry != &Adapter->AdapterFibContextList) {
3439 + // Extract the AdapterFibContext
3441 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3444 + // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3446 + NextEntry = Entry->Flink;
3448 + Entry = NextEntry;
3452 +#ifdef unix_config_file
3454 + // If this FileObject had the adapter open for configuration, then release it.
3456 + if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3458 + Adapter->AdapterConfigFileObject = NULL;
3463 + OsCvLockRelease(Adapter->AdapterFibMutex);
3465 + ClassDriver = Adapter->ClassDriverList;
3467 + while (ClassDriver) {
3469 + if (ClassDriver->CloseAdapter) {
3471 + Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3473 + if (Status != STATUS_SUCCESS)
3477 + ClassDriver = ClassDriver->Next;
3480 + return ( Status );
3484 diff -burN linux-2.4.9/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3485 --- linux-2.4.9/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3486 +++ linux/drivers/scsi/aacraid/comminit.c Thu Aug 16 13:41:30 2001
3489 + * Adaptec aacraid device driver for Linux.
3491 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3493 + * This program is free software; you can redistribute it and/or modify
3494 + * it under the terms of the GNU General Public License as published by
3495 + * the Free Software Foundation; either version 2, or (at your option)
3496 + * any later version.
3498 + * This program is distributed in the hope that it will be useful,
3499 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3500 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3501 + * GNU General Public License for more details.
3503 + * You should have received a copy of the GNU General Public License
3504 + * along with this program; see the file COPYING. If not, write to
3505 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3510 + * Abstract: This supports the initialization of the host adapter commuication interface.
3511 + * This is a platform dependent module for the pci cyclone board.
3515 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3517 +#include "comprocs.h"
3519 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3522 +AfaCommBugcheckHandler(
3528 +ThrottlePeriodEndDpcRtn(
3530 + IN PVOID DeferredContext,
3531 + IN PVOID SystemArgument1,
3532 + IN PVOID SystemArgument2);
3534 +FSA_COMM_DATA FsaCommData;
3537 +HardInterruptModeration1Changed(
3538 + IN PVOID AdapterContext,
3542 + PAFA_COMM_ADAPTER Adapter = AdapterContext;
3545 + // If we are using interrupt moderation, then disable the interrupt
3546 + // until we need to use it.
3548 + if (FsaCommData.HardInterruptModeration1)
3549 + DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3551 + EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3553 + return (STATUS_SUCCESS);
3557 +FsaFibTimeoutChanged(
3558 + IN PVOID AdapterContext,
3563 + // scale the new timeout from seconds to 100 nsec units
3565 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3567 + return (STATUS_SUCCESS);
3570 +#ifdef GATHER_FIB_TIMES
3571 +extern int GatherFibTimes;
3574 +FSA_USER_VAR FsaCommUserVars[] = {
3575 +#ifdef FIB_CHECKSUMS
3576 + { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3578 +#ifdef GATHER_FIB_TIMES
3579 + { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3581 + { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3582 + { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3583 + { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3584 + { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3585 + { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3586 + { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3587 + { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3588 + { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3589 + { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3590 + { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3593 +#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3597 +AacCommDriverEntry(
3602 +Routine Description:
3604 + This is the initialization routine for the FileArray Comm layer device driver.
3608 + DriverObject - Pointer to driver object created by the system.
3612 + AAC_STATUS - The function value is the final status from the initialization
3618 + AAC_STATUS Status;
3619 + PVOID BugCheckBuffer;
3621 + RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3625 + // Load the global timeout value for the adapter timeout
3626 + // Also init the global that enables or disables adapter timeouts
3629 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3631 + FsaCommData.FibTimeoutSeconds = 180;
3633 + FsaCommData.EnableAdapterTimeouts = TRUE;
3635 +// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3637 +#ifdef unix_fib_timeout
3638 + FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3641 + FsaCommData.EnableInterruptModeration = FALSE;
3644 + // Preload UserVars with all variables from the comm layer. The class layers will
3645 + // include theirs when they register.
3648 + FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3649 + FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3651 + RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3656 + // Call the disk driver to initialize itself.
3659 + AacDiskDriverEntry();
3665 + return (STATUS_SUCCESS);
3671 + IN PAFA_COMM_ADAPTER Adapter,
3672 + IN OUT PCOMM_QUE Queue,
3673 + IN QUEUE_TYPES WhichQueue
3677 +Routine Description:
3679 + This routine will release all of the resources used by a given queue.
3683 + Adapter - Which adapter the queue belongs to
3684 + Queue - Pointer to the queue itself
3685 + WhichQueue - Identifies which of the host queues this is.
3693 + switch (WhichQueue) {
3695 + case HostNormCmdQueue:
3697 + Os_remove_softintr( Queue->ConsumerRoutine );
3698 + OsSpinLockDestroy( Queue->QueueLock );
3699 + OsCv_destroy( &Queue->CommandReady );
3703 + case HostHighCmdQueue:
3705 + Os_remove_softintr( Queue->ConsumerRoutine );
3706 + OsSpinLockDestroy( Queue->QueueLock );
3707 + OsCv_destroy( &Queue->CommandReady );
3711 + case HostNormRespQueue:
3713 + Os_remove_softintr( Queue->ConsumerRoutine );
3714 + OsSpinLockDestroy( Queue->QueueLock );
3717 + case HostHighRespQueue:
3719 + Os_remove_softintr( Queue->ConsumerRoutine );
3720 + OsSpinLockDestroy( Queue->QueueLock );
3723 + case AdapNormCmdQueue:
3724 + case AdapHighCmdQueue:
3725 + case AdapNormRespQueue:
3726 + case AdapHighRespQueue:
3727 + OsCv_destroy( &Queue->QueueFull );
3734 + IN PAFA_COMM_ADAPTER Adapter,
3735 + IN OUT PCOMM_QUE Queue,
3736 + IN QUEUE_TYPES WhichQueue
3740 +Routine Description:
3742 + Will initialize all entries in the queue that is NT specific.
3748 + Nothing there is nothing to allocate so nothing should fail
3753 + Queue->NumOutstandingIos = 0;
3756 + // Store a pointer to the adapter structure.
3759 + Queue->Adapter = Adapter;
3761 + InitializeListHead( &Queue->OutstandingIoQueue );
3763 + switch (WhichQueue) {
3765 + case HostNormCmdQueue:
3767 + OsCv_init( &Queue->CommandReady);
3768 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3769 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3770 + NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3771 + (caddr_t)Queue ) != DDI_SUCCESS) {
3773 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3776 + InitializeListHead(&Queue->CommandQueue);
3780 + case HostHighCmdQueue:
3782 + OsCv_init( &Queue->CommandReady);
3783 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3784 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3785 + NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3786 + (caddr_t) Queue ) != DDI_SUCCESS) {
3788 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3791 + InitializeListHead(&Queue->CommandQueue);
3794 + case HostNormRespQueue:
3796 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3797 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3798 + NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3799 + (caddr_t) Queue ) != DDI_SUCCESS) {
3801 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3805 + case HostHighRespQueue:
3808 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3809 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3810 + NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3811 + (caddr_t) Queue ) != DDI_SUCCESS) {
3813 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3817 + case AdapNormCmdQueue:
3818 + case AdapHighCmdQueue:
3819 + case AdapNormRespQueue:
3820 + case AdapHighRespQueue:
3822 + OsCv_init( &Queue->QueueFull);
3828 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3831 +Routine Description:
3833 + Create and start the command receiver threads.
3852 +Routine Description:
3854 + This routine gets called to detach all resources that have been allocated for
3859 + Adapter - Pointer to the adapter structure to detach.
3863 + TRUE - All resources have been properly released.
3864 + FALSE - An error occured while trying to release resources.
3867 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3869 + PAFA_CLASS_DRIVER ClassDriver;
3871 + // First remove this adapter from the list of adapters.
3874 + if (FsaCommData.AdapterList == Adapter) {
3876 + FsaCommData.AdapterList = Adapter->NextAdapter;
3880 + PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3882 + CurrentAdapter = FsaCommData.AdapterList;
3883 + NextAdapter = CurrentAdapter->NextAdapter;
3885 + while (NextAdapter) {
3887 + if (NextAdapter == Adapter) {
3889 + CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3894 + CurrentAdapter = NextAdapter;
3895 + NextAdapter = CurrentAdapter->NextAdapter;
3900 + // First send a shutdown to the adapter.
3903 + AfaCommShutdown( Adapter );
3906 + // Destroy the FibContextZone for this adapter. This will free up all
3907 + // of the fib space used by this adapter.
3910 + FsaFreeFibContextZone( Adapter );
3913 + // Destroy the mutex used for synch'ing adapter fibs.
3916 + OsCvLockDestroy( Adapter->AdapterFibMutex );
3919 + // Detach all of the host queues.
3922 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3923 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3924 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3925 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3926 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3927 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3928 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3929 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3932 + // Destroy the mutex used to protect the FibContextZone
3935 + OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3938 + // Call the miniport to free the space allocated for the shared comm queues
3939 + // between the host and the adapter.
3942 + FsaFreeAdapterCommArea( Adapter );
3945 + // Free the memory used by the comm region for this adapter
3948 + OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3951 + // Free the memory used by the adapter structure.
3953 + ClassDriver = Adapter->ClassDriverList;
3954 + Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3955 + OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3957 + OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3963 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3965 + PVOID BugCheckBuffer;
3966 + PAFA_COMM_ADAPTER Adapter;
3967 + MAPFIB_CONTEXT MapFibContext;
3968 + LARGE_INTEGER Time;
3969 + char ErrorBuffer[60];
3971 + Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3973 + if (Adapter == NULL)
3976 + RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3980 + // Save the current adapter number and increment the total number.
3983 + Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3987 + // Fill in the pointer back to the device specific structures.
3988 + // The device specific driver has also passed a pointer for us to
3989 + // fill in with the Adapter object that we have created.
3992 + Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3993 + Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3994 + Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3995 + Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3996 + Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3998 + Adapter->Dip = NewAdapter->Dip;
4001 + // Fill in Our address into the function dispatch table
4004 + NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
4005 + NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
4006 + NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
4007 + NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
4010 + // Ok now init the communication subsystem
4013 + Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
4014 + if (Adapter->CommRegion == NULL) {
4015 + cmn_err(CE_WARN, "Error could not allocate comm region.\n");
4018 + RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
4021 + // Get a pointer to the iblock_cookie
4024 + ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
4026 + if (!CommInit(Adapter)) {
4027 + FsaCommPrint("Failed to init the commuication subsystem.\n");
4033 + // Initialize the list of AdapterFibContext's.
4036 + InitializeListHead(&Adapter->AdapterFibContextList);
4039 + // Initialize the fast mutex used for synchronization of the adapter fibs
4042 + Adapter->AdapterFibMutex = OsCvLockAlloc();
4043 + OsCvLockInit(Adapter->AdapterFibMutex, NULL);
4046 + // Allocate and start the FSA command threads. These threads will handle
4047 + // command requests from the adapter. They will wait on an event then pull
4048 + // all CDBs off the thread's queue. Each CDB will be given to a worker thread
4049 + // upto a defined limit. When that limit is reached wait a event will be waited
4050 + // on till a worker thread is finished.
4053 + if (!StartFsaCommandThreads(Adapter)) {
4054 + FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4058 +#ifdef unix_crash_dump
4060 + // Allocate and map a fib for use by the synch path, which is used for crash
4063 + // Allocate an entire page so that alignment is correct.
4066 + Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4067 + MapFibContext.Fib = Adapter->SyncFib;
4068 + MapFibContext.Size = sizeof(FIB);
4069 + MapFib( Adapter, &MapFibContext );
4070 + Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4073 + Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4075 + Adapter->CommFuncs.AllocateFib = AllocateFib;
4077 + Adapter->CommFuncs.FreeFib = FreeFib;
4078 + Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4079 + Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4081 + Adapter->CommFuncs.InitializeFib = InitializeFib;
4082 + Adapter->CommFuncs.GetFibData = FsaGetFibData;
4083 + Adapter->CommFuncs.SendFib = SendFib;
4084 + Adapter->CommFuncs.CompleteFib = CompleteFib;
4085 + Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4087 + Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4089 + Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4090 + Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4093 + // Add this adapter in to our Adapter List.
4096 + Adapter->NextAdapter = FsaCommData.AdapterList;
4097 + FsaCommData.AdapterList = Adapter;
4099 + NewAdapter->Adapter = Adapter;
4101 +// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4108 + PAFA_COMM_ADAPTER Adapter
4112 + // Now allocate and initialize the zone structures used as our pool
4113 + // of FIB context records. The size of the zone is based on the
4114 + // system memory size. We also initialize the mutex used to protect
4117 + Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4118 + OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4120 + Adapter->FibContextZoneExtendSize = 64;
4122 + return (STATUS_SUCCESS);
4129 +Routine Description:
4131 + Initializes the data structures that are required for the FSA commuication
4132 + interface to operate.
4136 + None - all global or allocated data.
4140 + TRUE - if we were able to init the commuication interface.
4141 + FALSE - If there were errors initing. This is a fatal error.
4144 +CommInit(PAFA_COMM_ADAPTER Adapter)
4147 + ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4148 + ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4149 + PQUEUE_INDEX Headers;
4150 + PQUEUE_ENTRY Queues;
4152 + PCOMM_REGION CommRegion = Adapter->CommRegion;
4154 + CommInitialize( Adapter );
4156 + FsaCommPrint("CommInit: Queue entry size is 0x%x, Queue index size is 0x%x, Number of total entries is 0x%x, # queues = 0x%x.\n",
4157 + sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4160 + // Allocate the physically contigous space for the commuication queue
4164 + TotalSize = SizeOfHeaders + SizeOfQueues;
4166 + if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4169 + Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4171 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4172 + NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4173 + (caddr_t)CommRegion ) != DDI_SUCCESS) {
4175 + cmn_err(CE_CONT, "Os_addr_intr failed\n");
4179 + // Adapter to Host normal priority Command queue
4182 + CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4183 + CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4184 + *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4185 + *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4187 + CommRegion->HostNormCmdQue.SavedIrql = 0;
4188 + CommRegion->HostNormCmdQue.BaseAddress = Queues;
4189 + CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4191 + CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4192 + if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4195 + InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4198 + Queues += HOST_NORM_CMD_ENTRIES;
4200 + // Adapter to Host high priority command queue
4202 + CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4203 + CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4204 + *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4205 + *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4207 + CommRegion->HostHighCmdQue.SavedIrql = 0;
4208 + CommRegion->HostHighCmdQue.BaseAddress = Queues;
4209 + CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4210 +// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4211 + CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4212 + if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4215 + InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4217 + Queues += HOST_HIGH_CMD_ENTRIES;
4219 + // Host to adapter normal priority command queue
4221 + CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4222 + CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4223 + *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4224 + *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4226 + CommRegion->AdapNormCmdQue.SavedIrql = 0;
4227 + CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4228 + CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4229 + InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4231 + Queues += ADAP_NORM_CMD_ENTRIES;
4233 + // host to adapter high priority command queue
4235 + CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4236 + CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4237 + *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4238 + *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4240 + CommRegion->AdapHighCmdQue.SavedIrql = 0;
4241 + CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4242 + CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4243 + InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4245 + Queues += ADAP_HIGH_CMD_ENTRIES;
4247 + // adapter to host normal priority response queue
4249 + CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4250 + CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4251 + *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4252 + *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4254 + CommRegion->HostNormRespQue.SavedIrql = 0;
4255 + CommRegion->HostNormRespQue.BaseAddress = Queues;
4256 + CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4257 +// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4258 + CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4259 + if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4262 + InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4264 + Queues += HOST_NORM_RESP_ENTRIES;
4266 + // adapter to host high priority response queue
4268 + CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4269 + CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4270 + *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4271 + *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4273 + CommRegion->HostHighRespQue.SavedIrql = 0;
4274 + CommRegion->HostHighRespQue.BaseAddress = Queues;
4275 + CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4276 +// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4277 + CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4278 + if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4281 + InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4283 + Queues += HOST_HIGH_RESP_ENTRIES;
4285 + // host to adapter normal priority response queue
4287 + CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4288 + CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4289 + *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4290 + *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4292 + CommRegion->AdapNormRespQue.SavedIrql = 0;
4293 + CommRegion->AdapNormRespQue.BaseAddress = Queues;
4294 + CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4295 + InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4297 + Queues += ADAP_NORM_RESP_ENTRIES;
4299 + // host to adapter high priority response queue
4301 + CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4302 + CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4303 + *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4304 + *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4306 + CommRegion->AdapHighRespQue.SavedIrql = 0;
4307 + CommRegion->AdapHighRespQue.BaseAddress = Queues;
4308 + CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4309 + InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4311 + CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4312 + CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4313 + CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4314 + CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4321 + PAFA_COMM_ADAPTER Adapter
4325 +Routine Description:
4327 + This routine will send a shutdown request to each adapter.
4331 + Adapter - which adapter to send the shutdown to.
4335 + NT Status success.
4340 + PFIB_CONTEXT FibContext;
4341 + PCLOSECOMMAND CloseCommand;
4342 + AAC_STATUS Status;
4344 + FibContext = AllocateFib( Adapter );
4346 + InitializeFib( FibContext );
4348 + CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4350 + CloseCommand->Command = VM_CloseAll;
4351 + CloseCommand->ContainerId = 0xffffffff;
4353 + Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4355 + if (Status != STATUS_SUCCESS) {
4357 + FreeFib( FibContext );
4363 + CompleteFib( FibContext );
4365 + FreeFib( FibContext );
4368 + Status = STATUS_SUCCESS;
4377 +AfaCommBugcheckHandler(
4383 +Routine Description:
4385 + This routine will shutdown the adapter if there is a bugcheck and
4386 + copy the shutdown data from the adapter response into the buffer
4387 + so it will show up in the host dump file.
4391 + Buffer - This buffer will be written to the host dump by nt for us.
4393 + Length - The size of the buffer.
4401 + PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4405 + NotifyAdapter(Adapter, HostShutdown);
4407 + Adapter = Adapter->NextAdapter;
4415 + PFIB_CONTEXT FibContext,
4416 + PDEVICE_OBJECT DeviceObject,
4417 + AAC_STATUS FsaStatus,
4418 + AAC_STATUS AacStatus,
4419 + ULONG LocationCode,
4428 + PAFA_COMM_ADAPTER Adapter
4431 + PMNTINFO DiskInfo;
4432 + PMNTINFORESPONSE DiskInfoResponse;
4433 + AAC_STATUS Status;
4434 + PCOMM_FIB_CONTEXT FibContext;
4436 + FibContext = AllocateFib( Adapter );
4438 + InitializeFib( FibContext );
4440 + DiskInfo = (PMNTINFO) FibContext->Fib->data;
4441 + DiskInfo->Command = VM_NameServe;
4442 + DiskInfo->MntCount = 0;
4443 + DiskInfo->MntType = FT_FILESYS;
4445 + Status = SendFib(ContainerCommand,
4455 + DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4457 + if (DiskInfoResponse->MntRespCount) {
4459 + cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4460 + DiskInfoResponse->MntTable[0].Capacity);
4464 + cmn_err(CE_CONT, "no containers found on adapter\n");
4468 + CompleteFib( FibContext );
4470 + FreeFib( FibContext );
4474 diff -burN linux-2.4.9/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4475 --- linux-2.4.9/drivers/scsi/aacraid/commsup.c Wed Dec 31 18:00:00 1969
4476 +++ linux/drivers/scsi/aacraid/commsup.c Thu Aug 16 13:41:30 2001
4479 + * Adaptec aacraid device driver for Linux.
4481 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4483 + * This program is free software; you can redistribute it and/or modify
4484 + * it under the terms of the GNU General Public License as published by
4485 + * the Free Software Foundation; either version 2, or (at your option)
4486 + * any later version.
4488 + * This program is distributed in the hope that it will be useful,
4489 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4490 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4491 + * GNU General Public License for more details.
4493 + * You should have received a copy of the GNU General Public License
4494 + * along with this program; see the file COPYING. If not, write to
4495 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4500 + * Abstract: Contain all routines that are required for FSA host/adapter
4506 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4508 +#include "comprocs.h"
4510 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4515 +ThrottleExceptionHandler(
4516 + IN PCOMM_REGION CommRegion,
4520 +void ThrottlePeriodEndDpcRtn(
4522 + IN PVOID DeferredContext,
4523 + IN PVOID SystemArgument1,
4524 + IN PVOID SystemArgument2
4530 +Routine Description:
4532 + This routine will free all resources used by a given FibContextSegment.
4536 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4537 + ZoneSegment - The segment to release resources from.
4541 + TRUE - All resources were properly freed.
4542 + FALSE - An Error occured while freeing resources.
4546 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4547 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4549 + PCOMM_FIB_CONTEXT FibContext;
4552 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4554 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4555 + i < ZoneSegment->ExtendSize; i++, FibContext++) {
4557 + OsCvLockDestroy( FibContext->FsaEventMutex );
4558 + OsCv_destroy( &FibContext->FsaEvent );
4562 + UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4564 + OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4566 + OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4572 +FsaFreeFibContextZone(
4573 + PAFA_COMM_ADAPTER Adapter
4577 +Routine Description:
4579 + This routine will walk through the FibContextSegmentList and free up all
4580 + resources used by the FibContextZone.
4584 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4588 + TRUE - All resources were properly freed.
4589 + FALSE - An Error occured while freeing resources.
4594 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4596 + ZoneSegment = Adapter->FibContextSegmentList;
4598 + while (ZoneSegment) {
4600 + NextZoneSegment = ZoneSegment->Next;
4602 + FsaFreeFibContextSegment( Adapter, ZoneSegment );
4604 + ZoneSegment = NextZoneSegment;
4613 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4617 + ULONG ZoneSegmentAllocSize, FibAllocSize;
4618 + PVOID FibContextSegment;
4619 + PCOMM_FIB_CONTEXT FibContext;
4621 + PVOID FibPhysicalAddress;
4623 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4626 + // Allocate space to describe this zone segment.
4629 + cmn_err (CE_DEBUG, "Entered FsaExtendFibContextZone");
4630 + ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4631 + if (ZoneSegment == NULL) {
4635 + ExtendSize = Adapter->FibContextZoneExtendSize;
4636 + ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4638 + FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4640 + if (FibContextSegment == NULL) {
4641 + OsFreeMemory(ZoneSegment);
4645 + RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4647 + ZoneSegment->FibContextSegment = FibContextSegment;
4648 + ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4649 + ZoneSegment->ExtendSize = ExtendSize;
4651 + FibAllocSize = ExtendSize * sizeof(FIB);
4654 + ZoneSegment->MapFibContext.Size = FibAllocSize;
4656 + AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4658 + Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4659 + FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4661 + RtlZeroMemory( Fib, FibAllocSize );
4663 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4665 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4666 + i < ExtendSize; i++, FibContext++) {
4668 + FibContext->Adapter = Adapter;
4670 + FibContext->Fib = Fib;
4671 + FibContext->FibData = (PVOID) FibContext->Fib->data;
4673 + OsCv_init( &FibContext->FsaEvent);
4674 + FibContext->FsaEventMutex = OsCvLockAlloc();
4675 + OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4677 + Fib->Header.XferState = 0xffffffff;
4678 + Fib->Header.SenderSize = sizeof(FIB);
4680 + FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4682 + Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4683 + FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4687 + // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4688 + // initialized, we just need to extend it.
4691 + if (Adapter->FibContextZone.TotalSegmentSize) {
4693 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4695 + ExExtendZone( &Adapter->FibContextZone,
4696 + FibContextSegment,
4697 + ZoneSegmentAllocSize );
4699 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4703 + if (ExInitializeZone( &Adapter->FibContextZone,
4704 + sizeof(COMM_FIB_CONTEXT),
4705 + FibContextSegment,
4706 + ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4707 + FsaBugCheck(0,0,0);
4712 + // Add this segment to the adapter's list of segments
4715 + ZoneSegment->Next = Adapter->FibContextSegmentList;
4716 + Adapter->FibContextSegmentList = ZoneSegment;
4725 +Routine Description:
4727 + This routine creates a new COMM_FIB_CONTEXT record
4731 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4735 + PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4739 +AllocateFib (IN PVOID AdapterArg)
4741 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4743 + PCOMM_FIB_CONTEXT FibContext;
4744 + int FullZoneLoopCounter = 0;
4748 + // Acquire the zone spin lock, and check to see if the zone is full.
4749 + // If it is, then release the spin lock and allocate more fibs for the
4750 + // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4751 + // the new fibs onto the zone.
4754 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4756 + while (ExIsFullZone( &Adapter->FibContextZone )) {
4758 + if (++FullZoneLoopCounter > 10)
4759 + FsaBugCheck(0,0,0);
4761 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4764 + cmn_err (CE_DEBUG, "Extending FibContextZone");
4765 + if (FsaExtendFibContextZone(Adapter) == FALSE) {
4769 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4774 + // At this point we now know that the zone has at least one more
4775 + // IRP context record available. So allocate from the zone and
4776 + // then release the mutex.
4779 + FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4781 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4784 + // Set the proper node type code and node byte size
4787 + FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4788 + FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4791 + // Null out fields that depend on being zero at the start of each I/O
4794 + FibContext->Fib->Header.XferState = 0;
4795 + FibContext->FibCallback = NULL;
4796 + FibContext->FibCallbackContext = NULL;
4800 + // return and tell the caller
4803 + return ((PFIB_CONTEXT) FibContext);
4809 +Routine Description:
4811 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4812 + from the Fsafs in memory data structures. It should only be called
4813 + by FsaCompleteRequest.
4817 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4825 +FreeFib (IN PFIB_CONTEXT Context)
4828 + PCOMM_FIB_CONTEXT FibContext = Context;
4830 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4832 + OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4834 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4836 + FsaCommData.TimedOutFibs++;
4838 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4839 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4843 + ASSERT(FibContext->Fib->Header.XferState == 0);
4845 + if (FibContext->Fib->Header.XferState != 0) {
4846 + cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4847 + FibContext, FibContext->Fib->Header.XferState);
4850 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4854 + OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4857 + // return and tell the caller
4866 +Routine Description:
4868 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4869 + from the Fsafs in memory data structures. It should only be called
4870 + from the dpc routines to from dpc to free an FibContext from an async or
4875 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4883 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4885 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4887 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4889 + OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4891 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4893 + FsaCommData.TimedOutFibs++;
4895 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4896 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4900 + ASSERT(FibContext->Fib->Header.XferState == 0);
4902 + if (FibContext->Fib->Header.XferState != 0) {
4903 + cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4904 + FibContext, FibContext->Fib->Header.XferState);
4908 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4912 + OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4915 + // return and tell the caller
4924 +Routine Description:
4926 + Will initialize a FIB of the requested size.
4930 + Fib is a pointer to a location which will receive the address of the allocated
4933 + Size is the size of the Fib to allocate.
4937 + NT_SUCCESS if a Fib was returned to the caller.
4938 + NT_ERROR if event was an invalid event.
4942 +InitializeFib (IN PFIB_CONTEXT Context)
4944 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4945 + PFIB Fib = FibContext->Fib;
4947 + Fib->Header.StructType = TFib;
4948 + Fib->Header.Size = sizeof(FIB);
4949 +// if (Fib->Header.XferState & AllocatedFromPool)
4950 +// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4952 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4953 + Fib->Header.SenderFibAddress = 0;
4954 + Fib->Header.ReceiverFibAddress = 0;
4955 + Fib->Header.SenderSize = sizeof(FIB);
4957 + return(STATUS_SUCCESS);
4963 +Routine Description:
4965 + Will allocate and initialize a FIB of the requested size and return a
4966 + pointer to the structure. The size allocated may be larger than the size
4967 + requested due to allocation performace optimizations.
4971 + Fib is a pointer to a location which will receive the address of the allocated
4974 + Size is the size of the Fib to allocate.
4976 + JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4977 + imbedded structure the FS always allocates. So just initiaize it and return.
4981 + NT_SUCCESS if a Fib was returned to the caller.
4982 + NT_ERROR if event was an invalid event.
4986 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4992 +Routine Description:
4994 + Will deallocate and return to the free pool the FIB pointed to by the
4995 + caller. Upon return accessing locations pointed to by the FIB parameter
4996 + could cause system access faults.
5000 + Fib is a pointer to the FIB that caller wishes to deallocate.
5004 + NT_SUCCESS if a Fib was returned to the caller.
5005 + NT_ERROR if event was an invalid event.
5009 +DeallocateFib (PFIB_CONTEXT Context)
5011 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5012 + PFIB Fib = FibContext->Fib;
5014 + if ( Fib->Header.StructType != TFib ) {
5015 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
5016 + return(STATUS_UNSUCCESSFUL);
5020 + Fib->Header.XferState = 0;
5022 + return(STATUS_SUCCESS);
5029 + IN PCOMM_QUE ResponseQueue,
5034 +Routine Description:
5036 + Gets a QE off the requested response queue and gets the response FIB into
5037 + host memory. The FIB may already be in host memory depending on the bus
5038 + interface, or may require the host to DMA it over from the adapter. The routine
5039 + will return the FIB to the caller.
5043 + ResponseQueue - Is the queue the caller wishes to have the response gotten from.
5044 + Fib - Is the Fib which was the response from the adapter
5048 + NT_SUCCESS if a Fib was returned to the caller.
5049 + NT_ERROR if there was no Fib to return to the caller.
5050 + bkpfix - add in all the other possible errors ect
5054 +return(STATUS_UNSUCCESSFUL);
5058 +// Commuication primitives define and support the queuing method we use to
5059 +// support host to adapter commuication. All queue accesses happen through
5060 +// these routines and are the only routines which have a knowledge of the
5061 +// how these queues are implemented.
5067 +Routine Description:
5069 + With a priority the routine returns a queue entry if the queue has free entries. If the queue
5070 + is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5075 + Priority is an enumerated type which determines which priority level
5076 + command queue the QE is going to be queued on.
5078 + Entry is a pointer to the address of where to return the address of
5079 + the queue entry from the requested command queue.
5081 + Index is a pointer to the address of where to store the index of the new
5082 + queue entry returned.
5084 + DontInterrupt - We set this true if the queue state is such that we don't
5085 + need to interrupt the adapter for this queue entry.
5089 + TRUE - If a queue entry is returned
5090 + FALSE - If there are no free queue entries on the requested command queue.
5094 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5095 + OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5096 + OUT ULONG *DontInterrupt)
5098 + ULONG QueueOffset;
5100 + PCOMM_REGION CommRegion;
5102 + CommRegion = Adapter->CommRegion;
5105 + // All of the queues wrap when they reach the end, so we check to see if they
5106 + // have reached the end and if they have we just set the index back to zero.
5107 + // This is a wrap. You could or off the high bits in all updates but this is
5108 + // a bit faster I think.
5111 + if (WhichQueue == AdapHighCmdQueue) {
5112 + *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5114 + if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5115 + *DontInterrupt = TRUE;
5117 + if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5120 + if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5122 + cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5123 + CommRegion->AdapHighCmdQue.NumOutstandingIos);
5125 + QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5126 + *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5130 + } else if (WhichQueue == AdapNormCmdQueue) {
5132 + *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5134 + if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5135 + *DontInterrupt = TRUE;
5138 + // If we are at the end of the QUEUE then wrap back to
5142 + if (*Index >= ADAP_NORM_CMD_ENTRIES)
5143 + *Index = 0; // Wrap to front of the Producer Queue.
5146 + // The IEEE spec says that it the producer is one behind the consumer then
5147 + // the queue is full.
5150 + ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5152 + if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5153 + cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5154 + CommRegion->AdapNormCmdQue.NumOutstandingIos);
5158 + // The success case just falls through and returns the a valid queue entry.
5162 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5163 + FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5164 + *Index, QueueOffset, Entry, *Entry);
5166 + *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5170 + } else if (WhichQueue == AdapHighRespQueue) {
5172 + *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5174 + if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5175 + *DontInterrupt = TRUE;
5177 + if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5180 + if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5182 + cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5183 + CommRegion->AdapHighRespQue.NumOutstandingIos);
5185 + *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5188 + } else if (WhichQueue == AdapNormRespQueue) {
5190 + *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5192 + if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5193 + *DontInterrupt = TRUE;
5196 + // If we are at the end of the QUEUE then wrap back to
5200 + if (*Index >= ADAP_NORM_RESP_ENTRIES)
5201 + *Index = 0; // Wrap to front of the Producer Queue.
5204 + // The IEEE spec says that it the producer is one behind the consumer then
5205 + // the queue is full.
5208 + if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5210 + cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5211 + CommRegion->AdapNormRespQue.NumOutstandingIos);
5214 + // The success case just falls through and returns the a valid queue entry.
5217 + *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5220 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5221 + FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5226 + cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5235 +#ifdef API_THROTTLE
5237 +void ThrottleCheck(
5238 + IN PAFA_COMM_ADAPTER Adapter,
5243 +Routine Description:
5245 + This routine implements data I/O throttling. Throttling occurs when
5246 + a CLI FIB is detected. To ensure the CLI responds quickly (the user
5247 + is waiting for the response), this mechanism restricts the queue
5248 + depth of data IOs at the adapter for a period of time (called the
5249 + Throttle Period, default 5 seconds).
5251 + The mechanism uses a counted semaphore to place threads into a wait
5252 + state should there be too many data I/Os outstanding.
5254 + At the start of a throttle period (indicated by the first CLI FIB)
5255 + a timer is started. When the timer expires, new requests can go to
5256 + the adapter freely. Throttled requests gradually drain to the
5257 + adapter as each outstanding throttle I/O completes.
5259 + To avoid hurting regular I/O performance, we use a flag in the FIB
5260 + header to mark FIBs involved in throttling. This means we only need
5261 + take the extra spinlock in the response DPC routine for FIBs who
5262 + were subject to throttling. If no throttling is occurring, the cost
5263 + to the regular code paths is a handful of instructions.
5267 + Adapter - Pointer to per-adapter context. This is used to locate the
5268 + throttle information for this adapter.
5270 + Fib - Pointer to the header for the fib being sent.
5278 + PCOMM_REGION CommRegion = Adapter->CommRegion;
5279 + AAC_STATUS Status;
5282 + // This routine is called under protection of the queue spinlock.
5283 + // As such we are allowed to check and change the counts for the
5285 + // Check the FIB. If its not a data operation, send it on without
5286 + // throttle check. If it is a data operation, check for throttle.
5289 + CommRegion->TotalFibs++; // Keep statistics
5291 + if ((Fib->Header.XferState & ApiFib) != 0) {
5293 + CommRegion->ApiFibs++; // Keep statistics
5296 + // Its an API fib. If the throttle is not already active,
5297 + // make it so. This will prevent new data Fibs being sent
5298 + // if they exceed the throttle check.
5301 + if (!CommRegion->ThrottleActive) {
5304 + CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5307 + // Schedule a timer for the throttle active period. When
5308 + // it expires, we'll be called back at routine ThrottleDpcRoutine
5309 + // above. This will signify the throttle active period ended
5310 + // and any waiting threads will be signalled to restart.
5313 + FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5314 + CommRegion->ThrottleTimerSets++;
5315 + InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5316 + CommRegion->ThrottleTimeout,
5317 + &CommRegion->ThrottleDpc);
5318 + ASSERT(InQue == FALSE);
5325 + // Its a non-API fib, so subject to throttle checks.
5326 + // The following are exempt from throttling:
5327 + // o FIBs marked as "throttle exempt" by upper layers.
5328 + // o I/Os issued from a raised IRQL. We can't suspend
5329 + // a thread when at raised IRQL so throttling is exempt.
5332 + if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5334 + CommRegion->NonPassiveFibs++;
5335 + FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5340 + if (CommRegion->ThrottleActive) {
5343 + // Throttle is active.
5344 + // Check if the FIB is a read or write. If so, and its to the
5345 + // file system information area, let it through without throttling.
5348 + if (Fib->Header.Command == ContainerCommand) {
5349 + PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5352 + // *** Note *** We are using read and write command formats
5353 + // interchangably here. This is ok for this purpose as the
5354 + // command is in the same place for both. Read and write command
5355 + // formats are different at higher offsets though.
5358 + if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5359 + (BlockDisk->Command == VM_CtBlockWrite)) &&
5360 + (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5362 + CommRegion->FSInfoFibs++; // Keep statistics
5370 + // Throttle the FIB.
5371 + // Mark it as throttle active so that it can signal a waiter
5372 + // when it completes.
5374 + CommRegion->ThrottledFibs++;
5375 + Fib->Header.Flags |= ThrottledFib;
5378 + // Release the spinlock so we can wait the thread if necessary.
5379 + // Since we specify a timeout, check the caller is at passive level.
5382 + OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5384 + FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5386 + Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5387 + Executive, // Don't allow user APCs to wake us
5388 + KernelMode, // Wait in kernel mode
5389 + FALSE, // Not alertable
5390 + &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5393 + // Check the signal status. If we've timed out, clear the throttle
5394 + // flag on the FIB to avoid us signalling the semaphore on completion.
5395 + // We never acquired the semaphore.
5397 + if (Status == STATUS_TIMEOUT) {
5399 + CommRegion->ThrottleTimedoutFibs++;
5400 + FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5401 + Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5405 + ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5410 + // We've been woken up and can now send the FIB to the adapter.
5411 + // Acquire the spinlock again so we can get a queue entry. This
5412 + // returns to GetQueueEntry.
5415 + FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5416 + KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5417 + CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5423 +#endif //#ifdef API_THROTTLE
5425 +int GetQueueEntryTimeouts = 0;
5430 +Routine Description:
5432 + Gets the next free QE off the requested priorty adapter command queue and
5433 + associates the Fib with the QE. The QE represented by index is ready to
5434 + insert on the queue when this routine returns success.
5438 + Index is the returned value which represents the QE which is ready to
5439 + insert on the adapter's command queue.
5441 + Priority is an enumerated type which determines which priority level
5442 + command queue the QE is going to be queued on.
5444 + Fib is a pointer to the FIB the caller wishes to have associated with the
5447 + Wait is a boolean which determines if the routine will wait if there are
5448 + no free QEs on the requested priority command queue.
5450 + FibContext is where the driver stores all system resources required to execute the
5451 + command requested from the calling thread. This includes mapping resources for
5452 + the FIB and the 'users' buffer.
5454 + DontInterrupt - We set this true if the queue state is such that we don't
5455 + need to interrupt the adapter for this queue entry.
5459 + NT_SUCCESS if a Fib was returned to the caller.
5460 + NT_ERROR if event was an invalid event.
5464 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5465 + IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5466 + IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5468 + PQUEUE_ENTRY QueueEntry = NULL;
5469 + BOOLEAN MapAddress = FALSE;
5471 + AAC_STATUS Status;
5472 + PCOMM_REGION CommRegion;
5474 + CommRegion = Adapter->CommRegion;
5477 + // Get the spinlock for the queue we are putting a command on
5480 + if (WhichQueue == AdapHighCmdQueue)
5481 + OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5482 + else if (WhichQueue == AdapNormCmdQueue)
5483 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5484 + else if (WhichQueue == AdapHighRespQueue)
5485 + OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5486 + else if (WhichQueue == AdapNormRespQueue)
5487 + OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5489 + FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5490 + return(FSA_INVALID_QUEUE);
5494 + // Get the pointers to a queue entry on the queue the caller wishes to queue
5495 + // a command request on. If there are no entries then wait if that is what the
5496 + // caller requested.
5499 + if (WhichQueue == AdapHighCmdQueue) {
5500 + // if no entries wait for some if caller wants to
5501 + while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5502 + cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5506 + // Setup queue entry with a command, status and Fib mapped
5509 + QueueEntry->Size = Fib->Header.Size;
5510 + MapAddress = TRUE;
5512 + } else if (WhichQueue == AdapNormCmdQueue) {
5513 + // if no entries wait for some if caller wants to
5514 + while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5515 + cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5519 + // Setup queue entry with command, status and Fib mapped
5522 + QueueEntry->Size = Fib->Header.Size;
5523 + MapAddress = TRUE;
5525 + } else if (WhichQueue == AdapHighRespQueue) {
5527 + while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5531 + // Setup queue entry with command, status and Fib mapped
5534 + QueueEntry->Size = Fib->Header.Size;
5535 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5536 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5537 + MapAddress = FALSE;
5539 + } else if (WhichQueue == AdapNormRespQueue) {
5540 + while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5544 + // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5547 + QueueEntry->Size = Fib->Header.Size;
5548 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5549 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5550 + MapAddress = FALSE;
5554 + // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5558 + QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5565 + FsaCommPrint("Queue Entry contents:.\n");
5566 + FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5567 + FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5568 + FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5569 + FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5572 + return(FSA_SUCCESS);
5578 +Routine Description:
5580 + Gets the next free QE off the requested priorty adapter command queue and
5581 + associates the Fib with the QE. The QE represented by index is ready to
5582 + insert on the queue when this routine returns success.
5586 + Index is the returned value which represents the QE which is ready to
5587 + insert on the adapter's command queue.
5589 + WhichQueue tells us which queue the caller wishes to have the entry put.
5593 + NT_SUCCESS if a Fib was returned to the caller.
5594 + NT_ERROR if event was an invalid event.
5599 + IN PAFA_COMM_ADAPTER Adapter,
5600 + IN QUEUE_INDEX Index,
5601 + IN QUEUE_TYPES WhichQueue,
5602 + IN ULONG DontInterrupt
5605 + PCOMM_REGION CommRegion;
5607 + CommRegion = Adapter->CommRegion;
5610 + // We have already verified the queue in getentry, but we still have to make
5611 + // sure we don't wrap here too.
5614 + if (WhichQueue == AdapHighCmdQueue) {
5616 + *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5618 + OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5620 + if (!DontInterrupt)
5621 + NotifyAdapter(Adapter, AdapHighCmdQue);
5623 + } else if (WhichQueue == AdapNormCmdQueue) {
5626 + FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5628 + *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5630 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5632 + if (!DontInterrupt)
5633 + NotifyAdapter(Adapter, AdapNormCmdQue);
5635 + } else if (WhichQueue == AdapHighRespQueue) {
5637 + *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5639 + OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5641 + if (!DontInterrupt)
5642 + NotifyAdapter(Adapter, AdapHighRespQue);
5644 + } else if (WhichQueue == AdapNormRespQueue) {
5646 + *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5648 + OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5650 + if (!DontInterrupt)
5651 + NotifyAdapter(Adapter, AdapNormRespQue);
5654 + FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5655 + return(FSA_INVALID_QUEUE_PRIORITY);
5658 + return(FSA_SUCCESS);
5661 +extern int GatherFibTimes;
5666 + FIB_COMMAND Command,
5670 + USHORT *ResponseSize
5674 +Routine Description:
5676 + This routine will send a synchronous FIB to the adapter and wait for its
5681 + DeviceExtension - Pointer to adapter extension structure.
5690 + PAFA_COMM_ADAPTER Adapter = Arg;
5692 + ULONG returnStatus;
5694 + Fib = Adapter->SyncFib;
5696 + Fib->Header.StructType = TFib;
5697 + Fib->Header.Size = sizeof(FIB);
5698 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5699 + Fib->Header.ReceiverFibAddress = 0;
5700 + Fib->Header.SenderSize = sizeof(FIB);
5701 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5702 + Fib->Header.Command = Command;
5705 + // Copy the Data portion into the Fib.
5708 + RtlCopyMemory( Fib->data, Data, Size );
5711 + Fib->Header.XferState |= (SentFromHost | NormalPriority);
5714 + // Set the size of the Fib we want to send to the adapter
5717 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5719 + if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5720 + Adapter->SyncFibPhysicalAddress )) {
5727 + // Copy the response back to the caller's buffer.
5730 + RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5732 + *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5735 + // Indicate success
5742 +// Define the highest level of host to adapter communication routines. These
5743 +// routines will support host to adapter FS commuication. These routines have
5744 +// no knowledge of the commuication method used. This level sends and receives
5745 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5752 +Routine Description:
5754 + Sends the requested FIB to the adapter and optionally will wait for a
5755 + response FIB. If the caller does not wish to wait for a response than
5756 + an event to wait on must be supplied. This event will be set when a
5757 + response FIB is received from the adapter.
5761 + Fib is a pointer to the FIB the caller wishes to send to the adapter.
5763 + Size - Size of the data portion of the Fib.
5765 + Priority is an enumerated type which determines which priority level
5766 + the caller wishes to send this command at.
5768 + Wait is a boolean which determines if the routine will wait for the
5769 + completion Fib to be returned(TRUE), or return when the Fib has been
5770 + successfully received by the adapter(FALSE).
5772 + WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5773 + FIB has been returned by the adapter.
5775 + ReturnFib is an optional pointer to a FIB that if present the response FIB will
5780 + NT_SUCCESS if a Fib was returned to the caller.
5781 + NT_ERROR if event was an invalid event.
5785 +SendFib (IN FIB_COMMAND Command,
5786 + IN PFIB_CONTEXT Context,
5788 + IN COMM_PRIORITIES Priority,
5791 + IN BOOLEAN ResponseExpected,
5792 + IN PFIB_CALLBACK FibCallback,
5793 + IN PVOID FibCallbackContext)
5795 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5796 + QUEUE_INDEX Index;
5797 + QUEUE_TYPES WhichQueue;
5798 + LARGE_INTEGER Timeout;
5799 + AAC_STATUS Status;
5800 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5801 + ULONG DontInterrupt = FALSE;
5802 + PFIB Fib = FibContext->Fib;
5803 + IN PCOMM_QUE OurQueue;
5805 + Timeout = FsaCommData.AdapterTimeout;
5807 + if (!(Fib->Header.XferState & HostOwned)) {
5808 + FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5809 + FsaCommLogEvent(FibContext,
5810 + FsaCommData.DeviceObject,
5811 + FSAFS_FIB_INVALID,
5812 + STATUS_UNSUCCESSFUL,
5813 + BugCheckFileId | __LINE__,
5814 + FACILITY_FSAFS_ERROR_CODE,
5818 + return(STATUS_UNSUCCESSFUL);
5823 + // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5824 + // are if the caller requests to wait and does not request a response and if the
5825 + // caller does not want a response and the Fib is not allocated from pool. If a response
5826 + // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5827 + // comes back from the adapter. No further processing will be done besides deleting the
5828 + // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5829 + // and the host can log that fact.
5831 + if (Wait && !ResponseExpected) {
5833 + FsaCommLogEvent(FibContext,
5834 + FsaCommData.DeviceObject,
5835 + FSAFS_FIB_INVALID,
5836 + STATUS_UNSUCCESSFUL,
5837 + BugCheckFileId | __LINE__,
5838 + FACILITY_FSAFS_ERROR_CODE,
5842 + return(STATUS_UNSUCCESSFUL);
5844 + } else if (!Wait && ResponseExpected) {
5845 + Fib->Header.XferState |= (Async | ResponseExpected);
5846 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5847 + } else if (!Wait && !ResponseExpected) {
5848 + Fib->Header.XferState |= NoResponseExpected;
5849 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5850 + } else if (Wait && ResponseExpected) {
5851 + Fib->Header.XferState |= ResponseExpected;
5852 + FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5855 + Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5858 + // Set FIB state to indicate where it came from and if we want a response from the
5859 + // adapter. Also load the command from the caller.
5862 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5863 + Fib->Header.Command = Command;
5864 + Fib->Header.XferState |= SentFromHost;
5865 + FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5868 + // Set the size of the Fib we want to send to the adapter
5871 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5872 + if (Fib->Header.Size > Fib->Header.SenderSize) {
5873 + return(STATUS_BUFFER_OVERFLOW);
5877 + // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5880 + if (Priority == FsaHigh) {
5881 + Fib->Header.XferState |= HighPriority;
5882 + WhichQueue = AdapHighCmdQueue;
5883 + OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5885 + Fib->Header.XferState |= NormalPriority;
5886 + WhichQueue = AdapNormCmdQueue;
5887 + OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5891 + OsCvLockAcquire( FibContext->FsaEventMutex );
5894 + if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5895 + return(STATUS_UNSUCCESSFUL);
5899 + cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5900 + cmn_err (CE_DEBUG,"Fib contents:.\n");
5901 + cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5902 + cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5905 + // Fill in the Callback and CallbackContext if we are not going to wait.
5910 + FibContext->FibCallback = FibCallback;
5911 + FibContext->FibCallbackContext = FibCallbackContext;
5915 + FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5917 + InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5918 + OurQueue->NumOutstandingIos++;
5920 + FibContext->FibComplete = 0;
5924 + if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5925 + return(STATUS_UNSUCCESSFUL);
5928 + // If the caller wanted us to wait for response wait now.
5929 + // If Timeouts are enabled than set the timeout otherwise wait forever.
5933 + while (FibContext->FibComplete == 0) {
5934 + OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5937 + OsCvLockRelease( FibContext->FsaEventMutex );
5939 + if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5940 + return(STATUS_IO_TIMEOUT);
5942 + return(STATUS_SUCCESS);
5947 + // If the user does not want a response than return success otherwise return pending
5950 + ASSERT( FibCallback );
5952 + if (ResponseExpected)
5953 + return(STATUS_PENDING);
5955 + return(STATUS_SUCCESS);
5960 + IN PAFA_COMM_ADAPTER Adapter,
5961 + PCOMM_QUE OurQueue,
5962 + OUT PQUEUE_ENTRY *Entry
5966 +Routine Description:
5968 + Will return a pointer to the entry on the top of the queue requested that we are a consumer
5969 + of, and return the address of the queue entry. It does not change the state of the queue.
5973 + OurQueue - is the queue the queue entry should be removed from.
5975 + Entry - is a pointer where the address of the queue entry should be returned.
5979 + TRUE if there was a queue entry on the response queue for the host to consume.
5980 + FALSE if there were no queue entries to consume.
5985 + QUEUE_INDEX Index;
5988 + if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5993 + // The consumer index must be wrapped if we have reached the end of
5995 + // Else we just use the entry pointed to by the header index
5998 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
6001 + Index = *OurQueue->Headers.ConsumerIndex;
6003 + *Entry = OurQueue->BaseAddress + Index;
6006 + FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
6015 +ConsumerEntryAvailable(
6016 + IN PAFA_COMM_ADAPTER Adapter,
6017 + PCOMM_QUE OurQueue
6020 + return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
6025 + IN PAFA_COMM_ADAPTER Adapter,
6026 + PCOMM_QUE OurQueue,
6027 + QUEUE_TYPES WhichQueue
6031 +Routine Description:
6033 + Frees up the current top of the queue we are a consumer of. If the queue was full
6034 + notify the producer that the queue is no longer full.
6038 + OurQueue - is the queue we will free the current consumer entry on.
6042 + TRUE if there was a queue entry on the response queue for the host to consume.
6043 + FALSE if there were no queue entries to consume.
6048 + BOOLEAN WasFull = FALSE;
6049 + HOST_2_ADAP_EVENT Notify;
6051 + if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
6054 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
6055 + *OurQueue->Headers.ConsumerIndex = 1;
6057 + *OurQueue->Headers.ConsumerIndex += 1;
6060 + switch (WhichQueue) {
6062 + case HostNormCmdQueue:
6063 + Notify = HostNormCmdNotFull;
6065 + case HostHighCmdQueue:
6066 + Notify = HostHighCmdNotFull;
6069 + case HostNormRespQueue:
6070 + Notify = HostNormRespNotFull;
6073 + case HostHighRespQueue:
6074 + Notify = HostHighRespNotFull;
6078 + NotifyAdapter(Adapter, Notify);
6084 +CompleteAdapterFib(
6085 + IN PFIB_CONTEXT Context,
6090 +Routine Description:
6092 + Will do all necessary work to complete a FIB that was sent from the adapter.
6096 + Fib is a pointer to the FIB that caller wishes to complete processing on.
6098 + Size - Size of the completion Packet(Opitional). If not present than the current
6099 + largest size in the Fib will be used
6101 + Adapter - Pointer to which adapter sent this FIB
6105 + NT_SUCCESS if a Fib was returned to the caller.
6106 + NT_ERROR if event was an invalid event.
6110 + PCOMM_FIB_CONTEXT FibContext = Context;
6111 + PFIB Fib = FibContext->Fib;
6112 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6113 + ULONG DontInterrupt = FALSE;
6115 + if (Fib->Header.XferState == 0)
6116 + return(STATUS_SUCCESS);
6119 + // If we plan to do anything check the structure type first.
6122 + if ( Fib->Header.StructType != TFib ) {
6123 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6124 + return(STATUS_UNSUCCESSFUL);
6128 + // This block handles the case where the adapter had sent us a command and we
6129 + // have finished processing the command. We call completeFib when we are done
6130 + // processing the command and want to send a response back to the adapter. This
6131 + // will send the completed cdb to the adapter.
6134 + if (Fib->Header.XferState & SentFromAdapter) {
6135 + Fib->Header.XferState |= HostProcessed;
6136 + if (Fib->Header.XferState & HighPriority) {
6137 + QUEUE_INDEX Index;
6140 + Size += sizeof(FIB_HEADER);
6141 + if (Size > Fib->Header.SenderSize)
6142 + return(STATUS_BUFFER_OVERFLOW);
6143 + Fib->Header.Size = Size;
6146 + if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6147 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6148 + return(FSA_FATAL);
6150 + if (InsertQueueEntry(Adapter,
6152 + AdapHighRespQueue,
6153 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6154 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6156 + } else if (Fib->Header.XferState & NormalPriority) {
6157 + QUEUE_INDEX Index;
6160 + Size += sizeof(FIB_HEADER);
6161 + if (Size > Fib->Header.SenderSize)
6162 + return(STATUS_BUFFER_OVERFLOW);
6163 + Fib->Header.Size = Size;
6166 + if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6167 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6168 + return(FSA_FATAL);
6170 + if (InsertQueueEntry(Adapter,
6172 + AdapNormRespQueue,
6173 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6174 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6178 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6179 + FsaBugCheck(0,0,0);
6181 + return(STATUS_SUCCESS);
6186 + IN PFIB_CONTEXT Context
6190 +Routine Description:
6192 + Will do all necessary work to complete a FIB. If the caller wishes to
6193 + reuse the FIB after post processing has been completed Reinitialize
6194 + should be called set to TRUE, otherwise the FIB will be returned to the
6195 + free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6196 + reinitialzied and is ready for reuse on return from this routine.
6200 + Fib is a pointer to the FIB that caller wishes to complete processing on.
6202 + Size - Size of the completion Packet(Opitional). If not present than the current
6203 + largest size in the Fib will be used
6205 + Reinitialize is a boolean which determines if the routine will ready the
6206 + completed FIB for reuse(TRUE) or not(FALSE).
6210 + NT_SUCCESS if a Fib was returned to the caller.
6211 + NT_ERROR if event was an invalid event.
6215 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6216 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6217 + PFIB Fib = FibContext->Fib;
6220 + // Check for a fib which has already been completed
6223 +// ASSERT(Fib->Header.XferState & AdapterProcessed);
6224 + if (Fib->Header.XferState == 0)
6225 + return(STATUS_SUCCESS);
6228 + // If we plan to do anything check the structure type first.
6231 + if ( Fib->Header.StructType != TFib ) {
6232 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6233 + return(STATUS_UNSUCCESSFUL);
6237 +//#if FSA_ADAPTER_METER
6239 + // Meter the completion
6241 + fsaMeterEnd( // meter the end of an operation
6242 + &(Adapter->FibMeter), // .. the meter
6243 + IrpContext->FibMeterType, // .. type of operation
6244 + &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6245 + FibGetMeterSize(Fib, // .. number of bytes in operation
6246 + IrpContext->FibMeterType,
6247 + IrpContext->FibSubCommand));
6248 +#endif // FSA_ADAPTER_METER
6251 + // This block completes a cdb which orginated on the host and we just need
6252 + // to deallocate the cdb or reinit it. At this point the command is complete
6253 + // that we had sent to the adapter and this cdb could be reused.
6256 + if ( (Fib->Header.XferState & SentFromHost) &&
6257 + (Fib->Header.XferState & AdapterProcessed)) {
6259 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6261 + return( DeallocateFib(FibContext) );
6264 + // This handles the case when the host has aborted the I/O to the
6265 + // adapter because the adapter is not responding
6268 + } else if (Fib->Header.XferState & SentFromHost) {
6270 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6273 + return( DeallocateFib(FibContext) );
6275 + } else if (Fib->Header.XferState & HostOwned) {
6277 + return(DeallocateFib(FibContext));
6280 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6281 + FsaBugCheck(0,0,0);
6283 + return(STATUS_SUCCESS);
6288 + IN PAFA_COMM_ADAPTER Adapter,
6289 + IN PCOMM_FIB_CONTEXT FibContext
6293 +Routine Description:
6295 + This routine handles a driver notify fib from the adapter and dispatches it to
6296 + the appropriate routine for handling.
6300 + Adapter - Which adapter this fib is from
6301 + FibContext - Pointer to FibContext from adapter.
6309 + PFIB Fib = FibContext->Fib;
6310 + PAFA_CLASS_DRIVER ClassDriver;
6311 + BOOLEAN Handled = FALSE;
6315 + // First loop through all of the class drivers to give them a chance to handle
6319 + ClassDriver = Adapter->ClassDriverList;
6321 + while (ClassDriver) {
6323 + if (ClassDriver->HandleAif) {
6325 + if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6333 + ClassDriver = ClassDriver->Next;
6339 + // Set the status of this FIB to be Invalid parameter.
6342 +// *(FSASTATUS *)Fib->data = ST_INVAL;
6343 + *(FSASTATUS *)Fib->data = ST_OK;
6346 + CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6353 + IN PAFA_COMM_ADAPTER Adapter
6357 +Routine Description:
6359 + Waits on the commandready event in it's queue. When the event gets set it will
6360 + pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6361 + When the queue is empty it will wait for more FIBs.
6365 + Context is used. All data os global
6373 + COMM_FIB_CONTEXT FibContext; // for error logging
6375 + PCOMM_REGION CommRegion = Adapter->CommRegion;
6376 + PLIST_ENTRY Entry;
6377 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6380 + // We can only have one thread per adapter for AIF's.
6383 + if (Adapter->AifThreadStarted) {
6387 +// cmn_err(CE_DEBUG, "AIF thread started");
6390 + // Let the DPC know it has a place to send the AIF's to.
6393 + Adapter->AifThreadStarted = TRUE;
6395 + RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6397 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6402 + // NOTE : the QueueLock is held at the top of each loop.
6405 + ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6407 + while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6408 + PLIST_ENTRY Entry;
6409 + PAIFCOMMANDTOHOST AifCommandToHost;
6411 + Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6413 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6415 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6418 + // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6419 + // can't do anything at this point since we don't have anything defined for this thread to
6423 + // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6425 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6428 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6429 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6430 + FibContext.Fib = Fib;
6431 + FibContext.FibData = Fib->data;
6432 + FibContext.Adapter = Adapter;
6436 + // We only handle AifRequest fibs from the adapter.
6439 + ASSERT(Fib->Header.Command == AifRequest);
6442 + AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6444 + if (AifCommandToHost->command == AifCmdDriverNotify) {
6448 + HandleDriverAif( Adapter, &FibContext );
6451 + AAC_UINT32 time_now, time_last;
6452 + time_now = (AAC_UINT32)OsGetSeconds();
6455 + OsCvLockAcquire(Adapter->AdapterFibMutex);
6457 + Entry = Adapter->AdapterFibContextList.Flink;
6460 + // For each Context that is on the AdapterFibContextList, make a copy of the
6461 + // fib, and then set the event to wake up the thread that is waiting for it.
6464 + while (Entry != &Adapter->AdapterFibContextList) {
6467 + // Extract the AdapterFibContext
6470 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6473 + // Check if the queue is getting backlogged
6475 + if ( AdapterFibContext->FibCount > 20 ) {
6476 + time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6479 + // has it been > 2 minutes since the last read off the queue?
6481 + if ((time_now - time_last) > 120) {
6482 + Entry = Entry->Flink;
6483 + // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6484 + // time_now - time_last,
6485 + // AdapterFibContext->FibCount);
6486 + FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6491 +// Warning: sleep possible while holding spinlock
6492 + NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6497 + // Make the copy of the FIB
6500 + RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6503 + // Put the FIB onto the AdapterFibContext's FibList
6506 + InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6507 + AdapterFibContext->FibCount++;
6510 + // Set the event to wake up the thread that will waiting.
6513 + OsCv_signal(&AdapterFibContext->UserEvent);
6517 + cmn_err (CE_WARN, "aifd: didn't allocate NewFib");
6521 + Entry = Entry->Flink;
6525 + // Set the status of this FIB
6528 + *(FSASTATUS *)Fib->data = ST_OK;
6530 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6532 + OsCvLockRelease(Adapter->AdapterFibMutex);
6536 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6541 + // There are no more AIF's, call cv_wait_sig to wait for more
6545 + // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6547 + if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6548 + CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6550 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6552 + Adapter->AifThreadStarted = FALSE;
6554 + // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6560 + // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6568 + IN PFIB_CONTEXT Context
6571 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6573 + return ((PVOID)FibContext->Fib->data);
6577 +#ifdef API_THROTTLE
6579 +void ThrottlePeriodEndDpcRtn(
6581 + IN PVOID DeferredContext,
6582 + IN PVOID SystemArgument1,
6583 + IN PVOID SystemArgument2
6587 +Routine Description:
6589 + This routine is called as a DPC when a throttle period expires. It
6590 + restarts all threads suspended due to the throttling flow control.
6592 + The throttling counted semaphore is signalled for all waiting threads
6593 + and the indicator of throttling active is cleared.
6597 + Dpc - Pointer to Dpc structure. Not used.
6598 + DefferedContext - Pointer to per-adapter context. This is used to locate the
6599 + throttle information for this adapter.
6600 + SystemArgument1 - Not used
6601 + SystemArgument2 - Not used
6609 + PCOMM_REGION CommRegion;
6610 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6612 + CommRegion = Adapter->CommRegion;
6615 + // Acquire the spinlock protecting the throttle status.
6617 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6619 + FsaCommPrint("ThrottlePeriodEndDpc\n");
6622 + // Check that the timer has fired as many times as it was set !
6625 + CommRegion->ThrottleTimerFires++;
6626 + ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6629 + // The throttle period is now over. Restart all threads waiting
6630 + // on the throttle being released.
6631 + // Clear the throttle active indicator. This will allow new FIBs
6632 + // to be sent to the adapter once we release the spinlock on exiting
6633 + // the DPC. This means all restarted threads will be runnable
6634 + // threads by then.
6637 + ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6638 + CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6640 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6643 +#endif // #ifdef API_THROTTLE
6646 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6647 + * Emacs will notice this stuff at the end of the file and automatically
6648 + * adjust the settings for this buffer only. This must remain at the end
6650 + * ---------------------------------------------------------------------------
6651 + * Local variables:
6652 + * c-indent-level: 4
6653 + * c-brace-imaginary-offset: 0
6654 + * c-brace-offset: -4
6655 + * c-argdecl-indent: 4
6656 + * c-label-offset: -4
6657 + * c-continued-statement-offset: 4
6658 + * c-continued-brace-offset: 0
6659 + * indent-tabs-mode: nil
6663 diff -burN linux-2.4.9/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6664 --- linux-2.4.9/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 18:00:00 1969
6665 +++ linux/drivers/scsi/aacraid/dpcsup.c Thu Aug 16 13:41:30 2001
6668 + * Adaptec aacraid device driver for Linux.
6670 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6672 + * This program is free software; you can redistribute it and/or modify
6673 + * it under the terms of the GNU General Public License as published by
6674 + * the Free Software Foundation; either version 2, or (at your option)
6675 + * any later version.
6677 + * This program is distributed in the hope that it will be useful,
6678 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6679 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6680 + * GNU General Public License for more details.
6682 + * You should have received a copy of the GNU General Public License
6683 + * along with this program; see the file COPYING. If not, write to
6684 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6689 + * Abstract: All DPC processing routines for the cyclone board occur here.
6694 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6696 +#include "comprocs.h"
6700 +// The Bug check file id for this module
6703 +#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6705 +#define Dbg (DEBUG_TRACE_DPCSUP)
6709 + IN PCOMM_REGION CommRegion
6713 +Routine Description:
6715 + This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6716 + no longer full. The Isr will pass the queue that we will set the not full event.
6720 + Dpc - Pointer to this routine.
6722 + Dummy - is a pointer to the comm region which is global so we don't need it anyway
6724 + Queue is a pointer to the queue structure we will operate on.
6726 + MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6735 +#ifdef unix_queue_full
6736 + KeSetEvent(&Queue->QueueFull, 0, FALSE);
6741 +int GatherFibTimes = 0;
6743 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6754 +Routine Description:
6756 + This DPC routine will be queued when the adapter interrupts us to let us know there
6757 + is a response on our normal priority queue. We will pull off all QE there are and wake
6758 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6763 + Dpc - Pointer to this routine.
6765 + OurQueue is a pointer to the queue structure we will operate on.
6767 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6775 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6777 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6778 + PQUEUE_ENTRY QueueEntry;
6780 + PCOMM_FIB_CONTEXT FibContext;
6784 + LARGE_INTEGER ResponseAllocSize;
6787 + FsaCommPrint("entering the host normal reponse dpc routine.\n");
6790 + OsSpinLockAcquire( OurQueue->QueueLock );
6793 + // Keep pulling response QEs off the response queue and waking
6794 + // up the waiters until there are no more QEs. We then return
6795 + // back to the system. If no response was requesed we just
6796 + // deallocate the Fib here and continue.
6800 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6802 + int IsFastResponse;
6804 + IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6805 + Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6807 + FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6809 + FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6811 + ASSERT(FibContext->Fib == Fib);
6814 + // Remove this FibContext from the Outstanding I/O queue.
6815 + // But only if it has not already been timed out.
6817 + // If the fib has been timed out already, then just continue.
6818 + // The caller has already been notified that the fib timed out.
6821 + if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6823 + RemoveEntryList( &FibContext->QueueEntry );
6824 + Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6828 + FsaCommLogEvent(FibContext,
6829 + FsaCommData.DeviceObject,
6830 + FSAFS_TIMED_OUT_FIB_COMPLETED,
6831 + STATUS_UNSUCCESSFUL,
6832 + BugCheckFileId | __LINE__,
6833 + FACILITY_FSAFS_ERROR_CODE,
6841 + OsSpinLockRelease( OurQueue->QueueLock );
6843 + if (IsFastResponse) {
6849 + *(FSASTATUS *)Fib->data = ST_OK;
6851 + Fib->Header.XferState |= AdapterProcessed;
6855 + ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6857 + FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6859 + ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6862 + if (Fib->Header.Command == NuFileSystem) {
6864 + FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6866 + if (*pStatus & 0xffff0000) {
6868 + ULONG Hint = *pStatus;
6873 + DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6874 + IrpContext->NonPaged->FileId.fid_driveno,
6875 + IrpContext->NonPaged->FileId.fid_f1,
6876 + IrpContext->NonPaged->FileId.fid_f2,
6877 + IrpContext->NonPaged->FileId.fid_hint,
6885 + if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6887 + ASSERT(FibContext->FibCallback);
6889 + if (Fib->Header.XferState & NoResponseExpected)
6890 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6892 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6895 + // NOTE: we can not touch the FibContext after this call, because it may have been
6899 + FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6903 + OsCvLockAcquire( FibContext->FsaEventMutex);
6905 + FibContext->FibComplete = 1;
6907 + OsCv_signal( &FibContext->FsaEvent );
6909 + OsCvLockRelease( FibContext->FsaEventMutex );
6911 + FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6918 + OsSpinLockAcquire( OurQueue->QueueLock );
6922 + if (Consumed > FsaCommData.PeakFibsConsumed)
6923 + FsaCommData.PeakFibsConsumed = Consumed;
6925 + if (Consumed == 0)
6926 + FsaCommData.ZeroFibsConsumed++;
6928 + if (FsaCommData.HardInterruptModeration) {
6931 + // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6932 + // been put on the queue. This removes the race condition that exists between the
6933 + // last time we checked the queue, and when we re-enabled the interrupt.
6935 + // If there is something on the queue, then go handle it.
6938 + EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6940 + if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6942 + DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6950 + FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6953 + OsSpinLockRelease( OurQueue->QueueLock );
6959 +Routine Description:
6961 + This DPC routine wiol be queued when the adapter interrupts us to let us know there
6962 + is a response on our high priority queue. We will pull off all QE there are and wake
6963 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6968 + Dpc - Pointer to this routine.
6970 + OurQueue is a pointer to the queue structure we will operate on.
6972 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6980 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6986 +Routine Description:
6988 + This DPC routine will be queued when the adapter interrupts us to let us know there
6989 + is a command on our high priority queue. We will pull off all QE there are and wake
6990 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6995 + Dpc - Pointer to this routine.
6997 + OurQueue is a pointer to the queue structure we will operate on.
6999 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7007 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
7013 +Routine Description:
7015 + This DPC routine will be queued when the adapter interrupts us to let us know there
7016 + is a command on our normal priority queue. We will pull off all QE there are and wake
7017 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
7022 + Dpc - Pointer to this routine.
7024 + OurQueue is a pointer to the queue structure we will operate on.
7026 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7034 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
7036 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
7037 + PQUEUE_ENTRY QueueEntry;
7039 + OsSpinLockAcquire( OurQueue->QueueLock );
7042 + // Keep pulling response QEs off the response queue and waking
7043 + // up the waiters until there are no more QEs. We then return
7044 + // back to the system.
7047 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
7051 + Fib = (PFIB)QueueEntry->FibAddress;
7054 + if (Adapter->AifThreadStarted) {
7057 +// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
7060 + InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7061 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7062 + OsCv_signal(&OurQueue->CommandReady);
7070 + COMM_FIB_CONTEXT FibContext;
7074 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7078 + OsSpinLockRelease( OurQueue->QueueLock );
7082 +// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7085 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7087 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7088 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7089 + FibContext.Fib = Fib;
7090 + FibContext.FibData = Fib->data;
7091 + FibContext.Adapter = Adapter;
7094 + // Set the status of this FIB
7097 + *(FSASTATUS *)Fib->data = ST_OK;
7099 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7103 + OsSpinLockAcquire( OurQueue->QueueLock );
7107 + OsSpinLockRelease( OurQueue->QueueLock );
7110 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7111 --- linux-2.4.9/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 18:00:00 1969
7112 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Thu Aug 16 13:41:30 2001
7115 + * Adaptec aacraid device driver for Linux.
7117 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7119 + * This program is free software; you can redistribute it and/or modify
7120 + * it under the terms of the GNU General Public License as published by
7121 + * the Free Software Foundation; either version 2, or (at your option)
7122 + * any later version.
7124 + * This program is distributed in the hope that it will be useful,
7125 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7126 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7127 + * GNU General Public License for more details.
7129 + * You should have received a copy of the GNU General Public License
7130 + * along with this program; see the file COPYING. If not, write to
7131 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7135 + * AacGenericTypes.h
7139 + * The module defines the generic data types that all of the other header files
7143 +#ifndef _AAC_GENERIC_TYPES
7144 +#define _AAC_GENERIC_TYPES
7146 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7148 +typedef char AAC_INT8, *PAAC_INT8;
7149 +typedef short AAC_INT16, *PAAC_INT16;
7150 +typedef int AAC_INT32, *PAAC_INT32;
7151 +typedef long long AAC_INT64, *PAAC_INT64;
7153 +typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7154 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7155 +typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7156 +typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7158 +typedef void AAC_VOID, *PAAC_VOID;
7161 +// this compiler uses 32 bit enum data types
7164 +#define AAC_32BIT_ENUMS 1
7166 +#define INTR_UNCLAIMED 1
7167 +#define INTR_CLAIMED 0
7169 +#endif // _AAC_GENERIC_TYPES
7171 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7172 --- linux-2.4.9/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 18:00:00 1969
7173 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Thu Aug 16 13:41:30 2001
7176 + * Adaptec aacraid device driver for Linux.
7178 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7180 + * This program is free software; you can redistribute it and/or modify
7181 + * it under the terms of the GNU General Public License as published by
7182 + * the Free Software Foundation; either version 2, or (at your option)
7183 + * any later version.
7185 + * This program is distributed in the hope that it will be useful,
7186 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7187 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7188 + * GNU General Public License for more details.
7190 + * You should have received a copy of the GNU General Public License
7191 + * along with this program; see the file COPYING. If not, write to
7192 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7200 + * Macro definition and typedefs
7204 +#ifndef _AAC_UNIX_DEFS
7205 +#define _AAC_UNIX_DEFS
7207 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7209 +#define AAC_MAX_ADAPTERS 64
7216 +#define PAGE_SIZE 4096
7219 +typedef VOID *PVOID;
7221 +typedef char CHAR, *PCHAR;
7222 +typedef unsigned char UCHAR, *PUCHAR;
7223 +typedef short SHORT, *PSHORT;
7224 +typedef short CSHORT, *PCSHORT;
7225 +typedef unsigned short USHORT, *PUSHORT;
7226 +typedef unsigned long ULONG, *PULONG;
7227 +typedef long LONG, *PLONG;
7229 +typedef unsigned long BOOLEAN;
7231 +typedef unsigned long AAC_STATUS, *PNT_STATUS;
7234 + unsigned long LowPart;
7235 + unsigned long HighPart;
7238 +typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7241 +typedef struct _AFA_IOCTL_CMD {
7247 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7251 +// Singly linked list structure. Can be used as either a list head, or
7255 +typedef struct _SINGLE_LIST_ENTRY {
7256 + struct _SINGLE_LIST_ENTRY *Next;
7257 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7261 +// Calculate the address of the base of the structure given its type, and an
7262 +// address of a field within the structure.
7265 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7266 + (PCHAR)(address) - \
7267 + (PCHAR)(&((type *)0)->field)))
7269 +typedef PVOID PMDL;
7270 +typedef PVOID PDEVICE_OBJECT;
7271 +typedef PVOID PADAPTER_OBJECT;
7272 +typedef ULONG KIRQL;
7273 +typedef PVOID HANDLE;
7274 +typedef PVOID KDPC, *PKDPC;
7275 +typedef PVOID PFILE_OBJECT;
7276 +typedef PVOID PIRP;
7277 +typedef PVOID PDRIVER_OBJECT;
7278 +typedef ULONG KTIMER;
7281 +#define STATUS_SUCCESS 0x00000000
7282 +#define STATUS_PENDING 0x40000001
7283 +#define STATUS_IO_TIMEOUT 0xc0000001
7284 +#define STATUS_UNSUCCESSFUL 0xc0000002
7285 +#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7286 +#define STATUS_BUFFER_OVERFLOW 0xc0000003
7294 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7300 +typedef struct _ZONE_SEGMENT_HEADER {
7301 + SINGLE_LIST_ENTRY SegmentList;
7303 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7305 +typedef struct _ZONE_HEADER {
7306 + SINGLE_LIST_ENTRY FreeList;
7307 + SINGLE_LIST_ENTRY SegmentList;
7309 + ULONG TotalSegmentSize;
7310 +} ZONE_HEADER, *PZONE_HEADER;
7316 +// ExAllocateFromZone(
7317 +// IN PZONE_HEADER Zone
7320 +// Routine Description:
7322 +// This routine removes an entry from the zone and returns a pointer to it.
7326 +// Zone - Pointer to the zone header controlling the storage from which the
7327 +// entry is to be allocated.
7331 +// The function value is a pointer to the storage allocated from the zone.
7335 +#define ExAllocateFromZone(Zone) \
7336 + (PVOID)((Zone)->FreeList.Next); \
7337 + if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7343 +// IN PZONE_HEADER Zone,
7347 +// Routine Description:
7349 +// This routine places the specified block of storage back onto the free
7350 +// list in the specified zone.
7354 +// Zone - Pointer to the zone header controlling the storage to which the
7355 +// entry is to be inserted.
7357 +// Block - Pointer to the block of storage to be freed back to the zone.
7361 +// Pointer to previous block of storage that was at the head of the free
7362 +// list. NULL implies the zone went from no available free blocks to
7363 +// at least one free block.
7367 +#define ExFreeToZone(Zone,Block) \
7368 + ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7369 + (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7370 + ((PSINGLE_LIST_ENTRY)(Block))->Next \
7377 +// IN PZONE_HEADER Zone
7380 +// Routine Description:
7382 +// This routine determines if the specified zone is full or not. A zone
7383 +// is considered full if the free list is empty.
7387 +// Zone - Pointer to the zone header to be tested.
7391 +// TRUE if the zone is full and FALSE otherwise.
7395 +#define ExIsFullZone(Zone) \
7396 + ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7399 +#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7400 +#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7403 +// Doubly-linked list manipulation routines. Implemented as macros
7404 +// but logically these are procedures.
7409 +// InitializeListHead(
7410 +// PLIST_ENTRY ListHead
7414 +#define InitializeListHead(ListHead) (\
7415 + (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7420 +// PLIST_ENTRY ListHead
7424 +#define IsListEmpty(ListHead) \
7425 + ((ListHead)->Flink == (ListHead))
7430 +// PLIST_ENTRY ListHead
7434 +#define RemoveHeadList(ListHead) \
7435 + (ListHead)->Flink;\
7436 + {RemoveEntryList((ListHead)->Flink)}
7441 +// RemoveEntryList(
7442 +// PLIST_ENTRY Entry
7446 +#define RemoveEntryList(Entry) {\
7447 + PLIST_ENTRY _EX_Blink;\
7448 + PLIST_ENTRY _EX_Flink;\
7449 + _EX_Flink = (Entry)->Flink;\
7450 + _EX_Blink = (Entry)->Blink;\
7451 + _EX_Blink->Flink = _EX_Flink;\
7452 + _EX_Flink->Blink = _EX_Blink;\
7458 +// PLIST_ENTRY ListHead,
7459 +// PLIST_ENTRY Entry
7463 +#define InsertTailList(ListHead,Entry) {\
7464 + PLIST_ENTRY _EX_Blink;\
7465 + PLIST_ENTRY _EX_ListHead;\
7466 + _EX_ListHead = (ListHead);\
7467 + _EX_Blink = _EX_ListHead->Blink;\
7468 + (Entry)->Flink = _EX_ListHead;\
7469 + (Entry)->Blink = _EX_Blink;\
7470 + _EX_Blink->Flink = (Entry);\
7471 + _EX_ListHead->Blink = (Entry);\
7474 +#endif /* AAC_UNIX_DEFS */
7475 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7476 --- linux-2.4.9/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 18:00:00 1969
7477 +++ linux/drivers/scsi/aacraid/include/adapter.h Thu Aug 16 13:41:30 2001
7480 + * Adaptec aacraid device driver for Linux.
7482 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7484 + * This program is free software; you can redistribute it and/or modify
7485 + * it under the terms of the GNU General Public License as published by
7486 + * the Free Software Foundation; either version 2, or (at your option)
7487 + * any later version.
7489 + * This program is distributed in the hope that it will be useful,
7490 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7491 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7492 + * GNU General Public License for more details.
7494 + * You should have received a copy of the GNU General Public License
7495 + * along with this program; see the file COPYING. If not, write to
7496 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7503 + * The module contains the definitions for a comm layer view of the adapter.
7512 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7514 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7516 + NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7517 + NODE_BYTE_SIZE NodeByteSize;
7518 + PFILE_OBJECT FileObject; // used for cleanup
7519 + LIST_ENTRY NextContext; // used to link context's into a linked list
7520 + OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7521 + BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7522 + ULONG FibCount; // total number of FIBs on FibList
7523 + LIST_ENTRY FibList;
7524 +} GET_ADAPTER_FIB_CONTEXT;
7525 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7528 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7530 + struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7531 + ULONG FibContextSegmentSize;
7532 + PVOID FibContextSegment;
7534 + MAPFIB_CONTEXT MapFibContext;
7536 +} FIB_CONTEXT_ZONE_SEGMENT;
7537 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7539 +typedef struct _AFA_COMM_ADAPTER {
7541 + struct _AFA_COMM_ADAPTER *NextAdapter;
7544 + // The following fields are used to allocate FIB context structures
7545 + // using the zone allocator, and other fixed sized structures from a
7546 + // small cache. The mutex protects access to the zone/lists
7549 + ZONE_HEADER FibContextZone;
7550 + OS_SPINLOCK *FibContextZoneSpinLock;
7551 + int FibContextZoneExtendSize;
7553 + PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7555 + PVOID FibContextTimedOutList;
7558 + ULONG SyncFibPhysicalAddress;
7560 + PCOMM_REGION CommRegion;
7562 + OS_SPINLOCK_COOKIE SpinLockCookie;
7565 + // The user API will use an IOCTL to register itself to receive FIBs
7566 + // from the adapter. The following list is used to keep track of all
7567 + // the threads that have requested these FIBs. The mutex is used to
7568 + // synchronize access to all data associated with the adapter fibs.
7570 + LIST_ENTRY AdapterFibContextList;
7571 + OS_CVLOCK *AdapterFibMutex;
7574 + // The following holds which FileObject is allow to send configuration
7575 + // commands to the adapter that would modify the configuration.
7577 + // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7580 + PFILE_OBJECT AdapterConfigFileObject;
7583 + // The following is really here because of the simulator
7585 + BOOLEAN InterruptsBelowDpc;
7588 + // The following is the device specific extension.
7590 + PVOID AdapterExtension;
7591 + PFSAPORT_FUNCS AdapterFuncs;
7595 + // The following are user variables that are specific to the mini port.
7597 + PFSA_USER_VAR AdapterUserVars;
7598 + ULONG AdapterUserVarsSize;
7601 + // The following is the number of the individual adapter..i.e. \Device\Afa0
7603 + LONG AdapterNumber;
7605 + AFACOMM_FUNCS CommFuncs;
7607 + PAFA_CLASS_DRIVER ClassDriverList;
7609 + BOOLEAN AifThreadStarted;
7611 +} AFA_COMM_ADAPTER;
7613 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7616 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7617 + Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7619 +#define FsaFreeAdapterCommArea(Adapter) \
7620 + Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7623 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7624 + Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7626 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7627 + Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7629 +#define InterruptAdapter(Adapter) \
7630 + Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7632 +#define NotifyAdapter(Adapter, AdapterEvent) \
7633 + Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7635 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7636 + Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7638 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7639 + Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7642 +#endif // _ADAPTER_
7643 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7644 --- linux-2.4.9/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 18:00:00 1969
7645 +++ linux/drivers/scsi/aacraid/include/afacomm.h Thu Aug 16 13:41:30 2001
7648 + * Adaptec aacraid device driver for Linux.
7650 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7652 + * This program is free software; you can redistribute it and/or modify
7653 + * it under the terms of the GNU General Public License as published by
7654 + * the Free Software Foundation; either version 2, or (at your option)
7655 + * any later version.
7657 + * This program is distributed in the hope that it will be useful,
7658 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7659 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7660 + * GNU General Public License for more details.
7662 + * You should have received a copy of the GNU General Public License
7663 + * along with this program; see the file COPYING. If not, write to
7664 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7670 + * This module defines all of the external interfaces to the AFA comm layer.
7678 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7680 +#include "fsaport.h"
7682 +typedef void *PFIB_CONTEXT;
7686 + PVOID FibCallbackContext,
7687 + PFIB_CONTEXT FibContext,
7692 +typedef PFIB_CONTEXT
7693 +(*PAFA_COMM_ALLOCATE_FIB) (
7694 + IN PVOID AdapterExtension
7698 +(*PAFA_COMM_FREE_FIB) (
7699 + IN PFIB_CONTEXT FibContext
7704 +(*PAFA_COMM_DEALLOCATE_FIB) (
7705 + IN PFIB_CONTEXT FibContext
7710 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7711 + IN PFIB_CONTEXT FibContext
7715 +(*PAFA_COMM_INITIALIZE_FIB) (
7716 + IN PFIB_CONTEXT FibContext
7720 +(*PAFA_COMM_GET_FIB_DATA) (
7721 + IN PFIB_CONTEXT FibContext
7725 +(*PAFA_COMM_SEND_FIB) (
7726 + IN FIB_COMMAND Command,
7727 + IN PFIB_CONTEXT FibContext,
7729 + IN COMM_PRIORITIES Priority,
7732 + IN BOOLEAN ResponseExpected,
7733 + IN PFIB_CALLBACK FibCallback,
7734 + IN PVOID FibCallbackContext
7738 +(*PAFA_COMM_COMPLETE_FIB) (
7739 + IN PFIB_CONTEXT FibContext
7743 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7744 + IN PFIB_CONTEXT FibContext,
7749 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7750 + PVOID AdapterExtension,
7751 + FIB_COMMAND Command,
7755 + USHORT *ResponseSize
7759 +typedef struct _AFACOMM_FUNCS {
7760 + ULONG SizeOfAfaCommFuncs;
7761 + PAFA_COMM_ALLOCATE_FIB AllocateFib;
7762 + PAFA_COMM_FREE_FIB FreeFib;
7763 + PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7764 + PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7765 + PAFA_COMM_INITIALIZE_FIB InitializeFib;
7766 + PAFA_COMM_GET_FIB_DATA GetFibData;
7767 + PAFA_COMM_SEND_FIB SendFib;
7768 + PAFA_COMM_COMPLETE_FIB CompleteFib;
7769 + PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7770 + PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7771 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7772 + PFSA_BUILD_SGMAP BuildSgMap;
7773 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7775 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7779 +(*PAFA_CLASS_OPEN_ADAPTER) (
7785 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7791 +(*PAFA_CLASS_DEV_CONTROL) (
7793 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
7798 +(*PAFA_CLASS_HANDLE_AIF) (
7800 + IN PFIB_CONTEXT FibContext
7804 +typedef struct _AFA_NEW_CLASS_DRIVER {
7805 + PVOID ClassDriverExtension;
7806 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7807 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7808 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7809 + PAFA_CLASS_HANDLE_AIF HandleAif;
7810 + PFSA_USER_VAR UserVars;
7811 + ULONG NumUserVars;
7812 +} AFA_NEW_CLASS_DRIVER;
7813 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7816 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7817 + PAFACOMM_FUNCS CommFuncs;
7818 + PVOID CommPortExtension;
7819 + PVOID MiniPortExtension;
7820 + OS_SPINLOCK_COOKIE SpinLockCookie;
7822 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7823 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7826 +typedef struct _AFA_CLASS_DRIVER {
7827 + struct _AFA_CLASS_DRIVER *Next;
7828 + PVOID ClassDriverExtension;
7829 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7830 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7831 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7832 + PAFA_CLASS_HANDLE_AIF HandleAif;
7833 +} AFA_CLASS_DRIVER;
7834 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7837 +#endif // _AFACOMM_
7838 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7839 --- linux-2.4.9/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7840 +++ linux/drivers/scsi/aacraid/include/aifstruc.h Thu Aug 16 13:41:30 2001
7843 + * Adaptec aacraid device driver for Linux.
7845 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7847 + * This program is free software; you can redistribute it and/or modify
7848 + * it under the terms of the GNU General Public License as published by
7849 + * the Free Software Foundation; either version 2, or (at your option)
7850 + * any later version.
7852 + * This program is distributed in the hope that it will be useful,
7853 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7854 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7855 + * GNU General Public License for more details.
7857 + * You should have received a copy of the GNU General Public License
7858 + * along with this program; see the file COPYING. If not, write to
7859 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7865 + * Define all shared data types relating to
7866 + * the set of features utilizing Adapter
7872 +#ifndef _AIFSTRUC_H
7873 +#define _AIFSTRUC_H
7875 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7877 +#include <protocol.h>
7880 +// Progress report structure definitions
7883 + AifJobStsSuccess = 1,
7884 + AifJobStsFinished,
7887 + AifJobStsLastReportMarker = 100, // All before mean last report
7888 + AifJobStsSuspended,
7892 +#ifdef AAC_32BIT_ENUMS
7893 +typedef _E_AifJobStatus AifJobStatus;
7895 +typedef AAC_UINT32 AifJobStatus;
7900 + AifJobScsiMin = 1, // Minimum value for Scsi operation
7901 + AifJobScsiZero, // SCSI device clear operation
7902 + AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7903 + AifJobScsiExercise, // SCSI device Exercise operation
7904 + AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7905 + // Add new SCSI task types above this line
7906 + AifJobScsiMax = 99, // Max Scsi value
7907 + AifJobCtrMin, // Min Ctr op value
7908 + AifJobCtrZero, // Container clear operation
7909 + AifJobCtrCopy, // Container copy operation
7910 + AifJobCtrCreateMirror, // Container Create Mirror operation
7911 + AifJobCtrMergeMirror, // Container Merge Mirror operation
7912 + AifJobCtrScrubMirror, // Container Scrub Mirror operation
7913 + AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7914 + AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7915 + AifJobCtrMorph, // Container morph operation
7916 + AifJobCtrPartCopy, // Container Partition copy operation
7917 + AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7918 + AifJobCtrCrazyCache, // crazy cache
7919 + // Add new container task types above this line
7920 + AifJobCtrMax = 199, // Max Ctr type operation
7921 + AifJobFsMin, // Min Fs type operation
7922 + AifJobFsCreate, // File System Create operation
7923 + AifJobFsVerify, // File System Verify operation
7924 + AifJobFsExtend, // File System Extend operation
7925 + // Add new file system task types above this line
7926 + AifJobFsMax = 299, // Max Fs type operation
7927 + // Add new API task types here
7928 + AifJobApiFormatNTFS, // Format a drive to NTFS
7929 + AifJobApiFormatFAT, // Format a drive to FAT
7930 + AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7931 + AifJobApiFormatFAT32, // Format a drive to FAT32
7932 + AifJobApiMax = 399, // Max API type operation
7933 + AifJobCtlContinuousCtrVerify, // Controller operation
7934 + AifJobCtlMax = 499 // Max Controller type operation
7938 +#ifdef AAC_32BIT_ENUMS
7939 +typedef _E_AifJobType AifJobType;
7941 +typedef AAC_UINT32 AifJobType;
7944 +union SrcContainer {
7946 + AAC_UINT32 master;
7947 + AAC_UINT32 container;
7950 +union DstContainer {
7953 + AAC_UINT32 container;
7957 +struct AifContainers {
7958 + union SrcContainer src;
7959 + union DstContainer dst;
7962 +union AifJobClient {
7964 + struct AifContainers container; // For Container nd file system progress ops;
7965 + AAC_INT32 scsi_dh; // For SCSI progress ops
7968 +struct AifJobDesc {
7969 + AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7970 + AifJobType type; // Operation that is being performed
7971 + union AifJobClient client; // Details
7974 +struct AifJobProgressReport {
7975 + struct AifJobDesc jd;
7976 + AifJobStatus status;
7977 + AAC_UINT32 finalTick;
7978 + AAC_UINT32 currentTick;
7979 + AAC_UINT32 jobSpecificData1;
7980 + AAC_UINT32 jobSpecificData2;
7984 +// Notification of events structure definition starts here
7987 + // General application notifies start here
7988 + AifEnGeneric = 1, // Generic notification
7989 + AifEnTaskComplete, // Task has completed
7990 + AifEnConfigChange, // Adapter configuration change occurred
7991 + AifEnContainerChange, // Adapter specific container configuration change
7992 + AifEnDeviceFailure, // SCSI device failed
7993 + AifEnMirrorFailover, // Mirror failover started
7994 + AifEnContainerEvent, // Significant container event
7995 + AifEnFileSystemChange, // File system changed
7996 + AifEnConfigPause, // Container pause event
7997 + AifEnConfigResume, // Container resume event
7998 + AifEnFailoverChange, // Failover space assignment changed
7999 + AifEnRAID5RebuildDone, // RAID5 rebuild finished
8000 + AifEnEnclosureManagement, // Enclosure management event
8001 + AifEnBatteryEvent, // Significant NV battery event
8002 + AifEnAddContainer, // A new container was created.
8003 + AifEnDeleteContainer, // A container was deleted.
8004 + AifEnSMARTEvent, // SMART Event
8005 + AifEnBatteryNeedsRecond, // The battery needs reconditioning
8006 + AifEnClusterEvent, // Some cluster event
8007 + AifEnDiskSetEvent, // A disk set event occured.
8008 + // Add general application notifies above this comment
8009 + AifDriverNotifyStart=199, // Notifies for host driver go here
8010 + // Host driver notifications start here
8011 + AifDenMorphComplete, // A morph operation completed
8012 + AifDenVolumeExtendComplete // A volume expand operation completed
8013 + // Add host driver notifications above this comment
8014 +} _E_AifEventNotifyType;
8016 +#ifdef AAC_32BIT_ENUMS
8017 +typedef _E_AifEventNotifyType AifEventNotifyType;
8019 +typedef AAC_UINT32 AifEventNotifyType;
8022 +struct AifEnsGeneric {
8023 + AAC_INT8 text[132]; // Generic text
8026 +struct AifEnsDeviceFailure {
8027 + AAC_INT32 deviceHandle; // SCSI device handle
8030 +struct AifEnsMirrorFailover {
8031 + AAC_UINT32 container; // Container with failed element
8032 + AAC_UINT32 failedSlice; // Old slice which failed
8033 + AAC_UINT32 creatingSlice; // New slice used for auto-create
8036 +struct AifEnsContainerChange {
8037 + AAC_UINT32 container[2]; // container that changed, -1 if no container
8040 +struct AifEnsContainerEvent {
8041 + AAC_UINT32 container; // container number
8042 + AAC_UINT32 eventType; // event type
8045 +struct AifEnsEnclosureEvent {
8046 + AAC_UINT32 empID; // enclosure management processor number
8047 + AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
8048 + AAC_UINT32 eventType; // event type
8052 +struct AifEnsBatteryEvent {
8053 + NVBATT_TRANSITION transition_type; // e.g. from low to ok
8054 + NVBATTSTATUS current_state; // current battery state
8055 + NVBATTSTATUS prior_state; // previous battery state
8058 +struct AifEnsDiskSetEvent {
8059 + AAC_UINT32 eventType;
8060 + AAC_UINT32 DsNum[2];
8061 + AAC_UINT32 CreatorId[2];
8066 +typedef enum _CLUSTER_AIF_EVENT {
8067 + CLUSTER_NULL_EVENT = 0,
8068 + CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
8069 + // (partner's agent may be up)
8070 + CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8071 + // (partner has rebooted)
8072 +} _E_CLUSTER_AIF_EVENT;
8074 +#ifdef AAC_32BIT_ENUMS
8075 +typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
8077 +typedef AAC_UINT32 CLUSTER_AIF_EVENT;
8080 +struct AifEnsClusterEvent {
8081 + CLUSTER_AIF_EVENT eventType;
8084 +struct AifEventNotify {
8085 + AifEventNotifyType type;
8087 + struct AifEnsGeneric EG;
8088 + struct AifEnsDeviceFailure EDF;
8089 + struct AifEnsMirrorFailover EMF;
8090 + struct AifEnsContainerChange ECC;
8091 + struct AifEnsContainerEvent ECE;
8092 + struct AifEnsEnclosureEvent EEE;
8093 + struct AifEnsBatteryEvent EBE;
8094 + struct AifEnsDiskSetEvent EDS;
8096 + struct AifEnsSMARTEvent ES;
8098 + struct AifEnsClusterEvent ECLE;
8103 +// Generic API structure
8105 +#define AIF_API_REPORT_MAX_SIZE 64
8106 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8111 +// For FIB communication, we need all of the following things
8112 +// to send back to the user.
8115 + AifCmdEventNotify = 1, // Notify of event
8116 + AifCmdJobProgress, // Progress report
8117 + AifCmdAPIReport, // Report from other user of API
8118 + AifCmdDriverNotify, // Notify host driver of event
8119 + AifReqJobList = 100, // Gets back complete job list
8120 + AifReqJobsForCtr, // Gets back jobs for specific container
8121 + AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8122 + AifReqJobReport, // Gets back a specific job report or list of them
8123 + AifReqTerminateJob, // Terminates job
8124 + AifReqSuspendJob, // Suspends a job
8125 + AifReqResumeJob, // Resumes a job
8126 + AifReqSendAPIReport, // API generic report requests
8127 + AifReqAPIJobStart, // Start a job from the API
8128 + AifReqAPIJobUpdate, // Update a job report from the API
8129 + AifReqAPIJobFinish // Finish a job from the API
8132 +#ifdef AAC_32BIT_ENUMS
8133 +typedef _E_AIFCOMMAND AIFCOMMAND;
8135 +typedef AAC_UINT32 AIFCOMMAND;
8141 +// Adapter Initiated FIB command structures. Start with the adapter
8142 +// initiated FIBs that really come from the adapter, and get responded
8145 +typedef struct _AIFCOMMANDTOHOST {
8146 + AIFCOMMAND command; // Tell host what type of notify this is
8147 + AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8149 + // First define data going to the adapter
8150 + struct AifEventNotify EN; // Event notify structure
8151 + struct AifJobProgressReport PR[1]; // Progress report
8154 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8157 +#endif // _AIFSTRUC_H
8161 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8162 --- linux-2.4.9/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 18:00:00 1969
8163 +++ linux/drivers/scsi/aacraid/include/build_number.h Thu Aug 16 18:16:55 2001
8166 + * Adaptec aacraid device driver for Linux.
8168 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8170 + * This program is free software; you can redistribute it and/or modify
8171 + * it under the terms of the GNU General Public License as published by
8172 + * the Free Software Foundation; either version 2, or (at your option)
8173 + * any later version.
8175 + * This program is distributed in the hope that it will be useful,
8176 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8177 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8178 + * GNU General Public License for more details.
8180 + * You should have received a copy of the GNU General Public License
8181 + * along with this program; see the file COPYING. If not, write to
8182 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8188 + * DThis module contains the single location where the build number
8194 +#ifndef _BUILD_NUMBER_H
8195 +#define _BUILD_NUMBER_H
8197 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.7 2001/08/10 Adaptec, Inc.";
8199 +#define REV_BUILD_NUMBER 5125
8202 +#endif // _BUILD_NUMBER_H
8204 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8205 --- linux-2.4.9/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8206 +++ linux/drivers/scsi/aacraid/include/commdata.h Thu Aug 16 13:41:30 2001
8209 + * Adaptec aacraid device driver for Linux.
8211 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8213 + * This program is free software; you can redistribute it and/or modify
8214 + * it under the terms of the GNU General Public License as published by
8215 + * the Free Software Foundation; either version 2, or (at your option)
8216 + * any later version.
8218 + * This program is distributed in the hope that it will be useful,
8219 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8220 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8221 + * GNU General Public License for more details.
8223 + * You should have received a copy of the GNU General Public License
8224 + * along with this program; see the file COPYING. If not, write to
8225 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8230 + * Abstract: Define the communication layer of the adapter
8238 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8240 +typedef struct _FSA_COMM_DATA {
8243 + // A pointer to the Driver and Device object we were initialized with
8246 + PDRIVER_OBJECT DriverObject;
8247 + PDEVICE_OBJECT DeviceObject;
8250 + // A list of all adapters we have configured.
8253 + PAFA_COMM_ADAPTER AdapterList;
8254 + ULONG TotalAdapters;
8257 + // Adapter timeout support. This is the default timeout to wait for the
8258 + // adapter to respond(setup in initfs.c), and a boolean to indicate if
8259 + // we should timeout requests to the adapter or not.
8262 + LARGE_INTEGER QueueFreeTimeout;
8263 + LARGE_INTEGER AdapterTimeout;
8264 + BOOLEAN EnableAdapterTimeouts;
8266 + ULONG FibTimeoutIncrement;
8270 + ULONG NoResponseSent;
8271 + ULONG NoResponseRecved;
8273 + ULONG AsyncRecved;
8275 + ULONG NormalRecved;
8277 + ULONG TimedOutFibs;
8280 + KTIMER TimeoutTimer;
8283 + // If this value is set to 1 then interrupt moderation will occur
8284 + // in the base commuication support.
8287 + ULONG EnableInterruptModeration;
8289 + int HardInterruptModeration;
8290 + int HardInterruptModeration1;
8291 + int PeakFibsConsumed;
8292 + int ZeroFibsConsumed;
8293 + int EnableFibTimeoutBreak;
8294 + ULONG FibTimeoutSeconds;
8297 + // The following holds all of the available user settable variables.
8298 + // This includes all for the comm layer as well as any from the class
8299 + // drivers as well.
8302 + FSA_USER_VAR *UserVars;
8303 + ULONG NumUserVars;
8308 +#ifdef FIB_CHECKSUMS
8309 + int do_fib_checksums;
8313 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8315 +extern FSA_COMM_DATA FsaCommData;
8318 +#endif // _COMMDATA_
8320 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8321 --- linux-2.4.9/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 18:00:00 1969
8322 +++ linux/drivers/scsi/aacraid/include/commerr.h Thu Aug 16 18:16:55 2001
8325 + * Adaptec aacraid device driver for Linux.
8327 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8329 + * This program is free software; you can redistribute it and/or modify
8330 + * it under the terms of the GNU General Public License as published by
8331 + * the Free Software Foundation; either version 2, or (at your option)
8332 + * any later version.
8334 + * This program is distributed in the hope that it will be useful,
8335 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8336 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8337 + * GNU General Public License for more details.
8339 + * You should have received a copy of the GNU General Public License
8340 + * along with this program; see the file COPYING. If not, write to
8341 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8346 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8355 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8358 +// Note: comments in the .mc file must use both ";" and "//".
8360 +// Status values are 32 bit values layed out as follows:
8362 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8363 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8364 +// +---+-+-------------------------+-------------------------------+
8365 +// |Sev|C| Facility | Code |
8366 +// +---+-+-------------------------+-------------------------------+
8370 +// Sev - is the severity code
8373 +// 01 - Informational
8377 +// C - is the Customer code flag
8379 +// Facility - is the facility code
8381 +// Code - is the facility's status code
8386 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8387 +// called with a device, the name of the device will be inserted into
8388 +// the message at %1. Otherwise, the place of %1 will be left empty.
8389 +// In either case, the insertion strings from the driver's error log
8390 +// entry starts at %2. In other words, the first insertion string goes
8391 +// to %2, the second to %3 and so on.
8395 +// Values are 32 bit values layed out as follows:
8397 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8398 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8399 +// +---+-+-+-----------------------+-------------------------------+
8400 +// |Sev|C|R| Facility | Code |
8401 +// +---+-+-+-----------------------+-------------------------------+
8405 +// Sev - is the severity code
8408 +// 01 - Informational
8412 +// C - is the Customer code flag
8414 +// R - is a reserved bit
8416 +// Facility - is the facility code
8418 +// Code - is the facility's status code
8421 +// Define the facility codes
8425 +#define FACILITY_FSAFS_ERROR_CODE 0x7
8430 +// MessageId: FSAFS_FIB_INVALID
8434 +// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8436 +#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8440 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8444 +// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8446 +#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8448 +#endif /* _FSAERR_ */
8449 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8450 --- linux-2.4.9/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 18:00:00 1969
8451 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Thu Aug 16 13:41:30 2001
8454 + * Adaptec aacraid device driver for Linux.
8456 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8458 + * This program is free software; you can redistribute it and/or modify
8459 + * it under the terms of the GNU General Public License as published by
8460 + * the Free Software Foundation; either version 2, or (at your option)
8461 + * any later version.
8463 + * This program is distributed in the hope that it will be useful,
8464 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8465 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8466 + * GNU General Public License for more details.
8468 + * You should have received a copy of the GNU General Public License
8469 + * along with this program; see the file COPYING. If not, write to
8470 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8473 + * commfibcontext.h
8475 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8480 +#ifndef _COMM_FIB_CONTEXT_
8481 +#define _COMM_FIB_CONTEXT_
8483 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8485 +typedef struct _COMM_FIB_CONTEXT {
8487 + PVOID Next; // this is used by the zone allocation
8490 + // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8492 + // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8493 + // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8497 + NODE_TYPE_CODE NodeTypeCode;
8498 + NODE_BYTE_SIZE NodeByteSize;
8501 + // The Adapter that this I/O is destined for.
8504 + PAFA_COMM_ADAPTER Adapter;
8506 + PHYSICAL_ADDRESS LogicalFibAddress;
8509 + // This is the event the sendfib routine will wait on if the
8510 + // caller did not pass one and this is synch io.
8514 + OS_CVLOCK *FsaEventMutex;
8516 + ULONG FibComplete; // gets set to 1 when fib is complete
8518 + PFIB_CALLBACK FibCallback;
8519 + PVOID FibCallbackContext;
8524 +#ifdef GATHER_FIB_TIMES
8525 + LARGE_INTEGER FibTimeStamp;
8526 + PFIB_TIMES FibTimesPtr;
8530 + // The following is used to put this fib context onto the Outstanding I/O queue.
8533 + LIST_ENTRY QueueEntry;
8536 + // The following is used to timeout a fib to the adapter.
8539 + LARGE_INTEGER TimeoutValue;
8545 +} COMM_FIB_CONTEXT;
8546 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8548 +#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8550 +#endif /* _COMM_FIB_CONTEXT_ */
8551 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8552 --- linux-2.4.9/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8553 +++ linux/drivers/scsi/aacraid/include/comprocs.h Thu Aug 16 13:41:30 2001
8556 + * Adaptec aacraid device driver for Linux.
8558 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8560 + * This program is free software; you can redistribute it and/or modify
8561 + * it under the terms of the GNU General Public License as published by
8562 + * the Free Software Foundation; either version 2, or (at your option)
8563 + * any later version.
8565 + * This program is distributed in the hope that it will be useful,
8566 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8567 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8568 + * GNU General Public License for more details.
8570 + * You should have received a copy of the GNU General Public License
8571 + * along with this program; see the file COPYING. If not, write to
8572 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8577 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8585 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8587 +#include "osheaders.h"
8589 +#include "AacGenericTypes.h"
8591 +#include "aac_unix_defs.h"
8593 +#include "nodetype.h"
8595 +// #define GATHER_FIB_TIMES
8597 +#include "fsatypes.h"
8599 +#include "perfpack.h"
8601 +#include "comstruc.h"
8603 +//#include "unix_protocol.h"
8607 +#include "protocol.h"
8609 +#include "fsaioctl.h"
8611 +#undef GATHER_FIB_TIMES
8613 +#include "aifstruc.h"
8615 +#include "fsaport.h"
8616 +#include "comsup.h"
8617 +#include "afacomm.h"
8618 +#include "adapter.h"
8620 +#include "commfibcontext.h"
8621 +#include "comproto.h"
8622 +#include "commdata.h"
8623 +#include "commerr.h"
8629 +// The following macro is used when sending and receiving FIBs. It is only used for
8633 +#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8635 +#define FIB_COUNTER_INCREMENT(Counter)
8641 +AfaCommAdapterDeviceControl (
8642 + IN PVOID AdapterArg,
8643 + IN PAFA_IOCTL_CMD IoctlCmdPtr
8647 +#endif // _COMPROCS_
8648 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8649 --- linux-2.4.9/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8650 +++ linux/drivers/scsi/aacraid/include/comproto.h Thu Aug 16 13:41:30 2001
8653 + * Adaptec aacraid device driver for Linux.
8655 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8657 + * This program is free software; you can redistribute it and/or modify
8658 + * it under the terms of the GNU General Public License as published by
8659 + * the Free Software Foundation; either version 2, or (at your option)
8660 + * any later version.
8662 + * This program is distributed in the hope that it will be useful,
8663 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8664 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8665 + * GNU General Public License for more details.
8667 + * You should have received a copy of the GNU General Public License
8668 + * along with this program; see the file COPYING. If not, write to
8669 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8674 + * Abstract: Global routines for the commuication interface that are device
8680 +#ifndef _COMM_PROTO
8681 +#define _COMM_PROTO
8683 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8686 +// define the routines we need so we can commuicate with the
8691 +// The following 4 dpc routines will support commuication from the adapter to the
8692 +// host. There is one DPC routine to deal with each type of queue that supports
8693 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8694 +// These routines will simply pull off the QE and set an event. In the case of a
8695 +// adapter to host command they will also put the FIB on a queue to be processed by
8696 +// a FS thread running at passive level.
8699 +// Handle queue not full notification to the file system thread waiting for a queue entry
8703 + IN PCOMM_REGION CommRegion
8706 +// Adapter to host normal priority responses
8709 +HostResponseNormalDpc(
8710 + IN PCOMM_QUE OurQueue
8713 +// Adapter to host high priority responses
8715 +HostResponseHighDpc(
8716 + IN PCOMM_QUE OurQueue
8719 +// Adapter to host high priority commands
8721 +HostCommandHighDpc(
8722 + IN PCOMM_QUE OurQueue
8726 +// Adapter to host normal priority commands
8728 +HostCommandNormDpc(
8729 + IN PCOMM_QUE OurQueue
8737 + FIB_COMMAND Command,
8741 + USHORT *ResponseSize
8751 + IN PFIB_CONTEXT FibContext
8756 + IN PFIB_CONTEXT FibContext
8761 + IN PFIB_CONTEXT FibContext
8768 + IN FIB_COMMAND Command,
8769 + IN PFIB_CONTEXT FibContext,
8771 + IN COMM_PRIORITIES Priority,
8774 + IN BOOLEAN ResponseExpected,
8775 + IN PFIB_CALLBACK FibCallback,
8776 + IN PVOID FibCallbackContext
8781 + IN PFIB_CONTEXT FibContext
8785 +CompleteAdapterFib(
8786 + IN PFIB_CONTEXT FibContext,
8792 + IN PFIB_CONTEXT FibContext
8798 + IN PFIB_CONTEXT FibContext
8804 +AfaCommOpenAdapter (
8805 + IN PVOID AdapterArg
8809 +AfaCommCloseAdapter (
8810 + IN PVOID AdapterArg
8815 +AfaCommInterruptHost(
8817 + ADAPTER_EVENT AdapterEvent
8821 +#endif // _COMM_PROTO
8822 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8823 --- linux-2.4.9/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8824 +++ linux/drivers/scsi/aacraid/include/comstruc.h Thu Aug 16 13:41:30 2001
8827 + * Adaptec aacraid device driver for Linux.
8829 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8831 + * This program is free software; you can redistribute it and/or modify
8832 + * it under the terms of the GNU General Public License as published by
8833 + * the Free Software Foundation; either version 2, or (at your option)
8834 + * any later version.
8836 + * This program is distributed in the hope that it will be useful,
8837 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8838 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8839 + * GNU General Public License for more details.
8841 + * You should have received a copy of the GNU General Public License
8842 + * along with this program; see the file COPYING. If not, write to
8843 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8848 + * Abstract: This module defines the data structures that make up the communication
8849 + * region for the FSA filesystem. This region is how the host based code
8850 + * communicates both control and data to the adapter based code.
8855 +#ifndef _COMM_STRUCT
8856 +#define _COMM_STRUCT
8858 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8861 +// Define all the constants needed for the communication interface
8864 +// Define how many queue entries each queue will have and the total number of
8865 +// entries for the entire communication interface. Also define how many queues
8868 +#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8869 +#define HOST_HIGH_CMD_ENTRIES 4
8870 +#define HOST_NORM_CMD_ENTRIES 8
8871 +#define ADAP_HIGH_CMD_ENTRIES 4
8872 +#define ADAP_NORM_CMD_ENTRIES 512
8873 +#define HOST_HIGH_RESP_ENTRIES 4
8874 +#define HOST_NORM_RESP_ENTRIES 512
8875 +#define ADAP_HIGH_RESP_ENTRIES 4
8876 +#define ADAP_NORM_RESP_ENTRIES 8
8878 +#define TOTAL_QUEUE_ENTRIES \
8879 + (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8880 + HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8885 +// Set the queues on a 16 byte alignment
8886 +#define QUEUE_ALIGNMENT 16
8890 +// The queue headers define the Communication Region queues. These
8891 +// are physically contiguous and accessible by both the adapter and the
8892 +// host. Even though all queue headers are in the same contiguous block they will be
8893 +// represented as individual units in the data structures.
8896 +typedef AAC_UINT32 QUEUE_INDEX;
8898 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8900 +typedef struct _QUEUE_ENTRY {
8902 + AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8903 + AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8907 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8911 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8912 +// adjacently and in that order.
8914 +typedef struct _QUEUE_HEADERS {
8916 + PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8917 + PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8918 + PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8921 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8924 +// Define all the events which the adapter would like to notify
8927 +typedef enum _ADAPTER_EVENT {
8928 + HostNormCmdQue = 1, // Change in host normal priority command queue
8929 + HostHighCmdQue, // Change in host high priority command queue
8930 + HostNormRespQue, // Change in host normal priority response queue
8931 + HostHighRespQue, // Change in host high priority response queue
8932 + AdapNormRespNotFull,
8933 + AdapHighRespNotFull,
8934 + AdapNormCmdNotFull,
8935 + AdapHighCmdNotFull,
8936 + SynchCommandComplete,
8937 + AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8939 +} _E_ADAPTER_EVENT;
8941 +#ifdef AAC_32BIT_ENUMS
8942 +typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8944 +typedef AAC_UINT32 ADAPTER_EVENT;
8948 +// Define all the events the host wishes to notify the
8951 +typedef enum _HOST_2_ADAP_EVENT {
8952 + AdapNormCmdQue = 1,
8959 + HostNormRespNotFull,
8960 + HostHighRespNotFull,
8961 + HostNormCmdNotFull,
8962 + HostHighCmdNotFull,
8965 +} _E_HOST_2_ADAP_EVENT;
8967 +#ifdef AAC_32BIT_ENUMS
8968 +typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8970 +typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8974 +// Define all the queues that the adapter and host use to communicate
8977 +typedef enum _QUEUE_TYPES {
8978 + HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8979 + HostHighCmdQueue, // Adapter to host high priority command traffic
8980 + AdapNormRespQueue, // Host to adapter normal priority response traffic
8981 + AdapHighRespQueue, // Host to adapter high priority response traffic
8982 + AdapNormCmdQueue, // Host to adapter normal priority command traffic
8983 + AdapHighCmdQueue, // Host to adapter high priority command traffic
8984 + HostNormRespQueue, // Adapter to host normal priority response traffic
8985 + HostHighRespQueue // Adapter to host high priority response traffic
8988 +#ifdef AAC_32BIT_ENUMS
8989 +typedef _E_QUEUE_TYPES QUEUE_TYPES;
8991 +typedef AAC_UINT32 QUEUE_TYPES;
8996 +// Assign type values to the FSA communication data structures
8999 +typedef enum _STRUCT_TYPES {
9005 +#ifdef AAC_32BIT_ENUMS
9006 +typedef _E_STRUCT_TYPES STRUCT_TYPES;
9008 +typedef AAC_UINT32 STRUCT_TYPES;
9012 +// Define the priority levels the FSA communication routines support.
9015 +typedef enum _COMM_PRIORITIES {
9018 +} _E_COMM_PRIORITIES;
9020 +#ifdef AAC_32BIT_ENUMS
9021 +typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
9023 +typedef AAC_UINT32 COMM_PRIORITIES;
9029 +// Define the LIST_ENTRY structure. This structure is used on the NT side to link
9030 +// the FIBs together in a linked list. Since this structure gets compiled on the adapter
9031 +// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
9032 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
9033 +// is already defined.
9034 +#if !defined(_NTDEF_) && !defined(_WINNT_)
9035 +typedef struct _LIST_ENTRY {
9036 + struct _LIST_ENTRY *Flink;
9037 + struct _LIST_ENTRY *Blink;
9039 +typedef LIST_ENTRY *PLIST_ENTRY;
9044 +// Define the FIB. The FIB is the where all the requested data and
9045 +// command information are put to the application on the FSA adapter.
9048 +typedef struct _FIB_HEADER {
9049 + AAC_UINT32 XferState; // Current transfer state for this CCB
9050 + AAC_UINT16 Command; // Routing information for the destination
9051 + AAC_UINT8 StructType; // Type FIB
9052 + AAC_UINT8 Flags; // Flags for FIB
9053 + AAC_UINT16 Size; // Size of this FIB in bytes
9054 + AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
9055 + AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
9056 + AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
9057 + AAC_UINT32 SenderData; // Place holder for the sender to store data
9061 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9062 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9064 + LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
9066 +#else // The MIDL compiler does not support unions without a discriminant.
9067 + struct { // Since nothing during the midl compile actually looks into this
9068 + struct { // structure, this shoudl be ok.
9069 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9070 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9077 +#define FibLinks _u._FibLinks
9080 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9083 +typedef struct _FIB {
9085 +#ifdef BRIDGE //rma
9088 + FIB_HEADER Header;
9090 + AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
9101 +typedef enum _FIB_COMMANDS {
9102 + TestCommandResponse = 1,
9103 + TestAdapterCommand = 2,
9105 + // Lowlevel and comm commands
9107 + LastTestCommand = 100,
9108 + ReinitHostNormCommandQueue = 101,
9109 + ReinitHostHighCommandQueue = 102,
9110 + ReinitHostHighRespQueue = 103,
9111 + ReinitHostNormRespQueue = 104,
9112 + ReinitAdapNormCommandQueue = 105,
9113 + ReinitAdapHighCommandQueue = 107,
9114 + ReinitAdapHighRespQueue = 108,
9115 + ReinitAdapNormRespQueue = 109,
9116 + InterfaceShutdown = 110,
9117 + DmaCommandFib = 120,
9118 + StartProfile = 121,
9119 + TermProfile = 122,
9121 + TakeABreakPt = 124,
9122 + RequestPerfData = 125,
9123 + SetInterruptDefTimer= 126,
9124 + SetInterruptDefCount= 127,
9125 + GetInterruptDefStatus= 128,
9126 + LastCommCommand = 129,
9128 + // Filesystem commands
9130 + NuFileSystem = 300,
9132 + HostFileSystem = 302,
9133 + LastFileSystemCommand = 303,
9135 + // Container Commands
9137 + ContainerCommand = 500,
9138 + ContainerCommand64 = 501,
9140 + // Cluster Commands
9142 + ClusterCommand = 550,
9144 + // Scsi Port commands (scsi passthrough)
9146 + ScsiPortCommand = 600,
9148 + // misc house keeping and generic adapter initiated commands
9151 + CheckRevision = 701,
9152 + FsaHostShutdown = 702,
9153 + RequestAdapterInfo = 703,
9154 + IsAdapterPaused = 704,
9155 + SendHostTime = 705,
9156 + LastMiscCommand = 706
9162 +typedef AAC_UINT16 FIB_COMMAND;
9165 +// Commands that will target the failover level on the FSA adapter
9168 +typedef enum _FIB_XFER_STATE {
9169 + HostOwned = (1<<0),
9170 + AdapterOwned = (1<<1),
9171 + FibInitialized = (1<<2),
9172 + FibEmpty = (1<<3),
9173 + AllocatedFromPool = (1<<4),
9174 + SentFromHost = (1<<5),
9175 + SentFromAdapter = (1<<6),
9176 + ResponseExpected = (1<<7),
9177 + NoResponseExpected = (1<<8),
9178 + AdapterProcessed = (1<<9),
9179 + HostProcessed = (1<<10),
9180 + HighPriority = (1<<11),
9181 + NormalPriority = (1<<12),
9183 + AsyncIo = (1<<13), // rpbfix: remove with new regime
9184 + PageFileIo = (1<<14), // rpbfix: remove with new regime
9185 + ShutdownRequest = (1<<15),
9186 + LazyWrite = (1<<16), // rpbfix: remove with new regime
9187 + AdapterMicroFib = (1<<17),
9188 + BIOSFibPath = (1<<18),
9189 + FastResponseCapable = (1<<19),
9190 + ApiFib = (1<<20) // Its an API Fib.
9192 +} _E_FIB_XFER_STATE;
9195 +typedef enum _FSA_ERRORS {
9198 + FSA_PENDING = 0x01,
9200 + FSA_INVALID_QUEUE = 0x03,
9201 + FSA_NOENTRIES = 0x04,
9202 + FSA_SENDFAILED = 0x05,
9203 + FSA_INVALID_QUEUE_PRIORITY = 0x06,
9204 + FSA_FIB_ALLOCATION_FAILED = 0x07,
9205 + FSA_FIB_DEALLOCATION_FAILED = 0x08
9211 +// The following defines needs to be updated any time there is an incompatible change made
9212 +// to the ADAPTER_INIT_STRUCT structure.
9214 +#define ADAPTER_INIT_STRUCT_REVISION 3
9216 +typedef struct _ADAPTER_INIT_STRUCT {
9217 + AAC_UINT32 InitStructRevision;
9218 + AAC_UINT32 MiniPortRevision;
9219 + AAC_UINT32 FilesystemRevision;
9220 + PAAC_VOID CommHeaderAddress;
9221 + PAAC_VOID FastIoCommAreaAddress;
9222 + PAAC_VOID AdapterFibsPhysicalAddress;
9223 + PAAC_VOID AdapterFibsVirtualAddress;
9224 + AAC_UINT32 AdapterFibsSize;
9225 + AAC_UINT32 AdapterFibAlign;
9226 + PAAC_VOID PrintfBufferAddress;
9227 + AAC_UINT32 PrintfBufferSize;
9228 + AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9229 + AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9230 +} ADAPTER_INIT_STRUCT;
9231 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9233 +#ifdef AAC_32BIT_ENUMS
9234 +typedef _E_FSA_ERRORS FSA_ERRORS;
9236 +typedef AAC_UINT32 FSA_ERRORS;
9239 +typedef enum _LOG_LEVEL {
9241 + LOG_INFORMATIONAL = 20,
9243 + LOG_LOW_ERROR = 40,
9244 + LOG_MEDIUM_ERROR = 50,
9245 + LOG_HIGH_ERROR = 60,
9248 + LOG_WINDBG_PRINT = 90
9251 +#ifdef AAC_32BIT_ENUMS
9252 +typedef _E_LOG_LEVEL LOG_LEVEL;
9254 +typedef AAC_UINT32 LOG_LEVEL;
9258 +#endif //_COMM_STRUCT
9261 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9262 --- linux-2.4.9/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 18:00:00 1969
9263 +++ linux/drivers/scsi/aacraid/include/comsup.h Thu Aug 16 13:41:30 2001
9266 + * Adaptec aacraid device driver for Linux.
9268 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9270 + * This program is free software; you can redistribute it and/or modify
9271 + * it under the terms of the GNU General Public License as published by
9272 + * the Free Software Foundation; either version 2, or (at your option)
9273 + * any later version.
9275 + * This program is distributed in the hope that it will be useful,
9276 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9277 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9278 + * GNU General Public License for more details.
9280 + * You should have received a copy of the GNU General Public License
9281 + * along with this program; see the file COPYING. If not, write to
9282 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9287 + * Abstract: This module defines the data structures that make up the
9288 + * commuication region for the FSA filesystem. This region is
9289 + * how the host based code commuicates both control and data
9290 + * to the adapter based code.
9295 +#ifndef _COMM_SUP_DEF
9296 +#define _COMM_SUP_DEF
9298 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9301 +// The adapter interface specs all queues to be located in the same physically
9302 +// contigous block. The host structure that defines the commuication queues will
9303 +// assume they are each a seperate physically contigous memory region that will
9304 +// support them all being one big contigous block.
9305 +// There is a command and response queue for each level and direction of
9306 +// commuication. These regions are accessed by both the host and adapter.
9308 +typedef struct _COMM_QUE {
9310 + PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9312 + PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9313 + QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9314 + ULONG QueueEntries; // Number of queue entries on this queue
9315 + OS_CV_T QueueFull; // Event to wait on if the queue is full
9316 + OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9317 + // This is only valid for adapter to host command queues.
9318 + OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9319 + KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9320 + ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9321 + // Only queues which the host will be the consumer will this field be valid
9322 + LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9323 + // only valid for command queues which receive entries from the adapter.
9324 + LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9325 + ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9327 + PVOID Adapter; // Back pointer to adapter structure
9330 +typedef COMM_QUE *PCOMM_QUE;
9333 +typedef struct _COMM_REGION {
9335 + COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9336 + COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9338 + COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9339 + COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9341 + COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9342 + COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9344 + COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9345 + COMM_QUE AdapHighRespQue; // A response for high priority host responses
9348 + // The 2 threads below are the threads which handle command traffic from the
9349 + // the adapter. There is one for normal priority and one for high priority queues.
9350 + // These threads will wait on the commandready event for it's queue.
9353 + HANDLE NormCommandThread;
9354 + HANDLE HighCommandThread;
9357 + // This dpc routine will handle the setting the of not full event when the adapter
9358 + // lets us know the queue is not longer full via interrupt
9361 + KDPC QueueNotFullDpc;
9363 +#ifdef API_THROTTLE
9365 + // Support for data I/O throttling to improve CLI performance
9366 + // while the system is under load.
9367 + // This is the throttling mechanism built into the COMM layer.
9368 + // Look in commsup.c, dpcsup.c and comminit.c for use.
9371 + int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9372 + int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9373 + LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9374 + LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9375 + BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9376 + KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9377 + KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9378 + KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9380 + unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9381 + unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9382 + unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9384 + unsigned int ThrottledFibs;
9385 + unsigned int ThrottleTimedoutFibs;
9386 + unsigned int ApiFibs;
9387 + unsigned int NonPassiveFibs;
9388 + unsigned int TotalFibs;
9389 + unsigned int FSInfoFibs;
9391 +#endif // #ifdef API_THROTTLE
9394 +typedef COMM_REGION *PCOMM_REGION;
9396 +#endif // _COMM_SUP
9397 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9398 --- linux-2.4.9/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 18:00:00 1969
9399 +++ linux/drivers/scsi/aacraid/include/fsact.h Thu Aug 16 13:41:30 2001
9402 + * Adaptec aacraid device driver for Linux.
9404 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9406 + * This program is free software; you can redistribute it and/or modify
9407 + * it under the terms of the GNU General Public License as published by
9408 + * the Free Software Foundation; either version 2, or (at your option)
9409 + * any later version.
9411 + * This program is distributed in the hope that it will be useful,
9412 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9413 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9414 + * GNU General Public License for more details.
9416 + * You should have received a copy of the GNU General Public License
9417 + * along with this program; see the file COPYING. If not, write to
9418 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9423 + * Abstract: Common container structures that are required to be
9424 + * known on both the host and adapter.
9431 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9433 +//#include <comstruc.h>
9434 +//#include <fsatypes.h>
9435 +#include <protocol.h> // definitions for FSASTATUS
9439 + * Object-Server / Volume-Manager Dispatch Classes
9441 +typedef enum _VM_COMMANDS {
9444 + VM_ContainerConfig,
9446 + VM_FilesystemIoctl,
9448 + VM_CtBlockRead, // see protocol.h for BlockRead command layout
9449 + VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9450 + VM_SliceBlockRead, // raw access to configured "storage objects"
9451 + VM_SliceBlockWrite,
9452 + VM_DriveBlockRead, // raw access to physical devices
9453 + VM_DriveBlockWrite,
9454 + VM_EnclosureMgt, // enclosure management
9455 + VM_Unused, // used to be diskset management
9456 + VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9457 + VM_CtPerf, // performance test
9458 + VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9459 + VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9460 + VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9461 + MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9464 +#ifdef AAC_32BIT_ENUMS
9465 +typedef _E_VMCOMMAND VMCOMMAND;
9467 +typedef AAC_UINT32 VMCOMMAND;
9473 +// Descriptive information (eg, vital stats)
9474 +// that a content manager might report. The
9475 +// FileArray filesystem component is one example
9476 +// of a content manager. Raw mode might be
9480 +struct FileSysInfo {
9482 + a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9483 + b) FSA usage (implemented by ObjType and ContentState fields)
9486 + e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9487 + f) I-node density - (computed from other fields)
9489 + AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9490 + AAC_UINT32 fsBlockSize;
9491 + AAC_UINT32 fsFragSize;
9492 + AAC_UINT32 fsMaxExtendSize;
9493 + AAC_UINT32 fsSpaceUnits;
9494 + AAC_UINT32 fsMaxNumFiles;
9495 + AAC_UINT32 fsNumFreeFiles;
9496 + AAC_UINT32 fsInodeDensity;
9497 +}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9499 +union ContentManagerInfo {
9500 + struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9504 +// Query for "mountable" objects, ie, objects that are typically
9505 +// associated with a drive letter on the client (host) side.
9508 +typedef struct _MNTOBJ {
9510 + AAC_UINT32 ObjectId;
9511 + FSASTRING FileSystemName; // if applicable
9512 + ContainerCreationInfo CreateInfo; // if applicable
9513 + AAC_UINT32 Capacity;
9514 + FSAVOLTYPE VolType; // substrate structure
9515 + FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9516 + AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9518 + union ContentManagerInfo
9519 + ObjExtension; // Info specific to content manager (eg, filesystem)
9521 + AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9526 +#define FSCS_READONLY 0x0002 // possible result of broken mirror
9530 +typedef struct _MNTINFO {
9532 + VMCOMMAND Command;
9534 + AAC_UINT32 MntCount;
9537 +typedef MNTINFO *PMNTINFO;
9539 +typedef struct _MNTINFORESPONSE {
9542 + FTYPE MntType; // should be same as that requested
9543 + AAC_UINT32 MntRespCount;
9544 + MNTOBJ MntTable[1];
9547 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9551 +// The following command is sent to shut down each container.
9554 +typedef struct _CLOSECOMMAND {
9556 + VMCOMMAND Command;
9557 + AAC_UINT32 ContainerId;
9560 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9563 +#endif /* _FSACT_H_ */
9566 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9567 --- linux-2.4.9/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 18:00:00 1969
9568 +++ linux/drivers/scsi/aacraid/include/fsafs.h Thu Aug 16 13:41:30 2001
9571 + * Adaptec aacraid device driver for Linux.
9573 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9575 + * This program is free software; you can redistribute it and/or modify
9576 + * it under the terms of the GNU General Public License as published by
9577 + * the Free Software Foundation; either version 2, or (at your option)
9578 + * any later version.
9580 + * This program is distributed in the hope that it will be useful,
9581 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9582 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9583 + * GNU General Public License for more details.
9585 + * You should have received a copy of the GNU General Public License
9586 + * along with this program; see the file COPYING. If not, write to
9587 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9592 + * Abstract: Common file system structures that are required to be
9593 + * known on both the host and adapter
9600 +#define _FSAFS_H_ 1
9602 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9604 +#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9607 + * Maximum number of filesystems.
9609 +#define NFILESYS 24
9612 + * File identifier.
9613 + * These are unique and self validating within a filesystem
9614 + * on a single machine and can persist across reboots.
9615 + * The hint field may be volatile and is not guaranteed to persist
9616 + * across reboots but is used to speed up the FID to file object translation
9617 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9618 + * the file object (assuming a filesystem context, i.e. driveno).
9621 + AAC_UINT32 hint; // last used hint for fast reclaim
9622 + AAC_UINT32 f1; // opaque
9623 + AAC_UINT32 f2; // opaque
9624 + } fileid_t; /* intra-filesystem file ID type */
9628 + * Generic file handle
9631 + fsid_t fh_fsid; /* File system id of mount point */
9632 + fileid_t fh_fid; /* File sys specific file id */
9634 +typedef struct fhandle fhandle_t;
9636 +#define FIDSIZE sizeof(fhandle_t)
9640 + AAC_INT8 fid_data[FIDSIZE];
9641 + struct fhandle fsafid;
9643 +} FSAFID; /* FSA File ID type */
9646 +#endif /* _FSAFS_H_ */
9648 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9649 --- linux-2.4.9/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9650 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h Thu Aug 16 13:41:30 2001
9653 + * Adaptec aacraid device driver for Linux.
9655 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9657 + * This program is free software; you can redistribute it and/or modify
9658 + * it under the terms of the GNU General Public License as published by
9659 + * the Free Software Foundation; either version 2, or (at your option)
9660 + * any later version.
9662 + * This program is distributed in the hope that it will be useful,
9663 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9664 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9665 + * GNU General Public License for more details.
9667 + * You should have received a copy of the GNU General Public License
9668 + * along with this program; see the file COPYING. If not, write to
9669 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9674 + * Abstract: Defines the interface structures between user mode applications
9675 + * and the fsa driver. This structures are used in
9676 + * DeviceIoControl() calls.
9681 +#ifndef _FSAIOCTL_H_
9682 +#define _FSAIOCTL_H_
9684 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9686 +#ifndef IOTRACEUSER
9691 +#define FILE_DEVICE_CONTROLLER 0x00000004
9694 +// Macro definition for defining IOCTL and FSCTL function control codes. Note
9695 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9696 +// 2048-4095 are reserved for customers.
9699 +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9700 + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9704 +// Define the method codes for how buffers are passed for I/O and FS controls
9707 +#define METHOD_BUFFERED 0
9710 +#define METHOD_NEITHER 3
9713 +// Define the access check value for any access
9716 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9717 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9718 +// constants *MUST* always be in sync.
9720 +#define FILE_ANY_ACCESS 0
9728 +typedef struct _UNIX_QUERY_DISK {
9729 + AAC_INT32 ContainerNumber;
9733 + AAC_BOOLEAN Valid;
9734 + AAC_BOOLEAN Locked;
9735 + AAC_BOOLEAN Deleted;
9736 + AAC_INT32 Instance;
9737 + AAC_INT8 diskDeviceName[10];
9738 + AAC_BOOLEAN UnMapped;
9740 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9743 +typedef struct _DELETE_DISK {
9744 + AAC_UINT32 NtDiskNumber;
9745 + AAC_UINT32 ContainerNumber;
9747 +typedef DELETE_DISK *PDELETE_DISK;
9750 +#endif /*IOTRACEUSER*/
9752 +#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9753 +#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9756 +#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9759 +#define FSACTL_GET_VAR 0x93
9760 +#define FSACTL_SET_VAR 0xa3
9761 +#define FSACTL_GET_FIBTIMES 0xb3
9762 +#define FSACTL_ZERO_FIBTIMES 0xc3
9765 +#define FSACTL_DELETE_DISK 0x163
9766 +#define FSACTL_QUERY_DISK 0x173
9769 +// AfaComm perfmon ioctls
9770 +#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9773 +#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9776 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9777 + char *AdapterFibContext;
9780 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9783 +// filesystem ioctls
9785 +#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9787 +#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9789 +#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9791 +#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9793 +#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9796 +#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9799 +#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9802 +#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9805 +#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9808 +#endif // _FSAIOCTL_H_
9811 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9812 --- linux-2.4.9/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 18:00:00 1969
9813 +++ linux/drivers/scsi/aacraid/include/fsaport.h Thu Aug 16 13:41:30 2001
9816 + * Adaptec aacraid device driver for Linux.
9818 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9820 + * This program is free software; you can redistribute it and/or modify
9821 + * it under the terms of the GNU General Public License as published by
9822 + * the Free Software Foundation; either version 2, or (at your option)
9823 + * any later version.
9825 + * This program is distributed in the hope that it will be useful,
9826 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9827 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9828 + * GNU General Public License for more details.
9830 + * You should have received a copy of the GNU General Public License
9831 + * along with this program; see the file COPYING. If not, write to
9832 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9837 + * Abstract: This module defines all of the globally used procedures in the FSA
9846 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9849 +// The scatter/gather map context is the information we
9850 +// we need to keep the map and transfer data to and from the
9854 +typedef struct _SGMAP_CONTEXT {
9856 + caddr_t BaseAddress;
9858 + ULONG NumberMapRegs;
9860 + ULONG ByteCount; // Used to check the Mdl length.
9861 + BOOLEAN WriteToDevice;
9867 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9869 +typedef struct _MAPFIB_CONTEXT {
9872 + ULONG NumberMapRegs;
9873 + PVOID FibVirtualAddress;
9875 + PVOID FibPhysicalAddress;
9879 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9882 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9883 + PVOID AdapterExtension,
9884 + IN OUT PVOID *BaseAddress,
9886 + IN ULONG Alignment
9890 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9891 + PVOID AdapterExtension
9895 +(*PFSA_FREE_DMA_RESOURCES)(
9896 + IN PVOID AdapterExtension,
9897 + IN PSGMAP_CONTEXT SgMapContext
9901 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9902 + IN PVOID AdapterExtension,
9903 + IN PMAPFIB_CONTEXT MapFibContext
9907 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9908 + IN PVOID AdapterExtension,
9909 + IN PMAPFIB_CONTEXT MapFibContext
9913 +(*PFSA_INTERRUPT_ADAPTER)(
9914 + IN PVOID AdapterExtension
9918 +(*PFSA_NOTIFY_ADAPTER)(
9919 + IN PVOID AdapterExtension,
9920 + IN HOST_2_ADAP_EVENT AdapterEvent
9924 +(*PFSA_RESET_DEVICE)(
9925 + PVOID AdapterExtension
9929 +(*PFSA_BUILD_SGMAP)(
9930 + IN PVOID AdapterExtension,
9931 + IN PSGMAP_CONTEXT SgMapContext
9935 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9936 + IN PVOID AdapterExtension,
9937 + IN PVOID AdapterAddress
9941 +(*PFSA_INTERRUPT_HOST)(
9943 + ADAPTER_EVENT AdapterEvent
9947 +(*PFSA_ENABLE_INTERRUPT)(
9949 + ADAPTER_EVENT AdapterEvent,
9950 + BOOLEAN AtDeviceIrq
9955 +(*PFSA_DISABLE_INTERRUPT)(
9957 + ADAPTER_EVENT AdapterEvent,
9958 + BOOLEAN AtDeviceIrq
9962 +(*PFSA_OPEN_ADAPTER) (
9967 +(*PFSA_DEVICE_CONTROL) (
9969 + IN PAFA_IOCTL_CMD IoctlCmdPtr
9973 +(*PFSA_CLOSE_ADAPTER) (
9978 +(*PFSA_SEND_SYNCH_FIB) (
9980 + IN ULONG FibPhysicalAddress
9983 +typedef struct _FSAPORT_FUNCS {
9984 + ULONG SizeOfFsaPortFuncs;
9986 + PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9987 + PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9988 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9989 + PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9990 + PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9991 + PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9992 + PFSA_NOTIFY_ADAPTER NotifyAdapter;
9993 + PFSA_ENABLE_INTERRUPT EnableInterrupt;
9994 + PFSA_DISABLE_INTERRUPT DisableInterrupt;
9995 + PFSA_RESET_DEVICE ResetDevice;
9996 + PFSA_BUILD_SGMAP BuildSgMap;
9997 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9999 + PFSA_INTERRUPT_HOST InterruptHost;
10000 + PFSA_OPEN_ADAPTER OpenAdapter;
10001 + PFSA_DEVICE_CONTROL DeviceControl;
10002 + PFSA_CLOSE_ADAPTER CloseAdapter;
10004 + PFSA_SEND_SYNCH_FIB SendSynchFib;
10007 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
10009 +typedef AAC_STATUS
10010 +(*PFSA_SETVAR_CALLBACK) (
10011 + IN PVOID Adapter,
10012 + IN ULONG NewValue
10015 +typedef struct _FSA_USER_VAR {
10018 + PFSA_SETVAR_CALLBACK SetVarCallback;
10021 +typedef FSA_USER_VAR *PFSA_USER_VAR;
10023 +typedef struct _FSA_NEW_ADAPTER {
10024 + PVOID AdapterExtension;
10025 + PFSAPORT_FUNCS AdapterFuncs;
10027 + BOOLEAN AdapterInterruptsBelowDpc;
10028 + PFSA_USER_VAR AdapterUserVars;
10029 + ULONG AdapterUserVarsSize;
10031 +} FSA_NEW_ADAPTER;
10032 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
10034 +#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
10035 +#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
10038 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
10039 --- linux-2.4.9/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
10040 +++ linux/drivers/scsi/aacraid/include/fsatypes.h Thu Aug 16 13:41:30 2001
10043 + * Adaptec aacraid device driver for Linux.
10045 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10047 + * This program is free software; you can redistribute it and/or modify
10048 + * it under the terms of the GNU General Public License as published by
10049 + * the Free Software Foundation; either version 2, or (at your option)
10050 + * any later version.
10052 + * This program is distributed in the hope that it will be useful,
10053 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10054 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10055 + * GNU General Public License for more details.
10057 + * You should have received a copy of the GNU General Public License
10058 + * along with this program; see the file COPYING. If not, write to
10059 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10064 + * Abstract: Define all shared data types here, ie, those
10065 + * types shared among several components, such
10066 + * as host (driver + apps), adapter, and BIOS.
10070 +#ifndef _FSATYPES_H
10071 +#define _FSATYPES_H
10073 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10075 +typedef AAC_UINT32 AAC_BOOLEAN;
10078 +// Define a 64-bit address structure for use on
10079 +// a 32-bit processor architecture.
10084 +} AAC_UINT64S, *PAAC_UINT64S;
10089 +// Container Types
10092 + AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
10093 + // know what it looks like. Note, BIOS sees this
10094 + // definition and it must be coded in such a way
10095 + // that it appears to be 64 bits. ints are 16 bits
10096 + // in BIOS land; fortunately, longs are 32 bits.
10102 +// ***********************
10103 +// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10104 +// ***********************
10105 +// drivers for CT_NONE to CT_PASSTHRU
10107 +typedef enum _FSAVOLTYPE {
10118 + CT_RAID10, // stripe of mirror
10119 + CT_RAID00, // stripe of stripe
10120 + CT_VOLUME_OF_MIRRORS, // volume of mirror
10121 + CT_PSEUDO_RAID3, // really raid4
10123 + CT_LAST_VOLUME_TYPE
10127 +#ifdef AAC_32BIT_ENUMS
10128 +typedef _E_FSAVOLTYPE FSAVOLTYPE;
10130 +typedef AAC_UINT32 FSAVOLTYPE;
10135 +// Types of objects addressable in some fashion by the client.
10136 +// This is a superset of those objects handled just by the filesystem
10137 +// and includes "raw" objects that an administrator would use to
10138 +// configure containers and filesystems.
10140 +typedef enum _FTYPE {
10141 + FT_REG = 1, // regular file
10142 + FT_DIR, // directory
10143 + FT_BLK, // "block" device - reserved
10144 + FT_CHR, // "character special" device - reserved
10145 + FT_LNK, // symbolic link
10146 + FT_SOCK, // socket
10148 + FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10149 + FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10150 + FT_SLICE, // virtual disk - raw volume - slice
10151 + FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10152 + FT_VOLUME, // Container - Volume Set
10153 + FT_STRIPE, // Container - Stripe Set
10154 + FT_MIRROR, // Container - Mirror Set
10155 + FT_RAID5, // Container - Raid 5 Set
10156 + FT_DATABASE // Storage object with "foreign" content manager
10159 +#ifdef AAC_32BIT_ENUMS
10160 +typedef _E_FTYPE FTYPE;
10162 +typedef AAC_UINT32 FTYPE;
10168 +// Host side memory scatter gather list
10169 +// Used by the adapter for read, write, and readdirplus operations
10171 +typedef PAAC_UINT8 HOSTADDRESS;
10173 +typedef struct _SGENTRY {
10174 + HOSTADDRESS SgAddress; /* 32-bit Base address. */
10175 + AAC_UINT32 SgByteCount; /* Length. */
10177 +typedef SGENTRY *PSGENTRY;
10184 +// This is the SGMAP structure for all commands that use
10185 +// 32-bit addressing.
10187 +// Note that the upper 16 bits of SgCount are used as flags.
10188 +// Only the lower 16 bits of SgCount are actually used as the
10189 +// SG element count.
10191 +typedef struct _SGMAP {
10192 + AAC_UINT32 SgCount;
10193 + SGENTRY SgEntry[1];
10195 +typedef SGMAP *PSGMAP;
10202 +// This is the SGMAP structure for 64-bit container commands.
10204 +typedef struct _SGMAP64 {
10205 + AAC_UINT8 SgCount;
10206 + AAC_UINT8 SgSectorsPerPage;
10207 + AAC_UINT16 SgByteOffset; // For the first page
10208 + AAC_UINT64S SgEntry[1]; // Must be last entry
10210 +typedef SGMAP64 *PSGMAP64;
10216 +// attempt at common time structure across host and adapter
10218 +typedef struct __TIME_T {
10220 + AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10221 + AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10224 +typedef TIME_T *PTIME_T;
10227 +#define timespec __TIME_T
10228 +#define ts_sec tv_sec
10229 +#define ts_nsec tv_usec
10235 +typedef struct _ContainerCreationInfo
10238 + AAC_UINT8 ViaBuildNumber; // e.g., 588
10239 + AAC_UINT8 MicroSecond; // e.g., 588
10240 + AAC_UINT8 Via; // e.g., 1 = FSU,
10242 + AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10243 + AAC_UINT32 Date; //
10244 + // unsigned Month :4; // 1 - 12
10245 + // unsigned Day :6; // 1 - 32
10246 + // unsigned Hour :6; // 0 - 23
10247 + // unsigned Minute :6; // 0 - 60
10248 + // unsigned Second :6; // 0 - 60
10249 + SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10250 +} ContainerCreationInfo;
10253 +#endif // _FSATYPES_H
10256 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10257 --- linux-2.4.9/drivers/scsi/aacraid/include/linit.h Wed Dec 31 18:00:00 1969
10258 +++ linux/drivers/scsi/aacraid/include/linit.h Thu Aug 16 13:41:30 2001
10261 + * Adaptec aacraid device driver for Linux.
10263 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10265 + * This program is free software; you can redistribute it and/or modify
10266 + * it under the terms of the GNU General Public License as published by
10267 + * the Free Software Foundation; either version 2, or (at your option)
10268 + * any later version.
10270 + * This program is distributed in the hope that it will be useful,
10271 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10272 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10273 + * GNU General Public License for more details.
10275 + * You should have received a copy of the GNU General Public License
10276 + * along with this program; see the file COPYING. If not, write to
10277 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10282 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10285 +/*------------------------------------------------------------------------------
10286 + * I N C L U D E S
10287 + *----------------------------------------------------------------------------*/
10292 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10294 +#include <linux/config.h>
10296 +/*------------------------------------------------------------------------------
10298 + *----------------------------------------------------------------------------*/
10299 +/* Define the AAC SCSI Host Template structure. */
10300 +#define AAC_HOST_TEMPLATE_ENTRY \
10301 + { name: "AAC", /* Driver Name */ \
10302 + proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10303 + detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10304 + release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10305 + info: AAC_DriverInfo, /* Driver Info Function */ \
10306 + ioctl: AAC_Ioctl, /* ioctl Interface */ \
10307 + command: AAC_Command, /* unqueued command */ \
10308 + queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10309 + abort: AAC_AbortCommand, /* Abort Command Function */ \
10310 + reset: AAC_ResetCommand, /* Reset Command Function */ \
10311 + bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10312 + can_queue: 1, /* Default initial value */ \
10313 + this_id: 0, /* Default initial value */ \
10314 + sg_tablesize: 0, /* Default initial value */ \
10315 + max_sectors: 128, /* max xfer size of 64k */ \
10316 + cmd_per_lun: 0, /* Default initial value */ \
10317 + present: 0, /* Default initial value */ \
10318 + unchecked_isa_dma: 0, /* Default Initial Value */ \
10319 + use_new_eh_code: 0, /* Default initial value */ \
10320 + eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10321 + eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10322 + eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10323 + eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10324 + eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10325 + use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10329 +/*------------------------------------------------------------------------------
10330 + * T Y P E D E F S / S T R U C T S
10331 + *----------------------------------------------------------------------------*/
10332 +typedef struct AAC_BIOS_DiskParameters
10337 +} AAC_BIOS_DiskParameters_T;
10340 +/*------------------------------------------------------------------------------
10341 + * P R O G R A M G L O B A L S
10342 + *----------------------------------------------------------------------------*/
10344 +const char *AAC_DriverInfo( struct Scsi_Host * );
10347 +/*------------------------------------------------------------------------------
10348 + * F U N C T I O N P R O T O T Y P E S
10349 + *----------------------------------------------------------------------------*/
10350 +/* Define prototypes for the AAC Driver Interface Functions. */
10351 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10352 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10353 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10354 +int AAC_Command( Scsi_Cmnd * );
10355 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10356 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10357 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10358 +int AAC_Ioctl( Scsi_Device *, int, void * );
10361 +void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10364 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10366 +#endif /* _LINIT_H_ */
10367 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10368 --- linux-2.4.9/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 18:00:00 1969
10369 +++ linux/drivers/scsi/aacraid/include/monkerapi.h Thu Aug 16 13:41:30 2001
10372 + * Adaptec aacraid device driver for Linux.
10374 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10376 + * This program is free software; you can redistribute it and/or modify
10377 + * it under the terms of the GNU General Public License as published by
10378 + * the Free Software Foundation; either version 2, or (at your option)
10379 + * any later version.
10381 + * This program is distributed in the hope that it will be useful,
10382 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10383 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10384 + * GNU General Public License for more details.
10386 + * You should have received a copy of the GNU General Public License
10387 + * along with this program; see the file COPYING. If not, write to
10388 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10393 + * Abstract: This module contains the definitions used by the Host Adapter
10394 + * Communications interface.
10395 + * This is the interface used for by host programs and the Adapter
10396 + * to communicate via synchronous commands via a shared set of registers
10397 + * on a platform (typically doorbells and mailboxes).
10400 +//**********************************************************************
10402 +// Monitor / Kernel API
10404 +// 03/24/1998 Bob Peret Initial creation
10406 +//**********************************************************************
10411 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10413 +#define BREAKPOINT_REQUEST 0x00000004
10414 +#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10417 +#define SEND_SYNCHRONOUS_FIB 0x0000000c
10422 +// Adapter Status Register
10424 +// Phase Staus mailbox is 32bits:
10425 +// <31:16> = Phase Status
10428 +// The adapter reports is present state through the phase. Only
10429 +// a single phase should be ever be set. Each phase can have multiple
10430 +// phase status bits to provide more detailed information about the
10431 +// state of the board. Care should be taken to ensure that any phase status
10432 +// bits that are set when changing the phase are also valid for the new phase
10433 +// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10434 +// for properly maintining the phase status mailbox when it is running.
10437 +// MONKER_API Phases
10439 +// Phases are bit oriented. It is NOT valid
10440 +// to have multiple bits set
10444 +#define SELF_TEST_FAILED 0x00000004
10447 +#define KERNEL_UP_AND_RUNNING 0x00000080
10448 +#define KERNEL_PANIC 0x00000100
10453 +// Doorbell bit defines
10457 +#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10460 +#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10461 +#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10462 +#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10463 +#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10464 +#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10467 +#endif // MONKER_H
10469 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10470 --- linux-2.4.9/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10471 +++ linux/drivers/scsi/aacraid/include/nodetype.h Thu Aug 16 13:41:30 2001
10474 + * Adaptec aacraid device driver for Linux.
10476 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10478 + * This program is free software; you can redistribute it and/or modify
10479 + * it under the terms of the GNU General Public License as published by
10480 + * the Free Software Foundation; either version 2, or (at your option)
10481 + * any later version.
10483 + * This program is distributed in the hope that it will be useful,
10484 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10485 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10486 + * GNU General Public License for more details.
10488 + * You should have received a copy of the GNU General Public License
10489 + * along with this program; see the file COPYING. If not, write to
10490 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10495 + * Abstract: This module defines all of the node type codes used in this development
10496 + * shell. Every major data structure in the file system is assigned a node
10497 + * type code that is. This code is the first CSHORT in the structure and is
10498 + * followed by a CSHORT containing the size, in bytes, of the structure.
10501 +#ifndef _NODETYPE_
10502 +#define _NODETYPE_
10504 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10506 +typedef CSHORT NODE_TYPE_CODE;
10509 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10510 +#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10513 +typedef CSHORT NODE_BYTE_SIZE;
10517 +// The following definitions are used to generate meaningful blue bugcheck
10518 +// screens. On a bugcheck the file system can output 4 ulongs of useful
10519 +// information. The first ulong will have encoded in it a source file id
10520 +// (in the high word) and the line number of the bugcheck (in the low word).
10521 +// The other values can be whatever the caller of the bugcheck routine deems
10524 +// Each individual file that calls bugcheck needs to have defined at the
10525 +// start of the file a constant called BugCheckFileId with one of the
10526 +// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10531 +#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10532 +#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10535 +#define FsaBugCheck(A,B,C) { cmn_err( CE_PANIC, "aacdisk: module %x, line %x, 0x%x, 0x%x, 0x%x ", BugCheckFileId, __LINE__, A, B, C); }
10538 +#endif // _NODETYPE_
10540 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10541 --- linux-2.4.9/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 18:00:00 1969
10542 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h Thu Aug 16 13:41:30 2001
10545 + * Adaptec aacraid device driver for Linux.
10547 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10549 + * This program is free software; you can redistribute it and/or modify
10550 + * it under the terms of the GNU General Public License as published by
10551 + * the Free Software Foundation; either version 2, or (at your option)
10552 + * any later version.
10554 + * This program is distributed in the hope that it will be useful,
10555 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10556 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10557 + * GNU General Public License for more details.
10559 + * You should have received a copy of the GNU General Public License
10560 + * along with this program; see the file COPYING. If not, write to
10561 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10566 + * Abstract: This file defines the data structures related to querying
10567 + * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10570 +#ifndef _NVRAMIOCTL_H_
10571 +#define _NVRAMIOCTL_H_ 1
10573 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10576 + * NVRAM/Write Cache subsystem states
10578 +typedef enum _NVSTATUS {
10579 + NVSTATUS_DISABLED = 0, // present, clean, not being used
10580 + NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10581 + NVSTATUS_ERROR, // present, dirty, contains dirty data
10582 + // for bad/missing device
10583 + NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10584 + // for bad/missing device
10585 + NVSTATUS_UNKNOWN // present?????
10588 +#ifdef AAC_32BIT_ENUMS
10589 +typedef _E_NVSTATUS NVSTATUS;
10591 +typedef AAC_UINT32 NVSTATUS;
10595 + * NVRAM/Write Cache subsystem battery component states
10598 +//NB: this enum should be identical to battery_status in nvram.h
10599 +// or else collapsed into one enum someday
10600 +typedef enum _NVBATTSTATUS {
10601 + NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10602 + NVBATTSTATUS_LOW, // battery is low on power
10603 + NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10604 + NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10605 +} _E_NVBATTSTATUS;
10607 +#ifdef AAC_32BIT_ENUMS
10608 +typedef _E_NVBATTSTATUS NVBATTSTATUS;
10610 +typedef AAC_UINT32 NVBATTSTATUS;
10614 + * battery transition type
10616 +typedef enum _NVBATT_TRANSITION {
10617 + NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10618 + NVBATT_TRANSITION_LOW, // battery is now low on power
10619 + NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10620 +} _E_NVBATT_TRANSITION;
10622 +#ifdef AAC_32BIT_ENUMS
10623 +typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10625 +typedef AAC_UINT32 NVBATT_TRANSITION;
10629 + * NVRAM Info structure returned for NVRAM_GetInfo call
10631 +typedef struct _NVRAMDEVINFO {
10632 + AAC_UINT32 NV_Enabled; /* write caching enabled */
10633 + AAC_UINT32 NV_Error; /* device in error state */
10634 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10635 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10636 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10638 +typedef struct _NVRAMINFO {
10639 + NVSTATUS NV_Status; /* nvram subsystem status */
10640 + NVBATTSTATUS NV_BattStatus; /* battery status */
10641 + AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10642 + AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10643 + AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10644 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10645 + AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10646 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10647 + AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10648 + NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10649 + AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10650 + AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10651 +} NVRAMINFO, *PNVRAMINFO;
10653 +#endif /* !_NVRAMIOCTL_H_ */
10656 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10657 --- linux-2.4.9/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 18:00:00 1969
10658 +++ linux/drivers/scsi/aacraid/include/osheaders.h Thu Aug 16 18:12:22 2001
10661 + * Adaptec aacraid device driver for Linux.
10663 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10665 + * This program is free software; you can redistribute it and/or modify
10666 + * it under the terms of the GNU General Public License as published by
10667 + * the Free Software Foundation; either version 2, or (at your option)
10668 + * any later version.
10670 + * This program is distributed in the hope that it will be useful,
10671 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10672 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10673 + * GNU General Public License for more details.
10675 + * You should have received a copy of the GNU General Public License
10676 + * along with this program; see the file COPYING. If not, write to
10677 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10682 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10685 +#ifndef _OSHEADERS_H_
10686 +#define _OSHEADERS_H_
10688 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10691 +#include <linux/version.h>
10692 +#include <linux/kernel.h>
10693 +#include <linux/config.h>
10694 +#include <linux/init.h>
10695 +#include <linux/types.h>
10696 +#include <linux/blk.h>
10697 +#include <linux/blkdev.h>
10698 +#include <linux/delay.h>
10699 +#include <linux/ioport.h>
10700 +#include <linux/mm.h>
10701 +#include <linux/sched.h>
10702 +#include <linux/stat.h>
10703 +#include <linux/pci.h>
10704 +#include <linux/interrupt.h>
10705 +#include <asm/dma.h>
10706 +#include <asm/io.h>
10707 +#include <linux/spinlock.h>
10708 +#include <asm/system.h>
10709 +#include <asm/bitops.h>
10710 +#include <asm/uaccess.h>
10711 +#include <linux/wait.h>
10712 +#include <linux/slab.h>
10713 +#include <linux/tqueue.h>
10714 +#include "ostypes.h"
10716 +#include "hosts.h"
10719 +#define intptr_t void *
10723 +#define cred_t void
10727 +#define paddr32_t unsigned
10731 +#define bzero(b,len) memset(b,0,len)
10735 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10739 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10742 +typedef unsigned uint_t;
10755 +#define CMN_ERR_LEVEL CE_NOTE
10761 +// usage of READ & WRITE as a typedefs in protocol.h
10762 +// conflicts with <linux/fs.h> definition.
10771 +typedef struct aac_options
10773 + int message_level;
10774 + int reverse_scan;
10777 +#endif // _OSHEADERS_H_
10787 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10788 --- linux-2.4.9/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 18:00:00 1969
10789 +++ linux/drivers/scsi/aacraid/include/ostypes.h Thu Aug 16 13:41:30 2001
10792 + * Adaptec aacraid device driver for Linux.
10794 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10796 + * This program is free software; you can redistribute it and/or modify
10797 + * it under the terms of the GNU General Public License as published by
10798 + * the Free Software Foundation; either version 2, or (at your option)
10799 + * any later version.
10801 + * This program is distributed in the hope that it will be useful,
10802 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10803 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10804 + * GNU General Public License for more details.
10806 + * You should have received a copy of the GNU General Public License
10807 + * along with this program; see the file COPYING. If not, write to
10808 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10813 + * Abstract: Holds all of the O/S specific types.
10816 +/*------------------------------------------------------------------------------
10818 + *----------------------------------------------------------------------------*/
10819 +#ifndef _OSTYPES_H_
10820 +#define _OSTYPES_H_
10822 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10824 +#include <linux/types.h>
10826 +#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10827 +#define MAXIMUM_NUM_ADAPTERS 8
10829 +#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10831 +#define Os_remove_softintr OsSoftInterruptRemove
10832 +#define OsPrintf printk
10833 +#define FsaCommPrint
10835 +// the return values for copy_from_user & copy_to_user is the
10836 +// number of bytes not transferred. Thus if an internal error
10837 +// occurs, the return value is greater than zero.
10838 +#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10839 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10841 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10842 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10844 +/*------------------------------------------------------------------------------
10845 + * S T R U C T S / T Y P E D E F S
10846 + *----------------------------------------------------------------------------*/
10847 +typedef struct OS_MUTEX
10849 + unsigned long lock_var;
10850 + wait_queue_head_t wq;
10854 +typedef struct OS_SPINLOCK
10856 + spinlock_t spin_lock;
10857 + unsigned cpu_lock_count[NR_CPUS];
10858 + unsigned long cpu_flags[NR_CPUS];
10859 + long lockout_count;
10862 +#ifdef CVLOCK_USE_SPINLOCK
10863 + typedef OS_SPINLOCK OS_CVLOCK;
10865 + typedef OS_MUTEX OS_CVLOCK;
10868 +typedef size_t OS_SIZE_T;
10870 +typedef struct OS_CV_T
10872 + unsigned long lock_var;
10873 + unsigned long type;
10874 + wait_queue_head_t wq;
10877 +struct fsa_scsi_hba {
10878 + void *CommonExtension;
10879 + unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10880 + unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10881 + unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10882 + unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10883 + unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10884 + unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10885 + long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10888 +typedef struct fsa_scsi_hba fsadev_t;
10890 +typedef struct OsKI
10892 + struct Scsi_Host *scsi_host_ptr;
10893 + void * dip; // #REVISIT#
10894 + fsadev_t fsa_dev;
10896 + int MiniPortIndex;
10899 +#define dev_info_t fsadev_t
10901 +typedef int OS_SPINLOCK_COOKIE;
10903 +typedef unsigned int OS_STATUS;
10905 +typedef struct tq_struct OS_SOFTINTR;
10907 +typedef OS_SOFTINTR *ddi_softintr_t;
10911 +//-----------------------------------------------------------------------------
10912 +// Conditional variable functions
10915 + OS_CV_T *cv_ptr );
10918 +//-----------------------------------------------------------------------------
10919 +// Printing functions
10920 +void printk_err(int flag, char *fmt, ...);
10922 +#define cmn_err printk_err
10926 +// just ignore these solaris ddi functions in the code
10928 +#define DDI_SUCCESS 0
10930 +#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10933 +#define ddi_remove_softintr(A) 0
10934 +#define ddi_get_soft_iblock_cookie(A, B, C) 0
10936 +#define ASSERT(expr) ((void) 0)
10937 +#define drv_usecwait udelay
10939 +#endif // _OSTYPES_H_
10940 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10941 --- linux-2.4.9/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 18:00:00 1969
10942 +++ linux/drivers/scsi/aacraid/include/pcisup.h Thu Aug 16 13:41:30 2001
10945 + * Adaptec aacraid device driver for Linux.
10947 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10949 + * This program is free software; you can redistribute it and/or modify
10950 + * it under the terms of the GNU General Public License as published by
10951 + * the Free Software Foundation; either version 2, or (at your option)
10952 + * any later version.
10954 + * This program is distributed in the hope that it will be useful,
10955 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10956 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10957 + * GNU General Public License for more details.
10959 + * You should have received a copy of the GNU General Public License
10960 + * along with this program; see the file COPYING. If not, write to
10961 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10966 + * Abstract: This module defines functions that are defined in PciSup.c
10972 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10976 + * define which interrupt handler needs to be installed
10982 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10983 + ULONG AdapterNumber; // Which FSA# this miniport is
10985 + ULONG PciBusNumber; // Which PCI bus we are located on
10986 + ULONG PciSlotNumber; // Whiat PCI slot we are in
10988 + PVOID Adapter; // Back pointer to Fsa adapter object
10989 + ULONG AdapterIndex; // Index into PlxAdapterTypes array
10990 + PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10992 + FSAPORT_FUNCS AdapterFuncs;
10993 + ULONG FilesystemRevision; // Main driver's revision number
10996 + PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
10997 + PVOID PhysicalInitStruct; // Holds physical address of the init struct
11000 + PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
11002 + BOOLEAN AdapterPrintfsToScreen;
11003 + BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
11007 + caddr_t CommAddress; // Base address of Comm area
11008 + paddr32_t CommPhysAddr; // Physical Address of Comm area
11011 + OsKI_t OsDep; // OS dependent kernel interfaces
11014 +} PCI_MINIPORT_COMMON_EXTENSION;
11016 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
11019 +(*PFSA_MINIPORT_INIT) (
11020 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
11021 + IN ULONG AdapterNumber,
11026 +typedef struct _FSA_MINIPORT {
11029 + USHORT SubVendorId;
11030 + USHORT SubSystemId;
11031 + PCHAR DevicePrefix;
11032 + PFSA_MINIPORT_INIT InitRoutine;
11033 + PCHAR DeviceName;
11037 +typedef FSA_MINIPORT *PFSA_MINIPORT;
11040 +#endif // _PCISUP_
11041 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11042 --- linux-2.4.9/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11043 +++ linux/drivers/scsi/aacraid/include/perfpack.h Thu Aug 16 13:41:30 2001
11046 + * Adaptec aacraid device driver for Linux.
11048 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11050 + * This program is free software; you can redistribute it and/or modify
11051 + * it under the terms of the GNU General Public License as published by
11052 + * the Free Software Foundation; either version 2, or (at your option)
11053 + * any later version.
11055 + * This program is distributed in the hope that it will be useful,
11056 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11057 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11058 + * GNU General Public License for more details.
11060 + * You should have received a copy of the GNU General Public License
11061 + * along with this program; see the file COPYING. If not, write to
11062 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11067 + * Abstract: This file defines the layout of the performance data that is passed
11068 + * back from the FSA filesystem driver.
11073 +#ifndef _FSA_PERFPACK_H_
11074 +#define _FSA_PERFPACK_H_ 1
11076 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11078 +//#define FSA_DO_PERF 1 /* enable the engineering counters */
11080 +#ifdef FSA_DO_PERF
11082 +// engineering counters
11084 +typedef struct _FSA_PERF_DATA {
11092 + ULONG CreateFibs;
11094 + ULONG RemoveFibs;
11095 + ULONG RemoveDirs;
11096 + ULONG RenameFibs;
11097 + ULONG ReadDirPlus;
11099 + ULONG WriteBytes;
11101 +// NT FSA entry points
11102 + ULONG FsaFsdCreateCount;
11103 + ULONG FsaFsdCloseCount;
11104 + ULONG FsaFsdReadCount;
11105 + ULONG FsaFsdWriteCount;
11106 + ULONG FsaFsdQueryInformationCount;
11108 + struct _FsaFsdSetInfomation{
11109 + ULONG FsaSetAllocationInfoCount;
11110 + ULONG FsaSetBasicInfoCount;
11111 + ULONG FsaSetDispositionInfoCount;
11112 + ULONG FsaSetEndOfFileInfoCount;
11113 + ULONG FsaSetPositionInfoCount;
11114 + ULONG FsaSetRenameInfoCount;
11115 + ULONG FsaClearArchiveBitCount;
11118 + ULONG FsaFsdFlushBuffersCount;
11119 + ULONG FsaFsdQueryVolumeInfoCount;
11120 + ULONG FsaFsdSetVolumeInfoCount;
11121 + ULONG FsaFsdCleanupCount;
11122 + ULONG FsaFsdDirectoryControlCount;
11123 + ULONG FsaFsdFileSystemControlCount;
11124 + ULONG FsaFsdLockControlCount;
11125 + ULONG FsaFsdDeviceControlCount;
11126 + ULONG FsaFsdShutdownCount;
11127 + ULONG FsaFsdQuerySecurityInfo;
11128 + ULONG FsaFsdSetSecurityInfo;
11129 + ULONG FastIoCheckIfPossibleCount;
11130 + ULONG FastIoReadCount;
11131 + ULONG FastIoWriteCount;
11132 + ULONG FastIoQueryBasicInfoCount;
11133 + ULONG FastIoQueryStandardInfoCount;
11134 + ULONG FastIoLockCount;
11135 + ULONG FastIoUnlockSingleCount;
11136 + ULONG FastIoUnlockAllCount;
11137 + ULONG FastIoUnlockAllByKeyCount;
11138 + ULONG FastIoDeviceControlCount;
11141 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11144 +#else /* FSA_DO_PERF */
11147 +// engineering performance counters are disabled
11149 +#define FSA_DO_PERF_INC(Counter) /* */
11150 +#define FSA_DO_FSP_PERF_INC(Counter) /* */
11152 +#endif /* FSA_DO_PERF */
11154 +#endif // _FSA_PERFPACK_H_
11155 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11156 --- linux-2.4.9/drivers/scsi/aacraid/include/port.h Wed Dec 31 18:00:00 1969
11157 +++ linux/drivers/scsi/aacraid/include/port.h Thu Aug 16 18:16:55 2001
11160 + * Adaptec aacraid device driver for Linux.
11162 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11164 + * This program is free software; you can redistribute it and/or modify
11165 + * it under the terms of the GNU General Public License as published by
11166 + * the Free Software Foundation; either version 2, or (at your option)
11167 + * any later version.
11169 + * This program is distributed in the hope that it will be useful,
11170 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11171 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11172 + * GNU General Public License for more details.
11174 + * You should have received a copy of the GNU General Public License
11175 + * along with this program; see the file COPYING. If not, write to
11176 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11181 + * Abstract: This module defines functions and structures that are in common among all miniports
11189 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11192 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11193 +extern int AfaPortPrinting;
11195 +#define AfaPortPrint
11198 +extern int AfaPortPrinting;
11202 +AfaPortAllocateAdapterCommArea(
11204 + IN OUT PVOID *CommHeaderAddress,
11205 + IN ULONG CommAreaSize,
11206 + IN ULONG CommAreaAlignment
11211 +AfaPortFreeAdapterCommArea(
11217 +AfaPortBuildSgMap(
11219 + IN PSGMAP_CONTEXT SgMapContext
11224 +AfaPortFreeDmaResources(
11226 + IN PSGMAP_CONTEXT SgMapContext
11231 +AfaPortAllocateAndMapFibSpace(
11233 + IN PMAPFIB_CONTEXT MapFibContext
11238 +AfaPortUnmapAndFreeFibSpace(
11240 + IN PMAPFIB_CONTEXT MapFibContext
11246 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11247 --- linux-2.4.9/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11248 +++ linux/drivers/scsi/aacraid/include/protocol.h Thu Aug 16 13:41:30 2001
11251 + * Adaptec aacraid device driver for Linux.
11253 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11255 + * This program is free software; you can redistribute it and/or modify
11256 + * it under the terms of the GNU General Public License as published by
11257 + * the Free Software Foundation; either version 2, or (at your option)
11258 + * any later version.
11260 + * This program is distributed in the hope that it will be useful,
11261 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11262 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11263 + * GNU General Public License for more details.
11265 + * You should have received a copy of the GNU General Public License
11266 + * along with this program; see the file COPYING. If not, write to
11267 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11272 + * Abstract: Defines the commands and command data which enables the nt
11273 + * filesystem driver to be the client of the fsa adapter
11274 + * filesystem. This protocol is largely modeled after the NFS
11275 + * V3 protocol with modifications allowed due to the unique
11276 + * client/server model FSA works under.
11282 +#ifndef _PROTOCOL_H_
11283 +#define _PROTOCOL_H_
11285 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11287 +#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11288 +#include <nvramioctl.h> // for NVRAMINFO definition
11290 +// #define MDL_READ_WRITE
11293 +// Define the command values
11295 +typedef enum _FSA_COMMANDS {
11308 + RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11312 + ReadDirectoryPlus,
11313 + FileSystemStatus,
11323 + SetFileSystemStatus,
11329 +#ifdef MDL_READ_WRITE
11331 + MdlWriteComplete,
11332 + MdlRead, // these are used solely for stats, Mdl really controlled by
11333 + MdlWrite, // flags field in Fib.
11338 + FaultInsertion, // Fault Insertion Command
11339 + CrazyCache, // crazycache
11340 + MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11343 +#ifdef AAC_32BIT_ENUMS
11344 +typedef _E_FSACOMMAND FSACOMMAND;
11346 +typedef AAC_UINT32 FSACOMMAND;
11352 +// Define the status returns
11354 +// See include\comm\errno.h for adapter kernel errno's
11355 +typedef enum _FSASTATUS {
11373 + ST_WOULDBLOCK = 35,
11374 + ST_NAMETOOLONG = 63,
11375 + ST_NOTEMPTY = 66,
11379 + ST_BADHANDLE = 10001,
11380 + ST_NOT_SYNC = 10002,
11381 + ST_BAD_COOKIE = 10003,
11382 + ST_NOTSUPP = 10004,
11383 + ST_TOOSMALL = 10005,
11384 + ST_SERVERFAULT = 10006,
11385 + ST_BADTYPE = 10007,
11386 + ST_JUKEBOX = 10008,
11387 + ST_NOTMOUNTED = 10009,
11388 + ST_MAINTMODE = 10010,
11389 + ST_STALEACL = 10011
11392 +#ifdef AAC_32BIT_ENUMS
11393 +typedef _E_FSASTATUS FSASTATUS;
11395 +typedef AAC_UINT32 FSASTATUS;
11399 +// On writes how does the client want the data written.
11402 +typedef enum _CACHELEVEL {
11407 +#ifdef AAC_32BIT_ENUMS
11408 +typedef _E_CACHELEVEL CACHELEVEL;
11410 +typedef AAC_UINT32 CACHELEVEL;
11414 +// Lets the client know at which level the data was commited on a write request
11417 +typedef enum _COMMITLEVEL {
11418 + CMFILE_SYNCH_NVRAM = 1,
11419 + CMDATA_SYNCH_NVRAM,
11425 +#ifdef AAC_32BIT_ENUMS
11426 +typedef _E_COMMITLEVEL COMMITLEVEL;
11428 +typedef AAC_UINT32 COMMITLEVEL;
11434 +// The following are all the different commands or FIBs which can be sent to the
11435 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11436 +// but others outside that subset are allowed to return not implemented. The client is then
11437 +// responsible for dealing with the fact it is not implemented.
11439 +typedef AAC_INT8 FSASTRING[16];
11442 +typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11450 +typedef struct _BLOCKREAD { // variable size struct
11452 + FSACOMMAND Command;
11453 + AAC_UINT32 ContainerId;
11454 + BYTECOUNT BlockNumber;
11455 + BYTECOUNT ByteCount;
11456 + SGMAP SgMap; // Must be last in struct because it is variable
11459 +typedef BLOCKREAD *PBLOCKREAD;
11461 +typedef struct _BLOCKREADRESPONSE {
11463 + FSASTATUS Status;
11464 + BYTECOUNT ByteCount;
11466 +} BLOCKREADRESPONSE;
11467 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11473 +typedef struct _BLOCKWRITE { // variable size struct
11475 + FSACOMMAND Command;
11476 + AAC_UINT32 ContainerId;
11477 + BYTECOUNT BlockNumber;
11478 + BYTECOUNT ByteCount;
11479 + CACHELEVEL Stable;
11480 + SGMAP SgMap; // Must be last in struct because it is variable
11483 +typedef BLOCKWRITE *PBLOCKWRITE;
11486 +typedef struct _BLOCKWRITERESPONSE {
11488 + FSASTATUS Status;
11489 + BYTECOUNT ByteCount;
11490 + COMMITLEVEL Committed;
11492 +} BLOCKWRITERESPONSE;
11493 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11497 +#endif // _PROTOCOL_H_
11499 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11500 --- linux-2.4.9/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11501 +++ linux/drivers/scsi/aacraid/include/revision.h Thu Aug 16 13:41:30 2001
11504 + * Adaptec aacraid device driver for Linux.
11506 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11508 + * This program is free software; you can redistribute it and/or modify
11509 + * it under the terms of the GNU General Public License as published by
11510 + * the Free Software Foundation; either version 2, or (at your option)
11511 + * any later version.
11513 + * This program is distributed in the hope that it will be useful,
11514 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11515 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11516 + * GNU General Public License for more details.
11518 + * You should have received a copy of the GNU General Public License
11519 + * along with this program; see the file COPYING. If not, write to
11520 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11525 + * Abstract: This module contains all of the revision information for
11526 + * the FSA product, as well as the support routines for
11527 + * checking module compatibility.
11529 + * Before editing anything in this module, make sure that
11530 + * you read the comments. Some lines are changed automatically
11531 + * as part of the build, and should never be changed by hand.
11533 + * Routines (all inlines):
11535 + * RevGetBuildNumber - Retrieve current build number
11536 + * RevGetExternalRev - Retrieve revision for external use
11537 + * RevGetFullRevision - Retrieve full revision structure
11539 + * RevCheckCompatibility - Checks compatibility base on internal table
11541 + * RevCheckCompatibilityFullInfo - Check for static component
11542 + * RevGetCompInfoTableSize - Get size for static component table
11543 + * RevGetCompInfoTable - Get actual table to place on static component
11544 + * RevGetBuildNumberFromInfo - Get build number for static component.
11550 +#ifndef _REVISION_H
11551 +#define _REVISION_H
11553 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11555 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11557 +typedef int REV_BOOL;
11559 +#define REV_TRUE 1
11560 +#define REV_FALSE 0
11563 +// Define Revision Levels for this product
11565 +// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11566 +// automatically by the build.
11568 +// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11570 +// IMPORTANT: Don't access these revisions directly. They can be
11571 +// accessed via, the RevGetXxxxx rouines.
11575 +#define REV_AS_LONGWORD \
11576 + ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11583 +// Enumerate the types of product levels we can have
11586 + RevType_Devo=1, // Development mode, testing all of latest
11587 + RevType_Alpha, // Alpha - Internal field test
11588 + RevType_Beta, // Beta - External field test
11589 + RevType_Release // Release - Retail version
11593 +// Define the basic structure for all revision information. Note
11594 +// that the ordering of the components is such that they should
11595 +// always increase. dash will be updated the most, then the version
11596 +// type, then minor and major.
11601 + unsigned char dash; // Dash version number
11602 + unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11603 + unsigned char minor;// Minor version minor
11604 + unsigned char major;// Major version number
11605 + } comp; // Components to external viewed rev number
11606 + unsigned long ul; // External revision as single 32-bit value
11607 + } external; // External revision number (union)
11608 + unsigned long buildNumber; // Automatically generated build number
11613 +// Define simple routines to get basic revision information. The
11614 +// definitions should never be accessed directly. These routines
11615 +// are meant to be used to access all relevant information no matter
11618 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11620 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11624 +// Enumerate different components that may have to check
11625 +// compatibility. This list of components can be changed
11628 +// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11629 +// incompatibilities between component rev checking will
11630 +// cause wrong checking results.
11633 + RevApplication = 1, // Any user End application
11634 + RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11635 + RevNetService, // Network Service Revision (under API)
11636 + RevApi, // ADAPTEC User mode API
11637 + RevFileSysDriver, // FSA File System Driver
11638 + RevMiniportDriver, // FSA File System Miniport Driver
11639 + RevAdapterSW, // Adapter Software (or NT Simulator)
11640 + RevMonitor, // Monitor for adapter hardware (MON960 for now)
11641 + RevRemoteApi // The remote API.
11642 + // ALWAYS ADD NEW COMPONENTS HERE - AT END
11646 +// Define a structure so that we can create a compatibility table.
11649 + RevComponent A,B;
11650 + unsigned long BuildNumOfB_RequiredByA;
11651 + unsigned long BuildNumOfA_RequiredByB;
11652 +} RevCompareElement;
11655 +// Now, define the table. This table should only be included once,
11656 +// in one program. If it is linked from 2 modules, there will likely
11657 +// be a multiply defined symbol error from the linker.
11659 +// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11660 +// allow access to the revision information table without a redefinition
11663 +extern const int RevCompareTableLength;
11665 +extern const RevCompareElement RevCompareTable[];
11667 +/********************************************************************\
11668 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11670 +* The following routine is used to check compatibility between
11671 +* the calling component and a component that has some dependencies
11672 +* on it. If this routine returns REV_FALSE, it is expected that the caller
11673 +* will send an appropriate incompatibility message and stop.
11675 +* This routine is only meant to check for compatibility in the
11676 +* absolute sense. If code wishes to execute a different path based
11677 +* on the CompB_BuildNumber, then this routine is not useful. The
11678 +* routine RevGetBuildNumber can be used to get the calling module's
11679 +* current build number for a comparison check.
11681 +* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11682 +* if the components are definitely not compatible, or there is an
11683 +* error when trying to figure it out. To be more specific:
11685 +* 1) REV_TRUE if component B is newer than calling component. (In this
11686 +* case, the revision check done by component B with respect to
11687 +* this component will give the real compatibility information.
11688 +* It is the only one with the knowledge, since this component
11689 +* could not look into the future.)
11690 +* 2) REV_TRUE if calling component is more recent and table shows okay
11691 +* 3) REV_FALSE if calling component more recent and table show not okay
11692 +* 4) REV_FALSE if calling component is more recent and table entry to
11693 +* check does not exist.
11695 +* Note that the CompB_BuildNumber must be attained by the calling
11696 +* routine through some mechanism done by the caller.
11700 +* callerComp - Name of component making this call
11701 +* compB - Name of component to check compatibility with
11702 +* compB_BuildNumber - Build number to component B
11710 +* REV_TRUE - Component compatibility is possible, continue as usual. compB
11711 +* must give true compatibility information.
11712 +* REV_FALSE - Incompatible components, notify and end
11714 +\********************************************************************/
11715 +static inline REV_BOOL RevCheckCompatibility(
11716 + RevComponent callerComp,
11717 + RevComponent compB,
11718 + unsigned long compB_BuildNumber)
11721 + unsigned long RevForB;
11724 + // Compatibility check is possible, so we should continue. When
11725 + // compB makes this call in its own component, it will get the
11726 + // true compatibility information, since only it can know.
11728 + if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11731 + // Go through rev table. When the components are found in the
11732 + // same table entry, return the approprate number.
11734 + for (i=0; i<RevCompareTableLength; i++) {
11735 + if (RevCompareTable[i].A == callerComp) {
11736 + if (RevCompareTable[i].B == compB) {
11737 + RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11738 + return (compB_BuildNumber >= RevForB);
11740 + } else if (RevCompareTable[i].B == callerComp) {
11741 + if (RevCompareTable[i].A == compB) {
11742 + RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11743 + return (compB_BuildNumber >= RevForB);
11749 + // Uh oh! No relevant table entry was found (this should never
11752 + return REV_FALSE;
11757 +// Now create a structure that can be used by a FIB to check
11760 +typedef struct _RevCheck {
11761 + RevComponent callingComponent;
11762 + FsaRevision callingRevision;
11765 +typedef struct _RevCheckResp {
11766 + REV_BOOL possiblyCompatible;
11767 + FsaRevision adapterSWRevision;
11771 +#endif /* _REVISION_H */
11774 +// The following allows for inclusion of revision.h in other h
11775 +// files. when you include this file in another h file, simply
11776 +// define REV_REFERENCE_ONLY. This will be undefined later, so that
11777 +// the single C file inclusion in the module will be used to
11778 +// implement the global structures.
11780 +#ifndef REV_REFERENCE_ONLY
11781 +#ifndef _REVISION_H_GLOBAL
11782 +#define _REVISION_H_GLOBAL
11787 +// The following array is the table of compatibility. This table
11788 +// can be modified in two ways:
11790 +// 1) A component which has an incompatible change done to
11791 +// it, can get a new build number.
11793 +// 2) A new component can be added, requiring more entries
11794 +// to be place into this table.
11797 +// In case (1), you must change the revision number in the appropriate
11798 +// column, based on which component absolutely requires an upgrade.
11800 +// Example: A new FIB used by the API, in build number 105
11801 +// {RevApi, RevAdapterSW, 100, 100}
11802 +// ---> would be changed to <---
11803 +// {RevApi, RevAdapterSW, 105, 100}
11805 +// Example: A structure is changed for a FIB that only the API uses
11806 +// {RevApi, RevAdapterSW, 100, 100}
11807 +// ---> would be changed to <---
11808 +// {RevApi, RevAdapterSW, 105, 105}
11811 +// In case (2), the less common case, the enumerated list of
11812 +// components must be changed to include the new component. Then
11813 +// entries need to be placed into this table.
11815 +// Since the revisions must be communicated between the two
11816 +// components, it is likely that you would need to put in the
11817 +// current build number for both columns. That is the recommended
11818 +// way to start revision test.
11820 +const RevCompareElement RevCompareTable[] = {
11821 + // Component A Component B MinBForA MinAForB
11822 + // ----------- ----------- -------- --------
11823 + {RevApplication, RevApi, 2120, 2120 },
11824 + {RevDkiCli, RevApi, 2120, 2120 },
11825 + {RevDkiCli, RevFileSysDriver, 257, 257 },
11826 + {RevDkiCli, RevMiniportDriver, 257, 257 },
11827 + {RevDkiCli, RevAdapterSW, 257, 257 },
11828 + {RevApi, RevFileSysDriver, 2120, 2120 },
11829 + {RevApi, RevMiniportDriver, 2120, 2120 },
11830 + {RevApi, RevAdapterSW, 2120, 2120 },
11831 + {RevApi, RevNetService, 2120, 2120 },
11832 + {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11833 + {RevFileSysDriver, RevAdapterSW, 257, 257 },
11834 + {RevMiniportDriver, RevAdapterSW, 257, 257 },
11835 + {RevMiniportDriver, RevMonitor, 100, 100 },
11836 + {RevApi, RevNetService, 2120, 2120 },
11837 + {RevApi, RevRemoteApi, 2120, 2120 },
11838 + {RevNetService, RevRemoteApi, 2120, 2120 }
11841 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11843 +#endif /* _REVISION_H_GLOBAL */
11844 +#endif /* REV_REFERENCE_ONLY */
11845 +#undef REV_REFERENCE_ONLY
11853 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11854 --- linux-2.4.9/drivers/scsi/aacraid/include/rx.h Wed Dec 31 18:00:00 1969
11855 +++ linux/drivers/scsi/aacraid/include/rx.h Thu Aug 16 13:41:30 2001
11858 + * Adaptec aacraid device driver for Linux.
11860 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11862 + * This program is free software; you can redistribute it and/or modify
11863 + * it under the terms of the GNU General Public License as published by
11864 + * the Free Software Foundation; either version 2, or (at your option)
11865 + * any later version.
11867 + * This program is distributed in the hope that it will be useful,
11868 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11869 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11870 + * GNU General Public License for more details.
11872 + * You should have received a copy of the GNU General Public License
11873 + * along with this program; see the file COPYING. If not, write to
11874 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11879 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11884 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11886 +typedef struct _Rx_ADAPTER_EXTENSION {
11889 + // The following must be first.
11891 + PPCI_MINIPORT_COMMON_EXTENSION Common;
11892 + struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11893 + USHORT LocalMaskInterruptControl;
11894 + PRx_DEVICE_REGISTERS Device;
11896 +} Rx_ADAPTER_EXTENSION;
11899 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11908 +#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11912 +#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11913 +#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11916 +#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11918 +#endif /* LINUX */
11922 +RxInterruptAdapter(
11929 + IN HOST_2_ADAP_EVENT AdapterEvent
11938 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11939 --- linux-2.4.9/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11940 +++ linux/drivers/scsi/aacraid/include/rxcommon.h Thu Aug 16 13:41:30 2001
11943 + * Adaptec aacraid device driver for Linux.
11945 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11947 + * This program is free software; you can redistribute it and/or modify
11948 + * it under the terms of the GNU General Public License as published by
11949 + * the Free Software Foundation; either version 2, or (at your option)
11950 + * any later version.
11952 + * This program is distributed in the hope that it will be useful,
11953 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11954 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11955 + * GNU General Public License for more details.
11957 + * You should have received a copy of the GNU General Public License
11958 + * along with this program; see the file COPYING. If not, write to
11959 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11964 + * Abstract: Structures and defines for the i960 Rx chip.
11969 +#ifndef _Rx_COMMON_H_
11970 +#define _Rx_COMMON_H_
11972 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11975 +// Rx Message Unit Registers
11978 +typedef volatile struct _StructRxMURegisters {
11979 + // Local | PCI* | Name
11981 + unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11982 + unsigned reserved0; // 1304h | 04h | Reserved
11983 + unsigned AWR; // 1308h | 08h | APIC Window Register
11984 + unsigned reserved1; // 130Ch | 0Ch | Reserved
11985 + unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11986 + unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11987 + unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11988 + unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11989 + unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11990 + unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11991 + unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11992 + unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11993 + // * Must access trhough ATU Inbound Translation Window
11996 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11998 +typedef volatile struct _Rx_Inbound {
12000 + unsigned Mailbox[8];
12004 +typedef Rx_Inbound *PRx_Inbound;
12006 +#define InboundMailbox0 IndexRegs.Mailbox[0]
12007 +#define InboundMailbox1 IndexRegs.Mailbox[1]
12008 +#define InboundMailbox2 IndexRegs.Mailbox[2]
12009 +#define InboundMailbox3 IndexRegs.Mailbox[3]
12010 +#define InboundMailbox4 IndexRegs.Mailbox[4]
12014 +#define INBOUNDDOORBELL_0 0x00000001
12015 +#define INBOUNDDOORBELL_1 0x00000002
12016 +#define INBOUNDDOORBELL_2 0x00000004
12017 +#define INBOUNDDOORBELL_3 0x00000008
12018 +#define INBOUNDDOORBELL_4 0x00000010
12019 +#define INBOUNDDOORBELL_5 0x00000020
12020 +#define INBOUNDDOORBELL_6 0x00000040
12023 +#define OUTBOUNDDOORBELL_0 0x00000001
12024 +#define OUTBOUNDDOORBELL_1 0x00000002
12025 +#define OUTBOUNDDOORBELL_2 0x00000004
12026 +#define OUTBOUNDDOORBELL_3 0x00000008
12027 +#define OUTBOUNDDOORBELL_4 0x00000010
12030 +#define InboundDoorbellReg MUnit.IDR
12032 +#define OutboundDoorbellReg MUnit.ODR
12035 +typedef struct _Rx_DEVICE_REGISTERS {
12036 + Rx_MU_CONFIG MUnit; // 1300h - 1334h
12037 + unsigned reserved1[6]; // 1338h - 134ch
12038 + Rx_Inbound IndexRegs;
12039 +} Rx_DEVICE_REGISTERS;
12041 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12044 +#endif // _Rx_COMMON_H_
12047 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12048 --- linux-2.4.9/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 18:00:00 1969
12049 +++ linux/drivers/scsi/aacraid/include/sap1.h Thu Aug 16 13:41:30 2001
12052 + * Adaptec aacraid device driver for Linux.
12054 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12056 + * This program is free software; you can redistribute it and/or modify
12057 + * it under the terms of the GNU General Public License as published by
12058 + * the Free Software Foundation; either version 2, or (at your option)
12059 + * any later version.
12061 + * This program is distributed in the hope that it will be useful,
12062 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12063 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12064 + * GNU General Public License for more details.
12066 + * You should have received a copy of the GNU General Public License
12067 + * along with this program; see the file COPYING. If not, write to
12068 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12073 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12080 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12082 +#define Sa_MINIPORT_REVISION 1
12084 +typedef struct _Sa_ADAPTER_EXTENSION {
12087 + // The following must be first.
12089 + PPCI_MINIPORT_COMMON_EXTENSION Common;
12090 + struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12091 + USHORT LocalMaskInterruptControl;
12092 + PSa_DEVICE_REGISTERS Device;
12094 +} Sa_ADAPTER_EXTENSION;
12096 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12106 +#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12107 +#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12110 +#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12111 +#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12113 +#endif /* LINUX */
12117 +SaInterruptAdapter(
12124 + IN HOST_2_ADAP_EVENT AdapterEvent
12133 +#endif /* _SAP1_H_ */
12136 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12137 --- linux-2.4.9/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 18:00:00 1969
12138 +++ linux/drivers/scsi/aacraid/include/sap1common.h Thu Aug 16 13:41:30 2001
12141 + * Adaptec aacraid device driver for Linux.
12143 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12145 + * This program is free software; you can redistribute it and/or modify
12146 + * it under the terms of the GNU General Public License as published by
12147 + * the Free Software Foundation; either version 2, or (at your option)
12148 + * any later version.
12150 + * This program is distributed in the hope that it will be useful,
12151 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12152 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12153 + * GNU General Public License for more details.
12155 + * You should have received a copy of the GNU General Public License
12156 + * along with this program; see the file COPYING. If not, write to
12157 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12162 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12166 +#ifndef _Sa_COMMON_H_
12167 +#define _Sa_COMMON_H_
12169 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12172 +// SaP1 Message Unit Registers
12175 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12177 + unsigned reserved[10]; // 00h-27h | Reserved
12178 + unsigned char LUT_Offset; // 28h | Looup Table Offset
12179 + unsigned char reserved1[3]; // 29h-2bh | Reserved
12180 + unsigned LUT_Data; // 2ch | Looup Table Data
12181 + unsigned reserved2[26]; // 30h-97h | Reserved
12182 + unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12183 + unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12184 + unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12185 + unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12186 + unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12187 + unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12188 + unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12189 + unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12190 + unsigned MAILBOX0; // a8h | Scratchpad 0
12191 + unsigned MAILBOX1; // ach | Scratchpad 1
12192 + unsigned MAILBOX2; // b0h | Scratchpad 2
12193 + unsigned MAILBOX3; // b4h | Scratchpad 3
12194 + unsigned MAILBOX4; // b8h | Scratchpad 4
12195 + unsigned MAILBOX5; // bch | Scratchpad 5
12196 + unsigned MAILBOX6; // c0h | Scratchpad 6
12197 + unsigned MAILBOX7; // c4h | Scratchpad 7
12199 + unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12200 + unsigned ROM_Control_Addr; // cch | Rom Control and Address
12202 + unsigned reserved3[12]; // d0h-ffh | reserved
12203 + unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12207 + // need to add DMA, I2O, UART, etc registers form 80h to 364h
12210 +}Sa_Drawbridge_CSR;
12212 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12215 +#define Mailbox0 SaDbCSR.MAILBOX0
12216 +#define Mailbox1 SaDbCSR.MAILBOX1
12217 +#define Mailbox2 SaDbCSR.MAILBOX2
12218 +#define Mailbox3 SaDbCSR.MAILBOX3
12219 +#define Mailbox4 SaDbCSR.MAILBOX4
12222 +#define Mailbox7 SaDbCSR.MAILBOX7
12224 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12225 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12226 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12229 +#define DOORBELL_0 0x00000001
12230 +#define DOORBELL_1 0x00000002
12231 +#define DOORBELL_2 0x00000004
12232 +#define DOORBELL_3 0x00000008
12233 +#define DOORBELL_4 0x00000010
12234 +#define DOORBELL_5 0x00000020
12235 +#define DOORBELL_6 0x00000040
12238 +#define PrintfReady DOORBELL_5
12239 +#define PrintfDone DOORBELL_5
12241 +typedef struct _Sa_DEVICE_REGISTERS {
12242 + Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12243 +} Sa_DEVICE_REGISTERS;
12245 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12248 +#endif // _Sa_COMMON_H_
12251 diff -burN linux-2.4.9/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12252 --- linux-2.4.9/drivers/scsi/aacraid/include/version.h Wed Dec 31 18:00:00 1969
12253 +++ linux/drivers/scsi/aacraid/include/version.h Thu Aug 16 18:16:55 2001
12256 + * Adaptec aacraid device driver for Linux.
12258 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12260 + * This program is free software; you can redistribute it and/or modify
12261 + * it under the terms of the GNU General Public License as published by
12262 + * the Free Software Foundation; either version 2, or (at your option)
12263 + * any later version.
12265 + * This program is distributed in the hope that it will be useful,
12266 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12267 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12268 + * GNU General Public License for more details.
12270 + * You should have received a copy of the GNU General Public License
12271 + * along with this program; see the file COPYING. If not, write to
12272 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12277 + * Abstract: Keeps track of build number for development purposes.
12280 +#ifndef _VERSION_H_
12281 +#define _VERSION_H_
12283 +static char *ident_version = "aacraid_ident version.h 1.0.7 2000/8/10 Adaptec, Inc.";
12285 +#include "build_number.h"
12287 +#define REV_MAJOR 3
12288 +#define REV_MINOR 0
12289 +#define REV_TYPE RevType_Release
12290 +#define REV_DASH 0
12292 +#define FSA_VERSION_STRING "3.0.0.5125\0"
12294 +#endif /* _VERSION_H_ */
12295 diff -burN linux-2.4.9/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12296 --- linux-2.4.9/drivers/scsi/aacraid/linit.c Wed Dec 31 18:00:00 1969
12297 +++ linux/drivers/scsi/aacraid/linit.c Thu Aug 16 13:41:30 2001
12300 + * Adaptec aacraid device driver for Linux.
12302 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12304 + * This program is free software; you can redistribute it and/or modify
12305 + * it under the terms of the GNU General Public License as published by
12306 + * the Free Software Foundation; either version 2, or (at your option)
12307 + * any later version.
12309 + * This program is distributed in the hope that it will be useful,
12310 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12311 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12312 + * GNU General Public License for more details.
12314 + * You should have received a copy of the GNU General Public License
12315 + * along with this program; see the file COPYING. If not, write to
12316 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12321 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12323 + * Provides the following driver entry points:
12324 + * AAC_DetectHostAdapter()
12325 + * AAC_ReleaseHostAdapter()
12326 + * AAC_QueueCommand()
12327 + * AAC_ResetCommand()
12328 + * AAC_BIOSDiskParameters()
12332 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12334 +/*------------------------------------------------------------------------------
12336 + *----------------------------------------------------------------------------*/
12337 +#define AAC_DRIVER_VERSION "0.1.1"
12338 +#define AAC_DRIVER_BUILD_DATE __DATE__
12339 +#define MAX_DRIVER_QUEUE_DEPTH 500
12341 +/*------------------------------------------------------------------------------
12342 + * I N C L U D E S
12343 + *----------------------------------------------------------------------------*/
12344 +#include "osheaders.h"
12346 +#include "AacGenericTypes.h"
12348 +#include <linux/module.h>
12350 +#include "linit.h"
12351 +#include "aac_unix_defs.h"
12352 +#include "fsatypes.h"
12353 +#include "comstruc.h"
12354 +#include "fsaport.h"
12355 +#include "pcisup.h"
12357 +#include "afacomm.h"
12358 +#include "nodetype.h"
12359 +#include "comsup.h"
12360 +#include "adapter.h"
12362 +/*------------------------------------------------------------------------------
12364 + *----------------------------------------------------------------------------*/
12365 +extern FSA_MINIPORT MiniPorts[];
12366 +extern int CommPrinting;
12367 +extern char DescriptionString[];
12368 +extern char devicestr[];
12370 +/*------------------------------------------------------------------------------
12371 + * M O D U L E G L O B A L S
12372 + *----------------------------------------------------------------------------*/
12373 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12375 +char g_DriverName[] = { "aacraid" };
12378 + The Loadable Kernel Module Installation Facility may pass us
12379 + a pointer to a driver specific options string to be parsed,
12380 + we assign this to options string.
12383 +static char * aacraid_options = NULL;
12384 +MODULE_PARM ( aacraid_options, "s" );
12385 +MODULE_PARM_DESC ( aacraid_options, "message_level:(int) reverse_scan:1 (default 0)");
12388 +static unsigned short perc_pciid[4] = { 0, 0, 0, 0 };
12389 +MODULE_PARM ( perc_pciid, "4h");
12390 +MODULE_PARM_DESC ( perc_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Dell PERC controllers.");
12392 +static unsigned short rx_pciid[4] = { 0, 0, 0, 0 };
12393 +MODULE_PARM ( rx_pciid, "4h");
12394 +MODULE_PARM_DESC ( rx_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Adaptec Rx controllers.");
12396 +static unsigned short sa_pciid[4] = { 0, 0, 0, 0 };
12397 +MODULE_PARM ( sa_pciid, "4h");
12398 +MODULE_PARM_DESC ( sa_pciid, "PCI vendor,device,subsystem vendor,subsystem device, for non-auto-recognized Adaptec Sa controllers.");
12400 +MODULE_AUTHOR ("Adaptec OEM RAID Solutions");
12404 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12405 +unsigned g_HostAdapterCount = 0;
12406 +unsigned g_chardev_major = 0;
12408 +int g_single_command_done = FALSE;
12410 +/*------------------------------------------------------------------------------
12411 + * F U N C T I O N P R O T O T Y P E S
12412 + *----------------------------------------------------------------------------*/
12414 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12418 +int AacHba_ProbeContainers(
12419 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12421 +int AacHba_DoScsiCmd(
12422 + Scsi_Cmnd *scsi_cmnd_ptr,
12425 +void AacHba_DetachAdapter(
12426 + IN PVOID AdapterArg );
12428 +int AacHba_ClassDriverInit(
12429 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12431 +void AacHba_AbortScsiCommand(
12432 + Scsi_Cmnd *scsi_cmnd_ptr );
12435 +/*------------------------------------------------------------------------------
12436 + * L O C A L F U N C T I O N P R O T O T Y P E S
12437 + *----------------------------------------------------------------------------*/
12438 +static int parse_keyword(
12440 + char * keyword );
12442 +static void AAC_ParseDriverOptions(
12443 + char * cmnd_line_options_str );
12445 +static void AAC_AnnounceDriver( void );
12447 +int AAC_ChardevIoctl(
12448 + struct inode * inode_ptr,
12449 + struct file * file_ptr,
12450 + unsigned int cmd,
12451 + unsigned long arg );
12453 +int AAC_ChardevOpen(
12454 + struct inode * inode_ptr,
12455 + struct file * file_ptr );
12457 +int AAC_ChardevRelease(
12458 + struct inode * inode_ptr,
12459 + struct file * file_ptr );
12461 +struct file_operations AAC_fops = {
12462 + NULL, // module name
12468 + AAC_ChardevIoctl, // ioctl
12470 + AAC_ChardevOpen, // open
12472 + AAC_ChardevRelease, // release
12475 + NULL, // check media change
12476 + NULL, // revalidate
12480 +/*------------------------------------------------------------------------------
12481 + * F U N C T I O N S
12482 + *----------------------------------------------------------------------------*/
12483 +/*------------------------------------------------------------------------------
12484 + AAC_AnnounceDriver()
12486 + Announce the driver name, version and date.
12487 + *----------------------------------------------------------------------------*/
12488 +static void AAC_AnnounceDriver( void ){
12489 + printk(KERN_ALERT "%s, %s\n",
12490 + "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12495 +/*------------------------------------------------------------------------------
12496 + AAC_DetectHostAdapter()
12498 + Probe for AAC Host Adapters initialize, register, and report the
12499 + configuration of each AAC Host Adapter found.
12503 + - Returns the number of adapters successfully initialized and
12505 + - Initialize all data necessary for this particular SCSI driver.
12507 + The detect routine must not call any of the mid level functions
12508 + to queue commands because things are not guaranteed to be set
12509 + up yet. The detect routine can send commands to the host adapter
12510 + as long as the program control will not be passed to scsi.c in
12511 + the processing of the command. Note especially that
12512 + scsi_malloc/scsi_free must not be called.
12513 + *----------------------------------------------------------------------------*/
12514 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12518 + uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12519 + struct Scsi_Host *host_ptr;
12520 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12521 + struct pci_dev *dev = NULL;
12522 + extern int NumMiniPorts;
12523 + fsadev_t *fsa_dev_ptr;
12524 + char *DeviceName;
12526 + struct pci_dev *devp;
12528 + int first_index, last_index, increment;
12530 + CommPrinting = TRUE;
12532 + EXPORT_NO_SYMBOLS;
12534 + AAC_AnnounceDriver();
12536 + /* setting up the proc directory structure */
12537 + HostTemplate->proc_name = "aacraid";
12539 + if( aacraid_options != NULL ) AAC_ParseDriverOptions( aacraid_options );
12541 + /* If we were passed a PCI device ID, handle that first. */
12542 + if ( perc_pciid[0] != 0 ) {
12543 + MiniPorts[0].VendorId = perc_pciid[0];
12544 + MiniPorts[0].DeviceId = perc_pciid[1];
12545 + MiniPorts[0].SubVendorId = perc_pciid[2];
12546 + MiniPorts[0].SubSystemId = perc_pciid[3];
12548 + if ( rx_pciid[0] != 0 ) {
12549 + MiniPorts[1].VendorId = rx_pciid[0];
12550 + MiniPorts[1].DeviceId = rx_pciid[1];
12551 + MiniPorts[1].SubVendorId = rx_pciid[2];
12552 + MiniPorts[1].SubSystemId = rx_pciid[3];
12554 + if ( sa_pciid[0] != 0 ) {
12555 + MiniPorts[2].VendorId = sa_pciid[0];
12556 + MiniPorts[2].DeviceId = sa_pciid[1];
12557 + MiniPorts[2].SubVendorId = sa_pciid[2];
12558 + MiniPorts[2].SubSystemId = sa_pciid[3];
12561 + // NumMiniPorts & MiniPorts[] defined in aacid.c
12562 + if (g_options.reverse_scan == 0) {
12564 + last_index = NumMiniPorts;
12567 + first_index = NumMiniPorts -1;
12572 + for( index = first_index; index != last_index; index += increment )
12574 + device_id = MiniPorts[index].DeviceId;
12575 + vendor_id = MiniPorts[index].VendorId;
12576 + DeviceName = MiniPorts[index].DeviceName;
12577 + cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12578 + DeviceName, vendor_id, device_id,
12579 + MiniPorts[index].SubVendorId,
12580 + MiniPorts[index].SubSystemId);
12582 + /* If vendor and device ID are 0, this is an unused entry, so skip! */
12583 + if ( vendor_id == 0 && device_id == 0 ) continue;
12585 + // pci_find_device traverses the pci_devices linked list for devices
12586 + // with matching vendor and device ids.
12588 + dev = NULL; // start from beginning of list
12589 + while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12591 + if (pci_enable_device(dev)) continue;
12593 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12594 + cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12597 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12598 + cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12602 + cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12603 + if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12604 + ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12609 + printk(KERN_ALERT "%s device detected\n", DeviceName );
12610 + cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12612 + // Increment the host adapter count
12613 + g_HostAdapterCount++;
12615 + // scsi_register() allocates memory for a Scsi_Hosts structure and
12616 + // links it into the linked list of host adapters. This linked list
12617 + // contains the data for all possible <supported> scsi hosts.
12618 + // This is similar to the Scsi_Host_Template, except that we have
12619 + // one entry for each actual physical host adapter on the system,
12620 + // stored as a linked list. If there are two AAC boards, then we
12621 + // will need to make two Scsi_Host entries, but there will be only
12622 + // one Scsi_Host_Template entry. The second argument to scsi_register()
12623 + // specifies the size of the extra memory we want to hold any device
12624 + // specific information.
12625 + host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12627 + // These three parameters can be used to allow for wide SCSI
12628 + // and for host adapters that support multiple buses.
12629 + host_ptr->max_id = 17;
12630 + host_ptr->max_lun = 8;
12631 + host_ptr->max_channel = 1;
12634 + host_ptr->irq = dev->irq; // Adapter IRQ number
12635 + /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12636 + host_ptr->base = ( char * )(dev->resource[0].start);
12637 + scsi_set_pci_device(host_ptr, dev);
12639 + cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12640 + cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12642 + // The unique_id field is a unique identifier that must be assigned
12643 + // so that we have some way of identifying each host adapter properly
12644 + // and uniquely. For hosts that do not support more than one card in the
12645 + // system, this does not need to be set. It is initialized to zero in
12646 + // scsi_register(). This is the value returned from OsGetDeviceInstance().
12648 + host_ptr->unique_id = g_HostAdapterCount - 1;
12649 + host_ptr->this_id = 16; // SCSI Id for the adapter itself
12651 + // Set the maximum number of simultaneous commands supported by the driver.
12652 + host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12654 + // Define the maximum number of scatter/gather elements supported by
12657 + host_ptr->sg_tablesize = 16;
12658 + host_ptr->max_sectors = 128;
12659 + host_ptr->cmd_per_lun = 1; // untagged queue depth
12661 + // This function is called after the device list has been built to find
12662 + // tagged queueing depth supported for each device.
12664 + host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12665 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12667 + // attach a pointer back to Scsi_Host
12668 + CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12669 + CommonExtensionPtr->OsDep.MiniPortIndex = index;
12671 + // Initialize the ordinal number of the device to -1
12672 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12673 + for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12674 + fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12676 + // Call initialization routine
12677 + cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12678 + if( ( *MiniPorts[index].InitRoutine )
12679 + ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12681 + // device initialization failed
12682 + cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12683 + scsi_unregister( host_ptr );
12684 + g_HostAdapterCount--;
12688 + cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12689 + AacHba_ClassDriverInit( CommonExtensionPtr );
12690 + cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12691 + AacHba_ProbeContainers( CommonExtensionPtr );
12692 + g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12696 + } /* end while */
12700 + if( g_HostAdapterCount ){
12701 + if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12702 + cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12705 + HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12707 + return( g_HostAdapterCount );
12711 +/*------------------------------------------------------------------------------
12712 + AAC_ReleaseHostAdapter()
12714 + Release all resources previously acquired to support a specific Host
12715 + Adapter and unregister the AAC Host Adapter.
12716 + *----------------------------------------------------------------------------*/
12717 +int AAC_ReleaseHostAdapter(
12718 + struct Scsi_Host *host_ptr )
12719 +/*----------------------------------------------------------------------------*/
12721 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12723 + cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12725 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12727 + // kill any threads we started
12728 + kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12730 + // Call the comm layer to detach from this adapter
12731 + AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12733 + // remove interrupt binding
12734 + OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12736 + SaDetachDevice( CommonExtensionPtr );
12738 + // unregister adapter
12739 + scsi_unregister( host_ptr );
12741 + if( g_chardev_major )
12743 + unregister_chrdev( g_chardev_major, devicestr );
12744 + g_chardev_major = 0;
12747 + return( 0 ); // #REVISIT# return code
12751 +/*------------------------------------------------------------------------------
12752 + AAC_QueueCommand()
12754 + Queues a command for execution by the associated Host Adapter.
12755 + *----------------------------------------------------------------------------*/
12756 +int AAC_QueueCommand(
12757 + Scsi_Cmnd *scsi_cmnd_ptr,
12758 + void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12759 +/*----------------------------------------------------------------------------*/
12762 + scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12764 + // AacHba_DoScsiCmd() handles command processing, setting the
12765 + // result code and calling completion routine.
12767 + if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 )) != 0 ) // call with wait = TRUE
12769 + if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 )) != 0 ) // call with wait = FALSE
12771 + cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12776 +/*------------------------------------------------------------------------------
12779 + Callback function for a non-queued command.
12782 + Sets g_single_command done to TRUE
12783 + *----------------------------------------------------------------------------*/
12785 + Scsi_Cmnd * scsi_cmnd_ptr )
12786 +/*----------------------------------------------------------------------------*/
12788 + g_single_command_done = TRUE;
12792 +/*------------------------------------------------------------------------------
12795 + Accepts a single command for execution by the associated Host Adapter.
12798 + Returns an int where:
12799 + Byte 0 = SCSI status code
12800 + Byte 1 = SCSI 1 byte message
12801 + Byte 2 = host error return
12802 + Byte 3 = mid level error return
12803 + *----------------------------------------------------------------------------*/
12805 + Scsi_Cmnd *scsi_cmnd_ptr )
12806 +/*----------------------------------------------------------------------------*/
12808 + scsi_cmnd_ptr->scsi_done = AAC_Done;
12810 + cmn_err( CE_DEBUG, "AAC_Command" );
12812 + // AacHba_DoScsiCmd() handles command processing, setting the
12813 + // result code and calling completion routine.
12814 + g_single_command_done = FALSE;
12816 + AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12817 + while( !g_single_command_done );
12818 + return( scsi_cmnd_ptr->result );
12822 +/*------------------------------------------------------------------------------
12823 + AAC_AbortCommand()
12825 + Abort command if possible.
12826 + *----------------------------------------------------------------------------*/
12827 +int AAC_AbortCommand(
12828 + Scsi_Cmnd *scsi_cmnd_ptr )
12829 +/*----------------------------------------------------------------------------*/
12831 + int target = scsi_cmnd_ptr->target;
12832 + int hba = scsi_cmnd_ptr->host->unique_id;
12834 + u_short interrupt_status;
12835 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12836 + char *DeviceName;
12838 + cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12839 + AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12841 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12842 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12845 + cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12846 + "command already completed", DeviceName, hba, target);
12847 + result = SCSI_ABORT_NOT_RUNNING;
12849 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12850 + "no command found\n", DeviceName, hba, target);
12851 + result = SCSI_ABORT_NOT_RUNNING;
12853 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12854 + "command reset\n", DeviceName, hba, target);
12855 + result = SCSI_ABORT_PENDING;
12857 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12858 + "abort tag not supported\n", DeviceName, hba, target);
12859 + result = SCSI_ABORT_SNOOZE;
12861 + cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12862 + DeviceName, hba, target);
12863 + result = SCSI_ABORT_PENDING;
12865 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12866 + DeviceName, hba, target);
12867 + result = SCSI_ABORT_BUSY;
12869 + cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12870 + DeviceName, hba, target);
12871 + result = SCSI_ABORT_SUCCESS;
12874 + // Abort not supported yet
12875 + result = SCSI_ABORT_BUSY;
12880 +/*------------------------------------------------------------------------------
12881 + AAC_ResetCommand()
12883 + Reset command handling.
12884 + *----------------------------------------------------------------------------*/
12885 +int AAC_ResetCommand(
12886 + struct scsi_cmnd *scsi_cmnd_ptr,
12887 + unsigned int reset_flags )
12888 +/*----------------------------------------------------------------------------*/
12890 + int target = scsi_cmnd_ptr->target;
12891 + int hba = scsi_cmnd_ptr->host->unique_id;
12892 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12893 + char *DeviceName;
12895 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12896 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12898 + cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12900 + return SCSI_RESET_PUNT;
12904 +/*------------------------------------------------------------------------------
12907 + Returns the host adapter name
12908 + *----------------------------------------------------------------------------*/
12909 +const char *AAC_DriverInfo(
12910 + struct Scsi_Host *host_ptr )
12911 +/*----------------------------------------------------------------------------*/
12913 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12914 + char *DeviceName;
12916 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12917 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12919 + cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12920 + return (DeviceName);
12924 +/*------------------------------------------------------------------------------
12925 + AAC_BIOSDiskParameters()
12927 + Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12928 + The default disk geometry is 64 heads, 32 sectors, and the appropriate
12929 + number of cylinders so as not to exceed drive capacity. In order for
12930 + disks equal to or larger than 1 GB to be addressable by the BIOS
12931 + without exceeding the BIOS limitation of 1024 cylinders, Extended
12932 + Translation should be enabled. With Extended Translation enabled,
12933 + drives between 1 GB inclusive and 2 GB exclusive are given a disk
12934 + geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12935 + are given a disk geometry of 255 heads and 63 sectors. However, if
12936 + the BIOS detects that the Extended Translation setting does not match
12937 + the geometry in the partition table, then the translation inferred
12938 + from the partition table will be used by the BIOS, and a warning may
12940 + *----------------------------------------------------------------------------*/
12941 +int AAC_BIOSDiskParameters(
12942 + Scsi_Disk *scsi_disk_ptr,
12944 + int *parameter_ptr )
12945 +/*----------------------------------------------------------------------------*/
12947 + AAC_BIOS_DiskParameters_T *disk_parameters =
12948 + ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12949 + struct buffer_head * buffer_head_ptr;
12951 + cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12953 + // Assuming extended translation is enabled - #REVISIT#
12954 + if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12956 + if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12958 + disk_parameters->heads = 255;
12959 + disk_parameters->sectors = 63;
12963 + disk_parameters->heads = 128;
12964 + disk_parameters->sectors = 32;
12969 + disk_parameters->heads = 64;
12970 + disk_parameters->sectors = 32;
12973 + disk_parameters->cylinders = scsi_disk_ptr->capacity
12974 + /( disk_parameters->heads * disk_parameters->sectors );
12976 + // Read the first 1024 bytes from the disk device
12977 + buffer_head_ptr = bread(
12978 + MKDEV( MAJOR( device ),
12979 + MINOR( device ) & ~0x0F ),
12982 + if( buffer_head_ptr == NULL )
12985 + If the boot sector partition table is valid, search for a partition
12986 + table entry whose end_head matches one of the standard geometry
12987 + translations ( 64/32, 128/32, 255/63 ).
12989 + if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12991 + struct partition *first_partition_entry =
12992 + ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12993 + struct partition *partition_entry = first_partition_entry;
12994 + int saved_cylinders = disk_parameters->cylinders;
12995 + int partition_number;
12996 + unsigned char partition_entry_end_head, partition_entry_end_sector;
12998 + for( partition_number = 0; partition_number < 4; partition_number++ )
13000 + partition_entry_end_head = partition_entry->end_head;
13001 + partition_entry_end_sector = partition_entry->end_sector & 0x3f;
13003 + if( partition_entry_end_head == ( 64 - 1 ) )
13005 + disk_parameters->heads = 64;
13006 + disk_parameters->sectors = 32;
13009 + else if( partition_entry_end_head == ( 128 - 1 ) )
13011 + disk_parameters->heads = 128;
13012 + disk_parameters->sectors = 32;
13015 + else if( partition_entry_end_head == ( 255 - 1 ) )
13017 + disk_parameters->heads = 255;
13018 + disk_parameters->sectors = 63;
13021 + partition_entry++;
13024 + if( partition_number == 4 )
13026 + partition_entry_end_head = first_partition_entry->end_head;
13027 + partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
13030 + disk_parameters->cylinders = scsi_disk_ptr->capacity
13031 + /( disk_parameters->heads * disk_parameters->sectors );
13033 + if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
13035 + if( disk_parameters->cylinders != saved_cylinders )
13036 + cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
13037 + disk_parameters->heads, disk_parameters->sectors, partition_number );
13039 + else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
13041 + cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
13042 + partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
13043 + cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
13044 + disk_parameters->heads, disk_parameters->sectors );
13048 + brelse( buffer_head_ptr );
13054 +/*------------------------------------------------------------------------------
13055 + AAC_SelectQueueDepths()
13057 + Selects queue depths for each target device based on the host adapter's
13058 + total capacity and the queue depth supported by the target device.
13059 + A queue depth of one automatically disables tagged queueing.
13060 + *----------------------------------------------------------------------------*/
13061 +void AAC_SelectQueueDepths(
13062 + struct Scsi_Host * host_ptr,
13063 + Scsi_Device * scsi_device_ptr )
13064 +/*----------------------------------------------------------------------------*/
13066 + Scsi_Device * device_ptr;
13068 + cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
13069 + cmn_err( CE_DEBUG, "Device # Q Depth Online" );
13070 + cmn_err( CE_DEBUG, "---------------------------" );
13071 + for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
13072 + if( device_ptr->host == host_ptr )
13074 + device_ptr->queue_depth = 10;
13075 + cmn_err( CE_DEBUG, " %2d %d %d",
13076 + device_ptr->id, device_ptr->queue_depth, device_ptr->online );
13081 +/*------------------------------------------------------------------------------
13082 + AAC_SearchBiosSignature()
13084 + Locate adapter signature in BIOS
13085 + *----------------------------------------------------------------------------*/
13086 +int AAC_SearchBiosSignature( void )
13087 +/*----------------------------------------------------------------------------*/
13093 + char name_buf[32];
13094 + int result = FALSE;
13096 + for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13098 + val = readb( base );
13099 + if( val != 0x55 )
13103 + namep = base + 0x1e;
13104 + memcpy_fromio( name_buf, namep, 32 );
13105 + name_buf[31] = '\0';
13107 + return( result );
13111 +/*------------------------------------------------------------------------------
13114 + Handle SCSI ioctls
13115 + *----------------------------------------------------------------------------*/
13117 + Scsi_Device * scsi_dev_ptr,
13120 +/*----------------------------------------------------------------------------*/
13122 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13124 + cmn_err( CE_DEBUG, "AAC_Ioctl" );
13125 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13126 + return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13131 +/*------------------------------------------------------------------------------
13132 + AAC_ChardevOpen()
13134 + Handle character device open
13138 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13139 + *----------------------------------------------------------------------------*/
13140 +int AAC_ChardevOpen(
13141 + struct inode * inode_ptr,
13142 + struct file * file_ptr )
13143 +/*----------------------------------------------------------------------------*/
13145 + unsigned minor_number;
13147 + cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13149 + // check device permissions in file_ptr->f_mode ??
13151 + // extract & check the minor number
13152 + minor_number = MINOR( inode_ptr->i_rdev );
13153 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13155 + cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13156 + return( -ENODEV );
13159 + MOD_INC_USE_COUNT;
13165 +/*------------------------------------------------------------------------------
13166 + AAC_ChardevRelease()
13168 + Handle character device release.
13172 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13173 + *----------------------------------------------------------------------------*/
13174 +int AAC_ChardevRelease(
13175 + struct inode * inode_ptr,
13176 + struct file * file_ptr )
13177 +/*----------------------------------------------------------------------------*/
13179 + cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13181 + MOD_DEC_USE_COUNT;
13187 +/*------------------------------------------------------------------------------
13188 + AAC_ChardevIoctl()
13190 + Handle character device interface ioctls
13194 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13195 + *----------------------------------------------------------------------------*/
13196 +int AAC_ChardevIoctl(
13197 + struct inode * inode_ptr,
13198 + struct file * file_ptr,
13199 + unsigned int cmd,
13200 + unsigned long arg )
13202 + unsigned minor_number;
13203 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13205 + cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13207 + // check device permissions in file_ptr->f_mode ??
13209 + // extract & check the minor number
13210 + minor_number = MINOR( inode_ptr->i_rdev );
13211 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13213 + cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13214 + return( -ENODEV );
13217 + // get device pointer
13218 + CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13220 + // dispatch ioctl - AacHba_Ioctl() returns zero on success
13221 + if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13222 + return( -EINVAL );
13228 +/*------------------------------------------------------------------------------
13231 + Look for the keyword in str_ptr
13236 + - return true and update the pointer str_ptr.
13239 + *----------------------------------------------------------------------------*/
13240 +static int parse_keyword(
13243 +/*----------------------------------------------------------------------------*/
13245 + char * ptr = *str_ptr;
13247 + while( *keyword != '\0' )
13249 + char string_char = *ptr++;
13250 + char keyword_char = *keyword++;
13252 + if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13253 + string_char += 'a' - 'Z';
13254 + if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13255 + keyword_char += 'a' - 'Z';
13256 + if( string_char != keyword_char )
13264 +/*------------------------------------------------------------------------------
13265 + AAC_ParseDriverOptions()
13267 + For modules the usage is:
13268 + insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13269 + *----------------------------------------------------------------------------*/
13270 +static void AAC_ParseDriverOptions(
13271 + char * cmnd_line_options_str )
13272 +/*----------------------------------------------------------------------------*/
13274 + int message_level;
13275 + int reverse_scan;
13279 + cp = cmnd_line_options_str;
13281 + cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13284 + if( parse_keyword( &cp, "message_level:" ) ) {
13285 + message_level = simple_strtoul( cp, 0, 0 );
13286 + if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13287 + g_options.message_level = message_level;
13288 + cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13291 + cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13293 + } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13294 + reverse_scan = simple_strtoul( cp, 0, 0 );
13295 + if (reverse_scan) {
13296 + g_options.reverse_scan = 1;
13297 + cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13301 + cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13305 + * skip to next option, accept " ", ";", and "," as delimiters
13307 + while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13310 + if (*cp) /* skip over the delimiter */
13317 +/*------------------------------------------------------------------------------
13318 + To use the low level SCSI driver support using the linux kernel loadable
13319 + module interface we should initialize the global variable driver_interface
13320 + (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13321 + *----------------------------------------------------------------------------*/
13323 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13325 +#include "scsi_module.c"
13328 +/*********************************************************************
13329 + AAC_ProcDirectoryInfo()
13331 + Implement /proc/scsi/<drivername>/<n>.
13332 + Used to export driver statistics and other infos to the world outside
13333 + the kernel using the proc file system. Also provides an interface to
13334 + feed the driver with information.
13338 + - if offset > 0 return 0
13339 + - if offset == 0 write data to proc_buffer and set the start_ptr to
13340 + beginning of proc_buffer, return the number of characters written.
13342 + - writes currently not supported, return 0
13343 +************************************************************/
13344 +int AAC_ProcDirectoryInfo(
13345 + char *proc_buffer, // read/write buffer
13346 + char **start_ptr, // start of valid data in the buffer
13347 + off_t offset, // offset from the beginning of the imaginary file
13348 + int bytes_available, // bytes available
13349 + int host_no, // SCSI host number
13350 + int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13353 + cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13355 + if( ( write ) || ( offset > 0 ) )
13358 + *start_ptr = proc_buffer;
13360 + return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13363 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13365 + void *BaseAddress;
13366 + ULONG PhysAddress;
13371 + AFA_COMM_ADAPTER *Adapter;
13372 + Adapter = CommonExtension->Adapter;
13375 + // Allocate 1 fib for synch fibs
13376 + // Allocate 1 page.
13377 + BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13378 + bzero(BaseAddress, PAGE_SIZE);
13379 + PhysAddress = virt_to_phys (BaseAddress);
13380 + Adapter->SyncFib = BaseAddress;
13381 + Adapter->SyncFibPhysicalAddress = PhysAddress;
13382 + cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13385 diff -burN linux-2.4.9/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13386 --- linux-2.4.9/drivers/scsi/aacraid/osddi.c Wed Dec 31 18:00:00 1969
13387 +++ linux/drivers/scsi/aacraid/osddi.c Thu Aug 16 13:41:30 2001
13390 + * Adaptec aacraid device driver for Linux.
13392 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13394 + * This program is free software; you can redistribute it and/or modify
13395 + * it under the terms of the GNU General Public License as published by
13396 + * the Free Software Foundation; either version 2, or (at your option)
13397 + * any later version.
13399 + * This program is distributed in the hope that it will be useful,
13400 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13401 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13402 + * GNU General Public License for more details.
13404 + * You should have received a copy of the GNU General Public License
13405 + * along with this program; see the file COPYING. If not, write to
13406 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13411 + * Abstract: This file contains all the proceedures which use LINUX specific Device
13412 + * Driver Interfaces.
13416 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13418 +#include "osheaders.h"
13420 +#include <linux/smp_lock.h>
13425 +#include "AacGenericTypes.h"
13426 +#include "aac_unix_defs.h"
13427 +#include "comstruc.h"
13428 +#include "monkerapi.h"
13429 +#include "protocol.h"
13430 +#include "fsafs.h"
13432 +#include "sap1common.h"
13433 +#include "fsaport.h"
13434 +#include "pcisup.h"
13436 +#include "nodetype.h"
13437 +#include "comsup.h"
13438 +#include "afacomm.h"
13439 +#include "adapter.h"
13445 + struct pt_regs *regs);
13450 + struct pt_regs *regs);
13452 +unsigned SaPciIsr (
13453 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13455 +unsigned RxPciIsr (
13456 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13459 +/*----------------------------------------------------------------------------*/
13460 +VOID AfaCommInterruptHost(
13461 + PVOID AdapterArg,
13462 + ADAPTER_EVENT AdapterEvent )
13463 +/*----------------------------------------------------------------------------*/
13465 + PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13466 + PCOMM_REGION CommRegion = Adapter->CommRegion;
13468 + switch (AdapterEvent) {
13470 + case HostNormRespQue:
13471 + OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13473 + // #REVIEW# - what do we do with this
13474 + // if (FsaCommData.HardInterruptModeration)
13475 + // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13479 + case AdapNormCmdNotFull:
13480 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13483 + case HostNormCmdQue:
13484 + OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13487 + case AdapNormRespNotFull:
13488 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13491 + // #REVIEW# - what do we do with these
13492 + case HostHighCmdQue:
13493 + case HostHighRespQue:
13494 + case AdapHighCmdNotFull:
13495 + case AdapHighRespNotFull:
13496 + case SynchCommandComplete:
13497 + case AdapInternalError:
13503 +// get the device name associated with this instance of the device
13504 +/*----------------------------------------------------------------------------*/
13505 +char *OsGetDeviceName(
13506 + void *AdapterExtension )
13507 +/*----------------------------------------------------------------------------*/
13509 + return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13510 + OsDep.scsi_host_ptr->hostt->name );
13514 +/*----------------------------------------------------------------------------*/
13515 +int OsGetDeviceInstance(
13516 + void *AdapterExtension )
13517 +/*----------------------------------------------------------------------------*/
13519 + return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13520 + OsDep.scsi_host_ptr->unique_id );
13524 +/*------------------------------------------------------------------------------
13525 + OsMapDeviceRegisters()
13528 + Return zero on success non-zero otherwise.
13529 + *----------------------------------------------------------------------------*/
13530 +int OsMapDeviceRegisters(
13531 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13532 +/*----------------------------------------------------------------------------*/
13534 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13536 + CommonExtension = AdapterExtension->Common;
13538 + if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13539 + ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13541 + cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13546 + cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13552 +/*------------------------------------------------------------------------------
13553 + OsUnMapDeviceRegisters()
13556 + *----------------------------------------------------------------------------*/
13557 +void OsUnMapDeviceRegisters(
13558 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13559 +/*----------------------------------------------------------------------------*/
13561 + iounmap( ( void * )AdapterExtension->Device );
13565 +/*----------------------------------------------------------------------------*/
13566 +int OsAttachInterrupt(
13567 + Sa_ADAPTER_EXTENSION *AdapterExtension ,
13569 +/*----------------------------------------------------------------------------*/
13571 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13575 + CommonExtension = AdapterExtension->Common;
13576 + irq_data = ( void * )AdapterExtension;
13578 + switch (WhichIsr) {
13580 + Isr = AacSaPciIsr;
13583 + Isr = AacRxPciIsr;
13586 + cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13587 + return( FAILURE );
13592 + if ( OsRegisterInterrupt (
13593 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13594 + Isr, // handler function
13598 + cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13599 + CommonExtension->OsDep.scsi_host_ptr->irq );
13600 + return( FAILURE );
13607 +/*----------------------------------------------------------------------------*/
13611 + struct pt_regs *regs)
13612 +/*----------------------------------------------------------------------------*/
13614 + // call the actual interrupt handler
13615 + SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13618 +/*----------------------------------------------------------------------------*/
13622 + struct pt_regs *regs)
13623 +/*----------------------------------------------------------------------------*/
13625 + // call the actual interrupt handler
13626 + RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13630 +/*----------------------------------------------------------------------------*/
13631 +void OsDetachInterrupt(
13632 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13633 +/*----------------------------------------------------------------------------*/
13635 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13638 + CommonExtension = AdapterExtension->Common;
13639 + irq_data = ( void * )AdapterExtension;
13641 + OsUnregisterInterrupt (
13642 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13647 +/*----------------------------------------------------------------------------*/
13649 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13650 +/*----------------------------------------------------------------------------*/
13655 +/*----------------------------------------------------------------------------*/
13657 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13658 +/*----------------------------------------------------------------------------*/
13663 +/*----------------------------------------------------------------------------*/
13664 +void OsDetachDevice(
13665 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13666 +/*----------------------------------------------------------------------------*/
13668 + OsUnMapDeviceRegisters( AdapterExtension );
13672 +/*----------------------------------------------------------------------------*/
13673 +ULONG *OsAllocCommPhysMem(
13674 + Sa_ADAPTER_EXTENSION *AdapterExtension,
13676 + ULONG **virt_addr_pptr,
13677 + ULONG *phys_addr_ptr )
13678 +/*----------------------------------------------------------------------------*/
13680 + if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13682 + *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13683 + if( !*phys_addr_ptr )
13685 + cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13688 + return( *virt_addr_pptr );
13694 +OsAifKernelThread(
13695 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13698 + struct fs_struct *fs;
13700 + struct task_struct *tsk;
13706 + * set up the name that will appear in 'ps'
13707 + * stored in task_struct.comm[16].
13710 + sprintf(tsk->comm, "AIFd");
13713 + // use_init_fs_context(); only exists in 2.2.13 onward.
13718 + * we were started as a result of loading the module.
13719 + * free all of user space pages
13728 + fs = init_task.fs;
13731 + tsk->session = 1;
13735 + atomic_inc(&fs->count);
13742 + NormCommandThread(AdapterExtension);
13743 + /* NOT REACHED */
13746 +/*----------------------------------------------------------------------------*/
13747 +void OsStartKernelThreads(
13748 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13749 +/*----------------------------------------------------------------------------*/
13751 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13752 + AFA_COMM_ADAPTER *Adapter;
13753 + extern void NormCommandThread(void *Adapter);
13755 + CommonExtension = AdapterExtension->Common;
13756 + Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13759 + // Start thread which will handle interrupts for this adapter
13761 + //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13764 + // Start thread which will handle AdapterInititatedFibs from this adapter
13766 + CommonExtension->OsDep.thread_pid =
13767 + kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13768 +// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13771 +/*----------------------------------------------------------------------------*/
13772 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13774 + IN PMAPFIB_CONTEXT MapFibContext )
13775 +/*----------------------------------------------------------------------------*/
13777 + PVOID BaseAddress;
13778 + ULONG PhysAddress;
13780 + if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13782 + cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13786 + PhysAddress = OsVirtToPhys( BaseAddress );
13788 + MapFibContext->FibVirtualAddress = BaseAddress;
13789 + MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13794 +/*----------------------------------------------------------------------------*/
13795 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13797 + IN PMAPFIB_CONTEXT MapFibContext )
13798 +/*----------------------------------------------------------------------------*/
13800 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13802 + OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13807 +/*----------------------------------------------------------------------------*/
13808 +BOOLEAN AfaPortFreeAdapterCommArea(
13810 +/*----------------------------------------------------------------------------*/
13812 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13814 + OsFreeMemory( CommonExtension->CommAddress, 0 );
13820 +/* ================================================================================ */
13822 + * Not sure if the functions below here ever get called in the current code
13823 + * These probably should be a different file.
13826 +ddi_dma_attr_t AfaPortDmaAttributes = {
13827 + //rpbfix : we may want something different for I/O
13844 +AfaPortBuildSgMap(
13846 + IN PSGMAP_CONTEXT SgMapContext
13851 +Routine Description:
13853 + This routine build a scatter gather map using the information
13854 + in the SgMapContext.
13858 + AdapterExtension - Pointer to adapter extension structure.
13859 + SgMapContext - Pointer to the SgMapContext for the request.
13867 + printk( KERN_ALERT "AfaPortBuildSgMap: unimplemented function called" );
13868 + return (STATUS_UNSUCCESSFUL);
13872 +AfaPortFreeDmaResources(
13874 + IN PSGMAP_CONTEXT SgMapContext
13879 +Routine Description:
13881 + Given a pointer to the IRP context will free all reserved DMA resources allocated for
13882 + the completed IO operation.
13886 + Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13887 + Context - Pointer to the Irp Context we use to store the dma mapping information
13888 + we need to do and complete the IO.
13897 diff -burN linux-2.4.9/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13898 --- linux-2.4.9/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 18:00:00 1969
13899 +++ linux/drivers/scsi/aacraid/osfuncs.c Thu Aug 16 18:15:01 2001
13902 + * Adaptec aacraid device driver for Linux.
13904 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13906 + * This program is free software; you can redistribute it and/or modify
13907 + * it under the terms of the GNU General Public License as published by
13908 + * the Free Software Foundation; either version 2, or (at your option)
13909 + * any later version.
13911 + * This program is distributed in the hope that it will be useful,
13912 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13913 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13914 + * GNU General Public License for more details.
13916 + * You should have received a copy of the GNU General Public License
13917 + * along with this program; see the file COPYING. If not, write to
13918 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13923 + * Abstract: Holds all of the O/S specific interface functions.
13927 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13929 +#include "osheaders.h"
13931 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13933 +extern aac_options_t g_options;
13935 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13936 +wait_queue_t * g_wait_queue_ptr = NULL;
13937 +wait_queue_t g_wait;
13939 +void OsTimeoutHandler(
13940 + struct semaphore * sem );
13942 +int * OsIdleTask( void * data );
13944 +//-----------------------------------------------------------------------------
13945 +// Memory Allocation functions
13947 +/*----------------------------------------------------------------------------*/
13948 +void * OsAllocMemory(
13950 + unsigned int Flags )
13951 +/*----------------------------------------------------------------------------*/
13955 + if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13956 + cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13957 + return( mem_ptr );
13961 +/*----------------------------------------------------------------------------*/
13962 +void OsFreeMemory(
13965 +/*----------------------------------------------------------------------------*/
13971 +/*----------------------------------------------------------------------------*/
13972 +int OsRegisterInterrupt(
13973 + unsigned int irq, // interrupt number
13974 + void ( *handler )( int, void*, struct pt_regs * ), // handler function
13975 + void *irq_data ) // argument to handler function
13976 +/*----------------------------------------------------------------------------*/
13978 + return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13982 +/*----------------------------------------------------------------------------*/
13983 +void OsUnregisterInterrupt(
13984 + unsigned int irq, // interrupt number
13986 +/*----------------------------------------------------------------------------*/
13989 + irq, // interrupt number
13994 +/*----------------------------------------------------------------------------*/
13995 +unsigned long OsVirtToPhys(
13996 + void * virtual_address )
13997 +/*----------------------------------------------------------------------------*/
13999 + return( virt_to_phys( virtual_address ) );
14003 +//-----------------------------------------------------------------------------
14004 +// MUTEX functions
14006 +/*----------------------------------------------------------------------------*/
14007 +OS_STATUS OsMutexInit(
14009 + OS_SPINLOCK_COOKIE Cookie )
14010 +/*----------------------------------------------------------------------------*/
14012 + Mutex->lock_var = 0;
14013 + // bzero (&Mutex->wq, sizeof (Mutex->wq));
14014 + init_waitqueue_head (&Mutex->wq);
14019 +/*----------------------------------------------------------------------------*/
14020 +void OsMutexDestroy(
14021 + OS_MUTEX *Mutex )
14022 +/*----------------------------------------------------------------------------*/
14027 +/*----------------------------------------------------------------------------*/
14028 +void OsMutexAcquire(
14029 + OS_MUTEX *Mutex )
14030 +/*----------------------------------------------------------------------------*/
14032 + // wait_queue_t wait = { current, NULL };
14033 + unsigned long time_stamp;
14035 + DECLARE_WAITQUEUE (wait, current);
14037 + time_stamp = jiffies;
14039 + if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14041 + if( in_interrupt() )
14042 + panic( "OsMutexAcquire going to sleep at interrupt time\n" );
14043 + current->state = TASK_INTERRUPTIBLE;
14044 + add_wait_queue( &( Mutex->wq ), &wait );
14045 + while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14047 + remove_wait_queue( &( Mutex->wq ), &wait );
14050 + if( ( jiffies - 1 ) > time_stamp )
14051 + cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
14052 + Mutex, jiffies - time_stamp );
14056 +/*----------------------------------------------------------------------------*/
14057 +void OsMutexRelease(
14058 + OS_MUTEX *Mutex )
14059 +/*----------------------------------------------------------------------------*/
14061 + if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14062 + cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14063 + wake_up_interruptible( &( Mutex->wq ) );
14066 +// see man hierarchy(D5)
14067 +#define FSA_LOCK 1
14069 +//-----------------------------------------------------------------------------
14070 +// Spinlock functions
14072 +/*----------------------------------------------------------------------------*/
14073 +OS_SPINLOCK * OsSpinLockAlloc( void )
14074 +/*----------------------------------------------------------------------------*/
14076 + OS_SPINLOCK *SpinLock;
14080 + SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14082 + if (SpinLock == NULL)
14083 + cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14085 + SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14086 + for( i = 0; i < NR_CPUS; i++ )
14087 + SpinLock->cpu_lock_count[ i ] = 0;
14088 + return( SpinLock );
14092 +/*----------------------------------------------------------------------------*/
14093 +OS_STATUS OsSpinLockInit(
14094 + OS_SPINLOCK *SpinLock,
14095 + OS_SPINLOCK_COOKIE Cookie )
14096 +/*----------------------------------------------------------------------------*/
14102 +/*----------------------------------------------------------------------------*/
14103 +void OsSpinLockDestroy(
14104 + OS_SPINLOCK *SpinLock )
14105 +/*----------------------------------------------------------------------------*/
14107 + kfree( SpinLock );
14112 +/*----------------------------------------------------------------------------*/
14113 +void OsSpinLockAcquire(
14114 + OS_SPINLOCK *SpinLock )
14115 +/*----------------------------------------------------------------------------*/
14121 + cpu_id = smp_processor_id();
14122 + if( SpinLock->cpu_lock_count[ cpu_id ] ){
14123 + cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14124 + cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14127 + spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14128 + SpinLock->cpu_lock_count[ cpu_id ]++;
14131 + cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14136 +/*----------------------------------------------------------------------------*/
14137 +void OsSpinLockRelease(
14138 + OS_SPINLOCK *SpinLock )
14139 +/*----------------------------------------------------------------------------*/
14145 + cpu_id = smp_processor_id();
14146 + SpinLock->cpu_lock_count[ cpu_id ]--;
14147 + spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14150 + cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14154 +/*----------------------------------------------------------------------------*/
14155 +inline int OsSpinLockOwned(
14156 + OS_SPINLOCK *SpinLock )
14157 +/*----------------------------------------------------------------------------*/
14159 + return spin_is_locked (&SpinLock->spin_lock);
14163 +//-----------------------------------------------------------------------------
14164 +// CvLock functions
14166 +/*----------------------------------------------------------------------------*/
14167 +OS_CVLOCK *OsCvLockAlloc( void )
14169 + OS_CVLOCK *cv_lock;
14172 +#ifdef CVLOCK_USE_SPINLOCK
14173 + cv_lock = OsSpinLockAlloc();
14175 + cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14176 + cv_lock->wq = NULL;
14177 + cv_lock->lock_var = 0;
14180 + return( cv_lock );
14184 +/*----------------------------------------------------------------------------*/
14185 +OS_STATUS OsCvLockInit(
14186 + OS_CVLOCK *cv_lock,
14187 + OS_SPINLOCK_COOKIE Cookie )
14188 +/*----------------------------------------------------------------------------*/
14194 +/*----------------------------------------------------------------------------*/
14195 +void OsCvLockDestroy(
14196 + OS_CVLOCK *cv_lock )
14197 +/*----------------------------------------------------------------------------*/
14200 + kfree( cv_lock );
14205 +/*----------------------------------------------------------------------------*/
14206 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14208 +#ifdef CVLOCK_USE_SPINLOCK
14209 + OsSpinLockAcquire( cv_lock );
14211 + OsMutexAcquire( cv_lock );
14216 +/*----------------------------------------------------------------------------*/
14217 +void OsCvLockRelease(
14218 + OS_CVLOCK *cv_lock )
14219 +/*----------------------------------------------------------------------------*/
14221 +#ifdef CVLOCK_USE_SPINLOCK
14222 + OsSpinLockRelease( cv_lock );
14224 + OsMutexRelease( cv_lock );
14229 +/*----------------------------------------------------------------------------*/
14230 +int OsCvLockOwned(
14231 + OS_CVLOCK *cv_lock )
14232 +/*----------------------------------------------------------------------------*/
14238 +//-----------------------------------------------------------------------------
14239 +// Conditional variable functions
14241 +/*----------------------------------------------------------------------------*/
14243 + OS_CV_T *cv_ptr )
14244 +/*----------------------------------------------------------------------------*/
14246 + cv_ptr->lock_var = 1;
14247 + init_waitqueue_head (&cv_ptr->wq);
14251 +/*----------------------------------------------------------------------------*/
14252 +void OsCv_destroy(
14253 + OS_CV_T *cv_ptr )
14254 +/*----------------------------------------------------------------------------*/
14259 +/*______________________________________________________________________________
14262 + -----------------------------------------------------------------------------*/
14263 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14265 + unsigned long flags;
14267 + DECLARE_WAITQUEUE (wait, current);
14269 + if( in_interrupt() )
14270 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14272 + cv_ptr->type = TASK_UNINTERRUPTIBLE;
14273 + current->state = TASK_UNINTERRUPTIBLE;
14275 + add_wait_queue( &cv_ptr->wq, &wait );
14277 + OsCvLockRelease( cv_lock_ptr );
14280 + while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14282 + if( in_interrupt() )
14283 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14287 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14289 + OsCvLockAcquire( cv_lock_ptr );
14293 +/*----------------------------------------------------------------------------*/
14294 +int OsCv_wait_sig(
14296 + OS_CVLOCK *cv_lock_ptr )
14297 +/*----------------------------------------------------------------------------*/
14299 + unsigned long flags;
14300 + int signal_state = 1;
14302 + DECLARE_WAITQUEUE (wait, current);
14304 + if( in_interrupt() )
14305 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14307 + cv_ptr->type = TASK_INTERRUPTIBLE;
14308 + current->state = TASK_INTERRUPTIBLE;
14310 + add_wait_queue( &( cv_ptr->wq ), &wait );
14312 + OsCvLockRelease( cv_lock_ptr );
14315 + while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14316 + ( !signal_pending( current ) ) )
14318 + if( in_interrupt() )
14319 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14323 + if( signal_pending( current ) )
14324 + signal_state = 0;
14326 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14328 + OsCvLockAcquire( cv_lock_ptr );
14329 + return( signal_state );
14333 +/*----------------------------------------------------------------------------*/
14335 + OS_CV_T *cv_ptr )
14336 +/*----------------------------------------------------------------------------*/
14339 + clear_bit( 0, &( cv_ptr->lock_var ) );
14340 + if( cv_ptr->type == TASK_INTERRUPTIBLE )
14341 + wake_up_interruptible( &( cv_ptr->wq ) );
14343 + wake_up( &( cv_ptr->wq ) );
14348 +// return time in seconds
14349 +/*----------------------------------------------------------------------------*/
14350 +unsigned long OsGetSeconds( void )
14351 +/*----------------------------------------------------------------------------*/
14353 + return( jiffies/HZ );
14357 +//-----------------------------------------------------------------------------
14358 +// Deferred procedure call functions
14360 +// create a soft interrupt object
14361 +/*----------------------------------------------------------------------------*/
14362 +int OsSoftInterruptAdd(
14363 + OS_SOFTINTR **ptr,
14366 +/*----------------------------------------------------------------------------*/
14368 + OS_SOFTINTR *tmp_ptr;
14370 + if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14372 + tmp_ptr->routine = handler;
14373 + tmp_ptr->data = data;
14374 + tmp_ptr->sync = 0;
14375 + INIT_LIST_HEAD(&tmp_ptr->list);
14383 + Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14385 +/*----------------------------------------------------------------------------*/
14386 +int * OsIdleTask( void * data )
14387 +/*----------------------------------------------------------------------------*/
14389 + DECLARE_WAITQUEUE (wait, current);
14393 + current->state = TASK_INTERRUPTIBLE;
14394 + add_wait_queue( &g_wait_queue_ptr, &wait );
14396 + remove_wait_queue( &g_wait_queue_ptr, &wait );
14397 + wait.task = current;
14398 + wait.task_list.next = NULL;
14404 +// dispatch a soft interrupt
14405 +/*----------------------------------------------------------------------------*/
14406 +void OsSoftInterruptTrigger(
14407 + OS_SOFTINTR *soft_intr_ptr )
14408 +/*----------------------------------------------------------------------------*/
14410 + // call the completion routine directly
14411 + soft_intr_ptr->routine( soft_intr_ptr->data );
14415 +// delete a soft interrupt object
14416 +/*----------------------------------------------------------------------------*/
14417 +void OsSoftInterruptRemove(
14418 + OS_SOFTINTR *arg )
14419 +/*----------------------------------------------------------------------------*/
14427 +/*----------------------------------------------------------------------------*/
14429 + unsigned time ) // in seconds
14430 +/*----------------------------------------------------------------------------*/
14432 + struct semaphore sem;
14433 + struct timer_list timer_var;
14435 + init_MUTEX_LOCKED (&sem);
14437 + // if( in_interrupt() )
14438 + // panic( "OsSleep going to sleep at interrupt time\n" );
14440 + init_timer( &timer_var );
14441 + timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14442 + timer_var.data = ( unsigned long )&sem;
14443 + timer_var.expires = jiffies + time * HZ;
14445 + add_timer( &timer_var );
14448 + del_timer( &timer_var );
14452 +/*----------------------------------------------------------------------------*/
14453 +void OsTimeoutHandler(
14454 + struct semaphore * sem )
14455 +/*----------------------------------------------------------------------------*/
14457 + if( sem != NULL )
14462 +/*----------------------------------------------------------------------------*/
14467 +/*----------------------------------------------------------------------------*/
14472 + va_start(ap, fmt);
14473 + (void) vsprintf(buf, fmt, ap);
14476 + if( flag <= g_options.message_level )
14477 + printk(KERN_ALERT "%s\n", buf);
14480 +/* void aac_show_tasks (struct list_head *our_tasks){ */
14482 +/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14484 +/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14485 +/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14487 +/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14489 +/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14490 +/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14492 +/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14495 diff -burN linux-2.4.9/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14496 --- linux-2.4.9/drivers/scsi/aacraid/ossup.c Wed Dec 31 18:00:00 1969
14497 +++ linux/drivers/scsi/aacraid/ossup.c Thu Aug 16 13:41:30 2001
14500 + * Adaptec aacraid device driver for Linux.
14502 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14504 + * This program is free software; you can redistribute it and/or modify
14505 + * it under the terms of the GNU General Public License as published by
14506 + * the Free Software Foundation; either version 2, or (at your option)
14507 + * any later version.
14509 + * This program is distributed in the hope that it will be useful,
14510 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14511 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14512 + * GNU General Public License for more details.
14514 + * You should have received a copy of the GNU General Public License
14515 + * along with this program; see the file COPYING. If not, write to
14516 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14525 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14527 +#include "osheaders.h"
14529 +#include "aac_unix_defs.h"
14534 + IN PZONE_HEADER Zone,
14535 + IN ULONG BlockSize,
14536 + IN PVOID InitialSegment,
14537 + IN ULONG InitialSegmentSize
14542 +Routine Description:
14544 + This function initializes a zone header. Once successfully
14545 + initialized, blocks can be allocated and freed from the zone, and
14546 + the zone can be extended.
14550 + Zone - Supplies the address of a zone header to be initialized.
14552 + BlockSize - Supplies the block size of the allocatable unit within
14553 + the zone. The size must be larger that the size of the
14554 + initial segment, and must be 64-bit aligned.
14556 + InitialSegment - Supplies the address of a segment of storage. The
14557 + first ZONE_SEGMENT_HEADER-sized portion of the segment
14558 + is used by the zone allocator. The remainder of
14559 + the segment is carved up into fixed size
14560 + (BlockSize) blocks and is made available for
14561 + allocation and deallocation from the zone. The
14562 + address of the segment must be aligned on a 64-bit
14565 + InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14569 + STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14570 + 64-bit boundaries, or BlockSize was larger than
14571 + the initial segment size.
14573 + STATUS_SUCCESS - The zone was successfully initialized.
14582 + Zone->BlockSize = BlockSize;
14584 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14585 + ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14586 + ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14588 + Zone->FreeList.Next = NULL;
14590 + p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14592 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14593 + i <= InitialSegmentSize - BlockSize;
14596 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14597 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14600 + Zone->TotalSegmentSize = i;
14603 + DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14604 + Zone, InitialSegment, InitialSegmentSize,
14609 + return STATUS_SUCCESS;
14614 + IN PZONE_HEADER Zone,
14615 + IN PVOID Segment,
14616 + IN ULONG SegmentSize
14621 +Routine Description:
14623 + This function extends a zone by adding another segment's worth of
14624 + blocks to the zone.
14628 + Zone - Supplies the address of a zone header to be extended.
14630 + Segment - Supplies the address of a segment of storage. The first
14631 + ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14632 + zone allocator. The remainder of the segment is carved up
14633 + into fixed-size (BlockSize) blocks and is added to the
14634 + zone. The address of the segment must be aligned on a 64-
14637 + SegmentSize - Supplies the size in bytes of Segment.
14641 + STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14642 + 64-bit boundaries, or BlockSize was larger than
14643 + the segment size.
14645 + STATUS_SUCCESS - The zone was successfully extended.
14654 + ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14655 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14657 + p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14659 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14660 + i <= SegmentSize - Zone->BlockSize;
14661 + i += Zone->BlockSize
14664 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14665 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14666 + p += Zone->BlockSize;
14668 + Zone->TotalSegmentSize += i;
14671 + DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14672 + Zone, Segment, SegmentSize, Zone->BlockSize, p
14676 + return STATUS_SUCCESS;
14683 +/* Function: InqStrCopy()
14685 + * Arguments: [2] pointer to char
14687 + * Purpose: Copy a String from one location to another
14688 + * without copying \0
14691 +InqStrCopy(char *a, char *b)
14694 + while(*a != (char)0)
14698 diff -burN linux-2.4.9/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14699 --- linux-2.4.9/drivers/scsi/aacraid/port.c Wed Dec 31 18:00:00 1969
14700 +++ linux/drivers/scsi/aacraid/port.c Thu Aug 16 13:41:30 2001
14703 + * Adaptec aacraid device driver for Linux.
14705 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14707 + * This program is free software; you can redistribute it and/or modify
14708 + * it under the terms of the GNU General Public License as published by
14709 + * the Free Software Foundation; either version 2, or (at your option)
14710 + * any later version.
14712 + * This program is distributed in the hope that it will be useful,
14713 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14714 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14715 + * GNU General Public License for more details.
14717 + * You should have received a copy of the GNU General Public License
14718 + * along with this program; see the file COPYING. If not, write to
14719 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14724 + * Abstract: All support routines for FSA communication which are miniport specific.
14728 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14730 +#include "osheaders.h"
14733 +#include "AacGenericTypes.h"
14735 +#include "aac_unix_defs.h"
14737 +#include "fsatypes.h"
14738 +#include "comstruc.h"
14739 +#include "protocol.h"
14741 +#include "fsaport.h"
14742 +#include "fsaioctl.h"
14744 +#include "pcisup.h"
14747 +int AfaPortPrinting = 1;
14749 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14750 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14751 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14752 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14758 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14759 + IN AAC_STATUS ErrorCode,
14760 + IN PUCHAR StringBuffer,
14761 + IN ULONG StringLength
14765 +Routine Description:
14767 + Does all of the work to log an error log entry
14770 + CommonExtension - Pointer to the adapter that caused the error.
14772 + ErrorCode - Which error is being logged.
14774 + StringBuffer - Pointer to optional String for error log entry.
14776 + StringLength - Length of StringBuffer.
14789 +AfaPortGetNextAdapterNumber(
14790 + IN PDRIVER_OBJECT DriverObject,
14791 + OUT PDEVICE_OBJECT *FsaDeviceObject,
14792 + OUT PFILE_OBJECT *FileObject,
14793 + OUT PULONG AdapterNumber
14798 +AfaPortAllocateAdapterCommArea(
14800 + IN OUT PVOID *CommHeaderAddress,
14801 + IN ULONG CommAreaSize,
14802 + IN ULONG CommAreaAlignment
14805 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14806 + PVOID BaseAddress;
14807 + PHYSICAL_ADDRESS PhysicalBaseAddress;
14808 + ULONG TotalSize, BytesToAlign;
14809 + size_t RealLength;
14811 +// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14812 +// ULONG AdapterFibsSize = PAGE_SIZE;
14813 + ULONG AdapterFibsSize = 4096;
14814 + ULONG PrintfBufferSize = 256;
14815 + PADAPTER_INIT_STRUCT InitStruct;
14816 + extern int MiniPortRevision;
14817 + ULONG PhysAddress;
14819 +// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14820 +// SizeOfFastIoComm + PrintfBufferSize;
14821 + TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14822 + PrintfBufferSize;
14825 + OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14827 + CommonExtension->CommAddress = BaseAddress;
14828 + CommonExtension->CommPhysAddr = PhysAddress;
14829 + CommonExtension->CommSize = TotalSize;
14831 + PhysicalBaseAddress.HighPart = 0;
14832 + PhysicalBaseAddress.LowPart = PhysAddress;
14834 + CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14835 + CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14837 + InitStruct = CommonExtension->InitStruct;
14839 + InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14840 + InitStruct->MiniPortRevision = MiniPortRevision;
14841 + InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14844 + // Adapter Fibs are the first thing allocated so that they start page aligned
14846 + InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14847 + InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14848 + InitStruct->AdapterFibsSize = AdapterFibsSize;
14849 + InitStruct->AdapterFibAlign = sizeof(FIB);
14852 + // Increment the base address by the amount already used
14854 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14855 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14858 + // Align the beginning of Headers to CommAreaAlignment
14860 + BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14861 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14862 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14865 + // Fill in addresses of the Comm Area Headers and Queues
14867 + *CommHeaderAddress = BaseAddress;
14868 + InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14871 + // Increment the base address by the size of the CommArea
14873 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14874 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14878 + // Place the Printf buffer area after the Fast I/O comm area.
14880 + CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14881 + InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14882 + InitStruct->PrintfBufferSize = PrintfBufferSize;
14883 + bzero (BaseAddress, PrintfBufferSize);
14885 + AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14886 + TotalSize, InitStruct->AdapterFibsVirtualAddress,
14887 + (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14889 + AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14896 + IN PDEVICE_OBJECT DeviceObject,
14901 +Routine Description:
14903 + The routine will get called each time a user issues a CreateFile on the DeviceObject
14906 + The main purpose of this routine is to set up any data structures that may be needed
14907 + to handle any requests made on this DeviceObject.
14911 + DeviceObject - Pointer to device object representing adapter
14913 + Irp - Pointer to Irp that caused this open
14918 + Status value returned from File system driver AdapterOpen
14927 + IN PDEVICE_OBJECT DeviceObject,
14932 +Routine Description:
14934 + This routine will get called each time a user issues a CloseHandle on the DeviceObject
14937 + The main purpose of this routine is to cleanup any data structures that have been set up
14938 + while this FileObject has been opened.
14942 + DeviceObject - Pointer to device object representing adapter
14944 + Irp - Pointer to Irp that caused this close
14948 + Status value returned from File system driver AdapterClose
14957 +AfaPortDeviceControl (
14958 + IN PDEVICE_OBJECT DeviceObject,
14966 +AfaPortGetMaxPhysicalPage(
14967 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14971 +Routine Description:
14973 + This routine determines the max physical page in host memory.
14981 + Max physical page in host memory.
14989 diff -burN linux-2.4.9/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14990 --- linux-2.4.9/drivers/scsi/aacraid/rx.c Wed Dec 31 18:00:00 1969
14991 +++ linux/drivers/scsi/aacraid/rx.c Thu Aug 16 13:41:30 2001
14994 + * Adaptec aacraid device driver for Linux.
14996 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14998 + * This program is free software; you can redistribute it and/or modify
14999 + * it under the terms of the GNU General Public License as published by
15000 + * the Free Software Foundation; either version 2, or (at your option)
15001 + * any later version.
15003 + * This program is distributed in the hope that it will be useful,
15004 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15005 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15006 + * GNU General Public License for more details.
15008 + * You should have received a copy of the GNU General Public License
15009 + * along with this program; see the file COPYING. If not, write to
15010 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15015 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
15019 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
15021 +#include "osheaders.h"
15024 +#include "AacGenericTypes.h"
15026 +#include "aac_unix_defs.h"
15028 +#include "fsatypes.h"
15029 +#include "comstruc.h"
15030 +#include "fsact.h"
15031 +#include "protocol.h"
15033 +#define DEFINE_PCI_IDS
15034 +#include "rxcommon.h"
15035 +#include "monkerapi.h"
15037 +#include "fsaport.h"
15038 +#include "fsaioctl.h"
15040 +#include "pcisup.h"
15045 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15047 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15049 +#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15051 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15055 +// The list of all the Rx adapter structures
15058 +PRx_ADAPTER_EXTENSION RxAdapterList;
15062 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15063 + IN ULONG AdapterNumber,
15071 + ULONG FibPhysicalAddress
15074 +FSA_USER_VAR RxUserVars[] = {
15075 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15080 +// Declare private use routines for this modual
15085 + IN PRx_ADAPTER_EXTENSION AdapterExtension
15090 +Routine Description:
15092 + The Isr routine for fsa Rx based adapter boards.
15099 + TRUE - if the interrupt was handled by this isr
15100 + FALSE - if the interrupt was not handled by this isr
15105 + ULONG DoorbellBits;
15106 + UCHAR InterruptStatus, Mask;
15107 + u_int OurInterrupt = INTR_UNCLAIMED;
15109 + //cmn_err(CE_WARN, "RxPciIsr entered\n");
15111 + InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15114 + // Read mask and invert because drawbridge is reversed.
15116 + // This allows us to only service interrupts that have been enabled.
15119 + Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15121 + // Check to see if this is our interrupt. If it isn't just return FALSE.
15124 + if (InterruptStatus & Mask) {
15126 + DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15128 + OurInterrupt = INTR_CLAIMED;
15130 + if (DoorbellBits & DoorBellPrintfReady) {
15132 + ULONG Length, Level;
15133 + unsigned char *cp;
15135 + cp = AdapterExtension->Common->PrintfBufferAddress;
15138 + // The size of the Printfbuffer is set in port.c
15139 + // There is no variable or define for it
15141 + if (Length > 255)
15144 + if (cp[Length] != 0) {
15145 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15149 + if (Level == LOG_HIGH_ERROR)
15150 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15152 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15154 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15156 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15158 + Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15161 + } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15163 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15164 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15166 + } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15168 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15169 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15171 + } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15173 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15174 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15176 + } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15178 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15179 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15184 + return(OurInterrupt);
15188 +RxEnableInterrupt(
15190 + ADAPTER_EVENT AdapterEvent,
15191 + BOOLEAN AtDeviceIrq
15195 +Routine Description:
15197 + This routine will enable the corresponding adapter event to cause an interrupt on
15202 + AdapterExtension - Which adapter to enable.
15204 + AdapterEvent - Which adapter event.
15206 + AtDeviceIrq - Whether the system is in DEVICE irql
15214 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15215 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15217 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15218 + switch (AdapterEvent) {
15220 + case HostNormCmdQue:
15222 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15226 + case HostNormRespQue:
15228 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15232 + case AdapNormCmdNotFull:
15234 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15238 + case AdapNormRespNotFull:
15240 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15249 +RxDisableInterrupt(
15251 + ADAPTER_EVENT AdapterEvent,
15252 + BOOLEAN AtDeviceIrq
15256 +Routine Description:
15258 + This routine will disable the corresponding adapter event to cause an interrupt on
15263 + AdapterExtension - Which adapter to enable.
15265 + AdapterEvent - Which adapter event.
15267 + AtDeviceIrq - Whether the system is in DEVICE irql
15275 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15276 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15278 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15280 + switch (AdapterEvent) {
15283 + case HostNormCmdQue:
15285 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15289 + case HostNormRespQue:
15291 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15295 + case AdapNormCmdNotFull:
15297 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15302 + case AdapNormRespNotFull:
15304 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15315 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15318 + PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15321 + // Free the register mapping.
15324 + OsDetachDevice( AdapterExtension);
15326 + OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15332 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15333 + IN ULONG AdapterNumber,
15340 +Routine Description:
15342 + Scans the PCI bus looking for the Rx card. When found all resources for the
15343 + device will be allocated and the interrupt vectors and csrs will be allocated and
15346 + The device_interface in the commregion will be allocated and linked to the comm region.
15353 + TRUE - if the device was setup with not problems
15354 + FALSE - if the device could not be mapped and init successfully
15359 + AAC_STATUS Status;
15360 + PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15361 + FSA_NEW_ADAPTER NewAdapter;
15362 + ULONG StartTime, EndTime, WaitTime;
15363 + ULONG InitStatus;
15368 + AfaPortPrint("In init device.\n");
15370 + //cmn_err(CE_WARN, "In RxInitDevice");
15372 +// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15373 + CommonExtension->AdapterNumber = AdapterNumber;
15376 + CommonExtension->PciBusNumber = PciBus;
15377 + CommonExtension->PciSlotNumber = PciSlot;
15380 + AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15381 + AdapterExtension->Common = CommonExtension;
15382 + CommonExtension->MiniPort = AdapterExtension;
15384 + instance = OsGetDeviceInstance(AdapterExtension);
15385 + name = OsGetDeviceName(AdapterExtension);
15387 + // Map in the registers from the adapter, register space 0 is config space,
15388 + // register space 1 is the memery space.
15391 + if (OsMapDeviceRegisters(AdapterExtension)) {
15393 + cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15394 + OsGetDeviceName(AdapterExtension), instance);
15399 + // Check to see if the board failed any self tests.
15402 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15404 + cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15405 + OsGetDeviceName(AdapterExtension), instance);
15409 + //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15410 + // OsGetDeviceName(AdapterExtension), instance);
15413 + // Check to see if the board panic'd while booting.
15416 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15418 + cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15419 + OsGetDeviceName(AdapterExtension), instance);
15424 + StartTime = OsGetSeconds();
15429 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
15432 + while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15434 + EndTime = OsGetSeconds();
15436 + WaitTime = EndTime - StartTime;
15438 + if ( WaitTime > (3 * 10) ) {
15440 + InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15442 + cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15443 + OsGetDeviceName(AdapterExtension), instance, InitStatus);
15449 + if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15450 + cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15455 + if (OsAttachDMA(AdapterExtension)) {
15456 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15461 + // Fill in the function dispatch table.
15464 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15465 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15466 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15467 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15468 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15469 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15470 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15471 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15472 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15473 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15474 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15475 + AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15476 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15478 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15480 + NewAdapter.AdapterExtension = CommonExtension;
15481 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15482 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15483 + NewAdapter.AdapterUserVars = RxUserVars;
15484 + NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15486 + NewAdapter.Dip = CommonExtension->OsDep.dip;
15489 + if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15491 + cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15492 + return (FAILURE);
15496 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15498 + if (AdapterExtension->Common->Adapter == NULL) {
15500 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15501 + cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15504 + return (FAILURE);
15509 + // Start any kernel threads needed
15511 + OsStartKernelThreads(AdapterExtension);
15514 + // Tell the adapter that all is configure, and it can start accepting requests
15517 + RxStartAdapter(AdapterExtension);
15525 + // Put this adapter into the list of Rx adapters
15528 + AdapterExtension->Next = RxAdapterList;
15529 + RxAdapterList = AdapterExtension;
15531 + AdapterExtension->Common->AdapterConfigured = TRUE;
15536 + // Call the disk layer to initialize itself.
15539 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15545 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15549 + OsAttachHBA(AdapterExtension);
15556 + PRx_ADAPTER_EXTENSION AdapterExtension
15559 + ULONG ReturnStatus;
15560 + LARGE_INTEGER HostTime;
15561 + ULONG ElapsedSeconds;
15562 + PADAPTER_INIT_STRUCT InitStruct;
15564 + //cmn_err(CE_WARN, "RxStartAdapter");
15566 + // Fill in the remaining pieces of the InitStruct.
15569 + InitStruct = AdapterExtension->Common->InitStruct;
15571 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15573 + ElapsedSeconds = OsGetSeconds();
15575 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
15578 + // Tell the adapter we are back and up and running so it will scan its command
15579 + // queues and enable our interrupts
15582 + AdapterExtension->LocalMaskInterruptControl =
15583 + (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15586 + // First clear out all interrupts. Then enable the one's that we can handle.
15589 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15590 + Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15591 +// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15592 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15594 + RxSendSynchCommand(AdapterExtension,
15595 + INIT_STRUCT_BASE_ADDRESS,
15596 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15614 +RxInterruptAdapter(
15619 +Routine Description:
15621 + The will cause the adapter to take a break point.
15633 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15634 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15636 + ULONG ReturnStatus;
15638 + RxSendSynchCommand(AdapterExtension,
15639 + BREAKPOINT_REQUEST,
15651 + IN HOST_2_ADAP_EVENT AdapterEvent
15655 +Routine Description:
15657 + Will read the adapter CSRs to find the reason the adapter has
15662 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15670 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15671 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15672 + ULONG ReturnStatus;
15674 + //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15676 + switch (AdapterEvent) {
15677 + case AdapNormCmdQue:
15679 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15682 + case HostNormRespNotFull:
15684 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15687 + case AdapNormRespQue:
15689 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15692 + case HostNormCmdNotFull:
15694 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15697 + case HostShutdown:
15699 +// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15704 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15707 + case AdapPrintfDone:
15708 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15713 + RxBugCheck(0,0,0);
15714 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15720 +RxSendSynchCommand(
15723 + ULONG Parameter1,
15724 + ULONG Parameter2,
15725 + ULONG Parameter3,
15726 + ULONG Parameter4,
15727 + PULONG ReturnStatus
15731 +Routine Description:
15733 + This routine will send a synchronous comamnd to the adapter and wait for its
15738 + AdapterExtension - Pointer to adapter extension structure.
15739 + Command - Which command to send
15740 + Parameter1 - 4 - Parameters for command
15741 + ReturnStatus - return status from adapter after completion of command
15750 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15751 + ULONG StartTime,EndTime,WaitTime;
15752 + BOOLEAN CommandSucceeded;
15754 + //cmn_err(CE_WARN, "RxSendSyncCommand");
15756 + // Write the Command into Mailbox 0
15759 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15762 + // Write the parameters into Mailboxes 1 - 4
15765 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15766 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15767 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15768 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15771 + // Clear the synch command doorbell to start on a clean slate.
15774 + Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15777 + // disable doorbell interrupts
15780 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15781 + Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15784 + // force the completion of the mask register write before issuing the interrupt.
15787 + Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15790 + // Signal that there is a new synch command
15793 + Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15795 + CommandSucceeded = FALSE;
15797 + StartTime = OsGetSeconds();
15800 + while (WaitTime < 30) { // wait up to 30 seconds
15802 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15805 + // Mon110 will set doorbell0 bit when it has completed the command.
15808 + if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15811 + // clear the doorbell.
15814 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15816 + CommandSucceeded = TRUE;
15820 + EndTime = OsGetSeconds();
15821 + WaitTime = EndTime - StartTime;
15825 + if (CommandSucceeded != TRUE) {
15828 + // restore interrupt mask even though we timed out
15831 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15832 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15834 + return (STATUS_IO_TIMEOUT);
15839 + // Pull the synch status from Mailbox 0.
15842 + *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15845 + // Clear the synch command doorbell.
15848 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15851 + // restore interrupt mask
15854 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15855 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15858 + // Return SUCCESS
15861 + return (STATUS_SUCCESS);
15868 + ULONG FibPhysicalAddress
15872 +Routine Description:
15874 + This routine will send a synchronous fib to the adapter and wait for its
15879 + AdapterExtension - Pointer to adapter extension structure.
15880 + FibPhysicalAddress - Physical address of fib to send.
15889 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15890 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15891 + ULONG returnStatus;
15893 + if (RxSendSynchCommand( AdapterExtension,
15894 + SEND_SYNCHRONOUS_FIB,
15895 + FibPhysicalAddress,
15899 + &returnStatus ) != STATUS_SUCCESS ) {
15910 diff -burN linux-2.4.9/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15911 --- linux-2.4.9/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 18:00:00 1969
15912 +++ linux/drivers/scsi/aacraid/sap1sup.c Thu Aug 16 13:41:30 2001
15915 + * Adaptec aacraid device driver for Linux.
15917 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15919 + * This program is free software; you can redistribute it and/or modify
15920 + * it under the terms of the GNU General Public License as published by
15921 + * the Free Software Foundation; either version 2, or (at your option)
15922 + * any later version.
15924 + * This program is distributed in the hope that it will be useful,
15925 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15926 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15927 + * GNU General Public License for more details.
15929 + * You should have received a copy of the GNU General Public License
15930 + * along with this program; see the file COPYING. If not, write to
15931 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15936 + * Abstract: Drawbridge specific support functions
15940 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15942 +#include "osheaders.h"
15945 +#include "AacGenericTypes.h"
15947 +#include "aac_unix_defs.h"
15949 +#include "fsatypes.h"
15950 +#include "comstruc.h"
15951 +#include "fsact.h"
15952 +#include "protocol.h"
15954 +#define DEFINE_PCI_IDS
15955 +#include "sap1common.h"
15956 +#include "monkerapi.h"
15958 +#include "fsaport.h"
15959 +#include "fsaioctl.h"
15962 +#include "pcisup.h"
15967 +#include "nodetype.h"
15968 +#include "comsup.h"
15969 +#include "afacomm.h"
15970 +#include "adapter.h"
15972 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15974 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15976 +#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15978 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15980 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15984 +// The list of all the Sa adapter structures
15987 +PSa_ADAPTER_EXTENSION SaAdapterList;
15991 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15992 + IN ULONG AdapterNumber,
16000 + ULONG FibPhysicalAddress
16003 +FSA_USER_VAR SaUserVars[] = {
16004 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
16009 +// Declare private use routines for this modual
16015 +Routine Description:
16017 + The Isr routine for fsa Sa based adapter boards.
16024 + TRUE - if the interrupt was handled by this isr
16025 + FALSE - if the interrupt was not handled by this isr
16029 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
16031 + USHORT InterruptStatus, Mask;
16032 + u_int OurInterrupt = INTR_UNCLAIMED;
16034 + InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
16037 + // Read mask and invert because drawbridge is reversed.
16039 + // This allows us to only service interrupts that have been enabled.
16042 + Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
16044 + // Check to see if this is our interrupt. If it isn't just return FALSE.
16047 + if (InterruptStatus & Mask) {
16049 + OurInterrupt = INTR_CLAIMED;
16051 + if (InterruptStatus & PrintfReady) {
16053 + ULONG Length, Level;
16054 + unsigned char *cp;
16056 + cp = AdapterExtension->Common->PrintfBufferAddress;
16059 + // The size of the Printbuffer is set in port.c
16060 + // There is no variable or define for it
16062 + if (Length > 255)
16065 + if (cp[Length] != 0) {
16066 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16070 + if (Level == LOG_HIGH_ERROR)
16071 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16073 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16075 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16077 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16079 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16081 + } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
16083 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16084 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16086 + } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
16088 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16089 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16091 + } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
16093 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16094 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16096 + } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
16098 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16099 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16104 + return(OurInterrupt);
16110 +Routine Description:
16112 + This routine will enable the corresponding adapter event to cause an interrupt on
16117 + AdapterExtension - Which adapter to enable.
16119 + AdapterEvent - Which adapter event.
16121 + AtDeviceIrq - Whether the system is in DEVICE irql
16129 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16131 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16132 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16134 + switch (AdapterEvent) {
16136 + case HostNormCmdQue:
16138 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16142 + case HostNormRespQue:
16144 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16148 + case AdapNormCmdNotFull:
16150 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16154 + case AdapNormRespNotFull:
16156 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16168 +Routine Description:
16170 + This routine will disable the corresponding adapter event to cause an interrupt on
16175 + AdapterExtension - Which adapter to enable.
16177 + AdapterEvent - Which adapter event.
16179 + AtDeviceIrq - Whether the system is in DEVICE irql
16187 +SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16189 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16190 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16192 + switch (AdapterEvent) {
16195 + case HostNormCmdQue:
16197 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16201 + case HostNormRespQue:
16203 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16207 + case AdapNormCmdNotFull:
16209 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16214 + case AdapNormRespNotFull:
16216 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16225 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16227 + PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16230 + // Free the register mapping.
16233 + OsDetachDevice(AdapterExtension);
16235 + OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16242 +Routine Description:
16244 + Scans the PCI bus looking for the Sa card. When found all resources for the
16245 + device will be allocated and the interrupt vectors and csrs will be allocated and
16248 + The device_interface in the commregion will be allocated and linked to the comm region.
16255 + TRUE - if the device was setup with not problems
16256 + FALSE - if the device could not be mapped and init successfully
16260 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16261 + IN ULONG AdapterNumber, IN ULONG PciBus,
16262 + IN ULONG PciSlot)
16264 + AAC_STATUS Status;
16265 + PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16266 + FSA_NEW_ADAPTER NewAdapter;
16267 + ULONG StartTime, EndTime, WaitTime;
16268 + ULONG InitStatus;
16272 + AfaPortPrint("In init device.\n");
16274 + CommonExtension->AdapterNumber = AdapterNumber;
16276 + CommonExtension->PciBusNumber = PciBus;
16277 + CommonExtension->PciSlotNumber = PciSlot;
16279 + AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16280 + AdapterExtension->Common = CommonExtension;
16281 + CommonExtension->MiniPort = AdapterExtension;
16283 + instance = OsGetDeviceInstance(AdapterExtension);
16284 + name = OsGetDeviceName(AdapterExtension);
16287 + // Map in the registers from the adapter, register space 0 is config space,
16288 + // register space 1 is the memery space.
16291 + if (OsMapDeviceRegisters(AdapterExtension)){
16292 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16298 + // Check to see if the board failed any self tests.
16301 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16303 + cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16309 + // Check to see if the board panic'd while booting.
16312 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16314 + cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16320 + StartTime = OsGetSeconds();
16325 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
16328 + while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16330 + EndTime = OsGetSeconds();
16332 + WaitTime = EndTime - StartTime;
16334 + if ( WaitTime > (3 * 60) ) {
16336 + InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16338 + cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16339 + name, instance, InitStatus);
16345 + if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16346 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16350 + if (OsAttachDMA(AdapterExtension)) {
16351 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16357 + // Fill in the function dispatch table.
16360 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16361 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16362 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16363 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16364 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16365 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16366 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16367 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16368 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16369 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16370 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16371 + AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16372 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16374 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16376 + NewAdapter.AdapterExtension = CommonExtension;
16377 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16378 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16379 + NewAdapter.AdapterUserVars = SaUserVars;
16380 + NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16382 + NewAdapter.Dip = CommonExtension->OsDep.dip;
16385 + if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16386 + cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16387 + return (FAILURE);
16391 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16393 + if (AdapterExtension->Common->Adapter == NULL) {
16395 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16396 + cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16398 + return (FAILURE);
16403 + // Start any kernel threads needed
16404 + OsStartKernelThreads(AdapterExtension);
16407 + // Tell the adapter that all is configure, and it can start accepting requests
16410 + SaStartAdapter(AdapterExtension);
16415 + // Put this adapter into the list of Sa adapters
16418 + AdapterExtension->Next = SaAdapterList;
16419 + SaAdapterList = AdapterExtension;
16421 + AdapterExtension->Common->AdapterConfigured = TRUE;
16426 + // Call the disk layer to initialize itself.
16429 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16435 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16437 + OsAttachHBA(AdapterExtension);
16443 + return (FAILURE);
16449 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16451 + ULONG ReturnStatus;
16452 + LARGE_INTEGER HostTime;
16453 + ULONG ElapsedSeconds;
16454 + PADAPTER_INIT_STRUCT InitStruct;
16457 + // Fill in the remaining pieces of the InitStruct.
16460 + InitStruct = AdapterExtension->Common->InitStruct;
16462 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16464 + ElapsedSeconds = OsGetSeconds();
16466 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
16469 + // Tell the adapter we are back and up and running so it will scan its command
16470 + // queues and enable our interrupts
16473 + AdapterExtension->LocalMaskInterruptControl =
16474 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16478 + // First clear out all interrupts. Then enable the one's that we can handle.
16481 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16482 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16483 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16485 + SaSendSynchCommand(AdapterExtension,
16486 + INIT_STRUCT_BASE_ADDRESS,
16487 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16497 +SaResetDevice (PVOID Arg1){
16504 +Routine Description:
16506 + The will cause the adapter to take a break point.
16518 +SaInterruptAdapter (PVOID Arg1)
16520 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16521 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16523 + ULONG ReturnStatus;
16525 + SaSendSynchCommand(AdapterExtension,
16526 + BREAKPOINT_REQUEST,
16538 +Routine Description:
16540 + Will read the adapter CSRs to find the reason the adapter has
16545 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16553 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16555 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16556 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16557 + ULONG ReturnStatus;
16559 + switch (AdapterEvent) {
16560 + case AdapNormCmdQue:
16562 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16565 + case HostNormRespNotFull:
16567 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16570 + case AdapNormRespQue:
16572 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16575 + case HostNormCmdNotFull:
16577 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16580 + case HostShutdown:
16582 +// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16587 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16590 + case AdapPrintfDone:
16591 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16596 + SaBugCheck(0,0,0);
16597 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16605 +Routine Description:
16607 + This routine will send a synchronous comamnd to the adapter and wait for its
16612 + AdapterExtension - Pointer to adapter extension structure.
16613 + Command - Which command to send
16614 + Parameter1 - 4 - Parameters for command
16615 + ReturnStatus - return status from adapter after completion of command
16624 +SaSendSynchCommand(
16627 + ULONG Parameter1,
16628 + ULONG Parameter2,
16629 + ULONG Parameter3,
16630 + ULONG Parameter4,
16631 + PULONG ReturnStatus
16634 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16635 + ULONG StartTime,EndTime,WaitTime;
16636 + BOOLEAN CommandSucceeded;
16639 + // Write the Command into Mailbox 0
16642 + Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16645 + // Write the parameters into Mailboxes 1 - 4
16648 + Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16649 + Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16650 + Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16651 + Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16654 + // Clear the synch command doorbell to start on a clean slate.
16657 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16660 + // Signal that there is a new synch command
16663 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16665 + CommandSucceeded = FALSE;
16667 + StartTime = OsGetSeconds();
16670 + while (WaitTime < 30) { // wait up to 30 seconds
16672 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16675 + // Mon110 will set doorbell0 bit when it has completed the command.
16678 + if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16680 + CommandSucceeded = TRUE;
16684 + EndTime = OsGetSeconds();
16685 + WaitTime = EndTime - StartTime;
16689 + if (CommandSucceeded != TRUE) {
16691 + return (STATUS_IO_TIMEOUT);
16696 + // Clear the synch command doorbell.
16699 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16702 + // Pull the synch status from Mailbox 0.
16705 + *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16708 + // Return SUCCESS
16711 + return (STATUS_SUCCESS);
16718 +Routine Description:
16720 + This routine will send a synchronous fib to the adapter and wait for its
16725 + AdapterExtension - Pointer to adapter extension structure.
16726 + FibPhysicalAddress - Physical address of fib to send.
16735 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16737 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16738 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16739 + ULONG returnStatus;
16741 + if (SaSendSynchCommand( AdapterExtension,
16742 + SEND_SYNCHRONOUS_FIB,
16743 + FibPhysicalAddress,
16747 + &returnStatus ) != STATUS_SUCCESS ) {
16759 + PVOID AdapterExtension,
16760 + ULONG *MappedBuffer)
16767 + PVOID AdapterExtension,
16768 + ULONG *MappedBuffer)
16773 diff -burN linux-2.4.9/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
16774 --- linux-2.4.9/drivers/scsi/scsi_scan.c Thu Aug 16 13:40:31 2001
16775 +++ linux/drivers/scsi/scsi_scan.c Thu Aug 16 18:10:10 2001
16776 @@ -160,6 +160,8 @@
16777 {"SONY", "TSL", "*", BLIST_FORCELUN}, // DDS3 & DDS4 autoloaders
16778 {"DELL", "PERCRAID", "*", BLIST_FORCELUN},
16779 {"HP", "NetRAID-4M", "*", BLIST_FORCELUN},
16780 + {"ADAPTEC", "AACRAID", "*", BLIST_FORCELUN},
16781 + {"ADAPTEC", "Adaptec 5400S", "*", BLIST_FORCELUN},
16784 * Must be at end of list...