1 diff -urN linux/arch/i386/defconfig linux/arch/i386/defconfig
2 --- linux/arch/i386/defconfig Thu Nov 16 21:20:29 2000
3 +++ linux/arch/i386/defconfig Thu Dec 21 13:27:04 2000
5 # CONFIG_SCSI_AHA152X is not set
6 # CONFIG_SCSI_AHA1542 is not set
7 # CONFIG_SCSI_AHA1740 is not set
8 +# CONFIG_SCSI_AACRAID is not set
9 # CONFIG_SCSI_AIC7XXX is not set
10 # CONFIG_SCSI_ADVANSYS is not set
11 # CONFIG_SCSI_IN2000 is not set
12 diff -urN linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
13 --- linux/drivers/scsi/Config.in Thu Dec 21 12:07:01 2000
14 +++ linux/drivers/scsi/Config.in Thu Dec 21 13:28:36 2000
16 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
17 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
18 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
19 +dep_tristate 'Adaptec AACRAID support EXPERIMENTAL' CONFIG_SCSI_AACRAID $CONFIG_SCSI
20 dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
21 if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
22 bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
23 diff -urN linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
24 --- linux/drivers/scsi/Makefile Thu Dec 21 12:07:01 2000
25 +++ linux/drivers/scsi/Makefile Thu Dec 21 14:20:35 2000
27 obj-$(CONFIG_SCSI_AHA152X) += aha152x.o
28 obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
29 obj-$(CONFIG_SCSI_AHA1740) += aha1740.o
30 +obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
31 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o
32 obj-$(CONFIG_SCSI_IPS) += ips.o
33 obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
35 sim710_u.h: sim710_d.h
42 diff -urN linux/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
43 --- linux/drivers/scsi/aacraid/Makefile Wed Dec 31 19:00:00 1969
44 +++ linux/drivers/scsi/aacraid/Makefile Thu Dec 21 13:14:30 2000
47 +# Makefile aacraid Raid Controller
50 +###############################################################################
51 +### SOURCE FILES DEFINES
52 +###############################################################################
70 + ./include/AacGenericTypes.h \
71 + ./include/aac_unix_defs.h \
72 + ./include/adapter.h \
73 + ./include/afacomm.h \
74 + ./include/aifstruc.h \
75 + ./include/build_number.h \
76 + ./include/commdata.h \
77 + ./include/commerr.h \
78 + ./include/commfibcontext.h \
79 + ./include/comprocs.h \
80 + ./include/comproto.h \
81 + ./include/comstruc.h \
82 + ./include/comsup.h \
85 + ./include/fsaioctl.h \
86 + ./include/fsaport.h \
87 + ./include/fsatypes.h \
89 + ./include/monkerapi.h \
90 + ./include/nodetype.h \
91 + ./include/nvramioctl.h \
92 + ./include/osheaders.h \
93 + ./include/ostypes.h \
94 + ./include/pcisup.h \
95 + ./include/perfpack.h \
97 + ./include/protocol.h \
98 + ./include/revision.h \
99 + ./include/rxcommon.h \
101 + ./include/sap1common.h \
103 + ./include/version.h
109 +###############################################################################
110 +### OBJECT FILES DEFINES
111 +###############################################################################
128 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
130 +###############################################################################
132 +###############################################################################
134 +# Remember that we're doing a chdir one level lower, so we need an extra ../
137 + -I../../../include -I..
139 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
143 + -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
144 + -Wall -Wstrict-prototypes \
149 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
151 +###############################################################################
152 +### DO GENERAL STUFF
153 +###############################################################################
156 +.SUFFIXES: .c .o .h .a
158 +all: source ${TARGET_OFILES} aacraid.o
160 +source: ${ALL_SOURCE}
165 +###############################################################################
167 +###############################################################################
169 +aacraid.o: source ${TARGET_OFILES}
170 + ld -r -o $@ $(TARGET_OFILES)
171 + cp -r aacraid.o ../
173 +###############################################################################
175 +###############################################################################
178 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
180 +aachba.o: ./aachba.c
181 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
184 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
186 +osfuncs.o: ./osfuncs.c
187 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
189 +commctrl.o: ./commctrl.c
190 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
192 +comminit.o: ./comminit.c
193 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
195 +commsup.o: ./commsup.c
196 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
198 +dpcsup.o: ./dpcsup.c
199 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
202 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
205 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
208 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
211 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
213 +sap1sup.o: ./sap1sup.c
214 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
217 diff -urN linux/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
218 --- linux/drivers/scsi/aacraid/README Wed Dec 31 19:00:00 1969
219 +++ linux/drivers/scsi/aacraid/README Thu Dec 21 13:14:30 2000
221 + AACRAID Driver for Linux
224 +-------------------------
225 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
226 +OEM based RAID controllers.
228 +Supported Cards/Chipsets
229 +-------------------------
230 + Dell Computer Corporation PERC 2 Quad Channel
231 + Dell Computer Corporation PERC 3/Di
232 + Dell Computer Corporation PERC 3/Si
235 +Not Supported Devices
236 +-------------------------
237 + Any and All Adaptec branded raid controllers.
240 +-------------------------
244 +-------------------------
245 +There is currently a mailing list being created for aacraid. This
246 +will all be straitened out before the driver is submitted for
247 +inclusion in the standard kernel distribution.
250 +Modified by Brian Boerner 2000
251 \ No newline at end of file
252 diff -urN linux/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
253 --- linux/drivers/scsi/aacraid/aachba.c Wed Dec 31 19:00:00 1969
254 +++ linux/drivers/scsi/aacraid/aachba.c Thu Dec 21 13:14:30 2000
257 + * Adaptec aacraid device driver for Linux.
259 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
261 + * This program is free software; you can redistribute it and/or modify
262 + * it under the terms of the GNU General Public License as published by
263 + * the Free Software Foundation; either version 2, or (at your option)
264 + * any later version.
266 + * This program is distributed in the hope that it will be useful,
267 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
268 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
269 + * GNU General Public License for more details.
271 + * You should have received a copy of the GNU General Public License
272 + * along with this program; see the file COPYING. If not, write to
273 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
278 + * Abstract: driver...
282 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
284 +/*------------------------------------------------------------------------------
286 + *----------------------------------------------------------------------------*/
287 +#include "osheaders.h"
288 +#include "AacGenericTypes.h"
289 +#include "aac_unix_defs.h"
290 +#include "comstruc.h"
291 +#include "monkerapi.h"
292 +#include "protocol.h"
295 +#include "fsaioctl.h"
297 +#include "sap1common.h"
298 +#include "fsaport.h"
301 +#include "nodetype.h"
303 +#include "afacomm.h"
304 +#include "adapter.h"
306 +/*------------------------------------------------------------------------------
308 + *----------------------------------------------------------------------------*/
310 +#define SS_TEST 0x00 /* Test unit ready */
311 +#define SS_REZERO 0x01 /* Rezero unit */
312 +#define SS_REQSEN 0x03 /* Request Sense */
313 +#define SS_REASGN 0x07 /* Reassign blocks */
314 +#define SS_READ 0x08 /* Read 6 */
315 +#define SS_WRITE 0x0A /* Write 6 */
316 +#define SS_INQUIR 0x12 /* inquiry */
317 +#define SS_ST_SP 0x1B /* Start/Stop unit */
318 +#define SS_LOCK 0x1E /* prevent/allow medium removal */
319 +#define SS_RESERV 0x16 /* Reserve */
320 +#define SS_RELES 0x17 /* Release */
321 +#define SS_MODESEN 0x1A /* Mode Sense 6 */
322 +#define SS_RDCAP 0x25 /* Read Capacity */
323 +#define SM_READ 0x28 /* Read 10 */
324 +#define SM_WRITE 0x2A /* Write 10 */
325 +#define SS_SEEK 0x2B /* Seek */
327 +/* values for inqd_pdt: Peripheral device type in plain English */
328 +#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
329 +#define INQD_PDT_PROC 0x03 /* Processor device */
330 +#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
331 +#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
332 +#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
333 +#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
335 +#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
336 +#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
338 +#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
339 +#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
340 +#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
342 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
344 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
346 +// ------------------------------------------------------
349 +#define SENKEY_NO_SENSE 0x00 //
350 +#define SENKEY_UNDEFINED 0x01 //
351 +#define SENKEY_NOT_READY 0x02 //
352 +#define SENKEY_MEDIUM_ERR 0x03 //
353 +#define SENKEY_HW_ERR 0x04 //
354 +#define SENKEY_ILLEGAL 0x05 //
355 +#define SENKEY_ATTENTION 0x06 //
356 +#define SENKEY_PROTECTED 0x07 //
357 +#define SENKEY_BLANK 0x08 //
358 +#define SENKEY_V_UNIQUE 0x09 //
359 +#define SENKEY_CPY_ABORT 0x0A //
360 +#define SENKEY_ABORT 0x0B //
361 +#define SENKEY_EQUAL 0x0C //
362 +#define SENKEY_VOL_OVERFLOW 0x0D //
363 +#define SENKEY_MISCOMP 0x0E //
364 +#define SENKEY_RESERVED 0x0F //
366 +// ------------------------------------------------------
369 +#define SENCODE_NO_SENSE 0x00
370 +#define SENCODE_END_OF_DATA 0x00
371 +#define SENCODE_BECOMING_READY 0x04
372 +#define SENCODE_INIT_CMD_REQUIRED 0x04
373 +#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
374 +#define SENCODE_INVALID_COMMAND 0x20
375 +#define SENCODE_LBA_OUT_OF_RANGE 0x21
376 +#define SENCODE_INVALID_CDB_FIELD 0x24
377 +#define SENCODE_LUN_NOT_SUPPORTED 0x25
378 +#define SENCODE_INVALID_PARAM_FIELD 0x26
379 +#define SENCODE_PARAM_NOT_SUPPORTED 0x26
380 +#define SENCODE_PARAM_VALUE_INVALID 0x26
381 +#define SENCODE_RESET_OCCURRED 0x29
382 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
383 +#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
384 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
385 +#define SENCODE_DIAGNOSTIC_FAILURE 0x40
386 +#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
387 +#define SENCODE_INVALID_MESSAGE_ERROR 0x49
388 +#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
389 +#define SENCODE_OVERLAPPED_COMMAND 0x4E
391 +// ------------------------------------------------------
392 +// Additional sense codes
394 +#define ASENCODE_NO_SENSE 0x00
395 +#define ASENCODE_END_OF_DATA 0x05
396 +#define ASENCODE_BECOMING_READY 0x01
397 +#define ASENCODE_INIT_CMD_REQUIRED 0x02
398 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
399 +#define ASENCODE_INVALID_COMMAND 0x00
400 +#define ASENCODE_LBA_OUT_OF_RANGE 0x00
401 +#define ASENCODE_INVALID_CDB_FIELD 0x00
402 +#define ASENCODE_LUN_NOT_SUPPORTED 0x00
403 +#define ASENCODE_INVALID_PARAM_FIELD 0x00
404 +#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
405 +#define ASENCODE_PARAM_VALUE_INVALID 0x02
406 +#define ASENCODE_RESET_OCCURRED 0x00
407 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
408 +#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
409 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
410 +#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
411 +#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
412 +#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
413 +#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
414 +#define ASENCODE_OVERLAPPED_COMMAND 0x00
416 +#define BYTE0( x ) ( unsigned char )( x )
417 +#define BYTE1( x ) ( unsigned char )( x >> 8 )
418 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
419 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
421 +/*------------------------------------------------------------------------------
422 + * S T R U C T S / T Y P E D E F S
423 + *----------------------------------------------------------------------------*/
424 +/* SCSI inquiry data */
425 +struct inquiry_data {
426 + unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
427 + unchar inqd_dtq; /* RMB | Device Type Qualifier */
428 + unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
429 + unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
430 + unchar inqd_len; /* Additional length (n-4) */
431 + unchar inqd_pad1[2]; /* Reserved - must be zero */
432 + unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
433 + unchar inqd_vid[8]; /* Vendor ID */
434 + unchar inqd_pid[16]; /* Product ID */
435 + unchar inqd_prl[4]; /* Product Revision Level */
439 + unchar error_code; // 70h (current errors), 71h(deferred errors)
440 + unchar valid:1; // A valid bit of one indicates that the information
441 + // field contains valid information as defined in the
442 + // SCSI-2 Standard.
444 + unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
447 + unchar sense_key:4; // Sense Key
449 + unchar ILI:1; // Incorrect Length Indicator
450 + unchar EOM:1; // End Of Medium - reserved for random access devices
451 + unchar filemark:1; // Filemark - reserved for random access devices
453 + unchar information[4]; // for direct-access devices, contains the unsigned
454 + // logical block address or residue associated with
456 + unchar add_sense_len; // number of additional sense bytes to follow this field
457 + unchar cmnd_info[4]; // not used
458 + unchar ASC; // Additional Sense Code
459 + unchar ASCQ; // Additional Sense Code Qualifier
460 + unchar FRUC; // Field Replaceable Unit Code - not used
462 + unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
464 + unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
465 + // the bit_ptr field has valid value
466 + unchar reserved2:2;
467 + unchar CD:1; // command data bit: 1- illegal parameter in CDB.
468 + // 0- illegal parameter in data.
471 + unchar field_ptr[2]; // byte of the CDB or parameter data in error
474 +/*------------------------------------------------------------------------------
476 + *----------------------------------------------------------------------------*/
477 +/*------------------------------------------------------------------------------
478 + * M O D U L E G L O B A L S
479 + *----------------------------------------------------------------------------*/
480 +static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
481 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
483 +/*------------------------------------------------------------------------------
484 + * F U N C T I O N P R O T O T Y P E S
485 + *----------------------------------------------------------------------------*/
486 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
487 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
488 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
489 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
490 + PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
492 +void AacHba_CompleteScsi(
493 + Scsi_Cmnd *scsi_cmnd_ptr );
495 +void AacHba_CompleteScsiNoLock(
496 + Scsi_Cmnd *scsi_cmnd_ptr );
498 +static void AacHba_ReadCallback(
500 + PFIB_CONTEXT FibContext,
503 +static void AacHba_WriteCallback(
505 + PFIB_CONTEXT FibContext,
508 +int AacHba_DoScsiRead(
509 + Scsi_Cmnd *scsi_cmnd_ptr,
513 +int AacHba_DoScsiWrite(
514 + Scsi_Cmnd *scsi_cmnd_ptr,
518 +int AacHba_QueryDisk(
519 + PVOID AdapterArg, // CommonExtensionPtr
520 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
522 +int AacHba_ForceDeleteDisk(
523 + PVOID AdapterArg, // CommonExtensionPtr
524 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
526 +int AacHba_DeleteDisk(
528 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
530 +void AacHba_DetachAdapter(
531 + IN PVOID AdapterArg );
533 +BOOLEAN AacCommDetachAdapter(
534 + IN PAFA_COMM_ADAPTER Adapter );
536 +void AacHba_SetSenseData(
540 + unchar a_sense_code,
541 + unchar incorrect_length,
542 + unchar bit_pointer,
543 + unsigned field_pointer,
544 + unsigned long residue );
546 +static void get_sd_devname(
550 +// Keep these here for the time being - #REVIEW#
552 +AfaCommAdapterDeviceControl (
553 + IN PVOID AdapterArg,
554 + IN PAFA_IOCTL_CMD IoctlCmdPtr
558 +AfaCommRegisterNewClassDriver(
559 + IN PAFA_COMM_ADAPTER Adapter,
560 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
561 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
565 +SetInqDataStr (int, void *, int);
566 +/*------------------------------------------------------------------------------
567 + * F U N C T I O N S
568 + *----------------------------------------------------------------------------*/
570 +/*------------------------------------------------------------------------------
571 + AacHba_ClassDriverInit()
573 + Setup 'core' class driver to answer ioctl's
574 + *----------------------------------------------------------------------------*/
575 +int AacHba_ClassDriverInit(
576 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
577 +/*----------------------------------------------------------------------------*/
579 + AFA_NEW_CLASS_DRIVER NewClassDriver;
580 + AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
581 + PAFA_COMM_ADAPTER Adapter;
583 + Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
585 + RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
587 + // ClassDriverExtension is the first argument passed to class driver functions below
588 + NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
590 + NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
591 + NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
592 + NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
593 + NewClassDriver.HandleAif = AacHba_HandleAif;
594 + AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
600 +/*------------------------------------------------------------------------------
601 + AacHba_ProbeContainers()
603 + Make a list of all containers in the system.
604 +------------------------------------------------------------------------------*/
605 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
607 + fsadev_t *fsa_dev_ptr;
610 + PMNTINFORESPONSE DiskInfoResponse;
611 + PFIB_CONTEXT FibContext;
612 + AFA_COMM_ADAPTER *Adapter;
618 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
619 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
620 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
622 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
624 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
625 + return( STATUS_UNSUCCESSFUL );
628 + for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
630 + Adapter->CommFuncs.InitializeFib( FibContext );
632 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
634 + DiskInfo->Command = VM_NameServe;
635 + DiskInfo->MntCount = Index;
636 + DiskInfo->MntType = FT_FILESYS;
638 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
649 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
653 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
656 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
657 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
661 + fsa_dev_ptr->ContainerValid[Index] = TRUE;
662 + fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
663 + fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
665 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
666 + fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
669 + Adapter->CommFuncs.CompleteFib( FibContext );
671 + // If there are no more containers, then stop asking.
672 + if ((Index + 1) >= DiskInfoResponse->MntRespCount)
676 + Adapter->CommFuncs.FreeFib( FibContext );
678 + g_fsa_dev_array[instance] = fsa_dev_ptr;
683 +/*------------------------------------------------------------------------------
684 + AacHba_ProbeContainer()
686 + Probe a single container.
687 + *----------------------------------------------------------------------------*/
688 +int AacHba_ProbeContainer(
689 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
691 +/*----------------------------------------------------------------------------*/
693 + fsadev_t *fsa_dev_ptr;
696 + PMNTINFORESPONSE DiskInfoResponse;
697 + PFIB_CONTEXT FibContext;
698 + AFA_COMM_ADAPTER *Adapter;
701 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
702 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
703 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
705 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
707 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
708 + return( STATUS_UNSUCCESSFUL );
711 + Adapter->CommFuncs.InitializeFib( FibContext );
713 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
715 + DiskInfo->Command = VM_NameServe;
716 + DiskInfo->MntCount = ContainerId;
717 + DiskInfo->MntType = FT_FILESYS;
719 + Status = Adapter->CommFuncs.SendFib (ContainerCommand,
730 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
731 + Adapter->CommFuncs.CompleteFib( FibContext );
732 + Adapter->CommFuncs.FreeFib( FibContext );
736 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
739 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
740 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
743 + fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
744 + fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
745 + fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
746 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
747 + fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
750 + Adapter->CommFuncs.CompleteFib( FibContext );
751 + Adapter->CommFuncs.FreeFib( FibContext );
757 +/*------------------------------------------------------------------------------
758 + AacHba_CompleteScsi()
760 + Call SCSI completion routine after acquiring io_request_lock
764 + *----------------------------------------------------------------------------*/
765 +void AacHba_CompleteScsi(
766 + Scsi_Cmnd *scsi_cmnd_ptr )
768 + unsigned long cpu_flags;
770 + spin_lock_irqsave( &io_request_lock, cpu_flags );
771 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
772 + spin_unlock_irqrestore( &io_request_lock, cpu_flags );
776 +/*------------------------------------------------------------------------------
777 + AacHba_CompleteScsiNoLock()
779 + Call SCSI completion routine
783 + *----------------------------------------------------------------------------*/
784 +void AacHba_CompleteScsiNoLock(
785 + Scsi_Cmnd *scsi_cmnd_ptr )
787 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
790 +/*------------------------------------------------------------------------------
793 + Process SCSI command
797 + Returns 0 on success, -1 on failure
798 + *----------------------------------------------------------------------------*/
799 +int AacHba_DoScsiCmd(
800 + Scsi_Cmnd *scsi_cmnd_ptr,
803 + int ContainerId = 0;
804 + fsadev_t *fsa_dev_ptr;
805 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
808 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
809 + MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
811 + fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
813 + // If the bus, target or lun is out of range, return fail
814 + // Test does not apply to ID 16, the pseudo id for the controller itself.
815 + if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
817 + if( ( scsi_cmnd_ptr->channel > 0 ) ||
818 + ( scsi_cmnd_ptr->target > 15 ) ||
819 + ( scsi_cmnd_ptr->lun > 7 ) )
821 + cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
822 + scsi_cmnd_ptr->channel,
823 + scsi_cmnd_ptr->target,
824 + scsi_cmnd_ptr->lun );
825 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
827 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
832 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
835 + // If the target container doesn't exist, it may have been newly created
836 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
838 + switch( scsi_cmnd_ptr->cmnd[0] )
843 + spin_unlock_irq( &io_request_lock );
844 + AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
845 + spin_lock_irq( &io_request_lock );
851 + // If the target container still doesn't exist, return failure
852 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
855 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
856 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
861 + else // the command is for the controller itself
862 + if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
863 + ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
865 + cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
866 + scsi_cmnd_ptr->cmnd[0] );
868 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
870 + AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
871 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
874 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
879 + // Handle commands here that don't really require going out to the adapter
880 + switch ( scsi_cmnd_ptr->cmnd[0] )
884 + struct inquiry_data *inq_data_ptr;
886 + cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
887 + inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
888 + bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
890 + inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
892 + inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
893 + // that the medium is removable
894 + inq_data_ptr->inqd_rdf = 2; // A response data format value of
895 + // two indicates that the data shall
896 + // be in the format specified in SCSI-2
897 + inq_data_ptr->inqd_len = 31;
899 + // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
900 + SetInqDataStr( MiniPortIndex,
901 + (void *)(inq_data_ptr->inqd_vid),
902 + fsa_dev_ptr->ContainerType[ContainerId]);
904 + if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
905 + inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
907 + inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
909 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
910 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
920 + cmn_err( CE_DEBUG, "READ CAPACITY command" );
921 + capacity = fsa_dev_ptr->ContainerSize[ContainerId];
922 + cp = scsi_cmnd_ptr->request_buffer;
923 + cp[0] = ( capacity >> 24 ) & 0xff;
924 + cp[1] = ( capacity >> 16 ) & 0xff;
925 + cp[2] = ( capacity >> 8 ) & 0xff;
926 + cp[3] = ( capacity >> 0 ) & 0xff;
932 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
933 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
942 + cmn_err( CE_DEBUG, "MODE SENSE command" );
943 + mode_buf = scsi_cmnd_ptr->request_buffer;
944 + mode_buf[0] = 0; // Mode data length (MSB)
945 + mode_buf[1] = 6; // Mode data length (LSB)
946 + mode_buf[2] = 0; // Medium type - default
947 + mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
948 + mode_buf[4] = 0; // reserved
949 + mode_buf[5] = 0; // reserved
950 + mode_buf[6] = 0; // Block descriptor length (MSB)
951 + mode_buf[7] = 0; // Block descriptor length (LSB)
953 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
954 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
960 + // These commands are all No-Ops
962 + cmn_err( CE_DEBUG, "TEST UNIT READY command" );
963 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
964 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
968 + cmn_err( CE_DEBUG, "REQUEST SENSE command" );
970 + memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
971 + sizeof( struct sense_data ) );
972 + bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
974 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
975 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
979 + cmn_err(CE_DEBUG, "LOCK command");
981 + if( scsi_cmnd_ptr->cmnd[4] )
982 + fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
984 + fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
986 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
987 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
991 + cmn_err( CE_DEBUG, "RESERVE command" );
992 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
993 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
997 + cmn_err( CE_DEBUG, "RELEASE command" );
998 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
999 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1003 + cmn_err( CE_DEBUG, "REZERO command" );
1004 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1005 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1009 + cmn_err( CE_DEBUG, "REASSIGN command" );
1010 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1011 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1015 + cmn_err( CE_DEBUG, "SEEK command" );
1016 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1017 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1021 + cmn_err( CE_DEBUG, "START/STOP command" );
1022 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1023 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1027 + switch ( scsi_cmnd_ptr->cmnd[0] )
1031 + // Hack to keep track of ordinal number of the device that corresponds
1032 + // to a container. Needed to convert containers to /dev/sd device names
1033 + fsa_dev_ptr->ContainerDevNo[ContainerId] =
1034 + DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1036 + return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1042 + return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1046 + // Unhandled commands
1048 + cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1049 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1051 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1052 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1055 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1060 +/*------------------------------------------------------------------------------
1061 + AacHba_DoScsiRead()
1063 + Handles SCSI READ requests
1067 + Returns 0 on success, -1 on failure
1068 + *----------------------------------------------------------------------------*/
1069 +int AacHba_DoScsiRead(
1070 + Scsi_Cmnd *scsi_cmnd_ptr,
1073 +/*----------------------------------------------------------------------------*/
1077 + u_long byte_count;
1080 + PBLOCKREAD BlockReadDisk;
1081 + PBLOCKREADRESPONSE BlockReadResponse;
1083 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1084 + AFA_COMM_ADAPTER *Adapter;
1085 + PFIB_CONTEXT cmd_fibcontext;
1087 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1088 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1090 + // Get block address and transfer length
1091 + if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1093 + cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1095 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1096 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1097 + scsi_cmnd_ptr->cmnd[3];
1098 + count = scsi_cmnd_ptr->cmnd[4];
1105 + cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1107 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1108 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1110 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1112 + cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1114 + //-------------------------------------------------------------------------
1115 + // Alocate and initialize a Fib
1116 + // Setup BlockRead command
1117 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1119 + cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1120 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1121 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1125 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1127 + BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1128 + BlockReadDisk->Command = VM_CtBlockRead;
1129 + BlockReadDisk->ContainerId = ContainerId;
1130 + BlockReadDisk->BlockNumber = lba;
1131 + BlockReadDisk->ByteCount = count * 512;
1132 + BlockReadDisk->SgMap.SgCount = 1;
1134 + if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1136 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1137 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1139 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1140 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1146 + //-------------------------------------------------------------------------
1147 + // Build Scatter/Gather list
1149 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1151 + struct scatterlist *scatterlist_ptr;
1154 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1157 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1159 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1160 + ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1161 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1162 + scatterlist_ptr[segment].length;
1164 +#ifdef DEBUG_SGBUFFER
1165 + memset( scatterlist_ptr[segment].address, 0xa5,
1166 + scatterlist_ptr[segment].length );
1169 + byte_count += scatterlist_ptr[segment].length;
1171 + if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1173 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1174 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1176 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1177 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1183 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1185 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1186 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1189 + BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1191 + if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1193 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1194 + MAX_DRIVER_SG_SEGMENT_COUNT );
1195 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1199 + else // one piece of contiguous phys mem
1201 + BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1202 + ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1203 + BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1205 + byte_count = scsi_cmnd_ptr->request_bufflen;
1207 + if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1209 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1210 + cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1211 + cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1212 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1214 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1215 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1222 + if( byte_count != BlockReadDisk->ByteCount )
1223 + cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1225 + //-------------------------------------------------------------------------
1226 + // Now send the Fib to the adapter
1228 + FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1232 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1242 + BlockReadResponse = ( PBLOCKREADRESPONSE )
1243 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1245 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1246 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1248 + if( BlockReadResponse->Status != ST_OK )
1250 + cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1251 + BlockReadResponse->Status );
1252 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1254 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1255 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1258 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1262 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1264 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1269 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1276 + ( PFIB_CALLBACK )AacHba_ReadCallback,
1277 + ( void *)scsi_cmnd_ptr );
1278 + // don't call done func here
1283 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1285 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1286 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1292 +/*------------------------------------------------------------------------------
1293 + AacHba_DoScsiWrite()
1295 + Handles SCSI WRITE requests
1299 + Returns 0 on success, -1 on failure
1300 + *----------------------------------------------------------------------------*/
1301 +int AacHba_DoScsiWrite(
1302 + Scsi_Cmnd *scsi_cmnd_ptr,
1305 +/*----------------------------------------------------------------------------*/
1309 + u_long byte_count;
1312 + PBLOCKWRITE BlockWriteDisk;
1313 + PBLOCKWRITERESPONSE BlockWriteResponse;
1315 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1316 + AFA_COMM_ADAPTER *Adapter;
1317 + PFIB_CONTEXT cmd_fibcontext;
1319 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1320 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1322 + // Get block address and transfer length
1323 + if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1325 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1326 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1327 + scsi_cmnd_ptr->cmnd[3];
1328 + count = scsi_cmnd_ptr->cmnd[4];
1335 + cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1337 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1338 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1340 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1343 + cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1345 + //-------------------------------------------------------------------------
1346 + // Alocate and initialize a Fib
1347 + // Setup BlockWrite command
1348 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1350 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1351 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1352 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1356 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1358 + BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1359 + BlockWriteDisk->Command = VM_CtBlockWrite;
1360 + BlockWriteDisk->ContainerId = ContainerId;
1361 + BlockWriteDisk->BlockNumber = lba;
1362 + BlockWriteDisk->ByteCount = count * 512;
1363 + BlockWriteDisk->SgMap.SgCount = 1;
1366 + if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1368 + struct scatterlist *scatterlist_ptr;
1370 + scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1372 + cmn_err( CE_WARN, "\n");
1373 + cmn_err( CE_WARN, "AacHba_`DoScsiWrite: WRITE request is larger than 64K");
1374 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1375 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1376 + cmn_err( CE_WARN, "Dump SG Element Size...");
1377 + for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1379 + cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length);
1381 + cmn_err (CE_WARN, "\n");
1383 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1385 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1386 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1392 + //-------------------------------------------------------------------------
1393 + // Build Scatter/Gather list
1395 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1397 + struct scatterlist *scatterlist_ptr;
1400 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1403 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1405 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1406 + ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1407 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1408 + scatterlist_ptr[segment].length;
1410 + byte_count += scatterlist_ptr[segment].length;
1412 + if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1414 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1415 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1417 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1418 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1425 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1427 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1428 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1431 + BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1433 + if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1435 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1436 + MAX_DRIVER_SG_SEGMENT_COUNT );
1437 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1441 + else // one piece of contiguous phys mem
1443 + BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1444 + ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1445 + BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1447 + byte_count = scsi_cmnd_ptr->request_bufflen;
1449 + if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1451 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1453 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1454 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1455 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1462 + if( byte_count != BlockWriteDisk->ByteCount )
1463 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1465 + //-------------------------------------------------------------------------
1466 + // Now send the Fib to the adapter
1468 + FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1472 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1482 + BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1483 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1485 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1486 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1488 + if( BlockWriteResponse->Status != ST_OK )
1490 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1491 + BlockWriteResponse->Status );
1492 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1493 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1494 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1496 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1500 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1502 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1507 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1514 + ( PFIB_CALLBACK )AacHba_WriteCallback,
1515 + ( void * )scsi_cmnd_ptr );
1517 + // don't call done func here - it should be called by the WriteCallback
1522 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1524 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1525 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1531 +/*------------------------------------------------------------------------------
1532 + AacHba_ReadCallback()
1533 + *----------------------------------------------------------------------------*/
1534 +void AacHba_ReadCallback(
1536 + PFIB_CONTEXT FibContext,
1538 +/*----------------------------------------------------------------------------*/
1540 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1541 + AFA_COMM_ADAPTER *Adapter;
1542 + BLOCKREADRESPONSE *BlockReadResponse;
1543 + Scsi_Cmnd * scsi_cmnd_ptr;
1547 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1549 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1550 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1552 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1554 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1555 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1556 + scsi_cmnd_ptr->cmnd[3];
1557 + cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1559 + if( FibContext == 0 )
1561 + cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1562 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1563 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1567 + BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1569 + if ( BlockReadResponse->Status == ST_OK )
1570 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1573 + cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1574 + BlockReadResponse->Status );
1575 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1576 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1577 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1581 +#ifdef DEBUG_SGBUFFER
1582 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1584 + struct scatterlist *scatterlist_ptr;
1585 + int i, segment, count;
1588 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1590 + for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1593 + ptr = scatterlist_ptr[segment].address;
1594 + for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1596 + if( *( ptr++ ) == 0xa5 )
1599 + if( count == scatterlist_ptr[segment].length )
1600 + cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1606 + Adapter->CommFuncs.CompleteFib( FibContext );
1607 + Adapter->CommFuncs.FreeFib( FibContext );
1609 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1612 +/*------------------------------------------------------------------------------
1613 + AacHba_WriteCallback()
1614 + *----------------------------------------------------------------------------*/
1615 +void AacHba_WriteCallback(
1617 + PFIB_CONTEXT FibContext,
1619 +/*----------------------------------------------------------------------------*/
1621 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1622 + AFA_COMM_ADAPTER *Adapter;
1623 + BLOCKWRITERESPONSE *BlockWriteResponse;
1624 + Scsi_Cmnd *scsi_cmnd_ptr;
1628 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1630 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1631 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1633 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1635 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1636 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1637 + scsi_cmnd_ptr->cmnd[3];
1638 + cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1639 + if( FibContext == 0 )
1641 + cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1642 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1643 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1647 + BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1648 + if (BlockWriteResponse->Status == ST_OK)
1649 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1652 + cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1653 + BlockWriteResponse->Status );
1654 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1655 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1656 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1660 + Adapter->CommFuncs.CompleteFib( FibContext );
1661 + Adapter->CommFuncs.FreeFib( FibContext );
1663 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1667 +/*------------------------------------------------------------------------------
1670 + Handle IOCTL requests
1674 + *----------------------------------------------------------------------------*/
1676 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1679 +/*----------------------------------------------------------------------------*/
1681 + Sa_ADAPTER_EXTENSION *AdapterExtension;
1682 + AFA_IOCTL_CMD IoctlCmd;
1685 + AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1687 + cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1690 + case FSACTL_SENDFIB:
1691 + cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1694 + case FSACTL_AIF_THREAD:
1695 + cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1698 + case FSACTL_NULL_IO_TEST:
1699 + cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1702 + case FSACTL_SIM_IO_TEST:
1703 + cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1706 + case FSACTL_GET_FIBTIMES:
1707 + cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1710 + case FSACTL_ZERO_FIBTIMES:
1711 + cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1714 + case FSACTL_GET_VAR:
1715 + cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1718 + case FSACTL_SET_VAR:
1719 + cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1722 + case FSACTL_OPEN_ADAPTER_CONFIG:
1723 + cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1726 + case FSACTL_CLOSE_ADAPTER_CONFIG:
1727 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1730 + case FSACTL_QUERY_ADAPTER_CONFIG:
1731 + cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1734 + case FSACTL_OPEN_GET_ADAPTER_FIB:
1735 + cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1738 + case FSACTL_GET_NEXT_ADAPTER_FIB:
1739 + cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1742 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
1743 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1746 + case FSACTL_MINIPORT_REV_CHECK:
1747 + cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1750 + case FSACTL_OPENCLS_COMM_PERF_DATA:
1751 + cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1754 + case FSACTL_GET_COMM_PERF_DATA:
1755 + cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1758 + case FSACTL_QUERY_DISK:
1759 + cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1762 + case FSACTL_DELETE_DISK:
1763 + cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1767 + cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1770 + IoctlCmd.cmd = cmd;
1771 + IoctlCmd.arg = ( intptr_t )arg;
1772 + IoctlCmd.flag = 0;
1773 + IoctlCmd.cred_p = 0;
1774 + IoctlCmd.rval_p = 0;
1776 + status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1777 + cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1782 +/*------------------------------------------------------------------------------
1783 + AacHba_AdapterDeviceControl()
1787 + Returns TRUE if ioctl handled, FALSE otherwise
1788 + *ReturnStatus set to completion status
1789 + *----------------------------------------------------------------------------*/
1790 +BOOLEAN AacHba_AdapterDeviceControl (
1791 + PVOID AdapterArg, // CommonExtensionPtr
1792 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
1793 + OUT int * ReturnStatus )
1794 +/*----------------------------------------------------------------------------*/
1796 + BOOLEAN Handled = TRUE; // start out handling it.
1797 + int Status = EFAULT;
1799 + switch( IoctlCmdPtr->cmd )
1801 + case FSACTL_QUERY_DISK:
1802 + Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1805 + case FSACTL_DELETE_DISK:
1806 + Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1809 + case FSACTL_FORCE_DELETE_DISK:
1810 + Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1814 + if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1823 + *ReturnStatus = Status;
1825 + return( Handled );
1829 +/*------------------------------------------------------------------------------
1830 + AacHba_QueryDisk()
1835 + -EFAULT = Bad address
1836 + -EINVAL = Bad container number
1837 + *----------------------------------------------------------------------------*/
1838 +int AacHba_QueryDisk(
1839 + PVOID AdapterArg, // CommonExtensionPtr
1840 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
1841 +/*----------------------------------------------------------------------------*/
1843 + UNIX_QUERY_DISK QueryDisk;
1844 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1845 + fsadev_t *fsa_dev_ptr;
1847 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1848 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1850 + if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1851 + return( -EFAULT );
1853 + if (QueryDisk.ContainerNumber == -1)
1854 + QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1856 + if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1858 + if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1859 + return( -EINVAL );
1861 + QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1862 + QueryDisk.Bus = 0;
1863 + QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1864 + QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1867 + return( -EINVAL );
1869 + QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1870 + QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1871 + QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1873 + if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1874 + QueryDisk.UnMapped = TRUE;
1876 + QueryDisk.UnMapped = FALSE;
1878 + get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1879 + QueryDisk.diskDeviceName );
1881 + if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1882 + return( -EFAULT );
1888 +/*------------------------------------------------------------------------------
1890 + *----------------------------------------------------------------------------*/
1891 +static void get_sd_devname(
1894 +/*----------------------------------------------------------------------------*/
1898 + sprintf(buffer, "%s", "");
1902 + if( disknum < 26 )
1903 + sprintf(buffer, "sd%c", 'a' + disknum);
1905 + unsigned int min1;
1906 + unsigned int min2;
1908 + * For larger numbers of disks, we need to go to a new
1911 + min1 = disknum / 26;
1912 + min2 = disknum % 26;
1913 + sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1918 +/*------------------------------------------------------------------------------
1919 + AacHba_ForceDeleteDisk()
1924 + -EFAULT = Bad address
1925 + -EINVAL = Bad container number
1926 + *----------------------------------------------------------------------------*/
1927 +int AacHba_ForceDeleteDisk(
1928 + PVOID AdapterArg, // CommonExtensionPtr
1929 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
1930 +/*----------------------------------------------------------------------------*/
1932 + DELETE_DISK DeleteDisk;
1933 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1934 + fsadev_t *fsa_dev_ptr;
1936 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1937 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1939 + if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
1940 + return( -EFAULT );
1942 + if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1943 + return( -EINVAL );
1945 + // Mark this container as being deleted.
1946 + fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
1948 + // Mark the container as no longer valid
1949 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1955 +/*------------------------------------------------------------------------------
1956 + AacHba_DeleteDisk()
1961 + -EFAULT = Bad address
1962 + -EINVAL = Bad container number
1963 + -EBUSY = Device locked
1964 + *----------------------------------------------------------------------------*/
1965 +int AacHba_DeleteDisk(
1967 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
1968 +/*----------------------------------------------------------------------------*/
1970 + DELETE_DISK DeleteDisk;
1971 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1972 + fsadev_t *fsa_dev_ptr;
1974 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1975 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1977 + if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
1978 + return( -EFAULT );
1980 + if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1981 + return( -EINVAL );
1983 + // If the container is locked, it can not be deleted by the API.
1984 + if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
1988 + // Mark the container as no longer being valid.
1989 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1990 + fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
1996 +/*------------------------------------------------------------------------------
1997 + AacHba_OpenAdapter()
1998 + *----------------------------------------------------------------------------*/
1999 +AAC_STATUS AacHba_OpenAdapter(
2000 + IN PVOID AdapterArg )
2001 +/*----------------------------------------------------------------------------*/
2003 + return( STATUS_SUCCESS );
2007 +/*------------------------------------------------------------------------------
2008 + AacHba_CloseAdapter()
2009 + *----------------------------------------------------------------------------*/
2010 +AAC_STATUS AacHba_CloseAdapter(
2011 + IN PVOID AdapterArg )
2012 +/*----------------------------------------------------------------------------*/
2014 + return( STATUS_SUCCESS );
2018 +/*------------------------------------------------------------------------------
2019 + AacHba_DetachAdapter()
2020 + *----------------------------------------------------------------------------*/
2021 +void AacHba_DetachAdapter(
2022 + IN PVOID AdapterArg )
2023 +/*----------------------------------------------------------------------------*/
2025 + AacCommDetachAdapter( AdapterArg );
2029 +/*------------------------------------------------------------------------------
2030 + AacHba_AbortScsiCommand()
2031 + *----------------------------------------------------------------------------*/
2032 +void AacHba_AbortScsiCommand(
2033 + Scsi_Cmnd *scsi_cmnd_ptr )
2034 +/*----------------------------------------------------------------------------*/
2036 + u_short interrupt_status;
2037 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2039 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2040 + interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2042 + cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2044 + if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2045 + cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2048 + if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2049 + cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2052 + if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2053 + cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2056 + if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2057 + cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2063 +/*------------------------------------------------------------------------------
2064 + AacHba_HandleAif()
2065 + *----------------------------------------------------------------------------*/
2066 +BOOLEAN AacHba_HandleAif(
2067 + IN PVOID AdapterArg,
2068 + IN PFIB_CONTEXT FibContext )
2069 +/*----------------------------------------------------------------------------*/
2075 +/*------------------------------------------------------------------------------
2076 + AacHba_SetSenseData()
2077 + Fill in the sense data.
2080 + *----------------------------------------------------------------------------*/
2081 +void AacHba_SetSenseData(
2084 + unchar sense_code,
2085 + unchar a_sense_code,
2086 + unchar incorrect_length,
2087 + unchar bit_pointer,
2088 + unsigned field_pointer,
2089 + unsigned long residue )
2090 +/*----------------------------------------------------------------------------*/
2092 + sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2093 + sense_buf[1] = 0; // Segment number, always zero
2095 + if( incorrect_length )
2097 + sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2098 + sense_buf[3] = BYTE3(residue);
2099 + sense_buf[4] = BYTE2(residue);
2100 + sense_buf[5] = BYTE1(residue);
2101 + sense_buf[6] = BYTE0(residue);
2104 + sense_buf[2] = sense_key; // Sense key
2106 + if( sense_key == SENKEY_ILLEGAL )
2107 + sense_buf[7] = 10; // Additional sense length
2109 + sense_buf[7] = 6; // Additional sense length
2111 + sense_buf[12] = sense_code; // Additional sense code
2112 + sense_buf[13] = a_sense_code; // Additional sense code qualifier
2113 + if( sense_key == SENKEY_ILLEGAL )
2115 + sense_buf[15] = 0;
2117 + if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2118 + sense_buf[15] = 0x80; // Std sense key specific field
2119 + // Illegal parameter is in the parameter block
2121 + if( sense_code == SENCODE_INVALID_CDB_FIELD )
2122 + sense_buf[15] = 0xc0; // Std sense key specific field
2123 + // Illegal parameter is in the CDB block
2124 + sense_buf[15] |= bit_pointer;
2125 + sense_buf[16] = field_pointer >> 8; // MSB
2126 + sense_buf[17] = field_pointer; // LSB
2130 diff -urN linux/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2131 --- linux/drivers/scsi/aacraid/aacid.c Wed Dec 31 19:00:00 1969
2132 +++ linux/drivers/scsi/aacraid/aacid.c Thu Dec 21 13:14:30 2000
2135 + * Adaptec aacraid device driver for Linux.
2137 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2139 + * This program is free software; you can redistribute it and/or modify
2140 + * it under the terms of the GNU General Public License as published by
2141 + * the Free Software Foundation; either version 2, or (at your option)
2142 + * any later version.
2144 + * This program is distributed in the hope that it will be useful,
2145 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2146 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2147 + * GNU General Public License for more details.
2149 + * You should have received a copy of the GNU General Public License
2150 + * along with this program; see the file COPYING. If not, write to
2151 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2156 + * Abstract: Data structures for controller specific info.
2160 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2162 +#include "osheaders.h"
2164 +#include "AacGenericTypes.h"
2166 +#include "aac_unix_defs.h"
2168 +#include "fsatypes.h"
2169 +#include "comstruc.h"
2170 +#include "fsaport.h"
2171 +#include "pcisup.h"
2173 +#include "version.h"
2176 +/* Function Prototypes */
2177 +void InqStrCopy(char *a, char *b); /* ossup.c */
2179 +/* Device name used to register and unregister
2180 + the device in linit.c */
2181 +char devicestr[]="aac";
2183 +char *container_types[] = {
2202 +/* Local Structure to set SCSI inquiry data strings */
2203 +typedef struct _INQSTR {
2204 + char vid[8]; /* Vendor ID */
2205 + char pid[16]; /* Product ID */
2206 + char prl[4]; /* Product Revision Level */
2207 +} INQSTR, *INQSTRP;
2209 +FSA_MINIPORT MiniPorts[];
2211 +/* Function: SetInqDataStr
2213 + * Arguments: [1] pointer to void [1] int
2215 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2216 + * and revision level. Allows strings to be set in platform dependant
2217 + * files instead of in OS dependant driver source.
2221 + int MiniPortIndex,
2225 + INQSTRP InqStrPtr;
2229 + mp = &MiniPorts[MiniPortIndex];
2231 + InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2233 + InqStrCopy (mp->Vendor, InqStrPtr->vid);
2234 + InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2236 + findit = InqStrPtr->pid;
2238 + for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2241 + if (tindex < (sizeof(container_types)/sizeof(char *))){
2242 + InqStrCopy (container_types[tindex], findit);
2244 + InqStrCopy ("0001", InqStrPtr->prl);
2249 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2250 + IN ULONG AdapterNumber,
2257 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2258 + IN ULONG AdapterNumber,
2265 + * Because of the way Linux names scsi devices, the order in this table has
2266 + * become important. Check for on-board Raid first, add-in cards second.
2269 +FSA_MINIPORT MiniPorts[] = {
2270 + { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2271 + { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2272 + { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2273 + { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2274 + { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2275 + { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2276 + { 0x1028, 0x0008, 0x1028, 0x00cf, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2277 + { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel */
2278 + { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2282 +#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2284 +int NumMiniPorts = NUM_MINIPORTS;
2286 +char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2287 diff -urN linux/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2288 --- linux/drivers/scsi/aacraid/commctrl.c Wed Dec 31 19:00:00 1969
2289 +++ linux/drivers/scsi/aacraid/commctrl.c Thu Dec 21 13:14:30 2000
2292 + * Adaptec aacraid device driver for Linux.
2294 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2296 + * This program is free software; you can redistribute it and/or modify
2297 + * it under the terms of the GNU General Public License as published by
2298 + * the Free Software Foundation; either version 2, or (at your option)
2299 + * any later version.
2301 + * This program is distributed in the hope that it will be useful,
2302 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2303 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2304 + * GNU General Public License for more details.
2306 + * You should have received a copy of the GNU General Public License
2307 + * along with this program; see the file COPYING. If not, write to
2308 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2313 + * Abstract: Contains all routines for control of the AFA comm layer
2317 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2319 +#include "comprocs.h"
2320 +#include "osheaders.h"
2321 +#include "ostypes.h"
2327 +typedef BOOLEAN BOOL;
2328 +#define inline /* _inline */
2330 +#include <revision.h>
2332 +FsaCtlCheckRevision(
2333 + IN PAFA_COMM_ADAPTER Adapter,
2334 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2338 +Routine Description:
2340 + This routine validates the revision of the caller with the current revision
2341 + of the filesystem.
2345 + Adapter - Supplies which adapter is being processed.
2347 + Irp - Supplies the Irp being processed.
2349 + IrpContext - Supplies the IrpContext.
2358 + RevCheck APIRevCheck;
2359 + RevCheckResp APIRevCheckResp;
2360 + RevComponent APICallingComponent;
2361 + ULONG APIBuildNumber;
2363 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2367 + APICallingComponent = APIRevCheck.callingComponent;
2368 + APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2370 + APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2372 + APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2373 + APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2375 + if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2384 +AfaCommAdapterDeviceControl(
2385 + IN PVOID AdapterArg,
2386 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2389 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2390 + int Status = ENOTTY;
2391 +// PIO_STACK_LOCATION IrpSp;
2392 + PAFA_CLASS_DRIVER ClassDriver;
2395 + // First loop through all of the class drivers to give them a chance to handle
2396 + // the Device control first.
2399 + ClassDriver = Adapter->ClassDriverList;
2401 + while (ClassDriver) {
2403 + if (ClassDriver->DeviceControl) {
2405 + if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2412 + ClassDriver = ClassDriver->Next;
2415 + switch (IoctlCmdPtr->cmd) {
2418 + case FSACTL_SENDFIB:
2420 + Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2423 + case FSACTL_AIF_THREAD:
2425 + Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2429 + case FSACTL_OPEN_GET_ADAPTER_FIB:
2431 + Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2434 + case FSACTL_GET_NEXT_ADAPTER_FIB:
2436 + Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2439 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
2441 + Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2444 + case FSACTL_MINIPORT_REV_CHECK:
2446 + Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2462 +AfaCommRegisterNewClassDriver(
2463 + IN PAFA_COMM_ADAPTER Adapter,
2464 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2465 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2469 +Routine Description:
2471 + This routine registers a new class driver for the comm layer.
2473 + It will return a pointer to the communication functions for the class driver
2478 + Adapter - Supplies which adapter is being processed.
2480 + Irp - Supplies the Irp being processed.
2484 + STATUS_SUCCESS - Everything OK.
2488 + AAC_STATUS Status;
2489 + PAFA_CLASS_DRIVER ClassDriver;
2492 + ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2494 + if (ClassDriver == NULL) {
2496 + Status = STATUS_INSUFFICIENT_RESOURCES;
2502 + // If the class driver has sent in user Vars, then copy them into the global
2506 + if (NewClassDriver->NumUserVars) {
2508 + PFSA_USER_VAR NewUserVars;
2510 + NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2511 + NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2514 + // First copy the existing into the new area.
2517 + RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2520 + // Next copy the new vars passed in from class driver.
2523 + RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2524 + NewClassDriver->UserVars,
2525 + NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2528 + // Free up the old user vars.
2531 + OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2534 + // Point the global to the new area.
2537 + FsaCommData.UserVars = NewUserVars;
2540 + // Update the total count.
2543 + FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2547 + ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2548 + ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2549 + ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2550 + ClassDriver->HandleAif = NewClassDriver->HandleAif;
2551 + ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2553 + ClassDriver->Next = Adapter->ClassDriverList;
2554 + Adapter->ClassDriverList = ClassDriver;
2557 + // Now return the information needed by the class driver to communicate to us.
2560 + NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2561 + NewClassDriverResponse->CommPortExtension = Adapter;
2562 + NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2563 + NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2564 + NewClassDriverResponse->Dip = Adapter->Dip;
2566 + return (STATUS_SUCCESS);
2573 + IN PAFA_COMM_ADAPTER Adapter,
2574 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2578 +Routine Description:
2580 + This routine sends a fib to the adapter on behalf of a user level
2585 + Adapter - Supplies which adapter is being processed.
2587 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2591 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2593 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2595 + STATUS_SUCCESS - Everything OK.
2600 +// PMDL DmaMdl = NULL;
2601 + PCOMM_FIB_CONTEXT FibContext;
2602 + PSGMAP_CONTEXT SgMapContext;
2603 + SGMAP_CONTEXT _SgMapContext;
2604 + QUEUE_TYPES WhichQueue;
2605 + PVOID UsersAddress;
2606 + AAC_STATUS Status;
2608 + FibContext = AllocateFib( Adapter );
2610 + KFib = FibContext->Fib;
2613 + // First copy in the header so that we can check the size field.
2616 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2617 + FreeFib( FibContext );
2623 + // Since we copy based on the fib header size, make sure that we
2624 + // will not overrun the buffer when we copy the memory. Return
2625 + // an error if we would.
2628 + if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2629 + FreeFib( FibContext );
2635 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2636 + FreeFib( FibContext );
2641 + WhichQueue = AdapNormCmdQueue;
2644 + if (KFib->Header.Command == TakeABreakPt) {
2646 + InterruptAdapter(Adapter);
2649 + // Since we didn't really send a fib, zero out the state to allow
2650 + // cleanup code not to assert.
2653 + KFib->Header.XferState = 0;
2658 + if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2659 + TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2660 + FsaCommPrint("User SendFib failed!.\n");
2663 + FreeFib( FibContext );
2667 + if (CompleteFib(FibContext) != FSA_SUCCESS) {
2668 + FsaCommPrint("User Complete FIB failed.\n");
2670 + FreeFib( FibContext );
2679 + // Make sure that the size returned by the adapter (which includes
2680 + // the header) is less than or equal to the size of a fib, so we
2681 + // don't corrupt application data. Then copy that size to the user
2682 + // buffer. (Don't try to add the header information again, since it
2683 + // was already included by the adapter.)
2685 + ASSERT(KFib->Header.Size <= sizeof(FIB));
2687 + if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2688 + FreeFib( FibContext );
2693 + FreeFib( FibContext );
2700 +AfaCommCtlAifThread(
2701 + IN PAFA_COMM_ADAPTER Adapter,
2702 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2706 +Routine Description:
2708 + This routine will act as the AIF thread for this adapter.
2712 + Adapter - Supplies which adapter is being processed.
2714 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2718 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2720 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2722 + STATUS_SUCCESS - Everything OK.
2726 + return (NormCommandThread(Adapter));
2731 +#ifdef GATHER_FIB_TIMES
2733 +AfaCommGetFibTimes(
2734 + IN PAFA_COMM_ADAPTER Adapter,
2739 +Routine Description:
2741 + This routine returns the gathered fibtimes to the user.
2745 + Adapter - Supplies which adapter is being processed.
2747 + Irp - Supplies the Irp being processed.
2751 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2753 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2755 + STATUS_SUCCESS - Everything OK.
2759 + PALL_FIB_TIMES AllFibTimes;
2760 + PLARGE_INTEGER FreqPtr;
2761 + PIO_STACK_LOCATION IrpSp;
2764 + // Get a pointer to the current Irp stack location
2767 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2769 + FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2771 + *FreqPtr = Adapter->FibTimesFrequency;
2773 + AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2775 + RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2777 + Irp->IoStatus.Information = 0;
2779 + return (STATUS_SUCCESS);
2784 +AfaCommZeroFibTimes(
2785 + IN PAFA_COMM_ADAPTER Adapter,
2790 +Routine Description:
2792 + This routine zero's the FibTimes structure within the adapter structure.
2796 + Adapter - Supplies which adapter is being processed.
2798 + Irp - Supplies the Irp being processed.
2802 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2804 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2806 + STATUS_SUCCESS - Everything OK.
2810 + PFIB_TIMES FibTimesPtr;
2812 + PIO_STACK_LOCATION IrpSp;
2815 + // Get a pointer to the current Irp stack location
2818 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2821 + // Initialize the Fib timing data structures
2823 + RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2825 + for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2827 + FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2829 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2830 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2831 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2832 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2834 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2836 + FibTimesPtr = &Adapter->FibTimes->Read[i];
2838 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2839 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2840 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2841 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2843 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2845 + FibTimesPtr = &Adapter->FibTimes->Write[i];
2847 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2848 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2849 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2850 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2853 + FibTimesPtr = &Adapter->FibTimes->Other;
2855 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2856 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2857 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2858 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2860 + Irp->IoStatus.Information = 0;
2862 + return (STATUS_SUCCESS);
2865 +#endif // GATHER_FIB_TIMES
2869 +FsaCtlOpenGetAdapterFib(
2870 + IN PAFA_COMM_ADAPTER Adapter,
2871 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2875 +Routine Description:
2877 + This routine will get the next Fib, if available, from the AdapterFibContext
2878 + passed in from the user.
2882 + Adapter - Supplies which adapter is being processed.
2884 + Irp - Supplies the Irp being processed.
2888 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2890 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2892 + STATUS_SUCCESS - Everything OK.
2896 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2898 +// PKEVENT eventObject = (PKEVENT) NULL;
2902 + // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2905 + AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2907 + if (AdapterFibContext == NULL) {
2913 + AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2914 + AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2918 + // Initialize the conditional variable use to wait for the next AIF.
2921 + OsCv_init( &AdapterFibContext->UserEvent);
2924 + // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
2927 + AdapterFibContext->WaitingForFib = FALSE;
2930 + // Initialize the FibList and set the count of fibs on the list to 0.
2933 + AdapterFibContext->FibCount = 0;
2934 + InitializeListHead(&AdapterFibContext->FibList);
2937 + // Overload FileObject with a time stamp.
2939 + AdapterFibContext->FileObject = (void *)OsGetSeconds();
2942 + // Now add this context onto the adapter's AdapterFibContext list.
2945 + OsCvLockAcquire(Adapter->AdapterFibMutex);
2947 + InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
2949 + OsCvLockRelease(Adapter->AdapterFibMutex);
2951 + if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
2952 + IoctlCmdPtr->flag )) {
2968 +FsaCtlGetNextAdapterFib(
2969 + IN PAFA_COMM_ADAPTER Adapter,
2970 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2974 +Routine Description:
2976 + This routine will get the next Fib, if available, from the AdapterFibContext
2977 + passed in from the user.
2981 + Adapter - Supplies which adapter is being processed.
2983 + Irp - Supplies the Irp being processed.
2987 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2989 + STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
2991 + STATUS_SUCCESS - Everything OK.
2995 + GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
2996 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
2999 + PLIST_ENTRY Entry;
3002 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3003 + sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3008 + // Extract the AdapterFibContext from the Input parameters.
3011 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3014 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3016 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3017 + // this is a valid address
3020 + Entry = Adapter->AdapterFibContextList.Flink;
3022 + while ( Entry != &Adapter->AdapterFibContextList ) {
3023 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3024 + if ( AdapterFibContext == aifcp ) { // We found a winner
3028 + Entry = Entry->Flink;
3031 + if ( found == 0 ) {
3032 + return ( EINVAL );;
3035 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3036 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3038 + return ( EINVAL );
3042 + Status = STATUS_SUCCESS;
3044 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3047 + // If there are no fibs to send back, then either wait or return EAGAIN
3051 + if (!IsListEmpty(&AdapterFibContext->FibList)) {
3053 + PLIST_ENTRY Entry;
3056 + // Pull the next fib from the FibList
3058 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3060 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3062 + AdapterFibContext->FibCount--;
3064 + if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3066 + OsCvLockRelease( Adapter->AdapterFibMutex );
3067 + OsFreeMemory( Fib, sizeof(Fib) );
3073 + // Free the space occupied by this copy of the fib.
3076 + OsFreeMemory(Fib, sizeof(FIB));
3081 + // Overload FileObject with a time stamp
3083 + AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3087 + if (AdapterFibIoctl.Wait) {
3089 + if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3105 + OsCvLockRelease( Adapter->AdapterFibMutex );
3111 +FsaCtlCloseGetAdapterFib(
3112 + IN PAFA_COMM_ADAPTER Adapter,
3113 + IN PAFA_IOCTL_CMD IoctlCmdPtr
3117 +Routine Description:
3119 + This routine will close down the AdapterFibContext passed in from the user.
3123 + Adapter - Supplies which adapter is being processed.
3125 + Irp - Supplies the Irp being processed.
3129 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3131 + STATUS_SUCCESS - Everything OK.
3135 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3136 + AAC_STATUS Status;
3138 + PLIST_ENTRY Entry;
3142 + // Extract the AdapterFibContext from the Input parameters
3145 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3147 + if (AdapterFibContext == 0) {
3148 + cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3153 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3155 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3156 + // this is a valid address
3159 + Entry = Adapter->AdapterFibContextList.Flink;
3161 + while ( Entry != &Adapter->AdapterFibContextList ) {
3162 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3163 + if ( AdapterFibContext == aifcp ) { // We found a winner
3167 + Entry = Entry->Flink;
3170 + if ( found == 0 ) {
3171 + return ( 0 ); // Already Gone
3174 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3175 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3181 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3183 + Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3185 + OsCvLockRelease(Adapter->AdapterFibMutex);
3191 +FsaCloseAdapterFibContext(
3192 + IN PAFA_COMM_ADAPTER Adapter,
3193 + IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3200 + // First free any FIBs that have not been consumed yet.
3203 + while (!IsListEmpty(&AdapterFibContext->FibList)) {
3205 + PLIST_ENTRY Entry;
3208 + // Pull the next fib from the FibList
3211 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3213 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3215 + AdapterFibContext->FibCount--;
3218 + // Free the space occupied by this copy of the fib.
3221 + OsFreeMemory(Fib, sizeof(FIB));
3225 + // Remove the Context from the AdapterFibContext List
3228 + RemoveEntryList(&AdapterFibContext->NextContext);
3230 + OsCv_destroy( &AdapterFibContext->UserEvent );
3233 + // Invalidate context
3236 + AdapterFibContext->NodeTypeCode = 0;
3239 + // Free the space occupied by the Context
3242 + OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3244 + Status = STATUS_SUCCESS;
3251 +AfaCommOpenAdapter(
3256 +Routine Description:
3258 + The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3261 + The main purpose of this routine is to set up any data structures that may be needed
3262 + to handle any requests made on this DeviceObject.
3266 + Adapter - Pointer to which adapter miniport was opened.
3276 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3277 + AAC_STATUS Status = STATUS_SUCCESS;
3278 + PAFA_CLASS_DRIVER ClassDriver;
3280 + ClassDriver = Adapter->ClassDriverList;
3282 + while (ClassDriver) {
3284 + if (ClassDriver->OpenAdapter) {
3286 + Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3288 + if (Status != STATUS_SUCCESS)
3292 + ClassDriver = ClassDriver->Next;
3295 + return ( Status );
3299 +AfaCommCloseAdapter(
3304 +Routine Description:
3306 + This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3309 + The main purpose of this routine is to cleanup any data structures that have been set up
3310 + while this FileObject has been opened.
3312 + This routine loops through all of the AdapterFibContext structures to determine if any need
3313 + to be deleted for this FileObject.
3317 + Adapter - Pointer to adapter miniport
3319 + Irp - Pointer to Irp that caused this close
3323 + Status value returned from File system driver AdapterClose
3327 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3328 + PLIST_ENTRY Entry, NextEntry;
3329 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3330 + AAC_STATUS Status = STATUS_SUCCESS;
3331 + PAFA_CLASS_DRIVER ClassDriver;
3333 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3335 + Entry = Adapter->AdapterFibContextList.Flink;
3338 + // Loop through all of the AdapterFibContext, looking for any that
3339 + // were created with the FileObject that is being closed.
3341 + while (Entry != &Adapter->AdapterFibContextList) {
3344 + // Extract the AdapterFibContext
3346 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3349 + // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3351 + NextEntry = Entry->Flink;
3353 + Entry = NextEntry;
3357 +#ifdef unix_config_file
3359 + // If this FileObject had the adapter open for configuration, then release it.
3361 + if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3363 + Adapter->AdapterConfigFileObject = NULL;
3368 + OsCvLockRelease(Adapter->AdapterFibMutex);
3370 + ClassDriver = Adapter->ClassDriverList;
3372 + while (ClassDriver) {
3374 + if (ClassDriver->CloseAdapter) {
3376 + Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3378 + if (Status != STATUS_SUCCESS)
3382 + ClassDriver = ClassDriver->Next;
3385 + return ( Status );
3389 diff -urN linux/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3390 --- linux/drivers/scsi/aacraid/comminit.c Wed Dec 31 19:00:00 1969
3391 +++ linux/drivers/scsi/aacraid/comminit.c Thu Dec 21 13:14:30 2000
3394 + * Adaptec aacraid device driver for Linux.
3396 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3398 + * This program is free software; you can redistribute it and/or modify
3399 + * it under the terms of the GNU General Public License as published by
3400 + * the Free Software Foundation; either version 2, or (at your option)
3401 + * any later version.
3403 + * This program is distributed in the hope that it will be useful,
3404 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3405 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3406 + * GNU General Public License for more details.
3408 + * You should have received a copy of the GNU General Public License
3409 + * along with this program; see the file COPYING. If not, write to
3410 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3415 + * Abstract: This supports the initialization of the host adapter commuication interface.
3416 + * This is a platform dependent module for the pci cyclone board.
3420 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3422 +#include "comprocs.h"
3424 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3427 +AfaCommBugcheckHandler(
3433 +ThrottlePeriodEndDpcRtn(
3435 + IN PVOID DeferredContext,
3436 + IN PVOID SystemArgument1,
3437 + IN PVOID SystemArgument2);
3439 +FSA_COMM_DATA FsaCommData;
3442 +HardInterruptModeration1Changed(
3443 + IN PVOID AdapterContext,
3447 + PAFA_COMM_ADAPTER Adapter = AdapterContext;
3450 + // If we are using interrupt moderation, then disable the interrupt
3451 + // until we need to use it.
3453 + if (FsaCommData.HardInterruptModeration1)
3454 + DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3456 + EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3458 + return (STATUS_SUCCESS);
3462 +FsaFibTimeoutChanged(
3463 + IN PVOID AdapterContext,
3468 + // scale the new timeout from seconds to 100 nsec units
3470 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3472 + return (STATUS_SUCCESS);
3475 +#ifdef GATHER_FIB_TIMES
3476 +extern int GatherFibTimes;
3479 +FSA_USER_VAR FsaCommUserVars[] = {
3480 +#ifdef FIB_CHECKSUMS
3481 + { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3483 +#ifdef GATHER_FIB_TIMES
3484 + { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3486 + { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3487 + { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3488 + { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3489 + { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3490 + { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3491 + { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3492 + { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3493 + { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3494 + { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3495 + { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3498 +#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3502 +AacCommDriverEntry(
3507 +Routine Description:
3509 + This is the initialization routine for the FileArray Comm layer device driver.
3513 + DriverObject - Pointer to driver object created by the system.
3517 + AAC_STATUS - The function value is the final status from the initialization
3523 + AAC_STATUS Status;
3524 + PVOID BugCheckBuffer;
3526 + RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3530 + // Load the global timeout value for the adapter timeout
3531 + // Also init the global that enables or disables adapter timeouts
3534 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3536 + FsaCommData.FibTimeoutSeconds = 180;
3538 + FsaCommData.EnableAdapterTimeouts = TRUE;
3540 +// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3542 +#ifdef unix_fib_timeout
3543 + FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3546 + FsaCommData.EnableInterruptModeration = FALSE;
3549 + // Preload UserVars with all variables from the comm layer. The class layers will
3550 + // include theirs when they register.
3553 + FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3554 + FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3556 + RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3561 + // Call the disk driver to initialize itself.
3564 + AacDiskDriverEntry();
3570 + return (STATUS_SUCCESS);
3576 + IN PAFA_COMM_ADAPTER Adapter,
3577 + IN OUT PCOMM_QUE Queue,
3578 + IN QUEUE_TYPES WhichQueue
3582 +Routine Description:
3584 + This routine will release all of the resources used by a given queue.
3588 + Adapter - Which adapter the queue belongs to
3589 + Queue - Pointer to the queue itself
3590 + WhichQueue - Identifies which of the host queues this is.
3598 + switch (WhichQueue) {
3600 + case HostNormCmdQueue:
3602 + Os_remove_softintr( Queue->ConsumerRoutine );
3603 + OsSpinLockDestroy( Queue->QueueLock );
3604 + OsCv_destroy( &Queue->CommandReady );
3608 + case HostHighCmdQueue:
3610 + Os_remove_softintr( Queue->ConsumerRoutine );
3611 + OsSpinLockDestroy( Queue->QueueLock );
3612 + OsCv_destroy( &Queue->CommandReady );
3616 + case HostNormRespQueue:
3618 + Os_remove_softintr( Queue->ConsumerRoutine );
3619 + OsSpinLockDestroy( Queue->QueueLock );
3622 + case HostHighRespQueue:
3624 + Os_remove_softintr( Queue->ConsumerRoutine );
3625 + OsSpinLockDestroy( Queue->QueueLock );
3628 + case AdapNormCmdQueue:
3629 + case AdapHighCmdQueue:
3630 + case AdapNormRespQueue:
3631 + case AdapHighRespQueue:
3632 + OsCv_destroy( &Queue->QueueFull );
3639 + IN PAFA_COMM_ADAPTER Adapter,
3640 + IN OUT PCOMM_QUE Queue,
3641 + IN QUEUE_TYPES WhichQueue
3645 +Routine Description:
3647 + Will initialize all entries in the queue that is NT specific.
3653 + Nothing there is nothing to allocate so nothing should fail
3658 + Queue->NumOutstandingIos = 0;
3661 + // Store a pointer to the adapter structure.
3664 + Queue->Adapter = Adapter;
3666 + InitializeListHead( &Queue->OutstandingIoQueue );
3668 + switch (WhichQueue) {
3670 + case HostNormCmdQueue:
3672 + OsCv_init( &Queue->CommandReady);
3673 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3674 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3675 + NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3676 + (caddr_t)Queue ) != DDI_SUCCESS) {
3678 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3681 + InitializeListHead(&Queue->CommandQueue);
3685 + case HostHighCmdQueue:
3687 + OsCv_init( &Queue->CommandReady);
3688 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3689 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3690 + NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3691 + (caddr_t) Queue ) != DDI_SUCCESS) {
3693 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3696 + InitializeListHead(&Queue->CommandQueue);
3699 + case HostNormRespQueue:
3701 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3702 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3703 + NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3704 + (caddr_t) Queue ) != DDI_SUCCESS) {
3706 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3710 + case HostHighRespQueue:
3713 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3714 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3715 + NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3716 + (caddr_t) Queue ) != DDI_SUCCESS) {
3718 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3722 + case AdapNormCmdQueue:
3723 + case AdapHighCmdQueue:
3724 + case AdapNormRespQueue:
3725 + case AdapHighRespQueue:
3727 + OsCv_init( &Queue->QueueFull);
3733 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3736 +Routine Description:
3738 + Create and start the command receiver threads.
3757 +Routine Description:
3759 + This routine gets called to detach all resources that have been allocated for
3764 + Adapter - Pointer to the adapter structure to detach.
3768 + TRUE - All resources have been properly released.
3769 + FALSE - An error occured while trying to release resources.
3772 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3774 + PAFA_CLASS_DRIVER ClassDriver;
3776 + // First remove this adapter from the list of adapters.
3779 + if (FsaCommData.AdapterList == Adapter) {
3781 + FsaCommData.AdapterList = Adapter->NextAdapter;
3785 + PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3787 + CurrentAdapter = FsaCommData.AdapterList;
3788 + NextAdapter = CurrentAdapter->NextAdapter;
3790 + while (NextAdapter) {
3792 + if (NextAdapter == Adapter) {
3794 + CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3799 + CurrentAdapter = NextAdapter;
3800 + NextAdapter = CurrentAdapter->NextAdapter;
3805 + // First send a shutdown to the adapter.
3808 + AfaCommShutdown( Adapter );
3811 + // Destroy the FibContextZone for this adapter. This will free up all
3812 + // of the fib space used by this adapter.
3815 + FsaFreeFibContextZone( Adapter );
3818 + // Destroy the mutex used for synch'ing adapter fibs.
3821 + OsCvLockDestroy( Adapter->AdapterFibMutex );
3824 + // Detach all of the host queues.
3827 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3828 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3829 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3830 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3831 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3832 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3833 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3834 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3837 + // Destroy the mutex used to protect the FibContextZone
3840 + OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3843 + // Call the miniport to free the space allocated for the shared comm queues
3844 + // between the host and the adapter.
3847 + FsaFreeAdapterCommArea( Adapter );
3850 + // Free the memory used by the comm region for this adapter
3853 + OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3856 + // Free the memory used by the adapter structure.
3858 + ClassDriver = Adapter->ClassDriverList;
3859 + Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3860 + OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3862 + OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3868 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3870 + PVOID BugCheckBuffer;
3871 + PAFA_COMM_ADAPTER Adapter;
3872 + MAPFIB_CONTEXT MapFibContext;
3873 + LARGE_INTEGER Time;
3874 + char ErrorBuffer[60];
3876 + Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3878 + if (Adapter == NULL)
3881 + RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3885 + // Save the current adapter number and increment the total number.
3888 + Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3892 + // Fill in the pointer back to the device specific structures.
3893 + // The device specific driver has also passed a pointer for us to
3894 + // fill in with the Adapter object that we have created.
3897 + Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3898 + Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3899 + Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3900 + Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3901 + Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3903 + Adapter->Dip = NewAdapter->Dip;
3906 + // Fill in Our address into the function dispatch table
3909 + NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3910 + NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3911 + NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3912 + NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3915 + // Ok now init the communication subsystem
3918 + Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3919 + if (Adapter->CommRegion == NULL) {
3920 + cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3923 + RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3926 + // Get a pointer to the iblock_cookie
3929 + ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
3931 + if (!CommInit(Adapter)) {
3932 + FsaCommPrint("Failed to init the commuication subsystem.\n");
3938 + // Initialize the list of AdapterFibContext's.
3941 + InitializeListHead(&Adapter->AdapterFibContextList);
3944 + // Initialize the fast mutex used for synchronization of the adapter fibs
3947 + Adapter->AdapterFibMutex = OsCvLockAlloc();
3948 + OsCvLockInit(Adapter->AdapterFibMutex, NULL);
3951 + // Allocate and start the FSA command threads. These threads will handle
3952 + // command requests from the adapter. They will wait on an event then pull
3953 + // all CDBs off the thread's queue. Each CDB will be given to a worker thread
3954 + // upto a defined limit. When that limit is reached wait a event will be waited
3955 + // on till a worker thread is finished.
3958 + if (!StartFsaCommandThreads(Adapter)) {
3959 + FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
3963 +#ifdef unix_crash_dump
3965 + // Allocate and map a fib for use by the synch path, which is used for crash
3968 + // Allocate an entire page so that alignment is correct.
3971 + Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
3972 + MapFibContext.Fib = Adapter->SyncFib;
3973 + MapFibContext.Size = sizeof(FIB);
3974 + MapFib( Adapter, &MapFibContext );
3975 + Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
3978 + Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
3980 + Adapter->CommFuncs.AllocateFib = AllocateFib;
3982 + Adapter->CommFuncs.FreeFib = FreeFib;
3983 + Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
3984 + Adapter->CommFuncs.DeallocateFib = DeallocateFib;
3986 + Adapter->CommFuncs.InitializeFib = InitializeFib;
3987 + Adapter->CommFuncs.GetFibData = FsaGetFibData;
3988 + Adapter->CommFuncs.SendFib = SendFib;
3989 + Adapter->CommFuncs.CompleteFib = CompleteFib;
3990 + Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
3992 + Adapter->CommFuncs.SendSynchFib = SendSynchFib;
3994 + Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
3995 + Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
3998 + // Add this adapter in to our Adapter List.
4001 + Adapter->NextAdapter = FsaCommData.AdapterList;
4002 + FsaCommData.AdapterList = Adapter;
4004 + NewAdapter->Adapter = Adapter;
4006 +// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4013 + PAFA_COMM_ADAPTER Adapter
4017 + // Now allocate and initialize the zone structures used as our pool
4018 + // of FIB context records. The size of the zone is based on the
4019 + // system memory size. We also initialize the mutex used to protect
4022 + Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4023 + OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4025 + Adapter->FibContextZoneExtendSize = 64;
4027 + return (STATUS_SUCCESS);
4034 +Routine Description:
4036 + Initializes the data structures that are required for the FSA commuication
4037 + interface to operate.
4041 + None - all global or allocated data.
4045 + TRUE - if we were able to init the commuication interface.
4046 + FALSE - If there were errors initing. This is a fatal error.
4049 +CommInit(PAFA_COMM_ADAPTER Adapter)
4052 + ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4053 + ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4054 + PQUEUE_INDEX Headers;
4055 + PQUEUE_ENTRY Queues;
4057 + PCOMM_REGION CommRegion = Adapter->CommRegion;
4059 + CommInitialize( Adapter );
4061 + FsaCommPrint("CommInit: Queue entry size is 0x%x, Queue index size is 0x%x, Number of total entries is 0x%x, # queues = 0x%x.\n",
4062 + sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4065 + // Allocate the physically contigous space for the commuication queue
4069 + TotalSize = SizeOfHeaders + SizeOfQueues;
4071 + if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4074 + Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4076 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4077 + NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4078 + (caddr_t)CommRegion ) != DDI_SUCCESS) {
4080 + cmn_err(CE_CONT, "Os_addr_intr failed\n");
4084 + // Adapter to Host normal priority Command queue
4087 + CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4088 + CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4089 + *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4090 + *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4092 + CommRegion->HostNormCmdQue.SavedIrql = 0;
4093 + CommRegion->HostNormCmdQue.BaseAddress = Queues;
4094 + CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4096 + CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4097 + if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4100 + InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4103 + Queues += HOST_NORM_CMD_ENTRIES;
4105 + // Adapter to Host high priority command queue
4107 + CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4108 + CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4109 + *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4110 + *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4112 + CommRegion->HostHighCmdQue.SavedIrql = 0;
4113 + CommRegion->HostHighCmdQue.BaseAddress = Queues;
4114 + CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4115 +// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4116 + CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4117 + if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4120 + InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4122 + Queues += HOST_HIGH_CMD_ENTRIES;
4124 + // Host to adapter normal priority command queue
4126 + CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4127 + CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4128 + *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4129 + *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4131 + CommRegion->AdapNormCmdQue.SavedIrql = 0;
4132 + CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4133 + CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4134 + InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4136 + Queues += ADAP_NORM_CMD_ENTRIES;
4138 + // host to adapter high priority command queue
4140 + CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4141 + CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4142 + *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4143 + *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4145 + CommRegion->AdapHighCmdQue.SavedIrql = 0;
4146 + CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4147 + CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4148 + InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4150 + Queues += ADAP_HIGH_CMD_ENTRIES;
4152 + // adapter to host normal priority response queue
4154 + CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4155 + CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4156 + *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4157 + *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4159 + CommRegion->HostNormRespQue.SavedIrql = 0;
4160 + CommRegion->HostNormRespQue.BaseAddress = Queues;
4161 + CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4162 +// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4163 + CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4164 + if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4167 + InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4169 + Queues += HOST_NORM_RESP_ENTRIES;
4171 + // adapter to host high priority response queue
4173 + CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4174 + CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4175 + *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4176 + *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4178 + CommRegion->HostHighRespQue.SavedIrql = 0;
4179 + CommRegion->HostHighRespQue.BaseAddress = Queues;
4180 + CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4181 +// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4182 + CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4183 + if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4186 + InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4188 + Queues += HOST_HIGH_RESP_ENTRIES;
4190 + // host to adapter normal priority response queue
4192 + CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4193 + CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4194 + *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4195 + *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4197 + CommRegion->AdapNormRespQue.SavedIrql = 0;
4198 + CommRegion->AdapNormRespQue.BaseAddress = Queues;
4199 + CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4200 + InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4202 + Queues += ADAP_NORM_RESP_ENTRIES;
4204 + // host to adapter high priority response queue
4206 + CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4207 + CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4208 + *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4209 + *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4211 + CommRegion->AdapHighRespQue.SavedIrql = 0;
4212 + CommRegion->AdapHighRespQue.BaseAddress = Queues;
4213 + CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4214 + InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4216 + CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4217 + CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4218 + CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4219 + CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4226 + PAFA_COMM_ADAPTER Adapter
4230 +Routine Description:
4232 + This routine will send a shutdown request to each adapter.
4236 + Adapter - which adapter to send the shutdown to.
4240 + NT Status success.
4245 + PFIB_CONTEXT FibContext;
4246 + PCLOSECOMMAND CloseCommand;
4247 + AAC_STATUS Status;
4249 + FibContext = AllocateFib( Adapter );
4251 + InitializeFib( FibContext );
4253 + CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4255 + CloseCommand->Command = VM_CloseAll;
4256 + CloseCommand->ContainerId = 0xffffffff;
4258 + Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4260 + if (Status != STATUS_SUCCESS) {
4262 + FreeFib( FibContext );
4268 + CompleteFib( FibContext );
4270 + FreeFib( FibContext );
4273 + Status = STATUS_SUCCESS;
4282 +AfaCommBugcheckHandler(
4288 +Routine Description:
4290 + This routine will shutdown the adapter if there is a bugcheck and
4291 + copy the shutdown data from the adapter response into the buffer
4292 + so it will show up in the host dump file.
4296 + Buffer - This buffer will be written to the host dump by nt for us.
4298 + Length - The size of the buffer.
4306 + PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4310 + NotifyAdapter(Adapter, HostShutdown);
4312 + Adapter = Adapter->NextAdapter;
4320 + PFIB_CONTEXT FibContext,
4321 + PDEVICE_OBJECT DeviceObject,
4322 + AAC_STATUS FsaStatus,
4323 + AAC_STATUS AacStatus,
4324 + ULONG LocationCode,
4333 + PAFA_COMM_ADAPTER Adapter
4336 + PMNTINFO DiskInfo;
4337 + PMNTINFORESPONSE DiskInfoResponse;
4338 + AAC_STATUS Status;
4339 + PCOMM_FIB_CONTEXT FibContext;
4341 + FibContext = AllocateFib( Adapter );
4343 + InitializeFib( FibContext );
4345 + DiskInfo = (PMNTINFO) FibContext->Fib->data;
4346 + DiskInfo->Command = VM_NameServe;
4347 + DiskInfo->MntCount = 0;
4348 + DiskInfo->MntType = FT_FILESYS;
4350 + Status = SendFib(ContainerCommand,
4360 + DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4362 + if (DiskInfoResponse->MntRespCount) {
4364 + cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4365 + DiskInfoResponse->MntTable[0].Capacity);
4369 + cmn_err(CE_CONT, "no containers found on adapter\n");
4373 + CompleteFib( FibContext );
4375 + FreeFib( FibContext );
4379 diff -urN linux/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4380 --- linux/drivers/scsi/aacraid/commsup.c Wed Dec 31 19:00:00 1969
4381 +++ linux/drivers/scsi/aacraid/commsup.c Thu Dec 21 13:14:30 2000
4384 + * Adaptec aacraid device driver for Linux.
4386 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4388 + * This program is free software; you can redistribute it and/or modify
4389 + * it under the terms of the GNU General Public License as published by
4390 + * the Free Software Foundation; either version 2, or (at your option)
4391 + * any later version.
4393 + * This program is distributed in the hope that it will be useful,
4394 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4395 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4396 + * GNU General Public License for more details.
4398 + * You should have received a copy of the GNU General Public License
4399 + * along with this program; see the file COPYING. If not, write to
4400 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4405 + * Abstract: Contain all routines that are required for FSA host/adapter
4411 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4413 +#include "comprocs.h"
4415 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4420 +ThrottleExceptionHandler(
4421 + IN PCOMM_REGION CommRegion,
4425 +void ThrottlePeriodEndDpcRtn(
4427 + IN PVOID DeferredContext,
4428 + IN PVOID SystemArgument1,
4429 + IN PVOID SystemArgument2
4435 +Routine Description:
4437 + This routine will free all resources used by a given FibContextSegment.
4441 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4442 + ZoneSegment - The segment to release resources from.
4446 + TRUE - All resources were properly freed.
4447 + FALSE - An Error occured while freeing resources.
4451 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4452 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4454 + PCOMM_FIB_CONTEXT FibContext;
4457 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4459 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4460 + i < ZoneSegment->ExtendSize; i++, FibContext++) {
4462 + OsCvLockDestroy( FibContext->FsaEventMutex );
4463 + OsCv_destroy( &FibContext->FsaEvent );
4467 + UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4469 + OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4471 + OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4477 +FsaFreeFibContextZone(
4478 + PAFA_COMM_ADAPTER Adapter
4482 +Routine Description:
4484 + This routine will walk through the FibContextSegmentList and free up all
4485 + resources used by the FibContextZone.
4489 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4493 + TRUE - All resources were properly freed.
4494 + FALSE - An Error occured while freeing resources.
4499 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4501 + ZoneSegment = Adapter->FibContextSegmentList;
4503 + while (ZoneSegment) {
4505 + NextZoneSegment = ZoneSegment->Next;
4507 + FsaFreeFibContextSegment( Adapter, ZoneSegment );
4509 + ZoneSegment = NextZoneSegment;
4518 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4522 + ULONG ZoneSegmentAllocSize, FibAllocSize;
4523 + PVOID FibContextSegment;
4524 + PCOMM_FIB_CONTEXT FibContext;
4526 + PVOID FibPhysicalAddress;
4528 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4531 + // Allocate space to describe this zone segment.
4534 + cmn_err (CE_DEBUG, "Entered FsaExtendFibConextZone");
4535 + ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4537 + ExtendSize = Adapter->FibContextZoneExtendSize;
4538 + ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4540 + FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4542 + if (FibContextSegment == NULL) {
4546 + RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4548 + ZoneSegment->FibContextSegment = FibContextSegment;
4549 + ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4550 + ZoneSegment->ExtendSize = ExtendSize;
4552 + FibAllocSize = ExtendSize * sizeof(FIB);
4555 + ZoneSegment->MapFibContext.Size = FibAllocSize;
4557 + AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4559 + Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4560 + FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4562 + RtlZeroMemory( Fib, FibAllocSize );
4564 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4566 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4567 + i < ExtendSize; i++, FibContext++) {
4569 + FibContext->Adapter = Adapter;
4571 + FibContext->Fib = Fib;
4572 + FibContext->FibData = (PVOID) FibContext->Fib->data;
4574 + OsCv_init( &FibContext->FsaEvent);
4575 + FibContext->FsaEventMutex = OsCvLockAlloc();
4576 + OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4578 + Fib->Header.XferState = 0xffffffff;
4579 + Fib->Header.SenderSize = sizeof(FIB);
4581 + FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4583 + Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4584 + FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4588 + // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4589 + // initialized, we just need to extend it.
4592 + if (Adapter->FibContextZone.TotalSegmentSize) {
4594 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4596 + ExExtendZone( &Adapter->FibContextZone,
4597 + FibContextSegment,
4598 + ZoneSegmentAllocSize );
4600 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4604 + if (ExInitializeZone( &Adapter->FibContextZone,
4605 + sizeof(COMM_FIB_CONTEXT),
4606 + FibContextSegment,
4607 + ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4608 + FsaBugCheck(0,0,0);
4613 + // Add this segment to the adapter's list of segments
4616 + ZoneSegment->Next = Adapter->FibContextSegmentList;
4617 + Adapter->FibContextSegmentList = ZoneSegment;
4626 +Routine Description:
4628 + This routine creates a new COMM_FIB_CONTEXT record
4632 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4636 + PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4640 +AllocateFib (IN PVOID AdapterArg)
4642 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4644 + PCOMM_FIB_CONTEXT FibContext;
4645 + int FullZoneLoopCounter = 0;
4649 + // Acquire the zone spin lock, and check to see if the zone is full.
4650 + // If it is, then release the spin lock and allocate more fibs for the
4651 + // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4652 + // the new fibs onto the zone.
4655 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4657 + while (ExIsFullZone( &Adapter->FibContextZone )) {
4659 + if (++FullZoneLoopCounter > 10)
4660 + FsaBugCheck(0,0,0);
4662 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4665 + cmn_err (CE_DEBUG, "Extending FibContextZone");
4666 + if (FsaExtendFibContextZone(Adapter) == FALSE) {
4670 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4675 + // At this point we now know that the zone has at least one more
4676 + // IRP context record available. So allocate from the zone and
4677 + // then release the mutex.
4680 + FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4682 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4685 + // Set the proper node type code and node byte size
4688 + FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4689 + FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4692 + // Null out fields that depend on being zero at the start of each I/O
4695 + FibContext->Fib->Header.XferState = 0;
4696 + FibContext->FibCallback = NULL;
4697 + FibContext->FibCallbackContext = NULL;
4701 + // return and tell the caller
4704 + return ((PFIB_CONTEXT) FibContext);
4710 +Routine Description:
4712 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4713 + from the Fsafs in memory data structures. It should only be called
4714 + by FsaCompleteRequest.
4718 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4726 +FreeFib (IN PFIB_CONTEXT Context)
4729 + PCOMM_FIB_CONTEXT FibContext = Context;
4731 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4733 + OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4735 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4737 + FsaCommData.TimedOutFibs++;
4739 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4740 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4744 + ASSERT(FibContext->Fib->Header.XferState == 0);
4746 + if (FibContext->Fib->Header.XferState != 0) {
4747 + cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4748 + FibContext, FibContext->Fib->Header.XferState);
4751 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4755 + OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4758 + // return and tell the caller
4767 +Routine Description:
4769 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4770 + from the Fsafs in memory data structures. It should only be called
4771 + from the dpc routines to from dpc to free an FibContext from an async or
4776 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4784 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4786 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4788 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4790 + OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4792 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4794 + FsaCommData.TimedOutFibs++;
4796 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4797 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4801 + ASSERT(FibContext->Fib->Header.XferState == 0);
4803 + if (FibContext->Fib->Header.XferState != 0) {
4804 + cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4805 + FibContext, FibContext->Fib->Header.XferState);
4809 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4813 + OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4816 + // return and tell the caller
4825 +Routine Description:
4827 + Will initialize a FIB of the requested size.
4831 + Fib is a pointer to a location which will receive the address of the allocated
4834 + Size is the size of the Fib to allocate.
4838 + NT_SUCCESS if a Fib was returned to the caller.
4839 + NT_ERROR if event was an invalid event.
4843 +InitializeFib (IN PFIB_CONTEXT Context)
4845 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4846 + PFIB Fib = FibContext->Fib;
4848 + Fib->Header.StructType = TFib;
4849 + Fib->Header.Size = sizeof(FIB);
4850 +// if (Fib->Header.XferState & AllocatedFromPool)
4851 +// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4853 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4854 + Fib->Header.SenderFibAddress = 0;
4855 + Fib->Header.ReceiverFibAddress = 0;
4856 + Fib->Header.SenderSize = sizeof(FIB);
4858 + return(STATUS_SUCCESS);
4864 +Routine Description:
4866 + Will allocate and initialize a FIB of the requested size and return a
4867 + pointer to the structure. The size allocated may be larger than the size
4868 + requested due to allocation performace optimizations.
4872 + Fib is a pointer to a location which will receive the address of the allocated
4875 + Size is the size of the Fib to allocate.
4877 + JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4878 + imbedded structure the FS always allocates. So just initiaize it and return.
4882 + NT_SUCCESS if a Fib was returned to the caller.
4883 + NT_ERROR if event was an invalid event.
4887 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4893 +Routine Description:
4895 + Will deallocate and return to the free pool the FIB pointed to by the
4896 + caller. Upon return accessing locations pointed to by the FIB parameter
4897 + could cause system access faults.
4901 + Fib is a pointer to the FIB that caller wishes to deallocate.
4905 + NT_SUCCESS if a Fib was returned to the caller.
4906 + NT_ERROR if event was an invalid event.
4910 +DeallocateFib (PFIB_CONTEXT Context)
4912 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4913 + PFIB Fib = FibContext->Fib;
4915 + if ( Fib->Header.StructType != TFib ) {
4916 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4917 + return(STATUS_UNSUCCESSFUL);
4921 + Fib->Header.XferState = 0;
4923 + return(STATUS_SUCCESS);
4930 + IN PCOMM_QUE ResponseQueue,
4935 +Routine Description:
4937 + Gets a QE off the requested response queue and gets the response FIB into
4938 + host memory. The FIB may already be in host memory depending on the bus
4939 + interface, or may require the host to DMA it over from the adapter. The routine
4940 + will return the FIB to the caller.
4944 + ResponseQueue - Is the queue the caller wishes to have the response gotten from.
4945 + Fib - Is the Fib which was the response from the adapter
4949 + NT_SUCCESS if a Fib was returned to the caller.
4950 + NT_ERROR if there was no Fib to return to the caller.
4951 + bkpfix - add in all the other possible errors ect
4955 +return(STATUS_UNSUCCESSFUL);
4959 +// Commuication primitives define and support the queuing method we use to
4960 +// support host to adapter commuication. All queue accesses happen through
4961 +// these routines and are the only routines which have a knowledge of the
4962 +// how these queues are implemented.
4968 +Routine Description:
4970 + With a priority the routine returns a queue entry if the queue has free entries. If the queue
4971 + is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
4976 + Priority is an enumerated type which determines which priority level
4977 + command queue the QE is going to be queued on.
4979 + Entry is a pointer to the address of where to return the address of
4980 + the queue entry from the requested command queue.
4982 + Index is a pointer to the address of where to store the index of the new
4983 + queue entry returned.
4985 + DontInterrupt - We set this true if the queue state is such that we don't
4986 + need to interrupt the adapter for this queue entry.
4990 + TRUE - If a queue entry is returned
4991 + FALSE - If there are no free queue entries on the requested command queue.
4995 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
4996 + OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
4997 + OUT ULONG *DontInterrupt)
4999 + ULONG QueueOffset;
5001 + PCOMM_REGION CommRegion;
5003 + CommRegion = Adapter->CommRegion;
5006 + // All of the queues wrap when they reach the end, so we check to see if they
5007 + // have reached the end and if they have we just set the index back to zero.
5008 + // This is a wrap. You could or off the high bits in all updates but this is
5009 + // a bit faster I think.
5012 + if (WhichQueue == AdapHighCmdQueue) {
5013 + *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5015 + if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5016 + *DontInterrupt = TRUE;
5018 + if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5021 + if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5023 + cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5024 + CommRegion->AdapHighCmdQue.NumOutstandingIos);
5026 + QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5027 + *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5031 + } else if (WhichQueue == AdapNormCmdQueue) {
5033 + *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5035 + if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5036 + *DontInterrupt = TRUE;
5039 + // If we are at the end of the QUEUE then wrap back to
5043 + if (*Index >= ADAP_NORM_CMD_ENTRIES)
5044 + *Index = 0; // Wrap to front of the Producer Queue.
5047 + // The IEEE spec says that it the producer is one behind the consumer then
5048 + // the queue is full.
5051 + ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5053 + if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5054 + cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5055 + CommRegion->AdapNormCmdQue.NumOutstandingIos);
5059 + // The success case just falls through and returns the a valid queue entry.
5063 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5064 + FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5065 + *Index, QueueOffset, Entry, *Entry);
5067 + *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5071 + } else if (WhichQueue == AdapHighRespQueue) {
5073 + *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5075 + if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5076 + *DontInterrupt = TRUE;
5078 + if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5081 + if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5083 + cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5084 + CommRegion->AdapHighRespQue.NumOutstandingIos);
5086 + *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5089 + } else if (WhichQueue == AdapNormRespQueue) {
5091 + *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5093 + if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5094 + *DontInterrupt = TRUE;
5097 + // If we are at the end of the QUEUE then wrap back to
5101 + if (*Index >= ADAP_NORM_RESP_ENTRIES)
5102 + *Index = 0; // Wrap to front of the Producer Queue.
5105 + // The IEEE spec says that it the producer is one behind the consumer then
5106 + // the queue is full.
5109 + if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5111 + cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5112 + CommRegion->AdapNormRespQue.NumOutstandingIos);
5115 + // The success case just falls through and returns the a valid queue entry.
5118 + *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5121 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5122 + FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5127 + cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5136 +#ifdef API_THROTTLE
5138 +void ThrottleCheck(
5139 + IN PAFA_COMM_ADAPTER Adapter,
5144 +Routine Description:
5146 + This routine implements data I/O throttling. Throttling occurs when
5147 + a CLI FIB is detected. To ensure the CLI responds quickly (the user
5148 + is waiting for the response), this mechanism restricts the queue
5149 + depth of data IOs at the adapter for a period of time (called the
5150 + Throttle Period, default 5 seconds).
5152 + The mechanism uses a counted semaphore to place threads into a wait
5153 + state should there be too many data I/Os outstanding.
5155 + At the start of a throttle period (indicated by the first CLI FIB)
5156 + a timer is started. When the timer expires, new requests can go to
5157 + the adapter freely. Throttled requests gradually drain to the
5158 + adapter as each outstanding throttle I/O completes.
5160 + To avoid hurting regular I/O performance, we use a flag in the FIB
5161 + header to mark FIBs involved in throttling. This means we only need
5162 + take the extra spinlock in the response DPC routine for FIBs who
5163 + were subject to throttling. If no throttling is occurring, the cost
5164 + to the regular code paths is a handful of instructions.
5168 + Adapter - Pointer to per-adapter context. This is used to locate the
5169 + throttle information for this adapter.
5171 + Fib - Pointer to the header for the fib being sent.
5179 + PCOMM_REGION CommRegion = Adapter->CommRegion;
5180 + AAC_STATUS Status;
5183 + // This routine is called under protection of the queue spinlock.
5184 + // As such we are allowed to check and change the counts for the
5186 + // Check the FIB. If its not a data operation, send it on without
5187 + // throttle check. If it is a data operation, check for throttle.
5190 + CommRegion->TotalFibs++; // Keep statistics
5192 + if ((Fib->Header.XferState & ApiFib) != 0) {
5194 + CommRegion->ApiFibs++; // Keep statistics
5197 + // Its an API fib. If the throttle is not already active,
5198 + // make it so. This will prevent new data Fibs being sent
5199 + // if they exceed the throttle check.
5202 + if (!CommRegion->ThrottleActive) {
5205 + CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5208 + // Schedule a timer for the throttle active period. When
5209 + // it expires, we'll be called back at routine ThrottleDpcRoutine
5210 + // above. This will signify the throttle active period ended
5211 + // and any waiting threads will be signalled to restart.
5214 + FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5215 + CommRegion->ThrottleTimerSets++;
5216 + InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5217 + CommRegion->ThrottleTimeout,
5218 + &CommRegion->ThrottleDpc);
5219 + ASSERT(InQue == FALSE);
5226 + // Its a non-API fib, so subject to throttle checks.
5227 + // The following are exempt from throttling:
5228 + // o FIBs marked as "throttle exempt" by upper layers.
5229 + // o I/Os issued from a raised IRQL. We can't suspend
5230 + // a thread when at raised IRQL so throttling is exempt.
5233 + if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5235 + CommRegion->NonPassiveFibs++;
5236 + FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5241 + if (CommRegion->ThrottleActive) {
5244 + // Throttle is active.
5245 + // Check if the FIB is a read or write. If so, and its to the
5246 + // file system information area, let it through without throttling.
5249 + if (Fib->Header.Command == ContainerCommand) {
5250 + PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5253 + // *** Note *** We are using read and write command formats
5254 + // interchangably here. This is ok for this purpose as the
5255 + // command is in the same place for both. Read and write command
5256 + // formats are different at higher offsets though.
5259 + if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5260 + (BlockDisk->Command == VM_CtBlockWrite)) &&
5261 + (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5263 + CommRegion->FSInfoFibs++; // Keep statistics
5271 + // Throttle the FIB.
5272 + // Mark it as throttle active so that it can signal a waiter
5273 + // when it completes.
5275 + CommRegion->ThrottledFibs++;
5276 + Fib->Header.Flags |= ThrottledFib;
5279 + // Release the spinlock so we can wait the thread if necessary.
5280 + // Since we specify a timeout, check the caller is at passive level.
5283 + OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5285 + FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5287 + Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5288 + Executive, // Don't allow user APCs to wake us
5289 + KernelMode, // Wait in kernel mode
5290 + FALSE, // Not alertable
5291 + &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5294 + // Check the signal status. If we've timed out, clear the throttle
5295 + // flag on the FIB to avoid us signalling the semaphore on completion.
5296 + // We never acquired the semaphore.
5298 + if (Status == STATUS_TIMEOUT) {
5300 + CommRegion->ThrottleTimedoutFibs++;
5301 + FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5302 + Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5306 + ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5311 + // We've been woken up and can now send the FIB to the adapter.
5312 + // Acquire the spinlock again so we can get a queue entry. This
5313 + // returns to GetQueueEntry.
5316 + FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5317 + KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5318 + CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5324 +#endif //#ifdef API_THROTTLE
5326 +int GetQueueEntryTimeouts = 0;
5331 +Routine Description:
5333 + Gets the next free QE off the requested priorty adapter command queue and
5334 + associates the Fib with the QE. The QE represented by index is ready to
5335 + insert on the queue when this routine returns success.
5339 + Index is the returned value which represents the QE which is ready to
5340 + insert on the adapter's command queue.
5342 + Priority is an enumerated type which determines which priority level
5343 + command queue the QE is going to be queued on.
5345 + Fib is a pointer to the FIB the caller wishes to have associated with the
5348 + Wait is a boolean which determines if the routine will wait if there are
5349 + no free QEs on the requested priority command queue.
5351 + FibContext is where the driver stores all system resources required to execute the
5352 + command requested from the calling thread. This includes mapping resources for
5353 + the FIB and the 'users' buffer.
5355 + DontInterrupt - We set this true if the queue state is such that we don't
5356 + need to interrupt the adapter for this queue entry.
5360 + NT_SUCCESS if a Fib was returned to the caller.
5361 + NT_ERROR if event was an invalid event.
5365 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5366 + IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5367 + IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5369 + PQUEUE_ENTRY QueueEntry = NULL;
5370 + BOOLEAN MapAddress = FALSE;
5372 + AAC_STATUS Status;
5373 + PCOMM_REGION CommRegion;
5375 + CommRegion = Adapter->CommRegion;
5378 + // Get the spinlock for the queue we are putting a command on
5381 + if (WhichQueue == AdapHighCmdQueue)
5382 + OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5383 + else if (WhichQueue == AdapNormCmdQueue)
5384 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5385 + else if (WhichQueue == AdapHighRespQueue)
5386 + OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5387 + else if (WhichQueue == AdapNormRespQueue)
5388 + OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5390 + FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5391 + return(FSA_INVALID_QUEUE);
5395 + // Get the pointers to a queue entry on the queue the caller wishes to queue
5396 + // a command request on. If there are no entries then wait if that is what the
5397 + // caller requested.
5400 + if (WhichQueue == AdapHighCmdQueue) {
5401 + // if no entries wait for some if caller wants to
5402 + while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5403 + cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5407 + // Setup queue entry with a command, status and Fib mapped
5410 + QueueEntry->Size = Fib->Header.Size;
5411 + MapAddress = TRUE;
5413 + } else if (WhichQueue == AdapNormCmdQueue) {
5414 + // if no entries wait for some if caller wants to
5415 + while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5416 + cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5420 + // Setup queue entry with command, status and Fib mapped
5423 + QueueEntry->Size = Fib->Header.Size;
5424 + MapAddress = TRUE;
5426 + } else if (WhichQueue == AdapHighRespQueue) {
5428 + while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5432 + // Setup queue entry with command, status and Fib mapped
5435 + QueueEntry->Size = Fib->Header.Size;
5436 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5437 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5438 + MapAddress = FALSE;
5440 + } else if (WhichQueue == AdapNormRespQueue) {
5441 + while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5445 + // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5448 + QueueEntry->Size = Fib->Header.Size;
5449 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5450 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5451 + MapAddress = FALSE;
5455 + // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5459 + QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5466 + FsaCommPrint("Queue Entry contents:.\n");
5467 + FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5468 + FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5469 + FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5470 + FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5473 + return(FSA_SUCCESS);
5479 +Routine Description:
5481 + Gets the next free QE off the requested priorty adapter command queue and
5482 + associates the Fib with the QE. The QE represented by index is ready to
5483 + insert on the queue when this routine returns success.
5487 + Index is the returned value which represents the QE which is ready to
5488 + insert on the adapter's command queue.
5490 + WhichQueue tells us which queue the caller wishes to have the entry put.
5494 + NT_SUCCESS if a Fib was returned to the caller.
5495 + NT_ERROR if event was an invalid event.
5500 + IN PAFA_COMM_ADAPTER Adapter,
5501 + IN QUEUE_INDEX Index,
5502 + IN QUEUE_TYPES WhichQueue,
5503 + IN ULONG DontInterrupt
5506 + PCOMM_REGION CommRegion;
5508 + CommRegion = Adapter->CommRegion;
5511 + // We have already verified the queue in getentry, but we still have to make
5512 + // sure we don't wrap here too.
5515 + if (WhichQueue == AdapHighCmdQueue) {
5517 + *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5519 + OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5521 + if (!DontInterrupt)
5522 + NotifyAdapter(Adapter, AdapHighCmdQue);
5524 + } else if (WhichQueue == AdapNormCmdQueue) {
5527 + FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5529 + *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5531 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5533 + if (!DontInterrupt)
5534 + NotifyAdapter(Adapter, AdapNormCmdQue);
5536 + } else if (WhichQueue == AdapHighRespQueue) {
5538 + *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5540 + OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5542 + if (!DontInterrupt)
5543 + NotifyAdapter(Adapter, AdapHighRespQue);
5545 + } else if (WhichQueue == AdapNormRespQueue) {
5547 + *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5549 + OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5551 + if (!DontInterrupt)
5552 + NotifyAdapter(Adapter, AdapNormRespQue);
5555 + FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5556 + return(FSA_INVALID_QUEUE_PRIORITY);
5559 + return(FSA_SUCCESS);
5562 +extern int GatherFibTimes;
5567 + FIB_COMMAND Command,
5571 + USHORT *ResponseSize
5575 +Routine Description:
5577 + This routine will send a synchronous FIB to the adapter and wait for its
5582 + DeviceExtension - Pointer to adapter extension structure.
5591 + PAFA_COMM_ADAPTER Adapter = Arg;
5593 + ULONG returnStatus;
5595 + Fib = Adapter->SyncFib;
5597 + Fib->Header.StructType = TFib;
5598 + Fib->Header.Size = sizeof(FIB);
5599 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5600 + Fib->Header.ReceiverFibAddress = 0;
5601 + Fib->Header.SenderSize = sizeof(FIB);
5602 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5603 + Fib->Header.Command = Command;
5606 + // Copy the Data portion into the Fib.
5609 + RtlCopyMemory( Fib->data, Data, Size );
5612 + Fib->Header.XferState |= (SentFromHost | NormalPriority);
5615 + // Set the size of the Fib we want to send to the adapter
5618 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5620 + if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5621 + Adapter->SyncFibPhysicalAddress )) {
5628 + // Copy the response back to the caller's buffer.
5631 + RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5633 + *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5636 + // Indicate success
5643 +// Define the highest level of host to adapter communication routines. These
5644 +// routines will support host to adapter FS commuication. These routines have
5645 +// no knowledge of the commuication method used. This level sends and receives
5646 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5653 +Routine Description:
5655 + Sends the requested FIB to the adapter and optionally will wait for a
5656 + response FIB. If the caller does not wish to wait for a response than
5657 + an event to wait on must be supplied. This event will be set when a
5658 + response FIB is received from the adapter.
5662 + Fib is a pointer to the FIB the caller wishes to send to the adapter.
5664 + Size - Size of the data portion of the Fib.
5666 + Priority is an enumerated type which determines which priority level
5667 + the caller wishes to send this command at.
5669 + Wait is a boolean which determines if the routine will wait for the
5670 + completion Fib to be returned(TRUE), or return when the Fib has been
5671 + successfully received by the adapter(FALSE).
5673 + WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5674 + FIB has been returned by the adapter.
5676 + ReturnFib is an optional pointer to a FIB that if present the response FIB will
5681 + NT_SUCCESS if a Fib was returned to the caller.
5682 + NT_ERROR if event was an invalid event.
5686 +SendFib (IN FIB_COMMAND Command,
5687 + IN PFIB_CONTEXT Context,
5689 + IN COMM_PRIORITIES Priority,
5692 + IN BOOLEAN ResponseExpected,
5693 + IN PFIB_CALLBACK FibCallback,
5694 + IN PVOID FibCallbackContext)
5696 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5697 + QUEUE_INDEX Index;
5698 + QUEUE_TYPES WhichQueue;
5699 + LARGE_INTEGER Timeout;
5700 + AAC_STATUS Status;
5701 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5702 + ULONG DontInterrupt = FALSE;
5703 + PFIB Fib = FibContext->Fib;
5704 + IN PCOMM_QUE OurQueue;
5706 + Timeout = FsaCommData.AdapterTimeout;
5708 + if (!(Fib->Header.XferState & HostOwned)) {
5709 + FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5710 + FsaCommLogEvent(FibContext,
5711 + FsaCommData.DeviceObject,
5712 + FSAFS_FIB_INVALID,
5713 + STATUS_UNSUCCESSFUL,
5714 + BugCheckFileId | __LINE__,
5715 + FACILITY_FSAFS_ERROR_CODE,
5719 + return(STATUS_UNSUCCESSFUL);
5724 + // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5725 + // are if the caller requests to wait and does not request a response and if the
5726 + // caller does not want a response and the Fib is not allocated from pool. If a response
5727 + // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5728 + // comes back from the adapter. No further processing will be done besides deleting the
5729 + // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5730 + // and the host can log that fact.
5732 + if (Wait && !ResponseExpected) {
5734 + FsaCommLogEvent(FibContext,
5735 + FsaCommData.DeviceObject,
5736 + FSAFS_FIB_INVALID,
5737 + STATUS_UNSUCCESSFUL,
5738 + BugCheckFileId | __LINE__,
5739 + FACILITY_FSAFS_ERROR_CODE,
5743 + return(STATUS_UNSUCCESSFUL);
5745 + } else if (!Wait && ResponseExpected) {
5746 + Fib->Header.XferState |= (Async | ResponseExpected);
5747 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5748 + } else if (!Wait && !ResponseExpected) {
5749 + Fib->Header.XferState |= NoResponseExpected;
5750 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5751 + } else if (Wait && ResponseExpected) {
5752 + Fib->Header.XferState |= ResponseExpected;
5753 + FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5756 + Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5759 + // Set FIB state to indicate where it came from and if we want a response from the
5760 + // adapter. Also load the command from the caller.
5763 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5764 + Fib->Header.Command = Command;
5765 + Fib->Header.XferState |= SentFromHost;
5766 + FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5769 + // Set the size of the Fib we want to send to the adapter
5772 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5773 + if (Fib->Header.Size > Fib->Header.SenderSize) {
5774 + return(STATUS_BUFFER_OVERFLOW);
5778 + // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5781 + if (Priority == FsaHigh) {
5782 + Fib->Header.XferState |= HighPriority;
5783 + WhichQueue = AdapHighCmdQueue;
5784 + OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5786 + Fib->Header.XferState |= NormalPriority;
5787 + WhichQueue = AdapNormCmdQueue;
5788 + OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5792 + OsCvLockAcquire( FibContext->FsaEventMutex );
5795 + if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5796 + return(STATUS_UNSUCCESSFUL);
5800 + cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5801 + cmn_err (CE_DEBUG,"Fib contents:.\n");
5802 + cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5803 + cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5806 + // Fill in the Callback and CallbackContext if we are not going to wait.
5811 + FibContext->FibCallback = FibCallback;
5812 + FibContext->FibCallbackContext = FibCallbackContext;
5816 + FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5818 + InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5819 + OurQueue->NumOutstandingIos++;
5821 + FibContext->FibComplete = 0;
5825 + if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5826 + return(STATUS_UNSUCCESSFUL);
5829 + // If the caller wanted us to wait for response wait now.
5830 + // If Timeouts are enabled than set the timeout otherwise wait forever.
5834 + while (FibContext->FibComplete == 0) {
5835 + OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5838 + OsCvLockRelease( FibContext->FsaEventMutex );
5840 + if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5841 + return(STATUS_IO_TIMEOUT);
5843 + return(STATUS_SUCCESS);
5848 + // If the user does not want a response than return success otherwise return pending
5851 + ASSERT( FibCallback );
5853 + if (ResponseExpected)
5854 + return(STATUS_PENDING);
5856 + return(STATUS_SUCCESS);
5861 + IN PAFA_COMM_ADAPTER Adapter,
5862 + PCOMM_QUE OurQueue,
5863 + OUT PQUEUE_ENTRY *Entry
5867 +Routine Description:
5869 + Will return a pointer to the entry on the top of the queue requested that we are a consumer
5870 + of, and return the address of the queue entry. It does not change the state of the queue.
5874 + OurQueue - is the queue the queue entry should be removed from.
5876 + Entry - is a pointer where the address of the queue entry should be returned.
5880 + TRUE if there was a queue entry on the response queue for the host to consume.
5881 + FALSE if there were no queue entries to consume.
5886 + QUEUE_INDEX Index;
5889 + if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5894 + // The consumer index must be wrapped if we have reached the end of
5896 + // Else we just use the entry pointed to by the header index
5899 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5902 + Index = *OurQueue->Headers.ConsumerIndex;
5904 + *Entry = OurQueue->BaseAddress + Index;
5907 + FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5916 +ConsumerEntryAvailable(
5917 + IN PAFA_COMM_ADAPTER Adapter,
5918 + PCOMM_QUE OurQueue
5921 + return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
5926 + IN PAFA_COMM_ADAPTER Adapter,
5927 + PCOMM_QUE OurQueue,
5928 + QUEUE_TYPES WhichQueue
5932 +Routine Description:
5934 + Frees up the current top of the queue we are a consumer of. If the queue was full
5935 + notify the producer that the queue is no longer full.
5939 + OurQueue - is the queue we will free the current consumer entry on.
5943 + TRUE if there was a queue entry on the response queue for the host to consume.
5944 + FALSE if there were no queue entries to consume.
5949 + BOOLEAN WasFull = FALSE;
5950 + HOST_2_ADAP_EVENT Notify;
5952 + if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
5955 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5956 + *OurQueue->Headers.ConsumerIndex = 1;
5958 + *OurQueue->Headers.ConsumerIndex += 1;
5961 + switch (WhichQueue) {
5963 + case HostNormCmdQueue:
5964 + Notify = HostNormCmdNotFull;
5966 + case HostHighCmdQueue:
5967 + Notify = HostHighCmdNotFull;
5970 + case HostNormRespQueue:
5971 + Notify = HostNormRespNotFull;
5974 + case HostHighRespQueue:
5975 + Notify = HostHighRespNotFull;
5979 + NotifyAdapter(Adapter, Notify);
5985 +CompleteAdapterFib(
5986 + IN PFIB_CONTEXT Context,
5991 +Routine Description:
5993 + Will do all necessary work to complete a FIB that was sent from the adapter.
5997 + Fib is a pointer to the FIB that caller wishes to complete processing on.
5999 + Size - Size of the completion Packet(Opitional). If not present than the current
6000 + largest size in the Fib will be used
6002 + Adapter - Pointer to which adapter sent this FIB
6006 + NT_SUCCESS if a Fib was returned to the caller.
6007 + NT_ERROR if event was an invalid event.
6011 + PCOMM_FIB_CONTEXT FibContext = Context;
6012 + PFIB Fib = FibContext->Fib;
6013 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6014 + ULONG DontInterrupt = FALSE;
6016 + if (Fib->Header.XferState == 0)
6017 + return(STATUS_SUCCESS);
6020 + // If we plan to do anything check the structure type first.
6023 + if ( Fib->Header.StructType != TFib ) {
6024 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6025 + return(STATUS_UNSUCCESSFUL);
6029 + // This block handles the case where the adapter had sent us a command and we
6030 + // have finished processing the command. We call completeFib when we are done
6031 + // processing the command and want to send a response back to the adapter. This
6032 + // will send the completed cdb to the adapter.
6035 + if (Fib->Header.XferState & SentFromAdapter) {
6036 + Fib->Header.XferState |= HostProcessed;
6037 + if (Fib->Header.XferState & HighPriority) {
6038 + QUEUE_INDEX Index;
6041 + Size += sizeof(FIB_HEADER);
6042 + if (Size > Fib->Header.SenderSize)
6043 + return(STATUS_BUFFER_OVERFLOW);
6044 + Fib->Header.Size = Size;
6047 + if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6048 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6049 + return(FSA_FATAL);
6051 + if (InsertQueueEntry(Adapter,
6053 + AdapHighRespQueue,
6054 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6055 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6057 + } else if (Fib->Header.XferState & NormalPriority) {
6058 + QUEUE_INDEX Index;
6061 + Size += sizeof(FIB_HEADER);
6062 + if (Size > Fib->Header.SenderSize)
6063 + return(STATUS_BUFFER_OVERFLOW);
6064 + Fib->Header.Size = Size;
6067 + if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6068 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6069 + return(FSA_FATAL);
6071 + if (InsertQueueEntry(Adapter,
6073 + AdapNormRespQueue,
6074 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6075 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6079 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6080 + FsaBugCheck(0,0,0);
6082 + return(STATUS_SUCCESS);
6087 + IN PFIB_CONTEXT Context
6091 +Routine Description:
6093 + Will do all necessary work to complete a FIB. If the caller wishes to
6094 + reuse the FIB after post processing has been completed Reinitialize
6095 + should be called set to TRUE, otherwise the FIB will be returned to the
6096 + free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6097 + reinitialzied and is ready for reuse on return from this routine.
6101 + Fib is a pointer to the FIB that caller wishes to complete processing on.
6103 + Size - Size of the completion Packet(Opitional). If not present than the current
6104 + largest size in the Fib will be used
6106 + Reinitialize is a boolean which determines if the routine will ready the
6107 + completed FIB for reuse(TRUE) or not(FALSE).
6111 + NT_SUCCESS if a Fib was returned to the caller.
6112 + NT_ERROR if event was an invalid event.
6116 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6117 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6118 + PFIB Fib = FibContext->Fib;
6121 + // Check for a fib which has already been completed
6124 +// ASSERT(Fib->Header.XferState & AdapterProcessed);
6125 + if (Fib->Header.XferState == 0)
6126 + return(STATUS_SUCCESS);
6129 + // If we plan to do anything check the structure type first.
6132 + if ( Fib->Header.StructType != TFib ) {
6133 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6134 + return(STATUS_UNSUCCESSFUL);
6138 +//#if FSA_ADAPTER_METER
6140 + // Meter the completion
6142 + fsaMeterEnd( // meter the end of an operation
6143 + &(Adapter->FibMeter), // .. the meter
6144 + IrpContext->FibMeterType, // .. type of operation
6145 + &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6146 + FibGetMeterSize(Fib, // .. number of bytes in operation
6147 + IrpContext->FibMeterType,
6148 + IrpContext->FibSubCommand));
6149 +#endif // FSA_ADAPTER_METER
6152 + // This block completes a cdb which orginated on the host and we just need
6153 + // to deallocate the cdb or reinit it. At this point the command is complete
6154 + // that we had sent to the adapter and this cdb could be reused.
6157 + if ( (Fib->Header.XferState & SentFromHost) &&
6158 + (Fib->Header.XferState & AdapterProcessed)) {
6160 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6162 + return( DeallocateFib(FibContext) );
6165 + // This handles the case when the host has aborted the I/O to the
6166 + // adapter because the adapter is not responding
6169 + } else if (Fib->Header.XferState & SentFromHost) {
6171 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6174 + return( DeallocateFib(FibContext) );
6176 + } else if (Fib->Header.XferState & HostOwned) {
6178 + return(DeallocateFib(FibContext));
6181 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6182 + FsaBugCheck(0,0,0);
6184 + return(STATUS_SUCCESS);
6189 + IN PAFA_COMM_ADAPTER Adapter,
6190 + IN PCOMM_FIB_CONTEXT FibContext
6194 +Routine Description:
6196 + This routine handles a driver notify fib from the adapter and dispatches it to
6197 + the appropriate routine for handling.
6201 + Adapter - Which adapter this fib is from
6202 + FibContext - Pointer to FibContext from adapter.
6210 + PFIB Fib = FibContext->Fib;
6211 + PAFA_CLASS_DRIVER ClassDriver;
6212 + BOOLEAN Handled = FALSE;
6216 + // First loop through all of the class drivers to give them a chance to handle
6220 + ClassDriver = Adapter->ClassDriverList;
6222 + while (ClassDriver) {
6224 + if (ClassDriver->HandleAif) {
6226 + if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6234 + ClassDriver = ClassDriver->Next;
6240 + // Set the status of this FIB to be Invalid parameter.
6243 +// *(FSASTATUS *)Fib->data = ST_INVAL;
6244 + *(FSASTATUS *)Fib->data = ST_OK;
6247 + CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6254 + IN PAFA_COMM_ADAPTER Adapter
6258 +Routine Description:
6260 + Waits on the commandready event in it's queue. When the event gets set it will
6261 + pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6262 + When the queue is empty it will wait for more FIBs.
6266 + Context is used. All data os global
6274 + COMM_FIB_CONTEXT FibContext; // for error logging
6276 + PCOMM_REGION CommRegion = Adapter->CommRegion;
6277 + PLIST_ENTRY Entry;
6278 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6281 + // We can only have one thread per adapter for AIF's.
6284 + if (Adapter->AifThreadStarted) {
6288 +// cmn_err(CE_DEBUG, "AIF thread started");
6291 + // Let the DPC know it has a place to send the AIF's to.
6294 + Adapter->AifThreadStarted = TRUE;
6296 + RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6298 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6303 + // NOTE : the QueueLock is held at the top of each loop.
6306 + ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6308 + while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6309 + PLIST_ENTRY Entry;
6310 + PAIFCOMMANDTOHOST AifCommandToHost;
6312 + Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6314 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6316 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6319 + // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6320 + // can't do anything at this point since we don't have anything defined for this thread to
6324 + // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6326 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6329 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6330 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6331 + FibContext.Fib = Fib;
6332 + FibContext.FibData = Fib->data;
6333 + FibContext.Adapter = Adapter;
6337 + // We only handle AifRequest fibs from the adapter.
6340 + ASSERT(Fib->Header.Command == AifRequest);
6343 + AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6345 + if (AifCommandToHost->command == AifCmdDriverNotify) {
6349 + HandleDriverAif( Adapter, &FibContext );
6352 + AAC_UINT32 time_now, time_last;
6353 + time_now = (AAC_UINT32)OsGetSeconds();
6356 + OsCvLockAcquire(Adapter->AdapterFibMutex);
6358 + Entry = Adapter->AdapterFibContextList.Flink;
6361 + // For each Context that is on the AdapterFibContextList, make a copy of the
6362 + // fib, and then set the event to wake up the thread that is waiting for it.
6365 + while (Entry != &Adapter->AdapterFibContextList) {
6368 + // Extract the AdapterFibContext
6371 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6374 + // Check if the queue is getting backlogged
6376 + if ( AdapterFibContext->FibCount > 20 ) {
6377 + time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6380 + // has it been > 2 minutes since the last read off the queue?
6382 + if ((time_now - time_last) > 120) {
6383 + Entry = Entry->Flink;
6384 + // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6385 + // time_now - time_last,
6386 + // AdapterFibContext->FibCount);
6387 + FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6392 +// Warning: sleep possible while holding spinlock
6393 + NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6398 + // Make the copy of the FIB
6401 + RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6404 + // Put the FIB onto the AdapterFibContext's FibList
6407 + InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6408 + AdapterFibContext->FibCount++;
6411 + // Set the event to wake up the thread that will waiting.
6414 + OsCv_signal(&AdapterFibContext->UserEvent);
6421 + Entry = Entry->Flink;
6425 + // Set the status of this FIB
6428 + *(FSASTATUS *)Fib->data = ST_OK;
6430 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6432 + OsCvLockRelease(Adapter->AdapterFibMutex);
6436 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6441 + // There are no more AIF's, call cv_wait_sig to wait for more
6445 + // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6447 + if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6448 + CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6450 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6452 + Adapter->AifThreadStarted = FALSE;
6454 + // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6460 + // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6468 + IN PFIB_CONTEXT Context
6471 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6473 + return ((PVOID)FibContext->Fib->data);
6477 +#ifdef API_THROTTLE
6479 +void ThrottlePeriodEndDpcRtn(
6481 + IN PVOID DeferredContext,
6482 + IN PVOID SystemArgument1,
6483 + IN PVOID SystemArgument2
6487 +Routine Description:
6489 + This routine is called as a DPC when a throttle period expires. It
6490 + restarts all threads suspended due to the throttling flow control.
6492 + The throttling counted semaphore is signalled for all waiting threads
6493 + and the indicator of throttling active is cleared.
6497 + Dpc - Pointer to Dpc structure. Not used.
6498 + DefferedContext - Pointer to per-adapter context. This is used to locate the
6499 + throttle information for this adapter.
6500 + SystemArgument1 - Not used
6501 + SystemArgument2 - Not used
6509 + PCOMM_REGION CommRegion;
6510 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6512 + CommRegion = Adapter->CommRegion;
6515 + // Acquire the spinlock protecting the throttle status.
6517 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6519 + FsaCommPrint("ThrottlePeriodEndDpc\n");
6522 + // Check that the timer has fired as many times as it was set !
6525 + CommRegion->ThrottleTimerFires++;
6526 + ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6529 + // The throttle period is now over. Restart all threads waiting
6530 + // on the throttle being released.
6531 + // Clear the throttle active indicator. This will allow new FIBs
6532 + // to be sent to the adapter once we release the spinlock on exiting
6533 + // the DPC. This means all restarted threads will be runnable
6534 + // threads by then.
6537 + ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6538 + CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6540 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6543 +#endif // #ifdef API_THROTTLE
6546 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6547 + * Emacs will notice this stuff at the end of the file and automatically
6548 + * adjust the settings for this buffer only. This must remain at the end
6550 + * ---------------------------------------------------------------------------
6551 + * Local variables:
6552 + * c-indent-level: 4
6553 + * c-brace-imaginary-offset: 0
6554 + * c-brace-offset: -4
6555 + * c-argdecl-indent: 4
6556 + * c-label-offset: -4
6557 + * c-continued-statement-offset: 4
6558 + * c-continued-brace-offset: 0
6559 + * indent-tabs-mode: nil
6563 diff -urN linux/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6564 --- linux/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 19:00:00 1969
6565 +++ linux/drivers/scsi/aacraid/dpcsup.c Thu Dec 21 13:14:30 2000
6568 + * Adaptec aacraid device driver for Linux.
6570 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6572 + * This program is free software; you can redistribute it and/or modify
6573 + * it under the terms of the GNU General Public License as published by
6574 + * the Free Software Foundation; either version 2, or (at your option)
6575 + * any later version.
6577 + * This program is distributed in the hope that it will be useful,
6578 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6579 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6580 + * GNU General Public License for more details.
6582 + * You should have received a copy of the GNU General Public License
6583 + * along with this program; see the file COPYING. If not, write to
6584 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6589 + * Abstract: All DPC processing routines for the cyclone board occur here.
6594 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6596 +#include "comprocs.h"
6600 +// The Bug check file id for this module
6603 +#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6605 +#define Dbg (DEBUG_TRACE_DPCSUP)
6609 + IN PCOMM_REGION CommRegion
6613 +Routine Description:
6615 + This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6616 + no longer full. The Isr will pass the queue that we will set the not full event.
6620 + Dpc - Pointer to this routine.
6622 + Dummy - is a pointer to the comm region which is global so we don't need it anyway
6624 + Queue is a pointer to the queue structure we will operate on.
6626 + MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6635 +#ifdef unix_queue_full
6636 + KeSetEvent(&Queue->QueueFull, 0, FALSE);
6641 +int GatherFibTimes = 0;
6643 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6654 +Routine Description:
6656 + This DPC routine will be queued when the adapter interrupts us to let us know there
6657 + is a response on our normal priority queue. We will pull off all QE there are and wake
6658 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6663 + Dpc - Pointer to this routine.
6665 + OurQueue is a pointer to the queue structure we will operate on.
6667 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6675 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6677 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6678 + PQUEUE_ENTRY QueueEntry;
6680 + PCOMM_FIB_CONTEXT FibContext;
6684 + LARGE_INTEGER ResponseAllocSize;
6687 + FsaCommPrint("entering the host normal reponse dpc routine.\n");
6690 + OsSpinLockAcquire( OurQueue->QueueLock );
6693 + // Keep pulling response QEs off the response queue and waking
6694 + // up the waiters until there are no more QEs. We then return
6695 + // back to the system. If no response was requesed we just
6696 + // deallocate the Fib here and continue.
6700 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6702 + int IsFastResponse;
6704 + IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6705 + Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6707 + FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6709 + FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6711 + ASSERT(FibContext->Fib == Fib);
6714 + // Remove this FibContext from the Outstanding I/O queue.
6715 + // But only if it has not already been timed out.
6717 + // If the fib has been timed out already, then just continue.
6718 + // The caller has already been notified that the fib timed out.
6721 + if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6723 + RemoveEntryList( &FibContext->QueueEntry );
6724 + Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6728 + FsaCommLogEvent(FibContext,
6729 + FsaCommData.DeviceObject,
6730 + FSAFS_TIMED_OUT_FIB_COMPLETED,
6731 + STATUS_UNSUCCESSFUL,
6732 + BugCheckFileId | __LINE__,
6733 + FACILITY_FSAFS_ERROR_CODE,
6741 + OsSpinLockRelease( OurQueue->QueueLock );
6743 + if (IsFastResponse) {
6749 + *(FSASTATUS *)Fib->data = ST_OK;
6751 + Fib->Header.XferState |= AdapterProcessed;
6755 + ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6757 + FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6759 + ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6762 + if (Fib->Header.Command == NuFileSystem) {
6764 + FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6766 + if (*pStatus & 0xffff0000) {
6768 + ULONG Hint = *pStatus;
6773 + DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6774 + IrpContext->NonPaged->FileId.fid_driveno,
6775 + IrpContext->NonPaged->FileId.fid_f1,
6776 + IrpContext->NonPaged->FileId.fid_f2,
6777 + IrpContext->NonPaged->FileId.fid_hint,
6785 + if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6787 + ASSERT(FibContext->FibCallback);
6789 + if (Fib->Header.XferState & NoResponseExpected)
6790 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6792 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6795 + // NOTE: we can not touch the FibContext after this call, because it may have been
6799 + FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6803 + OsCvLockAcquire( FibContext->FsaEventMutex);
6805 + FibContext->FibComplete = 1;
6807 + OsCv_signal( &FibContext->FsaEvent );
6809 + OsCvLockRelease( FibContext->FsaEventMutex );
6811 + FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6818 + OsSpinLockAcquire( OurQueue->QueueLock );
6822 + if (Consumed > FsaCommData.PeakFibsConsumed)
6823 + FsaCommData.PeakFibsConsumed = Consumed;
6825 + if (Consumed == 0)
6826 + FsaCommData.ZeroFibsConsumed++;
6828 + if (FsaCommData.HardInterruptModeration) {
6831 + // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6832 + // been put on the queue. This removes the race condition that exists between the
6833 + // last time we checked the queue, and when we re-enabled the interrupt.
6835 + // If there is something on the queue, then go handle it.
6838 + EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6840 + if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6842 + DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6850 + FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6853 + OsSpinLockRelease( OurQueue->QueueLock );
6859 +Routine Description:
6861 + This DPC routine wiol be queued when the adapter interrupts us to let us know there
6862 + is a response on our high priority queue. We will pull off all QE there are and wake
6863 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6868 + Dpc - Pointer to this routine.
6870 + OurQueue is a pointer to the queue structure we will operate on.
6872 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6880 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6886 +Routine Description:
6888 + This DPC routine will be queued when the adapter interrupts us to let us know there
6889 + is a command on our high priority queue. We will pull off all QE there are and wake
6890 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6895 + Dpc - Pointer to this routine.
6897 + OurQueue is a pointer to the queue structure we will operate on.
6899 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6907 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6913 +Routine Description:
6915 + This DPC routine will be queued when the adapter interrupts us to let us know there
6916 + is a command on our normal priority queue. We will pull off all QE there are and wake
6917 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6922 + Dpc - Pointer to this routine.
6924 + OurQueue is a pointer to the queue structure we will operate on.
6926 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6934 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
6936 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6937 + PQUEUE_ENTRY QueueEntry;
6939 + OsSpinLockAcquire( OurQueue->QueueLock );
6942 + // Keep pulling response QEs off the response queue and waking
6943 + // up the waiters until there are no more QEs. We then return
6944 + // back to the system.
6947 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6951 + Fib = (PFIB)QueueEntry->FibAddress;
6954 + if (Adapter->AifThreadStarted) {
6957 +// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
6960 + InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
6961 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
6962 + OsCv_signal(&OurQueue->CommandReady);
6970 + COMM_FIB_CONTEXT FibContext;
6974 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
6978 + OsSpinLockRelease( OurQueue->QueueLock );
6982 +// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
6985 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6987 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6988 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6989 + FibContext.Fib = Fib;
6990 + FibContext.FibData = Fib->data;
6991 + FibContext.Adapter = Adapter;
6994 + // Set the status of this FIB
6997 + *(FSASTATUS *)Fib->data = ST_OK;
6999 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7003 + OsSpinLockAcquire( OurQueue->QueueLock );
7007 + OsSpinLockRelease( OurQueue->QueueLock );
7010 diff -urN linux/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7011 --- linux/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 19:00:00 1969
7012 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Thu Dec 21 13:14:30 2000
7015 + * Adaptec aacraid device driver for Linux.
7017 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7019 + * This program is free software; you can redistribute it and/or modify
7020 + * it under the terms of the GNU General Public License as published by
7021 + * the Free Software Foundation; either version 2, or (at your option)
7022 + * any later version.
7024 + * This program is distributed in the hope that it will be useful,
7025 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7026 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7027 + * GNU General Public License for more details.
7029 + * You should have received a copy of the GNU General Public License
7030 + * along with this program; see the file COPYING. If not, write to
7031 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7035 + * AacGenericTypes.h
7039 + * The module defines the generic data types that all of the other header files
7043 +#ifndef _AAC_GENERIC_TYPES
7044 +#define _AAC_GENERIC_TYPES
7046 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7048 +typedef char AAC_INT8, *PAAC_INT8;
7049 +typedef short AAC_INT16, *PAAC_INT16;
7050 +typedef int AAC_INT32, *PAAC_INT32;
7051 +typedef long long AAC_INT64, *PAAC_INT64;
7053 +typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7054 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7055 +typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7056 +typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7058 +typedef void AAC_VOID, *PAAC_VOID;
7061 +// this compiler uses 32 bit enum data types
7064 +#define AAC_32BIT_ENUMS 1
7066 +#define INTR_UNCLAIMED 1
7067 +#define INTR_CLAIMED 0
7069 +#endif // _AAC_GENERIC_TYPES
7071 diff -urN linux/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7072 --- linux/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 19:00:00 1969
7073 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Thu Dec 21 13:14:30 2000
7076 + * Adaptec aacraid device driver for Linux.
7078 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7080 + * This program is free software; you can redistribute it and/or modify
7081 + * it under the terms of the GNU General Public License as published by
7082 + * the Free Software Foundation; either version 2, or (at your option)
7083 + * any later version.
7085 + * This program is distributed in the hope that it will be useful,
7086 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7087 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7088 + * GNU General Public License for more details.
7090 + * You should have received a copy of the GNU General Public License
7091 + * along with this program; see the file COPYING. If not, write to
7092 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7100 + * Macro definition and typedefs
7104 +#ifndef _AAC_UNIX_DEFS
7105 +#define _AAC_UNIX_DEFS
7107 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7109 +#define AAC_MAX_ADAPTERS 64
7116 +#define PAGE_SIZE 4096
7119 +typedef VOID *PVOID;
7121 +typedef char CHAR, *PCHAR;
7122 +typedef unsigned char UCHAR, *PUCHAR;
7123 +typedef short SHORT, *PSHORT;
7124 +typedef short CSHORT, *PCSHORT;
7125 +typedef unsigned short USHORT, *PUSHORT;
7126 +typedef unsigned long ULONG, *PULONG;
7127 +typedef long LONG, *PLONG;
7129 +typedef unsigned long BOOLEAN;
7131 +typedef unsigned long AAC_STATUS, *PNT_STATUS;
7134 + unsigned long LowPart;
7135 + unsigned long HighPart;
7138 +typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7141 +typedef struct _AFA_IOCTL_CMD {
7147 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7151 +// Singly linked list structure. Can be used as either a list head, or
7155 +typedef struct _SINGLE_LIST_ENTRY {
7156 + struct _SINGLE_LIST_ENTRY *Next;
7157 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7161 +// Calculate the address of the base of the structure given its type, and an
7162 +// address of a field within the structure.
7165 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7166 + (PCHAR)(address) - \
7167 + (PCHAR)(&((type *)0)->field)))
7169 +typedef PVOID PMDL;
7170 +typedef PVOID PDEVICE_OBJECT;
7171 +typedef PVOID PADAPTER_OBJECT;
7172 +typedef ULONG KIRQL;
7173 +typedef PVOID HANDLE;
7174 +typedef PVOID KDPC, *PKDPC;
7175 +typedef PVOID PFILE_OBJECT;
7176 +typedef PVOID PIRP;
7177 +typedef PVOID PDRIVER_OBJECT;
7178 +typedef ULONG KTIMER;
7181 +#define STATUS_SUCCESS 0x00000000
7182 +#define STATUS_PENDING 0x40000001
7183 +#define STATUS_IO_TIMEOUT 0xc0000001
7184 +#define STATUS_UNSUCCESSFUL 0xc0000002
7185 +#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7186 +#define STATUS_BUFFER_OVERFLOW 0xc0000003
7194 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7200 +typedef struct _ZONE_SEGMENT_HEADER {
7201 + SINGLE_LIST_ENTRY SegmentList;
7203 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7205 +typedef struct _ZONE_HEADER {
7206 + SINGLE_LIST_ENTRY FreeList;
7207 + SINGLE_LIST_ENTRY SegmentList;
7209 + ULONG TotalSegmentSize;
7210 +} ZONE_HEADER, *PZONE_HEADER;
7216 +// ExAllocateFromZone(
7217 +// IN PZONE_HEADER Zone
7220 +// Routine Description:
7222 +// This routine removes an entry from the zone and returns a pointer to it.
7226 +// Zone - Pointer to the zone header controlling the storage from which the
7227 +// entry is to be allocated.
7231 +// The function value is a pointer to the storage allocated from the zone.
7235 +#define ExAllocateFromZone(Zone) \
7236 + (PVOID)((Zone)->FreeList.Next); \
7237 + if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7243 +// IN PZONE_HEADER Zone,
7247 +// Routine Description:
7249 +// This routine places the specified block of storage back onto the free
7250 +// list in the specified zone.
7254 +// Zone - Pointer to the zone header controlling the storage to which the
7255 +// entry is to be inserted.
7257 +// Block - Pointer to the block of storage to be freed back to the zone.
7261 +// Pointer to previous block of storage that was at the head of the free
7262 +// list. NULL implies the zone went from no available free blocks to
7263 +// at least one free block.
7267 +#define ExFreeToZone(Zone,Block) \
7268 + ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7269 + (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7270 + ((PSINGLE_LIST_ENTRY)(Block))->Next \
7277 +// IN PZONE_HEADER Zone
7280 +// Routine Description:
7282 +// This routine determines if the specified zone is full or not. A zone
7283 +// is considered full if the free list is empty.
7287 +// Zone - Pointer to the zone header to be tested.
7291 +// TRUE if the zone is full and FALSE otherwise.
7295 +#define ExIsFullZone(Zone) \
7296 + ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7299 +#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7300 +#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7303 +// Doubly-linked list manipulation routines. Implemented as macros
7304 +// but logically these are procedures.
7309 +// InitializeListHead(
7310 +// PLIST_ENTRY ListHead
7314 +#define InitializeListHead(ListHead) (\
7315 + (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7320 +// PLIST_ENTRY ListHead
7324 +#define IsListEmpty(ListHead) \
7325 + ((ListHead)->Flink == (ListHead))
7330 +// PLIST_ENTRY ListHead
7334 +#define RemoveHeadList(ListHead) \
7335 + (ListHead)->Flink;\
7336 + {RemoveEntryList((ListHead)->Flink)}
7341 +// RemoveEntryList(
7342 +// PLIST_ENTRY Entry
7346 +#define RemoveEntryList(Entry) {\
7347 + PLIST_ENTRY _EX_Blink;\
7348 + PLIST_ENTRY _EX_Flink;\
7349 + _EX_Flink = (Entry)->Flink;\
7350 + _EX_Blink = (Entry)->Blink;\
7351 + _EX_Blink->Flink = _EX_Flink;\
7352 + _EX_Flink->Blink = _EX_Blink;\
7358 +// PLIST_ENTRY ListHead,
7359 +// PLIST_ENTRY Entry
7363 +#define InsertTailList(ListHead,Entry) {\
7364 + PLIST_ENTRY _EX_Blink;\
7365 + PLIST_ENTRY _EX_ListHead;\
7366 + _EX_ListHead = (ListHead);\
7367 + _EX_Blink = _EX_ListHead->Blink;\
7368 + (Entry)->Flink = _EX_ListHead;\
7369 + (Entry)->Blink = _EX_Blink;\
7370 + _EX_Blink->Flink = (Entry);\
7371 + _EX_ListHead->Blink = (Entry);\
7374 +#endif /* AAC_UNIX_DEFS */
7375 diff -urN linux/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7376 --- linux/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 19:00:00 1969
7377 +++ linux/drivers/scsi/aacraid/include/adapter.h Thu Dec 21 13:14:30 2000
7380 + * Adaptec aacraid device driver for Linux.
7382 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7384 + * This program is free software; you can redistribute it and/or modify
7385 + * it under the terms of the GNU General Public License as published by
7386 + * the Free Software Foundation; either version 2, or (at your option)
7387 + * any later version.
7389 + * This program is distributed in the hope that it will be useful,
7390 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7391 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7392 + * GNU General Public License for more details.
7394 + * You should have received a copy of the GNU General Public License
7395 + * along with this program; see the file COPYING. If not, write to
7396 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7403 + * The module contains the definitions for a comm layer view of the adapter.
7412 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7414 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7416 + NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7417 + NODE_BYTE_SIZE NodeByteSize;
7418 + PFILE_OBJECT FileObject; // used for cleanup
7419 + LIST_ENTRY NextContext; // used to link context's into a linked list
7420 + OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7421 + BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7422 + ULONG FibCount; // total number of FIBs on FibList
7423 + LIST_ENTRY FibList;
7424 +} GET_ADAPTER_FIB_CONTEXT;
7425 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7428 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7430 + struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7431 + ULONG FibContextSegmentSize;
7432 + PVOID FibContextSegment;
7434 + MAPFIB_CONTEXT MapFibContext;
7436 +} FIB_CONTEXT_ZONE_SEGMENT;
7437 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7439 +typedef struct _AFA_COMM_ADAPTER {
7441 + struct _AFA_COMM_ADAPTER *NextAdapter;
7444 + // The following fields are used to allocate FIB context structures
7445 + // using the zone allocator, and other fixed sized structures from a
7446 + // small cache. The mutex protects access to the zone/lists
7449 + ZONE_HEADER FibContextZone;
7450 + OS_SPINLOCK *FibContextZoneSpinLock;
7451 + int FibContextZoneExtendSize;
7453 + PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7455 + PVOID FibContextTimedOutList;
7458 + ULONG SyncFibPhysicalAddress;
7460 + PCOMM_REGION CommRegion;
7462 + OS_SPINLOCK_COOKIE SpinLockCookie;
7465 + // The user API will use an IOCTL to register itself to receive FIBs
7466 + // from the adapter. The following list is used to keep track of all
7467 + // the threads that have requested these FIBs. The mutex is used to
7468 + // synchronize access to all data associated with the adapter fibs.
7470 + LIST_ENTRY AdapterFibContextList;
7471 + OS_CVLOCK *AdapterFibMutex;
7474 + // The following holds which FileObject is allow to send configuration
7475 + // commands to the adapter that would modify the configuration.
7477 + // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7480 + PFILE_OBJECT AdapterConfigFileObject;
7483 + // The following is really here because of the simulator
7485 + BOOLEAN InterruptsBelowDpc;
7488 + // The following is the device specific extension.
7490 + PVOID AdapterExtension;
7491 + PFSAPORT_FUNCS AdapterFuncs;
7495 + // The following are user variables that are specific to the mini port.
7497 + PFSA_USER_VAR AdapterUserVars;
7498 + ULONG AdapterUserVarsSize;
7501 + // The following is the number of the individual adapter..i.e. \Device\Afa0
7503 + LONG AdapterNumber;
7505 + AFACOMM_FUNCS CommFuncs;
7507 + PAFA_CLASS_DRIVER ClassDriverList;
7509 + BOOLEAN AifThreadStarted;
7511 +} AFA_COMM_ADAPTER;
7513 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7516 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7517 + Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7519 +#define FsaFreeAdapterCommArea(Adapter) \
7520 + Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7523 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7524 + Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7526 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7527 + Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7529 +#define InterruptAdapter(Adapter) \
7530 + Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7532 +#define NotifyAdapter(Adapter, AdapterEvent) \
7533 + Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7535 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7536 + Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7538 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7539 + Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7542 +#endif // _ADAPTER_
7543 diff -urN linux/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7544 --- linux/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 19:00:00 1969
7545 +++ linux/drivers/scsi/aacraid/include/afacomm.h Thu Dec 21 13:14:30 2000
7548 + * Adaptec aacraid device driver for Linux.
7550 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7552 + * This program is free software; you can redistribute it and/or modify
7553 + * it under the terms of the GNU General Public License as published by
7554 + * the Free Software Foundation; either version 2, or (at your option)
7555 + * any later version.
7557 + * This program is distributed in the hope that it will be useful,
7558 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7559 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7560 + * GNU General Public License for more details.
7562 + * You should have received a copy of the GNU General Public License
7563 + * along with this program; see the file COPYING. If not, write to
7564 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7570 + * This module defines all of the external interfaces to the AFA comm layer.
7578 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7580 +#include "fsaport.h"
7582 +typedef void *PFIB_CONTEXT;
7586 + PVOID FibCallbackContext,
7587 + PFIB_CONTEXT FibContext,
7592 +typedef PFIB_CONTEXT
7593 +(*PAFA_COMM_ALLOCATE_FIB) (
7594 + IN PVOID AdapterExtension
7598 +(*PAFA_COMM_FREE_FIB) (
7599 + IN PFIB_CONTEXT FibContext
7604 +(*PAFA_COMM_DEALLOCATE_FIB) (
7605 + IN PFIB_CONTEXT FibContext
7610 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7611 + IN PFIB_CONTEXT FibContext
7615 +(*PAFA_COMM_INITIALIZE_FIB) (
7616 + IN PFIB_CONTEXT FibContext
7620 +(*PAFA_COMM_GET_FIB_DATA) (
7621 + IN PFIB_CONTEXT FibContext
7625 +(*PAFA_COMM_SEND_FIB) (
7626 + IN FIB_COMMAND Command,
7627 + IN PFIB_CONTEXT FibContext,
7629 + IN COMM_PRIORITIES Priority,
7632 + IN BOOLEAN ResponseExpected,
7633 + IN PFIB_CALLBACK FibCallback,
7634 + IN PVOID FibCallbackContext
7638 +(*PAFA_COMM_COMPLETE_FIB) (
7639 + IN PFIB_CONTEXT FibContext
7643 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7644 + IN PFIB_CONTEXT FibContext,
7649 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7650 + PVOID AdapterExtension,
7651 + FIB_COMMAND Command,
7655 + USHORT *ResponseSize
7659 +typedef struct _AFACOMM_FUNCS {
7660 + ULONG SizeOfAfaCommFuncs;
7661 + PAFA_COMM_ALLOCATE_FIB AllocateFib;
7662 + PAFA_COMM_FREE_FIB FreeFib;
7663 + PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7664 + PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7665 + PAFA_COMM_INITIALIZE_FIB InitializeFib;
7666 + PAFA_COMM_GET_FIB_DATA GetFibData;
7667 + PAFA_COMM_SEND_FIB SendFib;
7668 + PAFA_COMM_COMPLETE_FIB CompleteFib;
7669 + PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7670 + PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7671 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7672 + PFSA_BUILD_SGMAP BuildSgMap;
7673 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7675 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7679 +(*PAFA_CLASS_OPEN_ADAPTER) (
7685 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7691 +(*PAFA_CLASS_DEV_CONTROL) (
7693 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
7698 +(*PAFA_CLASS_HANDLE_AIF) (
7700 + IN PFIB_CONTEXT FibContext
7704 +typedef struct _AFA_NEW_CLASS_DRIVER {
7705 + PVOID ClassDriverExtension;
7706 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7707 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7708 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7709 + PAFA_CLASS_HANDLE_AIF HandleAif;
7710 + PFSA_USER_VAR UserVars;
7711 + ULONG NumUserVars;
7712 +} AFA_NEW_CLASS_DRIVER;
7713 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7716 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7717 + PAFACOMM_FUNCS CommFuncs;
7718 + PVOID CommPortExtension;
7719 + PVOID MiniPortExtension;
7720 + OS_SPINLOCK_COOKIE SpinLockCookie;
7722 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7723 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7726 +typedef struct _AFA_CLASS_DRIVER {
7727 + struct _AFA_CLASS_DRIVER *Next;
7728 + PVOID ClassDriverExtension;
7729 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7730 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7731 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7732 + PAFA_CLASS_HANDLE_AIF HandleAif;
7733 +} AFA_CLASS_DRIVER;
7734 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7737 +#endif // _AFACOMM_
7738 diff -urN linux/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7739 --- linux/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 19:00:00 1969
7740 +++ linux/drivers/scsi/aacraid/include/aifstruc.h Thu Dec 21 13:14:30 2000
7743 + * Adaptec aacraid device driver for Linux.
7745 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7747 + * This program is free software; you can redistribute it and/or modify
7748 + * it under the terms of the GNU General Public License as published by
7749 + * the Free Software Foundation; either version 2, or (at your option)
7750 + * any later version.
7752 + * This program is distributed in the hope that it will be useful,
7753 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7754 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7755 + * GNU General Public License for more details.
7757 + * You should have received a copy of the GNU General Public License
7758 + * along with this program; see the file COPYING. If not, write to
7759 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7765 + * Define all shared data types relating to
7766 + * the set of features utilizing Adapter
7772 +#ifndef _AIFSTRUC_H
7773 +#define _AIFSTRUC_H
7775 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7777 +#include <protocol.h>
7780 +// Progress report structure definitions
7783 + AifJobStsSuccess = 1,
7784 + AifJobStsFinished,
7787 + AifJobStsLastReportMarker = 100, // All before mean last report
7788 + AifJobStsSuspended,
7792 +#ifdef AAC_32BIT_ENUMS
7793 +typedef _E_AifJobStatus AifJobStatus;
7795 +typedef AAC_UINT32 AifJobStatus;
7800 + AifJobScsiMin = 1, // Minimum value for Scsi operation
7801 + AifJobScsiZero, // SCSI device clear operation
7802 + AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7803 + AifJobScsiExercise, // SCSI device Exercise operation
7804 + AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7805 + // Add new SCSI task types above this line
7806 + AifJobScsiMax = 99, // Max Scsi value
7807 + AifJobCtrMin, // Min Ctr op value
7808 + AifJobCtrZero, // Container clear operation
7809 + AifJobCtrCopy, // Container copy operation
7810 + AifJobCtrCreateMirror, // Container Create Mirror operation
7811 + AifJobCtrMergeMirror, // Container Merge Mirror operation
7812 + AifJobCtrScrubMirror, // Container Scrub Mirror operation
7813 + AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7814 + AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7815 + AifJobCtrMorph, // Container morph operation
7816 + AifJobCtrPartCopy, // Container Partition copy operation
7817 + AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7818 + AifJobCtrCrazyCache, // crazy cache
7819 + // Add new container task types above this line
7820 + AifJobCtrMax = 199, // Max Ctr type operation
7821 + AifJobFsMin, // Min Fs type operation
7822 + AifJobFsCreate, // File System Create operation
7823 + AifJobFsVerify, // File System Verify operation
7824 + AifJobFsExtend, // File System Extend operation
7825 + // Add new file system task types above this line
7826 + AifJobFsMax = 299, // Max Fs type operation
7827 + // Add new API task types here
7828 + AifJobApiFormatNTFS, // Format a drive to NTFS
7829 + AifJobApiFormatFAT, // Format a drive to FAT
7830 + AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7831 + AifJobApiFormatFAT32, // Format a drive to FAT32
7832 + AifJobApiMax = 399, // Max API type operation
7833 + AifJobCtlContinuousCtrVerify, // Controller operation
7834 + AifJobCtlMax = 499 // Max Controller type operation
7838 +#ifdef AAC_32BIT_ENUMS
7839 +typedef _E_AifJobType AifJobType;
7841 +typedef AAC_UINT32 AifJobType;
7844 +union SrcContainer {
7846 + AAC_UINT32 master;
7847 + AAC_UINT32 container;
7850 +union DstContainer {
7853 + AAC_UINT32 container;
7857 +struct AifContainers {
7858 + union SrcContainer src;
7859 + union DstContainer dst;
7862 +union AifJobClient {
7864 + struct AifContainers container; // For Container nd file system progress ops;
7865 + AAC_INT32 scsi_dh; // For SCSI progress ops
7868 +struct AifJobDesc {
7869 + AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7870 + AifJobType type; // Operation that is being performed
7871 + union AifJobClient client; // Details
7874 +struct AifJobProgressReport {
7875 + struct AifJobDesc jd;
7876 + AifJobStatus status;
7877 + AAC_UINT32 finalTick;
7878 + AAC_UINT32 currentTick;
7879 + AAC_UINT32 jobSpecificData1;
7880 + AAC_UINT32 jobSpecificData2;
7884 +// Notification of events structure definition starts here
7887 + // General application notifies start here
7888 + AifEnGeneric = 1, // Generic notification
7889 + AifEnTaskComplete, // Task has completed
7890 + AifEnConfigChange, // Adapter configuration change occurred
7891 + AifEnContainerChange, // Adapter specific container configuration change
7892 + AifEnDeviceFailure, // SCSI device failed
7893 + AifEnMirrorFailover, // Mirror failover started
7894 + AifEnContainerEvent, // Significant container event
7895 + AifEnFileSystemChange, // File system changed
7896 + AifEnConfigPause, // Container pause event
7897 + AifEnConfigResume, // Container resume event
7898 + AifEnFailoverChange, // Failover space assignment changed
7899 + AifEnRAID5RebuildDone, // RAID5 rebuild finished
7900 + AifEnEnclosureManagement, // Enclosure management event
7901 + AifEnBatteryEvent, // Significant NV battery event
7902 + AifEnAddContainer, // A new container was created.
7903 + AifEnDeleteContainer, // A container was deleted.
7904 + AifEnSMARTEvent, // SMART Event
7905 + AifEnBatteryNeedsRecond, // The battery needs reconditioning
7906 + AifEnClusterEvent, // Some cluster event
7907 + AifEnDiskSetEvent, // A disk set event occured.
7908 + // Add general application notifies above this comment
7909 + AifDriverNotifyStart=199, // Notifies for host driver go here
7910 + // Host driver notifications start here
7911 + AifDenMorphComplete, // A morph operation completed
7912 + AifDenVolumeExtendComplete // A volume expand operation completed
7913 + // Add host driver notifications above this comment
7914 +} _E_AifEventNotifyType;
7916 +#ifdef AAC_32BIT_ENUMS
7917 +typedef _E_AifEventNotifyType AifEventNotifyType;
7919 +typedef AAC_UINT32 AifEventNotifyType;
7922 +struct AifEnsGeneric {
7923 + AAC_INT8 text[132]; // Generic text
7926 +struct AifEnsDeviceFailure {
7927 + AAC_INT32 deviceHandle; // SCSI device handle
7930 +struct AifEnsMirrorFailover {
7931 + AAC_UINT32 container; // Container with failed element
7932 + AAC_UINT32 failedSlice; // Old slice which failed
7933 + AAC_UINT32 creatingSlice; // New slice used for auto-create
7936 +struct AifEnsContainerChange {
7937 + AAC_UINT32 container[2]; // container that changed, -1 if no container
7940 +struct AifEnsContainerEvent {
7941 + AAC_UINT32 container; // container number
7942 + AAC_UINT32 eventType; // event type
7945 +struct AifEnsEnclosureEvent {
7946 + AAC_UINT32 empID; // enclosure management processor number
7947 + AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
7948 + AAC_UINT32 eventType; // event type
7952 +struct AifEnsBatteryEvent {
7953 + NVBATT_TRANSITION transition_type; // e.g. from low to ok
7954 + NVBATTSTATUS current_state; // current battery state
7955 + NVBATTSTATUS prior_state; // previous battery state
7958 +struct AifEnsDiskSetEvent {
7959 + AAC_UINT32 eventType;
7960 + AAC_UINT32 DsNum[2];
7961 + AAC_UINT32 CreatorId[2];
7966 +typedef enum _CLUSTER_AIF_EVENT {
7967 + CLUSTER_NULL_EVENT = 0,
7968 + CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
7969 + // (partner's agent may be up)
7970 + CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
7971 + // (partner has rebooted)
7972 +} _E_CLUSTER_AIF_EVENT;
7974 +#ifdef AAC_32BIT_ENUMS
7975 +typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
7977 +typedef AAC_UINT32 CLUSTER_AIF_EVENT;
7980 +struct AifEnsClusterEvent {
7981 + CLUSTER_AIF_EVENT eventType;
7984 +struct AifEventNotify {
7985 + AifEventNotifyType type;
7987 + struct AifEnsGeneric EG;
7988 + struct AifEnsDeviceFailure EDF;
7989 + struct AifEnsMirrorFailover EMF;
7990 + struct AifEnsContainerChange ECC;
7991 + struct AifEnsContainerEvent ECE;
7992 + struct AifEnsEnclosureEvent EEE;
7993 + struct AifEnsBatteryEvent EBE;
7994 + struct AifEnsDiskSetEvent EDS;
7996 + struct AifEnsSMARTEvent ES;
7998 + struct AifEnsClusterEvent ECLE;
8003 +// Generic API structure
8005 +#define AIF_API_REPORT_MAX_SIZE 64
8006 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8011 +// For FIB communication, we need all of the following things
8012 +// to send back to the user.
8015 + AifCmdEventNotify = 1, // Notify of event
8016 + AifCmdJobProgress, // Progress report
8017 + AifCmdAPIReport, // Report from other user of API
8018 + AifCmdDriverNotify, // Notify host driver of event
8019 + AifReqJobList = 100, // Gets back complete job list
8020 + AifReqJobsForCtr, // Gets back jobs for specific container
8021 + AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8022 + AifReqJobReport, // Gets back a specific job report or list of them
8023 + AifReqTerminateJob, // Terminates job
8024 + AifReqSuspendJob, // Suspends a job
8025 + AifReqResumeJob, // Resumes a job
8026 + AifReqSendAPIReport, // API generic report requests
8027 + AifReqAPIJobStart, // Start a job from the API
8028 + AifReqAPIJobUpdate, // Update a job report from the API
8029 + AifReqAPIJobFinish // Finish a job from the API
8032 +#ifdef AAC_32BIT_ENUMS
8033 +typedef _E_AIFCOMMAND AIFCOMMAND;
8035 +typedef AAC_UINT32 AIFCOMMAND;
8041 +// Adapter Initiated FIB command structures. Start with the adapter
8042 +// initiated FIBs that really come from the adapter, and get responded
8045 +typedef struct _AIFCOMMANDTOHOST {
8046 + AIFCOMMAND command; // Tell host what type of notify this is
8047 + AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8049 + // First define data going to the adapter
8050 + struct AifEventNotify EN; // Event notify structure
8051 + struct AifJobProgressReport PR[1]; // Progress report
8054 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8057 +#endif // _AIFSTRUC_H
8061 diff -urN linux/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8062 --- linux/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 19:00:00 1969
8063 +++ linux/drivers/scsi/aacraid/include/build_number.h Thu Dec 21 13:14:30 2000
8066 + * Adaptec aacraid device driver for Linux.
8068 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8070 + * This program is free software; you can redistribute it and/or modify
8071 + * it under the terms of the GNU General Public License as published by
8072 + * the Free Software Foundation; either version 2, or (at your option)
8073 + * any later version.
8075 + * This program is distributed in the hope that it will be useful,
8076 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8077 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8078 + * GNU General Public License for more details.
8080 + * You should have received a copy of the GNU General Public License
8081 + * along with this program; see the file COPYING. If not, write to
8082 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8088 + * DThis module contains the single location where the build number
8094 +#ifndef _BUILD_NUMBER_H
8095 +#define _BUILD_NUMBER_H
8097 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8099 +#define REV_BUILD_NUMBER 3911
8102 +#endif // _BUILD_NUMBER_H
8104 diff -urN linux/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8105 --- linux/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 19:00:00 1969
8106 +++ linux/drivers/scsi/aacraid/include/commdata.h Thu Dec 21 13:14:30 2000
8109 + * Adaptec aacraid device driver for Linux.
8111 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8113 + * This program is free software; you can redistribute it and/or modify
8114 + * it under the terms of the GNU General Public License as published by
8115 + * the Free Software Foundation; either version 2, or (at your option)
8116 + * any later version.
8118 + * This program is distributed in the hope that it will be useful,
8119 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8120 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8121 + * GNU General Public License for more details.
8123 + * You should have received a copy of the GNU General Public License
8124 + * along with this program; see the file COPYING. If not, write to
8125 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8130 + * Abstract: Define the communication layer of the adapter
8138 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8140 +typedef struct _FSA_COMM_DATA {
8143 + // A pointer to the Driver and Device object we were initialized with
8146 + PDRIVER_OBJECT DriverObject;
8147 + PDEVICE_OBJECT DeviceObject;
8150 + // A list of all adapters we have configured.
8153 + PAFA_COMM_ADAPTER AdapterList;
8154 + ULONG TotalAdapters;
8157 + // Adapter timeout support. This is the default timeout to wait for the
8158 + // adapter to respond(setup in initfs.c), and a boolean to indicate if
8159 + // we should timeout requests to the adapter or not.
8162 + LARGE_INTEGER QueueFreeTimeout;
8163 + LARGE_INTEGER AdapterTimeout;
8164 + BOOLEAN EnableAdapterTimeouts;
8166 + ULONG FibTimeoutIncrement;
8170 + ULONG NoResponseSent;
8171 + ULONG NoResponseRecved;
8173 + ULONG AsyncRecved;
8175 + ULONG NormalRecved;
8177 + ULONG TimedOutFibs;
8180 + KTIMER TimeoutTimer;
8183 + // If this value is set to 1 then interrupt moderation will occur
8184 + // in the base commuication support.
8187 + ULONG EnableInterruptModeration;
8189 + int HardInterruptModeration;
8190 + int HardInterruptModeration1;
8191 + int PeakFibsConsumed;
8192 + int ZeroFibsConsumed;
8193 + int EnableFibTimeoutBreak;
8194 + ULONG FibTimeoutSeconds;
8197 + // The following holds all of the available user settable variables.
8198 + // This includes all for the comm layer as well as any from the class
8199 + // drivers as well.
8202 + FSA_USER_VAR *UserVars;
8203 + ULONG NumUserVars;
8208 +#ifdef FIB_CHECKSUMS
8209 + int do_fib_checksums;
8213 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8215 +extern FSA_COMM_DATA FsaCommData;
8218 +#endif // _COMMDATA_
8220 diff -urN linux/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8221 --- linux/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 19:00:00 1969
8222 +++ linux/drivers/scsi/aacraid/include/commerr.h Thu Dec 21 13:14:30 2000
8225 + * Adaptec aacraid device driver for Linux.
8227 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8229 + * This program is free software; you can redistribute it and/or modify
8230 + * it under the terms of the GNU General Public License as published by
8231 + * the Free Software Foundation; either version 2, or (at your option)
8232 + * any later version.
8234 + * This program is distributed in the hope that it will be useful,
8235 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8236 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8237 + * GNU General Public License for more details.
8239 + * You should have received a copy of the GNU General Public License
8240 + * along with this program; see the file COPYING. If not, write to
8241 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8246 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8255 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8258 +// Note: comments in the .mc file must use both ";" and "//".
8260 +// Status values are 32 bit values layed out as follows:
8262 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8263 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8264 +// +---+-+-------------------------+-------------------------------+
8265 +// |Sev|C| Facility | Code |
8266 +// +---+-+-------------------------+-------------------------------+
8270 +// Sev - is the severity code
8273 +// 01 - Informational
8277 +// C - is the Customer code flag
8279 +// Facility - is the facility code
8281 +// Code - is the facility's status code
8286 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8287 +// called with a device, the name of the device will be inserted into
8288 +// the message at %1. Otherwise, the place of %1 will be left empty.
8289 +// In either case, the insertion strings from the driver's error log
8290 +// entry starts at %2. In other words, the first insertion string goes
8291 +// to %2, the second to %3 and so on.
8295 +// Values are 32 bit values layed out as follows:
8297 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8298 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8299 +// +---+-+-+-----------------------+-------------------------------+
8300 +// |Sev|C|R| Facility | Code |
8301 +// +---+-+-+-----------------------+-------------------------------+
8305 +// Sev - is the severity code
8308 +// 01 - Informational
8312 +// C - is the Customer code flag
8314 +// R - is a reserved bit
8316 +// Facility - is the facility code
8318 +// Code - is the facility's status code
8321 +// Define the facility codes
8325 +#define FACILITY_FSAFS_ERROR_CODE 0x7
8330 +// MessageId: FSAFS_FIB_INVALID
8334 +// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8336 +#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8340 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8344 +// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8346 +#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8349 diff -urN linux/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8350 --- linux/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 19:00:00 1969
8351 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Thu Dec 21 13:14:30 2000
8354 + * Adaptec aacraid device driver for Linux.
8356 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8358 + * This program is free software; you can redistribute it and/or modify
8359 + * it under the terms of the GNU General Public License as published by
8360 + * the Free Software Foundation; either version 2, or (at your option)
8361 + * any later version.
8363 + * This program is distributed in the hope that it will be useful,
8364 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8365 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8366 + * GNU General Public License for more details.
8368 + * You should have received a copy of the GNU General Public License
8369 + * along with this program; see the file COPYING. If not, write to
8370 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8373 + * commfibcontext.h
8375 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8380 +#ifndef _COMM_FIB_CONTEXT_
8381 +#define _COMM_FIB_CONTEXT_
8383 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8385 +typedef struct _COMM_FIB_CONTEXT {
8387 + PVOID Next; // this is used by the zone allocation
8390 + // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8392 + // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8393 + // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8397 + NODE_TYPE_CODE NodeTypeCode;
8398 + NODE_BYTE_SIZE NodeByteSize;
8401 + // The Adapter that this I/O is destined for.
8404 + PAFA_COMM_ADAPTER Adapter;
8406 + PHYSICAL_ADDRESS LogicalFibAddress;
8409 + // This is the event the sendfib routine will wait on if the
8410 + // caller did not pass one and this is synch io.
8414 + OS_CVLOCK *FsaEventMutex;
8416 + ULONG FibComplete; // gets set to 1 when fib is complete
8418 + PFIB_CALLBACK FibCallback;
8419 + PVOID FibCallbackContext;
8424 +#ifdef GATHER_FIB_TIMES
8425 + LARGE_INTEGER FibTimeStamp;
8426 + PFIB_TIMES FibTimesPtr;
8430 + // The following is used to put this fib context onto the Outstanding I/O queue.
8433 + LIST_ENTRY QueueEntry;
8436 + // The following is used to timeout a fib to the adapter.
8439 + LARGE_INTEGER TimeoutValue;
8445 +} COMM_FIB_CONTEXT;
8446 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8448 +#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8450 +#endif /* _COMM_FIB_CONTEXT_ */
8451 diff -urN linux/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8452 --- linux/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 19:00:00 1969
8453 +++ linux/drivers/scsi/aacraid/include/comprocs.h Thu Dec 21 13:14:30 2000
8456 + * Adaptec aacraid device driver for Linux.
8458 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8460 + * This program is free software; you can redistribute it and/or modify
8461 + * it under the terms of the GNU General Public License as published by
8462 + * the Free Software Foundation; either version 2, or (at your option)
8463 + * any later version.
8465 + * This program is distributed in the hope that it will be useful,
8466 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8467 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8468 + * GNU General Public License for more details.
8470 + * You should have received a copy of the GNU General Public License
8471 + * along with this program; see the file COPYING. If not, write to
8472 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8477 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8485 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8487 +#include "osheaders.h"
8489 +#include "AacGenericTypes.h"
8491 +#include "aac_unix_defs.h"
8493 +#include "nodetype.h"
8495 +// #define GATHER_FIB_TIMES
8497 +#include "fsatypes.h"
8499 +#include "perfpack.h"
8501 +#include "comstruc.h"
8503 +//#include "unix_protocol.h"
8507 +#include "protocol.h"
8509 +#include "fsaioctl.h"
8511 +#undef GATHER_FIB_TIMES
8513 +#include "aifstruc.h"
8515 +#include "fsaport.h"
8516 +#include "comsup.h"
8517 +#include "afacomm.h"
8518 +#include "adapter.h"
8520 +#include "commfibcontext.h"
8521 +#include "comproto.h"
8522 +#include "commdata.h"
8523 +#include "commerr.h"
8529 +// The following macro is used when sending and receiving FIBs. It is only used for
8533 +#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8535 +#define FIB_COUNTER_INCREMENT(Counter)
8541 +AfaCommAdapterDeviceControl (
8542 + IN PVOID AdapterArg,
8543 + IN PAFA_IOCTL_CMD IoctlCmdPtr
8547 +#endif // _COMPROCS_
8548 diff -urN linux/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8549 --- linux/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 19:00:00 1969
8550 +++ linux/drivers/scsi/aacraid/include/comproto.h Thu Dec 21 13:14:30 2000
8553 + * Adaptec aacraid device driver for Linux.
8555 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8557 + * This program is free software; you can redistribute it and/or modify
8558 + * it under the terms of the GNU General Public License as published by
8559 + * the Free Software Foundation; either version 2, or (at your option)
8560 + * any later version.
8562 + * This program is distributed in the hope that it will be useful,
8563 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8564 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8565 + * GNU General Public License for more details.
8567 + * You should have received a copy of the GNU General Public License
8568 + * along with this program; see the file COPYING. If not, write to
8569 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8574 + * Abstract: Global routines for the commuication interface that are device
8580 +#ifndef _COMM_PROTO
8581 +#define _COMM_PROTO
8583 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8586 +// define the routines we need so we can commuicate with the
8591 +// The following 4 dpc routines will support commuication from the adapter to the
8592 +// host. There is one DPC routine to deal with each type of queue that supports
8593 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8594 +// These routines will simply pull off the QE and set an event. In the case of a
8595 +// adapter to host command they will also put the FIB on a queue to be processed by
8596 +// a FS thread running at passive level.
8599 +// Handle queue not full notification to the file system thread waiting for a queue entry
8603 + IN PCOMM_REGION CommRegion
8606 +// Adapter to host normal priority responses
8609 +HostResponseNormalDpc(
8610 + IN PCOMM_QUE OurQueue
8613 +// Adapter to host high priority responses
8615 +HostResponseHighDpc(
8616 + IN PCOMM_QUE OurQueue
8619 +// Adapter to host high priority commands
8621 +HostCommandHighDpc(
8622 + IN PCOMM_QUE OurQueue
8626 +// Adapter to host normal priority commands
8628 +HostCommandNormDpc(
8629 + IN PCOMM_QUE OurQueue
8637 + FIB_COMMAND Command,
8641 + USHORT *ResponseSize
8651 + IN PFIB_CONTEXT FibContext
8656 + IN PFIB_CONTEXT FibContext
8661 + IN PFIB_CONTEXT FibContext
8668 + IN FIB_COMMAND Command,
8669 + IN PFIB_CONTEXT FibContext,
8671 + IN COMM_PRIORITIES Priority,
8674 + IN BOOLEAN ResponseExpected,
8675 + IN PFIB_CALLBACK FibCallback,
8676 + IN PVOID FibCallbackContext
8681 + IN PFIB_CONTEXT FibContext
8685 +CompleteAdapterFib(
8686 + IN PFIB_CONTEXT FibContext,
8692 + IN PFIB_CONTEXT FibContext
8698 + IN PFIB_CONTEXT FibContext
8704 +AfaCommOpenAdapter (
8705 + IN PVOID AdapterArg
8709 +AfaCommCloseAdapter (
8710 + IN PVOID AdapterArg
8715 +AfaCommInterruptHost(
8717 + ADAPTER_EVENT AdapterEvent
8721 +#endif // _COMM_PROTO
8722 diff -urN linux/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8723 --- linux/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 19:00:00 1969
8724 +++ linux/drivers/scsi/aacraid/include/comstruc.h Thu Dec 21 13:14:30 2000
8727 + * Adaptec aacraid device driver for Linux.
8729 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8731 + * This program is free software; you can redistribute it and/or modify
8732 + * it under the terms of the GNU General Public License as published by
8733 + * the Free Software Foundation; either version 2, or (at your option)
8734 + * any later version.
8736 + * This program is distributed in the hope that it will be useful,
8737 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8738 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8739 + * GNU General Public License for more details.
8741 + * You should have received a copy of the GNU General Public License
8742 + * along with this program; see the file COPYING. If not, write to
8743 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8748 + * Abstract: This module defines the data structures that make up the communication
8749 + * region for the FSA filesystem. This region is how the host based code
8750 + * communicates both control and data to the adapter based code.
8755 +#ifndef _COMM_STRUCT
8756 +#define _COMM_STRUCT
8758 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8761 +// Define all the constants needed for the communication interface
8764 +// Define how many queue entries each queue will have and the total number of
8765 +// entries for the entire communication interface. Also define how many queues
8768 +#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8769 +#define HOST_HIGH_CMD_ENTRIES 4
8770 +#define HOST_NORM_CMD_ENTRIES 8
8771 +#define ADAP_HIGH_CMD_ENTRIES 4
8772 +#define ADAP_NORM_CMD_ENTRIES 512
8773 +#define HOST_HIGH_RESP_ENTRIES 4
8774 +#define HOST_NORM_RESP_ENTRIES 512
8775 +#define ADAP_HIGH_RESP_ENTRIES 4
8776 +#define ADAP_NORM_RESP_ENTRIES 8
8778 +#define TOTAL_QUEUE_ENTRIES \
8779 + (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8780 + HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8785 +// Set the queues on a 16 byte alignment
8786 +#define QUEUE_ALIGNMENT 16
8790 +// The queue headers define the Communication Region queues. These
8791 +// are physically contiguous and accessible by both the adapter and the
8792 +// host. Even though all queue headers are in the same contiguous block they will be
8793 +// represented as individual units in the data structures.
8796 +typedef AAC_UINT32 QUEUE_INDEX;
8798 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8800 +typedef struct _QUEUE_ENTRY {
8802 + AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8803 + AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8807 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8811 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8812 +// adjacently and in that order.
8814 +typedef struct _QUEUE_HEADERS {
8816 + PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8817 + PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8818 + PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8821 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8824 +// Define all the events which the adapter would like to notify
8827 +typedef enum _ADAPTER_EVENT {
8828 + HostNormCmdQue = 1, // Change in host normal priority command queue
8829 + HostHighCmdQue, // Change in host high priority command queue
8830 + HostNormRespQue, // Change in host normal priority response queue
8831 + HostHighRespQue, // Change in host high priority response queue
8832 + AdapNormRespNotFull,
8833 + AdapHighRespNotFull,
8834 + AdapNormCmdNotFull,
8835 + AdapHighCmdNotFull,
8836 + SynchCommandComplete,
8837 + AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8839 +} _E_ADAPTER_EVENT;
8841 +#ifdef AAC_32BIT_ENUMS
8842 +typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8844 +typedef AAC_UINT32 ADAPTER_EVENT;
8848 +// Define all the events the host wishes to notify the
8851 +typedef enum _HOST_2_ADAP_EVENT {
8852 + AdapNormCmdQue = 1,
8859 + HostNormRespNotFull,
8860 + HostHighRespNotFull,
8861 + HostNormCmdNotFull,
8862 + HostHighCmdNotFull,
8865 +} _E_HOST_2_ADAP_EVENT;
8867 +#ifdef AAC_32BIT_ENUMS
8868 +typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8870 +typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8874 +// Define all the queues that the adapter and host use to communicate
8877 +typedef enum _QUEUE_TYPES {
8878 + HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8879 + HostHighCmdQueue, // Adapter to host high priority command traffic
8880 + AdapNormRespQueue, // Host to adapter normal priority response traffic
8881 + AdapHighRespQueue, // Host to adapter high priority response traffic
8882 + AdapNormCmdQueue, // Host to adapter normal priority command traffic
8883 + AdapHighCmdQueue, // Host to adapter high priority command traffic
8884 + HostNormRespQueue, // Adapter to host normal priority response traffic
8885 + HostHighRespQueue // Adapter to host high priority response traffic
8888 +#ifdef AAC_32BIT_ENUMS
8889 +typedef _E_QUEUE_TYPES QUEUE_TYPES;
8891 +typedef AAC_UINT32 QUEUE_TYPES;
8896 +// Assign type values to the FSA communication data structures
8899 +typedef enum _STRUCT_TYPES {
8905 +#ifdef AAC_32BIT_ENUMS
8906 +typedef _E_STRUCT_TYPES STRUCT_TYPES;
8908 +typedef AAC_UINT32 STRUCT_TYPES;
8912 +// Define the priority levels the FSA communication routines support.
8915 +typedef enum _COMM_PRIORITIES {
8918 +} _E_COMM_PRIORITIES;
8920 +#ifdef AAC_32BIT_ENUMS
8921 +typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
8923 +typedef AAC_UINT32 COMM_PRIORITIES;
8929 +// Define the LIST_ENTRY structure. This structure is used on the NT side to link
8930 +// the FIBs together in a linked list. Since this structure gets compiled on the adapter
8931 +// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
8932 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
8933 +// is already defined.
8934 +#if !defined(_NTDEF_) && !defined(_WINNT_)
8935 +typedef struct _LIST_ENTRY {
8936 + struct _LIST_ENTRY *Flink;
8937 + struct _LIST_ENTRY *Blink;
8939 +typedef LIST_ENTRY *PLIST_ENTRY;
8944 +// Define the FIB. The FIB is the where all the requested data and
8945 +// command information are put to the application on the FSA adapter.
8948 +typedef struct _FIB_HEADER {
8949 + AAC_UINT32 XferState; // Current transfer state for this CCB
8950 + AAC_UINT16 Command; // Routing information for the destination
8951 + AAC_UINT8 StructType; // Type FIB
8952 + AAC_UINT8 Flags; // Flags for FIB
8953 + AAC_UINT16 Size; // Size of this FIB in bytes
8954 + AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
8955 + AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
8956 + AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
8957 + AAC_UINT32 SenderData; // Place holder for the sender to store data
8961 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
8962 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
8964 + LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
8966 +#else // The MIDL compiler does not support unions without a discriminant.
8967 + struct { // Since nothing during the midl compile actually looks into this
8968 + struct { // structure, this shoudl be ok.
8969 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
8970 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
8977 +#define FibLinks _u._FibLinks
8980 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
8983 +typedef struct _FIB {
8985 +#ifdef BRIDGE //rma
8988 + FIB_HEADER Header;
8990 + AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
9001 +typedef enum _FIB_COMMANDS {
9002 + TestCommandResponse = 1,
9003 + TestAdapterCommand = 2,
9005 + // Lowlevel and comm commands
9007 + LastTestCommand = 100,
9008 + ReinitHostNormCommandQueue = 101,
9009 + ReinitHostHighCommandQueue = 102,
9010 + ReinitHostHighRespQueue = 103,
9011 + ReinitHostNormRespQueue = 104,
9012 + ReinitAdapNormCommandQueue = 105,
9013 + ReinitAdapHighCommandQueue = 107,
9014 + ReinitAdapHighRespQueue = 108,
9015 + ReinitAdapNormRespQueue = 109,
9016 + InterfaceShutdown = 110,
9017 + DmaCommandFib = 120,
9018 + StartProfile = 121,
9019 + TermProfile = 122,
9021 + TakeABreakPt = 124,
9022 + RequestPerfData = 125,
9023 + SetInterruptDefTimer= 126,
9024 + SetInterruptDefCount= 127,
9025 + GetInterruptDefStatus= 128,
9026 + LastCommCommand = 129,
9028 + // Filesystem commands
9030 + NuFileSystem = 300,
9032 + HostFileSystem = 302,
9033 + LastFileSystemCommand = 303,
9035 + // Container Commands
9037 + ContainerCommand = 500,
9038 + ContainerCommand64 = 501,
9040 + // Cluster Commands
9042 + ClusterCommand = 550,
9044 + // Scsi Port commands (scsi passthrough)
9046 + ScsiPortCommand = 600,
9048 + // misc house keeping and generic adapter initiated commands
9051 + CheckRevision = 701,
9052 + FsaHostShutdown = 702,
9053 + RequestAdapterInfo = 703,
9054 + IsAdapterPaused = 704,
9055 + SendHostTime = 705,
9056 + LastMiscCommand = 706
9062 +typedef AAC_UINT16 FIB_COMMAND;
9065 +// Commands that will target the failover level on the FSA adapter
9068 +typedef enum _FIB_XFER_STATE {
9069 + HostOwned = (1<<0),
9070 + AdapterOwned = (1<<1),
9071 + FibInitialized = (1<<2),
9072 + FibEmpty = (1<<3),
9073 + AllocatedFromPool = (1<<4),
9074 + SentFromHost = (1<<5),
9075 + SentFromAdapter = (1<<6),
9076 + ResponseExpected = (1<<7),
9077 + NoResponseExpected = (1<<8),
9078 + AdapterProcessed = (1<<9),
9079 + HostProcessed = (1<<10),
9080 + HighPriority = (1<<11),
9081 + NormalPriority = (1<<12),
9083 + AsyncIo = (1<<13), // rpbfix: remove with new regime
9084 + PageFileIo = (1<<14), // rpbfix: remove with new regime
9085 + ShutdownRequest = (1<<15),
9086 + LazyWrite = (1<<16), // rpbfix: remove with new regime
9087 + AdapterMicroFib = (1<<17),
9088 + BIOSFibPath = (1<<18),
9089 + FastResponseCapable = (1<<19),
9090 + ApiFib = (1<<20) // Its an API Fib.
9092 +} _E_FIB_XFER_STATE;
9095 +typedef enum _FSA_ERRORS {
9098 + FSA_PENDING = 0x01,
9100 + FSA_INVALID_QUEUE = 0x03,
9101 + FSA_NOENTRIES = 0x04,
9102 + FSA_SENDFAILED = 0x05,
9103 + FSA_INVALID_QUEUE_PRIORITY = 0x06,
9104 + FSA_FIB_ALLOCATION_FAILED = 0x07,
9105 + FSA_FIB_DEALLOCATION_FAILED = 0x08
9111 +// The following defines needs to be updated any time there is an incompatible change made
9112 +// to the ADAPTER_INIT_STRUCT structure.
9114 +#define ADAPTER_INIT_STRUCT_REVISION 3
9116 +typedef struct _ADAPTER_INIT_STRUCT {
9117 + AAC_UINT32 InitStructRevision;
9118 + AAC_UINT32 MiniPortRevision;
9119 + AAC_UINT32 FilesystemRevision;
9120 + PAAC_VOID CommHeaderAddress;
9121 + PAAC_VOID FastIoCommAreaAddress;
9122 + PAAC_VOID AdapterFibsPhysicalAddress;
9123 + PAAC_VOID AdapterFibsVirtualAddress;
9124 + AAC_UINT32 AdapterFibsSize;
9125 + AAC_UINT32 AdapterFibAlign;
9126 + PAAC_VOID PrintfBufferAddress;
9127 + AAC_UINT32 PrintfBufferSize;
9128 + AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9129 + AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9130 +} ADAPTER_INIT_STRUCT;
9131 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9133 +#ifdef AAC_32BIT_ENUMS
9134 +typedef _E_FSA_ERRORS FSA_ERRORS;
9136 +typedef AAC_UINT32 FSA_ERRORS;
9139 +typedef enum _LOG_LEVEL {
9141 + LOG_INFORMATIONAL = 20,
9143 + LOG_LOW_ERROR = 40,
9144 + LOG_MEDIUM_ERROR = 50,
9145 + LOG_HIGH_ERROR = 60,
9148 + LOG_WINDBG_PRINT = 90
9151 +#ifdef AAC_32BIT_ENUMS
9152 +typedef _E_LOG_LEVEL LOG_LEVEL;
9154 +typedef AAC_UINT32 LOG_LEVEL;
9158 +#endif //_COMM_STRUCT
9161 diff -urN linux/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9162 --- linux/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 19:00:00 1969
9163 +++ linux/drivers/scsi/aacraid/include/comsup.h Thu Dec 21 13:14:30 2000
9166 + * Adaptec aacraid device driver for Linux.
9168 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9170 + * This program is free software; you can redistribute it and/or modify
9171 + * it under the terms of the GNU General Public License as published by
9172 + * the Free Software Foundation; either version 2, or (at your option)
9173 + * any later version.
9175 + * This program is distributed in the hope that it will be useful,
9176 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9177 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9178 + * GNU General Public License for more details.
9180 + * You should have received a copy of the GNU General Public License
9181 + * along with this program; see the file COPYING. If not, write to
9182 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9187 + * Abstract: This module defines the data structures that make up the
9188 + * commuication region for the FSA filesystem. This region is
9189 + * how the host based code commuicates both control and data
9190 + * to the adapter based code.
9195 +#ifndef _COMM_SUP_DEF
9196 +#define _COMM_SUP_DEF
9198 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9201 +// The adapter interface specs all queues to be located in the same physically
9202 +// contigous block. The host structure that defines the commuication queues will
9203 +// assume they are each a seperate physically contigous memory region that will
9204 +// support them all being one big contigous block.
9205 +// There is a command and response queue for each level and direction of
9206 +// commuication. These regions are accessed by both the host and adapter.
9208 +typedef struct _COMM_QUE {
9210 + PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9212 + PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9213 + QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9214 + ULONG QueueEntries; // Number of queue entries on this queue
9215 + OS_CV_T QueueFull; // Event to wait on if the queue is full
9216 + OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9217 + // This is only valid for adapter to host command queues.
9218 + OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9219 + KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9220 + ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9221 + // Only queues which the host will be the consumer will this field be valid
9222 + LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9223 + // only valid for command queues which receive entries from the adapter.
9224 + LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9225 + ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9227 + PVOID Adapter; // Back pointer to adapter structure
9230 +typedef COMM_QUE *PCOMM_QUE;
9233 +typedef struct _COMM_REGION {
9235 + COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9236 + COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9238 + COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9239 + COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9241 + COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9242 + COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9244 + COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9245 + COMM_QUE AdapHighRespQue; // A response for high priority host responses
9248 + // The 2 threads below are the threads which handle command traffic from the
9249 + // the adapter. There is one for normal priority and one for high priority queues.
9250 + // These threads will wait on the commandready event for it's queue.
9253 + HANDLE NormCommandThread;
9254 + HANDLE HighCommandThread;
9257 + // This dpc routine will handle the setting the of not full event when the adapter
9258 + // lets us know the queue is not longer full via interrupt
9261 + KDPC QueueNotFullDpc;
9263 +#ifdef API_THROTTLE
9265 + // Support for data I/O throttling to improve CLI performance
9266 + // while the system is under load.
9267 + // This is the throttling mechanism built into the COMM layer.
9268 + // Look in commsup.c, dpcsup.c and comminit.c for use.
9271 + int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9272 + int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9273 + LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9274 + LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9275 + BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9276 + KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9277 + KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9278 + KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9280 + unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9281 + unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9282 + unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9284 + unsigned int ThrottledFibs;
9285 + unsigned int ThrottleTimedoutFibs;
9286 + unsigned int ApiFibs;
9287 + unsigned int NonPassiveFibs;
9288 + unsigned int TotalFibs;
9289 + unsigned int FSInfoFibs;
9291 +#endif // #ifdef API_THROTTLE
9294 +typedef COMM_REGION *PCOMM_REGION;
9296 +#endif // _COMM_SUP
9297 diff -urN linux/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9298 --- linux/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 19:00:00 1969
9299 +++ linux/drivers/scsi/aacraid/include/fsact.h Thu Dec 21 13:14:30 2000
9302 + * Adaptec aacraid device driver for Linux.
9304 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9306 + * This program is free software; you can redistribute it and/or modify
9307 + * it under the terms of the GNU General Public License as published by
9308 + * the Free Software Foundation; either version 2, or (at your option)
9309 + * any later version.
9311 + * This program is distributed in the hope that it will be useful,
9312 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9313 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9314 + * GNU General Public License for more details.
9316 + * You should have received a copy of the GNU General Public License
9317 + * along with this program; see the file COPYING. If not, write to
9318 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9323 + * Abstract: Common container structures that are required to be
9324 + * known on both the host and adapter.
9331 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9333 +//#include <comstruc.h>
9334 +//#include <fsatypes.h>
9335 +#include <protocol.h> // definitions for FSASTATUS
9339 + * Object-Server / Volume-Manager Dispatch Classes
9341 +typedef enum _VM_COMMANDS {
9344 + VM_ContainerConfig,
9346 + VM_FilesystemIoctl,
9348 + VM_CtBlockRead, // see protocol.h for BlockRead command layout
9349 + VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9350 + VM_SliceBlockRead, // raw access to configured "storage objects"
9351 + VM_SliceBlockWrite,
9352 + VM_DriveBlockRead, // raw access to physical devices
9353 + VM_DriveBlockWrite,
9354 + VM_EnclosureMgt, // enclosure management
9355 + VM_Unused, // used to be diskset management
9356 + VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9357 + VM_CtPerf, // performance test
9358 + VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9359 + VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9360 + VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9361 + MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9364 +#ifdef AAC_32BIT_ENUMS
9365 +typedef _E_VMCOMMAND VMCOMMAND;
9367 +typedef AAC_UINT32 VMCOMMAND;
9373 +// Descriptive information (eg, vital stats)
9374 +// that a content manager might report. The
9375 +// FileArray filesystem component is one example
9376 +// of a content manager. Raw mode might be
9380 +struct FileSysInfo {
9382 + a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9383 + b) FSA usage (implemented by ObjType and ContentState fields)
9386 + e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9387 + f) I-node density - (computed from other fields)
9389 + AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9390 + AAC_UINT32 fsBlockSize;
9391 + AAC_UINT32 fsFragSize;
9392 + AAC_UINT32 fsMaxExtendSize;
9393 + AAC_UINT32 fsSpaceUnits;
9394 + AAC_UINT32 fsMaxNumFiles;
9395 + AAC_UINT32 fsNumFreeFiles;
9396 + AAC_UINT32 fsInodeDensity;
9397 +}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9399 +union ContentManagerInfo {
9400 + struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9404 +// Query for "mountable" objects, ie, objects that are typically
9405 +// associated with a drive letter on the client (host) side.
9408 +typedef struct _MNTOBJ {
9410 + AAC_UINT32 ObjectId;
9411 + FSASTRING FileSystemName; // if applicable
9412 + ContainerCreationInfo CreateInfo; // if applicable
9413 + AAC_UINT32 Capacity;
9414 + FSAVOLTYPE VolType; // substrate structure
9415 + FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9416 + AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9418 + union ContentManagerInfo
9419 + ObjExtension; // Info specific to content manager (eg, filesystem)
9421 + AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9426 +#define FSCS_READONLY 0x0002 // possible result of broken mirror
9430 +typedef struct _MNTINFO {
9432 + VMCOMMAND Command;
9434 + AAC_UINT32 MntCount;
9437 +typedef MNTINFO *PMNTINFO;
9439 +typedef struct _MNTINFORESPONSE {
9442 + FTYPE MntType; // should be same as that requested
9443 + AAC_UINT32 MntRespCount;
9444 + MNTOBJ MntTable[1];
9447 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9451 +// The following command is sent to shut down each container.
9454 +typedef struct _CLOSECOMMAND {
9456 + VMCOMMAND Command;
9457 + AAC_UINT32 ContainerId;
9460 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9463 +#endif /* _FSACT_H_ */
9466 diff -urN linux/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9467 --- linux/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 19:00:00 1969
9468 +++ linux/drivers/scsi/aacraid/include/fsafs.h Thu Dec 21 13:14:30 2000
9471 + * Adaptec aacraid device driver for Linux.
9473 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9475 + * This program is free software; you can redistribute it and/or modify
9476 + * it under the terms of the GNU General Public License as published by
9477 + * the Free Software Foundation; either version 2, or (at your option)
9478 + * any later version.
9480 + * This program is distributed in the hope that it will be useful,
9481 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9482 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9483 + * GNU General Public License for more details.
9485 + * You should have received a copy of the GNU General Public License
9486 + * along with this program; see the file COPYING. If not, write to
9487 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9492 + * Abstract: Common file system structures that are required to be
9493 + * known on both the host and adapter
9500 +#define _FSAFS_H_ 1
9502 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9504 +#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9507 + * Maximum number of filesystems.
9509 +#define NFILESYS 24
9512 + * File identifier.
9513 + * These are unique and self validating within a filesystem
9514 + * on a single machine and can persist across reboots.
9515 + * The hint field may be volatile and is not guaranteed to persist
9516 + * across reboots but is used to speed up the FID to file object translation
9517 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9518 + * the file object (assuming a filesystem context, i.e. driveno).
9521 + AAC_UINT32 hint; // last used hint for fast reclaim
9522 + AAC_UINT32 f1; // opaque
9523 + AAC_UINT32 f2; // opaque
9524 + } fileid_t; /* intra-filesystem file ID type */
9528 + * Generic file handle
9531 + fsid_t fh_fsid; /* File system id of mount point */
9532 + fileid_t fh_fid; /* File sys specific file id */
9534 +typedef struct fhandle fhandle_t;
9536 +#define FIDSIZE sizeof(fhandle_t)
9540 + AAC_INT8 fid_data[FIDSIZE];
9541 + struct fhandle fsafid;
9543 +} FSAFID; /* FSA File ID type */
9546 +#endif /* _FSAFS_H_ */
9548 diff -urN linux/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9549 --- linux/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 19:00:00 1969
9550 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h Thu Dec 21 13:14:30 2000
9553 + * Adaptec aacraid device driver for Linux.
9555 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9557 + * This program is free software; you can redistribute it and/or modify
9558 + * it under the terms of the GNU General Public License as published by
9559 + * the Free Software Foundation; either version 2, or (at your option)
9560 + * any later version.
9562 + * This program is distributed in the hope that it will be useful,
9563 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9564 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9565 + * GNU General Public License for more details.
9567 + * You should have received a copy of the GNU General Public License
9568 + * along with this program; see the file COPYING. If not, write to
9569 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9574 + * Abstract: Defines the interface structures between user mode applications
9575 + * and the fsa driver. This structures are used in
9576 + * DeviceIoControl() calls.
9581 +#ifndef _FSAIOCTL_H_
9582 +#define _FSAIOCTL_H_
9584 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9586 +#ifndef IOTRACEUSER
9591 +#define FILE_DEVICE_CONTROLLER 0x00000004
9594 +// Macro definition for defining IOCTL and FSCTL function control codes. Note
9595 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9596 +// 2048-4095 are reserved for customers.
9599 +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9600 + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9604 +// Define the method codes for how buffers are passed for I/O and FS controls
9607 +#define METHOD_BUFFERED 0
9610 +#define METHOD_NEITHER 3
9613 +// Define the access check value for any access
9616 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9617 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9618 +// constants *MUST* always be in sync.
9620 +#define FILE_ANY_ACCESS 0
9628 +typedef struct _UNIX_QUERY_DISK {
9629 + AAC_INT32 ContainerNumber;
9633 + AAC_BOOLEAN Valid;
9634 + AAC_BOOLEAN Locked;
9635 + AAC_BOOLEAN Deleted;
9636 + AAC_INT32 Instance;
9637 + AAC_INT8 diskDeviceName[10];
9638 + AAC_BOOLEAN UnMapped;
9640 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9643 +typedef struct _DELETE_DISK {
9644 + AAC_UINT32 NtDiskNumber;
9645 + AAC_UINT32 ContainerNumber;
9647 +typedef DELETE_DISK *PDELETE_DISK;
9650 +#endif /*IOTRACEUSER*/
9652 +#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9653 +#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9656 +#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9659 +#define FSACTL_GET_VAR 0x93
9660 +#define FSACTL_SET_VAR 0xa3
9661 +#define FSACTL_GET_FIBTIMES 0xb3
9662 +#define FSACTL_ZERO_FIBTIMES 0xc3
9665 +#define FSACTL_DELETE_DISK 0x163
9666 +#define FSACTL_QUERY_DISK 0x173
9669 +// AfaComm perfmon ioctls
9670 +#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9673 +#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9676 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9677 + char *AdapterFibContext;
9680 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9683 +// filesystem ioctls
9685 +#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9687 +#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9689 +#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9691 +#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9693 +#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9696 +#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9699 +#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9702 +#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9705 +#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9708 +#endif // _FSAIOCTL_H_
9711 diff -urN linux/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9712 --- linux/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 19:00:00 1969
9713 +++ linux/drivers/scsi/aacraid/include/fsaport.h Thu Dec 21 13:14:30 2000
9716 + * Adaptec aacraid device driver for Linux.
9718 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9720 + * This program is free software; you can redistribute it and/or modify
9721 + * it under the terms of the GNU General Public License as published by
9722 + * the Free Software Foundation; either version 2, or (at your option)
9723 + * any later version.
9725 + * This program is distributed in the hope that it will be useful,
9726 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9727 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9728 + * GNU General Public License for more details.
9730 + * You should have received a copy of the GNU General Public License
9731 + * along with this program; see the file COPYING. If not, write to
9732 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9737 + * Abstract: This module defines all of the globally used procedures in the FSA
9746 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9749 +// The scatter/gather map context is the information we
9750 +// we need to keep the map and transfer data to and from the
9754 +typedef struct _SGMAP_CONTEXT {
9756 + caddr_t BaseAddress;
9758 + ULONG NumberMapRegs;
9760 + ULONG ByteCount; // Used to check the Mdl length.
9761 + BOOLEAN WriteToDevice;
9767 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9769 +typedef struct _MAPFIB_CONTEXT {
9772 + ULONG NumberMapRegs;
9773 + PVOID FibVirtualAddress;
9775 + PVOID FibPhysicalAddress;
9779 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9782 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9783 + PVOID AdapterExtension,
9784 + IN OUT PVOID *BaseAddress,
9786 + IN ULONG Alignment
9790 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9791 + PVOID AdapterExtension
9795 +(*PFSA_FREE_DMA_RESOURCES)(
9796 + IN PVOID AdapterExtension,
9797 + IN PSGMAP_CONTEXT SgMapContext
9801 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9802 + IN PVOID AdapterExtension,
9803 + IN PMAPFIB_CONTEXT MapFibContext
9807 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9808 + IN PVOID AdapterExtension,
9809 + IN PMAPFIB_CONTEXT MapFibContext
9813 +(*PFSA_INTERRUPT_ADAPTER)(
9814 + IN PVOID AdapterExtension
9818 +(*PFSA_NOTIFY_ADAPTER)(
9819 + IN PVOID AdapterExtension,
9820 + IN HOST_2_ADAP_EVENT AdapterEvent
9824 +(*PFSA_RESET_DEVICE)(
9825 + PVOID AdapterExtension
9829 +(*PFSA_BUILD_SGMAP)(
9830 + IN PVOID AdapterExtension,
9831 + IN PSGMAP_CONTEXT SgMapContext
9835 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9836 + IN PVOID AdapterExtension,
9837 + IN PVOID AdapterAddress
9841 +(*PFSA_INTERRUPT_HOST)(
9843 + ADAPTER_EVENT AdapterEvent
9847 +(*PFSA_ENABLE_INTERRUPT)(
9849 + ADAPTER_EVENT AdapterEvent,
9850 + BOOLEAN AtDeviceIrq
9855 +(*PFSA_DISABLE_INTERRUPT)(
9857 + ADAPTER_EVENT AdapterEvent,
9858 + BOOLEAN AtDeviceIrq
9862 +(*PFSA_OPEN_ADAPTER) (
9867 +(*PFSA_DEVICE_CONTROL) (
9869 + IN PAFA_IOCTL_CMD IoctlCmdPtr
9873 +(*PFSA_CLOSE_ADAPTER) (
9878 +(*PFSA_SEND_SYNCH_FIB) (
9880 + IN ULONG FibPhysicalAddress
9883 +typedef struct _FSAPORT_FUNCS {
9884 + ULONG SizeOfFsaPortFuncs;
9886 + PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9887 + PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9888 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9889 + PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9890 + PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9891 + PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9892 + PFSA_NOTIFY_ADAPTER NotifyAdapter;
9893 + PFSA_ENABLE_INTERRUPT EnableInterrupt;
9894 + PFSA_DISABLE_INTERRUPT DisableInterrupt;
9895 + PFSA_RESET_DEVICE ResetDevice;
9896 + PFSA_BUILD_SGMAP BuildSgMap;
9897 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9899 + PFSA_INTERRUPT_HOST InterruptHost;
9900 + PFSA_OPEN_ADAPTER OpenAdapter;
9901 + PFSA_DEVICE_CONTROL DeviceControl;
9902 + PFSA_CLOSE_ADAPTER CloseAdapter;
9904 + PFSA_SEND_SYNCH_FIB SendSynchFib;
9907 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9910 +(*PFSA_SETVAR_CALLBACK) (
9915 +typedef struct _FSA_USER_VAR {
9918 + PFSA_SETVAR_CALLBACK SetVarCallback;
9921 +typedef FSA_USER_VAR *PFSA_USER_VAR;
9923 +typedef struct _FSA_NEW_ADAPTER {
9924 + PVOID AdapterExtension;
9925 + PFSAPORT_FUNCS AdapterFuncs;
9927 + BOOLEAN AdapterInterruptsBelowDpc;
9928 + PFSA_USER_VAR AdapterUserVars;
9929 + ULONG AdapterUserVarsSize;
9932 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
9934 +#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9935 +#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9938 diff -urN linux/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
9939 --- linux/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 19:00:00 1969
9940 +++ linux/drivers/scsi/aacraid/include/fsatypes.h Thu Dec 21 13:14:30 2000
9943 + * Adaptec aacraid device driver for Linux.
9945 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9947 + * This program is free software; you can redistribute it and/or modify
9948 + * it under the terms of the GNU General Public License as published by
9949 + * the Free Software Foundation; either version 2, or (at your option)
9950 + * any later version.
9952 + * This program is distributed in the hope that it will be useful,
9953 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9954 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9955 + * GNU General Public License for more details.
9957 + * You should have received a copy of the GNU General Public License
9958 + * along with this program; see the file COPYING. If not, write to
9959 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9964 + * Abstract: Define all shared data types here, ie, those
9965 + * types shared among several components, such
9966 + * as host (driver + apps), adapter, and BIOS.
9970 +#ifndef _FSATYPES_H
9971 +#define _FSATYPES_H
9973 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
9975 +typedef AAC_UINT32 AAC_BOOLEAN;
9978 +// Define a 64-bit address structure for use on
9979 +// a 32-bit processor architecture.
9984 +} AAC_UINT64S, *PAAC_UINT64S;
9992 + AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
9993 + // know what it looks like. Note, BIOS sees this
9994 + // definition and it must be coded in such a way
9995 + // that it appears to be 64 bits. ints are 16 bits
9996 + // in BIOS land; fortunately, longs are 32 bits.
10002 +// ***********************
10003 +// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10004 +// ***********************
10005 +// drivers for CT_NONE to CT_PASSTHRU
10007 +typedef enum _FSAVOLTYPE {
10018 + CT_RAID10, // stripe of mirror
10019 + CT_RAID00, // stripe of stripe
10020 + CT_VOLUME_OF_MIRRORS, // volume of mirror
10021 + CT_PSEUDO_RAID3, // really raid4
10023 + CT_LAST_VOLUME_TYPE
10027 +#ifdef AAC_32BIT_ENUMS
10028 +typedef _E_FSAVOLTYPE FSAVOLTYPE;
10030 +typedef AAC_UINT32 FSAVOLTYPE;
10035 +// Types of objects addressable in some fashion by the client.
10036 +// This is a superset of those objects handled just by the filesystem
10037 +// and includes "raw" objects that an administrator would use to
10038 +// configure containers and filesystems.
10040 +typedef enum _FTYPE {
10041 + FT_REG = 1, // regular file
10042 + FT_DIR, // directory
10043 + FT_BLK, // "block" device - reserved
10044 + FT_CHR, // "character special" device - reserved
10045 + FT_LNK, // symbolic link
10046 + FT_SOCK, // socket
10048 + FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10049 + FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10050 + FT_SLICE, // virtual disk - raw volume - slice
10051 + FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10052 + FT_VOLUME, // Container - Volume Set
10053 + FT_STRIPE, // Container - Stripe Set
10054 + FT_MIRROR, // Container - Mirror Set
10055 + FT_RAID5, // Container - Raid 5 Set
10056 + FT_DATABASE // Storage object with "foreign" content manager
10059 +#ifdef AAC_32BIT_ENUMS
10060 +typedef _E_FTYPE FTYPE;
10062 +typedef AAC_UINT32 FTYPE;
10068 +// Host side memory scatter gather list
10069 +// Used by the adapter for read, write, and readdirplus operations
10071 +typedef PAAC_UINT8 HOSTADDRESS;
10073 +typedef struct _SGENTRY {
10074 + HOSTADDRESS SgAddress; /* 32-bit Base address. */
10075 + AAC_UINT32 SgByteCount; /* Length. */
10077 +typedef SGENTRY *PSGENTRY;
10084 +// This is the SGMAP structure for all commands that use
10085 +// 32-bit addressing.
10087 +// Note that the upper 16 bits of SgCount are used as flags.
10088 +// Only the lower 16 bits of SgCount are actually used as the
10089 +// SG element count.
10091 +typedef struct _SGMAP {
10092 + AAC_UINT32 SgCount;
10093 + SGENTRY SgEntry[1];
10095 +typedef SGMAP *PSGMAP;
10102 +// This is the SGMAP structure for 64-bit container commands.
10104 +typedef struct _SGMAP64 {
10105 + AAC_UINT8 SgCount;
10106 + AAC_UINT8 SgSectorsPerPage;
10107 + AAC_UINT16 SgByteOffset; // For the first page
10108 + AAC_UINT64S SgEntry[1]; // Must be last entry
10110 +typedef SGMAP64 *PSGMAP64;
10116 +// attempt at common time structure across host and adapter
10118 +typedef struct __TIME_T {
10120 + AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10121 + AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10124 +typedef TIME_T *PTIME_T;
10127 +#define timespec __TIME_T
10128 +#define ts_sec tv_sec
10129 +#define ts_nsec tv_usec
10135 +typedef struct _ContainerCreationInfo
10138 + AAC_UINT8 ViaBuildNumber; // e.g., 588
10139 + AAC_UINT8 MicroSecond; // e.g., 588
10140 + AAC_UINT8 Via; // e.g., 1 = FSU,
10142 + AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10143 + AAC_UINT32 Date; //
10144 + // unsigned Month :4; // 1 - 12
10145 + // unsigned Day :6; // 1 - 32
10146 + // unsigned Hour :6; // 0 - 23
10147 + // unsigned Minute :6; // 0 - 60
10148 + // unsigned Second :6; // 0 - 60
10149 + SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10150 +} ContainerCreationInfo;
10153 +#endif // _FSATYPES_H
10156 diff -urN linux/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10157 --- linux/drivers/scsi/aacraid/include/linit.h Wed Dec 31 19:00:00 1969
10158 +++ linux/drivers/scsi/aacraid/include/linit.h Thu Dec 21 13:14:30 2000
10161 + * Adaptec aacraid device driver for Linux.
10163 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10165 + * This program is free software; you can redistribute it and/or modify
10166 + * it under the terms of the GNU General Public License as published by
10167 + * the Free Software Foundation; either version 2, or (at your option)
10168 + * any later version.
10170 + * This program is distributed in the hope that it will be useful,
10171 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10172 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10173 + * GNU General Public License for more details.
10175 + * You should have received a copy of the GNU General Public License
10176 + * along with this program; see the file COPYING. If not, write to
10177 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10182 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10185 +/*------------------------------------------------------------------------------
10186 + * I N C L U D E S
10187 + *----------------------------------------------------------------------------*/
10192 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10194 +#include <linux/config.h>
10196 +/*------------------------------------------------------------------------------
10198 + *----------------------------------------------------------------------------*/
10199 +/* Define the AAC SCSI Host Template structure. */
10200 +#define AAC_HOST_TEMPLATE_ENTRY \
10201 + { name: "AAC", /* Driver Name */ \
10202 + proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10203 + detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10204 + release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10205 + info: AAC_DriverInfo, /* Driver Info Function */ \
10206 + ioctl: AAC_Ioctl, /* ioctl Interface */ \
10207 + command: AAC_Command, /* unqueued command */ \
10208 + queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10209 + abort: AAC_AbortCommand, /* Abort Command Function */ \
10210 + reset: AAC_ResetCommand, /* Reset Command Function */ \
10211 + bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10212 + can_queue: 1, /* Default initial value */ \
10213 + this_id: 0, /* Default initial value */ \
10214 + sg_tablesize: 0, /* Default initial value */ \
10215 + cmd_per_lun: 0, /* Default initial value */ \
10216 + present: 0, /* Default initial value */ \
10217 + unchecked_isa_dma: 0, /* Default Initial Value */ \
10218 + use_new_eh_code: 0, /* Default initial value */ \
10219 + eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10220 + eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10221 + eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10222 + eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10223 + eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10224 + use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10228 +/*------------------------------------------------------------------------------
10229 + * T Y P E D E F S / S T R U C T S
10230 + *----------------------------------------------------------------------------*/
10231 +typedef struct AAC_BIOS_DiskParameters
10236 +} AAC_BIOS_DiskParameters_T;
10239 +/*------------------------------------------------------------------------------
10240 + * P R O G R A M G L O B A L S
10241 + *----------------------------------------------------------------------------*/
10243 +const char *AAC_DriverInfo( struct Scsi_Host * );
10246 +/*------------------------------------------------------------------------------
10247 + * F U N C T I O N P R O T O T Y P E S
10248 + *----------------------------------------------------------------------------*/
10249 +/* Define prototypes for the AAC Driver Interface Functions. */
10250 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10251 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10252 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10253 +int AAC_Command( Scsi_Cmnd * );
10254 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10255 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10256 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10257 +int AAC_Ioctl( Scsi_Device *, int, void * );
10260 +void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10263 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10265 +#endif /* _LINIT_H_ */
10266 diff -urN linux/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10267 --- linux/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 19:00:00 1969
10268 +++ linux/drivers/scsi/aacraid/include/monkerapi.h Thu Dec 21 13:14:30 2000
10271 + * Adaptec aacraid device driver for Linux.
10273 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10275 + * This program is free software; you can redistribute it and/or modify
10276 + * it under the terms of the GNU General Public License as published by
10277 + * the Free Software Foundation; either version 2, or (at your option)
10278 + * any later version.
10280 + * This program is distributed in the hope that it will be useful,
10281 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10282 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10283 + * GNU General Public License for more details.
10285 + * You should have received a copy of the GNU General Public License
10286 + * along with this program; see the file COPYING. If not, write to
10287 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10292 + * Abstract: This module contains the definitions used by the Host Adapter
10293 + * Communications interface.
10294 + * This is the interface used for by host programs and the Adapter
10295 + * to communicate via synchronous commands via a shared set of registers
10296 + * on a platform (typically doorbells and mailboxes).
10299 +//**********************************************************************
10301 +// Monitor / Kernel API
10303 +// 03/24/1998 Bob Peret Initial creation
10305 +//**********************************************************************
10310 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10312 +#define BREAKPOINT_REQUEST 0x00000004
10313 +#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10316 +#define SEND_SYNCHRONOUS_FIB 0x0000000c
10321 +// Adapter Status Register
10323 +// Phase Staus mailbox is 32bits:
10324 +// <31:16> = Phase Status
10327 +// The adapter reports is present state through the phase. Only
10328 +// a single phase should be ever be set. Each phase can have multiple
10329 +// phase status bits to provide more detailed information about the
10330 +// state of the board. Care should be taken to ensure that any phase status
10331 +// bits that are set when changing the phase are also valid for the new phase
10332 +// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10333 +// for properly maintining the phase status mailbox when it is running.
10336 +// MONKER_API Phases
10338 +// Phases are bit oriented. It is NOT valid
10339 +// to have multiple bits set
10343 +#define SELF_TEST_FAILED 0x00000004
10346 +#define KERNEL_UP_AND_RUNNING 0x00000080
10347 +#define KERNEL_PANIC 0x00000100
10352 +// Doorbell bit defines
10356 +#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10359 +#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10360 +#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10361 +#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10362 +#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10363 +#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10366 +#endif // MONKER_H
10368 diff -urN linux/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10369 --- linux/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 19:00:00 1969
10370 +++ linux/drivers/scsi/aacraid/include/nodetype.h Thu Dec 21 13:14:30 2000
10373 + * Adaptec aacraid device driver for Linux.
10375 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10377 + * This program is free software; you can redistribute it and/or modify
10378 + * it under the terms of the GNU General Public License as published by
10379 + * the Free Software Foundation; either version 2, or (at your option)
10380 + * any later version.
10382 + * This program is distributed in the hope that it will be useful,
10383 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10384 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10385 + * GNU General Public License for more details.
10387 + * You should have received a copy of the GNU General Public License
10388 + * along with this program; see the file COPYING. If not, write to
10389 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10394 + * Abstract: This module defines all of the node type codes used in this development
10395 + * shell. Every major data structure in the file system is assigned a node
10396 + * type code that is. This code is the first CSHORT in the structure and is
10397 + * followed by a CSHORT containing the size, in bytes, of the structure.
10400 +#ifndef _NODETYPE_
10401 +#define _NODETYPE_
10403 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10405 +typedef CSHORT NODE_TYPE_CODE;
10408 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10409 +#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10412 +typedef CSHORT NODE_BYTE_SIZE;
10416 +// The following definitions are used to generate meaningful blue bugcheck
10417 +// screens. On a bugcheck the file system can output 4 ulongs of useful
10418 +// information. The first ulong will have encoded in it a source file id
10419 +// (in the high word) and the line number of the bugcheck (in the low word).
10420 +// The other values can be whatever the caller of the bugcheck routine deems
10423 +// Each individual file that calls bugcheck needs to have defined at the
10424 +// start of the file a constant called BugCheckFileId with one of the
10425 +// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10430 +#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10431 +#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10434 +#define FsaBugCheck(A,B,C) { cmn_err( CE_PANIC, "aacdisk: module %x, line %x, 0x%x, 0x%x, 0x%x ", BugCheckFileId, __LINE__, A, B, C); }
10437 +#endif // _NODETYPE_
10439 diff -urN linux/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10440 --- linux/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 19:00:00 1969
10441 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h Thu Dec 21 13:14:30 2000
10444 + * Adaptec aacraid device driver for Linux.
10446 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10448 + * This program is free software; you can redistribute it and/or modify
10449 + * it under the terms of the GNU General Public License as published by
10450 + * the Free Software Foundation; either version 2, or (at your option)
10451 + * any later version.
10453 + * This program is distributed in the hope that it will be useful,
10454 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10455 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10456 + * GNU General Public License for more details.
10458 + * You should have received a copy of the GNU General Public License
10459 + * along with this program; see the file COPYING. If not, write to
10460 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10465 + * Abstract: This file defines the data structures related to querying
10466 + * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10469 +#ifndef _NVRAMIOCTL_H_
10470 +#define _NVRAMIOCTL_H_ 1
10472 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10475 + * NVRAM/Write Cache subsystem states
10477 +typedef enum _NVSTATUS {
10478 + NVSTATUS_DISABLED = 0, // present, clean, not being used
10479 + NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10480 + NVSTATUS_ERROR, // present, dirty, contains dirty data
10481 + // for bad/missing device
10482 + NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10483 + // for bad/missing device
10484 + NVSTATUS_UNKNOWN // present?????
10487 +#ifdef AAC_32BIT_ENUMS
10488 +typedef _E_NVSTATUS NVSTATUS;
10490 +typedef AAC_UINT32 NVSTATUS;
10494 + * NVRAM/Write Cache subsystem battery component states
10497 +//NB: this enum should be identical to battery_status in nvram.h
10498 +// or else collapsed into one enum someday
10499 +typedef enum _NVBATTSTATUS {
10500 + NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10501 + NVBATTSTATUS_LOW, // battery is low on power
10502 + NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10503 + NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10504 +} _E_NVBATTSTATUS;
10506 +#ifdef AAC_32BIT_ENUMS
10507 +typedef _E_NVBATTSTATUS NVBATTSTATUS;
10509 +typedef AAC_UINT32 NVBATTSTATUS;
10513 + * battery transition type
10515 +typedef enum _NVBATT_TRANSITION {
10516 + NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10517 + NVBATT_TRANSITION_LOW, // battery is now low on power
10518 + NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10519 +} _E_NVBATT_TRANSITION;
10521 +#ifdef AAC_32BIT_ENUMS
10522 +typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10524 +typedef AAC_UINT32 NVBATT_TRANSITION;
10528 + * NVRAM Info structure returned for NVRAM_GetInfo call
10530 +typedef struct _NVRAMDEVINFO {
10531 + AAC_UINT32 NV_Enabled; /* write caching enabled */
10532 + AAC_UINT32 NV_Error; /* device in error state */
10533 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10534 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10535 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10537 +typedef struct _NVRAMINFO {
10538 + NVSTATUS NV_Status; /* nvram subsystem status */
10539 + NVBATTSTATUS NV_BattStatus; /* battery status */
10540 + AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10541 + AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10542 + AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10543 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10544 + AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10545 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10546 + AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10547 + NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10548 + AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10549 + AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10550 +} NVRAMINFO, *PNVRAMINFO;
10552 +#endif /* !_NVRAMIOCTL_H_ */
10555 diff -urN linux/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10556 --- linux/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 19:00:00 1969
10557 +++ linux/drivers/scsi/aacraid/include/osheaders.h Thu Dec 21 13:14:30 2000
10560 + * Adaptec aacraid device driver for Linux.
10562 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10564 + * This program is free software; you can redistribute it and/or modify
10565 + * it under the terms of the GNU General Public License as published by
10566 + * the Free Software Foundation; either version 2, or (at your option)
10567 + * any later version.
10569 + * This program is distributed in the hope that it will be useful,
10570 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10571 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10572 + * GNU General Public License for more details.
10574 + * You should have received a copy of the GNU General Public License
10575 + * along with this program; see the file COPYING. If not, write to
10576 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10581 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10584 +#ifndef _OSHEADERS_H_
10585 +#define _OSHEADERS_H_
10587 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10589 +#include <linux/autoconf.h> // retrieve the kernel configuration info
10590 +#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10591 +#define MODVERSIONS // force it on
10594 +#include <linux/version.h>
10596 +#if defined( MODVERSIONS ) && defined( MODULE )
10597 +#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10599 +#include <linux/modversions-smp.h>
10600 +#elif defined( BOOT_DRIVER )
10601 +#include <linux/modversions-BOOT.h>
10603 +#include <linux/modversions-up.h>
10604 +#endif // ifdef __SMP__
10606 +#include <linux/modversions.h>
10611 +#include <linux/kernel.h>
10612 +#include <linux/config.h>
10613 +#include <linux/init.h>
10614 +#include <linux/types.h>
10615 +#include <linux/blk.h>
10616 +#include <linux/blkdev.h>
10617 +#include <linux/delay.h>
10618 +#include <linux/ioport.h>
10619 +#include <linux/mm.h>
10620 +#include <linux/sched.h>
10621 +#include <linux/stat.h>
10622 +#include <linux/pci.h>
10623 +#include <linux/interrupt.h>
10624 +#include <asm/dma.h>
10625 +#include <asm/io.h>
10626 +#include <linux/spinlock.h>
10627 +#include <asm/system.h>
10628 +#include <asm/bitops.h>
10629 +#include <asm/uaccess.h>
10630 +#include <linux/wait.h>
10631 +#include <linux/malloc.h>
10632 +#include <linux/tqueue.h>
10634 +#include <linux/tasks.h>
10636 +#include <ostypes.h>
10638 +#include "hosts.h"
10641 +#define intptr_t void *
10645 +#define cred_t void
10649 +#define paddr32_t unsigned
10653 +#define bzero(b,len) memset(b,0,len)
10657 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10661 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10664 +typedef unsigned uint_t;
10677 +#define CMN_ERR_LEVEL CE_NOTE
10683 +// usage of READ & WRITE as a typedefs in protocol.h
10684 +// conflicts with <linux/fs.h> definition.
10693 +typedef struct aac_options
10695 + int message_level;
10696 + int reverse_scan;
10699 +#endif // _OSHEADERS_H_
10709 diff -urN linux/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10710 --- linux/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 19:00:00 1969
10711 +++ linux/drivers/scsi/aacraid/include/ostypes.h Thu Dec 21 13:14:30 2000
10714 + * Adaptec aacraid device driver for Linux.
10716 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10718 + * This program is free software; you can redistribute it and/or modify
10719 + * it under the terms of the GNU General Public License as published by
10720 + * the Free Software Foundation; either version 2, or (at your option)
10721 + * any later version.
10723 + * This program is distributed in the hope that it will be useful,
10724 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10725 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10726 + * GNU General Public License for more details.
10728 + * You should have received a copy of the GNU General Public License
10729 + * along with this program; see the file COPYING. If not, write to
10730 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10735 + * Abstract: Holds all of the O/S specific types.
10738 +/*------------------------------------------------------------------------------
10740 + *----------------------------------------------------------------------------*/
10741 +#ifndef _OSTYPES_H_
10742 +#define _OSTYPES_H_
10744 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10746 +#include <linux/types.h>
10748 +#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10749 +#define MAXIMUM_NUM_ADAPTERS 8
10751 +#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10753 +#define Os_remove_softintr OsSoftInterruptRemove
10754 +#define OsPrintf printk
10755 +#define FsaCommPrint
10757 +// the return values for copy_from_user & copy_to_user is the
10758 +// number of bytes not transferred. Thus if an internal error
10759 +// occurs, the return value is greater than zero.
10760 +#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10761 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10763 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10764 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10766 +/*------------------------------------------------------------------------------
10767 + * S T R U C T S / T Y P E D E F S
10768 + *----------------------------------------------------------------------------*/
10769 +typedef struct OS_MUTEX
10771 + unsigned long lock_var;
10772 + wait_queue_head_t wq;
10776 +typedef struct OS_SPINLOCK
10778 + spinlock_t spin_lock;
10779 + unsigned cpu_lock_count[NR_CPUS];
10781 + long lockout_count;
10784 +#ifdef CVLOCK_USE_SPINLOCK
10785 + typedef OS_SPINLOCK OS_CVLOCK;
10787 + typedef OS_MUTEX OS_CVLOCK;
10790 +typedef size_t OS_SIZE_T;
10792 +typedef struct OS_CV_T
10794 + unsigned long lock_var;
10795 + unsigned long type;
10796 + wait_queue_head_t wq;
10799 +struct fsa_scsi_hba {
10800 + void *CommonExtension;
10801 + unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10802 + unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10803 + unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10804 + unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10805 + unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10806 + unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10807 + long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10810 +typedef struct fsa_scsi_hba fsadev_t;
10812 +typedef struct OsKI
10814 + struct Scsi_Host *scsi_host_ptr;
10815 + void * dip; // #REVISIT#
10816 + fsadev_t fsa_dev;
10818 + int MiniPortIndex;
10821 +#define dev_info_t fsadev_t
10823 +typedef int OS_SPINLOCK_COOKIE;
10825 +typedef unsigned int OS_STATUS;
10827 +typedef struct tq_struct OS_SOFTINTR;
10829 +typedef OS_SOFTINTR *ddi_softintr_t;
10833 +//-----------------------------------------------------------------------------
10834 +// Conditional variable functions
10837 + OS_CV_T *cv_ptr );
10840 +//-----------------------------------------------------------------------------
10841 +// Printing functions
10842 +void printk_err(int flag, char *fmt, ...);
10844 +#define cmn_err printk_err
10848 +// just ignore these solaris ddi functions in the code
10850 +#define DDI_SUCCESS 0
10852 +#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10855 +#define ddi_remove_softintr(A) 0
10856 +#define ddi_get_soft_iblock_cookie(A, B, C) 0
10858 +#define ASSERT(expr) ((void) 0)
10859 +#define drv_usecwait udelay
10861 +#endif // _OSTYPES_H_
10862 diff -urN linux/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10863 --- linux/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 19:00:00 1969
10864 +++ linux/drivers/scsi/aacraid/include/pcisup.h Thu Dec 21 13:14:30 2000
10867 + * Adaptec aacraid device driver for Linux.
10869 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10871 + * This program is free software; you can redistribute it and/or modify
10872 + * it under the terms of the GNU General Public License as published by
10873 + * the Free Software Foundation; either version 2, or (at your option)
10874 + * any later version.
10876 + * This program is distributed in the hope that it will be useful,
10877 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10878 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10879 + * GNU General Public License for more details.
10881 + * You should have received a copy of the GNU General Public License
10882 + * along with this program; see the file COPYING. If not, write to
10883 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10888 + * Abstract: This module defines functions that are defined in PciSup.c
10894 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10898 + * define which interrupt handler needs to be installed
10904 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10905 + ULONG AdapterNumber; // Which FSA# this miniport is
10907 + ULONG PciBusNumber; // Which PCI bus we are located on
10908 + ULONG PciSlotNumber; // Whiat PCI slot we are in
10910 + PVOID Adapter; // Back pointer to Fsa adapter object
10911 + ULONG AdapterIndex; // Index into PlxAdapterTypes array
10912 + PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10914 + FSAPORT_FUNCS AdapterFuncs;
10915 + ULONG FilesystemRevision; // Main driver's revision number
10918 + PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
10919 + PVOID PhysicalInitStruct; // Holds physical address of the init struct
10922 + PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
10924 + BOOLEAN AdapterPrintfsToScreen;
10925 + BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
10929 + caddr_t CommAddress; // Base address of Comm area
10930 + paddr32_t CommPhysAddr; // Physical Address of Comm area
10933 + OsKI_t OsDep; // OS dependent kernel interfaces
10936 +} PCI_MINIPORT_COMMON_EXTENSION;
10938 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
10941 +(*PFSA_MINIPORT_INIT) (
10942 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
10943 + IN ULONG AdapterNumber,
10948 +typedef struct _FSA_MINIPORT {
10951 + USHORT SubVendorId;
10952 + USHORT SubSystemId;
10953 + PCHAR DevicePrefix;
10954 + PFSA_MINIPORT_INIT InitRoutine;
10955 + PCHAR DeviceName;
10959 +typedef FSA_MINIPORT *PFSA_MINIPORT;
10962 +#endif // _PCISUP_
10963 diff -urN linux/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
10964 --- linux/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 19:00:00 1969
10965 +++ linux/drivers/scsi/aacraid/include/perfpack.h Thu Dec 21 13:14:30 2000
10968 + * Adaptec aacraid device driver for Linux.
10970 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10972 + * This program is free software; you can redistribute it and/or modify
10973 + * it under the terms of the GNU General Public License as published by
10974 + * the Free Software Foundation; either version 2, or (at your option)
10975 + * any later version.
10977 + * This program is distributed in the hope that it will be useful,
10978 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10979 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10980 + * GNU General Public License for more details.
10982 + * You should have received a copy of the GNU General Public License
10983 + * along with this program; see the file COPYING. If not, write to
10984 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10989 + * Abstract: This file defines the layout of the performance data that is passed
10990 + * back from the FSA filesystem driver.
10995 +#ifndef _FSA_PERFPACK_H_
10996 +#define _FSA_PERFPACK_H_ 1
10998 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11000 +//#define FSA_DO_PERF 1 /* enable the engineering counters */
11002 +#ifdef FSA_DO_PERF
11004 +// engineering counters
11006 +typedef struct _FSA_PERF_DATA {
11014 + ULONG CreateFibs;
11016 + ULONG RemoveFibs;
11017 + ULONG RemoveDirs;
11018 + ULONG RenameFibs;
11019 + ULONG ReadDirPlus;
11021 + ULONG WriteBytes;
11023 +// NT FSA entry points
11024 + ULONG FsaFsdCreateCount;
11025 + ULONG FsaFsdCloseCount;
11026 + ULONG FsaFsdReadCount;
11027 + ULONG FsaFsdWriteCount;
11028 + ULONG FsaFsdQueryInformationCount;
11030 + struct _FsaFsdSetInfomation{
11031 + ULONG FsaSetAllocationInfoCount;
11032 + ULONG FsaSetBasicInfoCount;
11033 + ULONG FsaSetDispositionInfoCount;
11034 + ULONG FsaSetEndOfFileInfoCount;
11035 + ULONG FsaSetPositionInfoCount;
11036 + ULONG FsaSetRenameInfoCount;
11037 + ULONG FsaClearArchiveBitCount;
11040 + ULONG FsaFsdFlushBuffersCount;
11041 + ULONG FsaFsdQueryVolumeInfoCount;
11042 + ULONG FsaFsdSetVolumeInfoCount;
11043 + ULONG FsaFsdCleanupCount;
11044 + ULONG FsaFsdDirectoryControlCount;
11045 + ULONG FsaFsdFileSystemControlCount;
11046 + ULONG FsaFsdLockControlCount;
11047 + ULONG FsaFsdDeviceControlCount;
11048 + ULONG FsaFsdShutdownCount;
11049 + ULONG FsaFsdQuerySecurityInfo;
11050 + ULONG FsaFsdSetSecurityInfo;
11051 + ULONG FastIoCheckIfPossibleCount;
11052 + ULONG FastIoReadCount;
11053 + ULONG FastIoWriteCount;
11054 + ULONG FastIoQueryBasicInfoCount;
11055 + ULONG FastIoQueryStandardInfoCount;
11056 + ULONG FastIoLockCount;
11057 + ULONG FastIoUnlockSingleCount;
11058 + ULONG FastIoUnlockAllCount;
11059 + ULONG FastIoUnlockAllByKeyCount;
11060 + ULONG FastIoDeviceControlCount;
11063 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11066 +#else /* FSA_DO_PERF */
11069 +// engineering performance counters are disabled
11071 +#define FSA_DO_PERF_INC(Counter) /* */
11072 +#define FSA_DO_FSP_PERF_INC(Counter) /* */
11074 +#endif /* FSA_DO_PERF */
11076 +#endif // _FSA_PERFPACK_H_
11077 diff -urN linux/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11078 --- linux/drivers/scsi/aacraid/include/port.h Wed Dec 31 19:00:00 1969
11079 +++ linux/drivers/scsi/aacraid/include/port.h Thu Dec 21 13:14:30 2000
11082 + * Adaptec aacraid device driver for Linux.
11084 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11086 + * This program is free software; you can redistribute it and/or modify
11087 + * it under the terms of the GNU General Public License as published by
11088 + * the Free Software Foundation; either version 2, or (at your option)
11089 + * any later version.
11091 + * This program is distributed in the hope that it will be useful,
11092 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11093 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11094 + * GNU General Public License for more details.
11096 + * You should have received a copy of the GNU General Public License
11097 + * along with this program; see the file COPYING. If not, write to
11098 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11103 + * Abstract: This module defines functions and structures that are in common among all miniports
11111 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11114 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11115 +extern int AfaPortPrinting;
11117 +#define AfaPortPrint
11120 +extern int AfaPortPrinting;
11124 +AfaPortAllocateAdapterCommArea(
11126 + IN OUT PVOID *CommHeaderAddress,
11127 + IN ULONG CommAreaSize,
11128 + IN ULONG CommAreaAlignment
11133 +AfaPortFreeAdapterCommArea(
11139 +AfaPortBuildSgMap(
11141 + IN PSGMAP_CONTEXT SgMapContext
11146 +AfaPortFreeDmaResources(
11148 + IN PSGMAP_CONTEXT SgMapContext
11153 +AfaPortAllocateAndMapFibSpace(
11155 + IN PMAPFIB_CONTEXT MapFibContext
11160 +AfaPortUnmapAndFreeFibSpace(
11162 + IN PMAPFIB_CONTEXT MapFibContext
11168 diff -urN linux/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11169 --- linux/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 19:00:00 1969
11170 +++ linux/drivers/scsi/aacraid/include/protocol.h Thu Dec 21 13:14:30 2000
11173 + * Adaptec aacraid device driver for Linux.
11175 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11177 + * This program is free software; you can redistribute it and/or modify
11178 + * it under the terms of the GNU General Public License as published by
11179 + * the Free Software Foundation; either version 2, or (at your option)
11180 + * any later version.
11182 + * This program is distributed in the hope that it will be useful,
11183 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11184 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11185 + * GNU General Public License for more details.
11187 + * You should have received a copy of the GNU General Public License
11188 + * along with this program; see the file COPYING. If not, write to
11189 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11194 + * Abstract: Defines the commands and command data which enables the nt
11195 + * filesystem driver to be the client of the fsa adapter
11196 + * filesystem. This protocol is largely modeled after the NFS
11197 + * V3 protocol with modifications allowed due to the unique
11198 + * client/server model FSA works under.
11204 +#ifndef _PROTOCOL_H_
11205 +#define _PROTOCOL_H_
11207 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11209 +#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11210 +#include <nvramioctl.h> // for NVRAMINFO definition
11212 +// #define MDL_READ_WRITE
11215 +// Define the command values
11217 +typedef enum _FSA_COMMANDS {
11230 + RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11234 + ReadDirectoryPlus,
11235 + FileSystemStatus,
11245 + SetFileSystemStatus,
11251 +#ifdef MDL_READ_WRITE
11253 + MdlWriteComplete,
11254 + MdlRead, // these are used solely for stats, Mdl really controlled by
11255 + MdlWrite, // flags field in Fib.
11260 + FaultInsertion, // Fault Insertion Command
11261 + CrazyCache, // crazycache
11262 + MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11265 +#ifdef AAC_32BIT_ENUMS
11266 +typedef _E_FSACOMMAND FSACOMMAND;
11268 +typedef AAC_UINT32 FSACOMMAND;
11274 +// Define the status returns
11276 +// See include\comm\errno.h for adapter kernel errno's
11277 +typedef enum _FSASTATUS {
11295 + ST_WOULDBLOCK = 35,
11296 + ST_NAMETOOLONG = 63,
11297 + ST_NOTEMPTY = 66,
11301 + ST_BADHANDLE = 10001,
11302 + ST_NOT_SYNC = 10002,
11303 + ST_BAD_COOKIE = 10003,
11304 + ST_NOTSUPP = 10004,
11305 + ST_TOOSMALL = 10005,
11306 + ST_SERVERFAULT = 10006,
11307 + ST_BADTYPE = 10007,
11308 + ST_JUKEBOX = 10008,
11309 + ST_NOTMOUNTED = 10009,
11310 + ST_MAINTMODE = 10010,
11311 + ST_STALEACL = 10011
11314 +#ifdef AAC_32BIT_ENUMS
11315 +typedef _E_FSASTATUS FSASTATUS;
11317 +typedef AAC_UINT32 FSASTATUS;
11321 +// On writes how does the client want the data written.
11324 +typedef enum _CACHELEVEL {
11329 +#ifdef AAC_32BIT_ENUMS
11330 +typedef _E_CACHELEVEL CACHELEVEL;
11332 +typedef AAC_UINT32 CACHELEVEL;
11336 +// Lets the client know at which level the data was commited on a write request
11339 +typedef enum _COMMITLEVEL {
11340 + CMFILE_SYNCH_NVRAM = 1,
11341 + CMDATA_SYNCH_NVRAM,
11347 +#ifdef AAC_32BIT_ENUMS
11348 +typedef _E_COMMITLEVEL COMMITLEVEL;
11350 +typedef AAC_UINT32 COMMITLEVEL;
11356 +// The following are all the different commands or FIBs which can be sent to the
11357 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11358 +// but others outside that subset are allowed to return not implemented. The client is then
11359 +// responsible for dealing with the fact it is not implemented.
11361 +typedef AAC_INT8 FSASTRING[16];
11364 +typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11372 +typedef struct _BLOCKREAD { // variable size struct
11374 + FSACOMMAND Command;
11375 + AAC_UINT32 ContainerId;
11376 + BYTECOUNT BlockNumber;
11377 + BYTECOUNT ByteCount;
11378 + SGMAP SgMap; // Must be last in struct because it is variable
11381 +typedef BLOCKREAD *PBLOCKREAD;
11383 +typedef struct _BLOCKREADRESPONSE {
11385 + FSASTATUS Status;
11386 + BYTECOUNT ByteCount;
11388 +} BLOCKREADRESPONSE;
11389 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11395 +typedef struct _BLOCKWRITE { // variable size struct
11397 + FSACOMMAND Command;
11398 + AAC_UINT32 ContainerId;
11399 + BYTECOUNT BlockNumber;
11400 + BYTECOUNT ByteCount;
11401 + CACHELEVEL Stable;
11402 + SGMAP SgMap; // Must be last in struct because it is variable
11405 +typedef BLOCKWRITE *PBLOCKWRITE;
11408 +typedef struct _BLOCKWRITERESPONSE {
11410 + FSASTATUS Status;
11411 + BYTECOUNT ByteCount;
11412 + COMMITLEVEL Committed;
11414 +} BLOCKWRITERESPONSE;
11415 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11419 +#endif // _PROTOCOL_H_
11421 diff -urN linux/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11422 --- linux/drivers/scsi/aacraid/include/revision.h Wed Dec 31 19:00:00 1969
11423 +++ linux/drivers/scsi/aacraid/include/revision.h Thu Dec 21 13:14:30 2000
11426 + * Adaptec aacraid device driver for Linux.
11428 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11430 + * This program is free software; you can redistribute it and/or modify
11431 + * it under the terms of the GNU General Public License as published by
11432 + * the Free Software Foundation; either version 2, or (at your option)
11433 + * any later version.
11435 + * This program is distributed in the hope that it will be useful,
11436 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11437 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11438 + * GNU General Public License for more details.
11440 + * You should have received a copy of the GNU General Public License
11441 + * along with this program; see the file COPYING. If not, write to
11442 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11447 + * Abstract: This module contains all of the revision information for
11448 + * the FSA product, as well as the support routines for
11449 + * checking module compatibility.
11451 + * Before editing anything in this module, make sure that
11452 + * you read the comments. Some lines are changed automatically
11453 + * as part of the build, and should never be changed by hand.
11455 + * Routines (all inlines):
11457 + * RevGetBuildNumber - Retrieve current build number
11458 + * RevGetExternalRev - Retrieve revision for external use
11459 + * RevGetFullRevision - Retrieve full revision structure
11461 + * RevCheckCompatibility - Checks compatibility base on internal table
11463 + * RevCheckCompatibilityFullInfo - Check for static component
11464 + * RevGetCompInfoTableSize - Get size for static component table
11465 + * RevGetCompInfoTable - Get actual table to place on static component
11466 + * RevGetBuildNumberFromInfo - Get build number for static component.
11472 +#ifndef _REVISION_H
11473 +#define _REVISION_H
11475 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11477 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11479 +typedef int REV_BOOL;
11481 +#define REV_TRUE 1
11482 +#define REV_FALSE 0
11485 +// Define Revision Levels for this product
11487 +// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11488 +// automatically by the build.
11490 +// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11492 +// IMPORTANT: Don't access these revisions directly. They can be
11493 +// accessed via, the RevGetXxxxx rouines.
11497 +#define REV_AS_LONGWORD \
11498 + ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11505 +// Enumerate the types of product levels we can have
11508 + RevType_Devo=1, // Development mode, testing all of latest
11509 + RevType_Alpha, // Alpha - Internal field test
11510 + RevType_Beta, // Beta - External field test
11511 + RevType_Release // Release - Retail version
11515 +// Define the basic structure for all revision information. Note
11516 +// that the ordering of the components is such that they should
11517 +// always increase. dash will be updated the most, then the version
11518 +// type, then minor and major.
11523 + unsigned char dash; // Dash version number
11524 + unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11525 + unsigned char minor;// Minor version minor
11526 + unsigned char major;// Major version number
11527 + } comp; // Components to external viewed rev number
11528 + unsigned long ul; // External revision as single 32-bit value
11529 + } external; // External revision number (union)
11530 + unsigned long buildNumber; // Automatically generated build number
11535 +// Define simple routines to get basic revision information. The
11536 +// definitions should never be accessed directly. These routines
11537 +// are meant to be used to access all relevant information no matter
11540 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11542 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11546 +// Enumerate different components that may have to check
11547 +// compatibility. This list of components can be changed
11550 +// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11551 +// incompatibilities between component rev checking will
11552 +// cause wrong checking results.
11555 + RevApplication = 1, // Any user End application
11556 + RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11557 + RevNetService, // Network Service Revision (under API)
11558 + RevApi, // ADAPTEC User mode API
11559 + RevFileSysDriver, // FSA File System Driver
11560 + RevMiniportDriver, // FSA File System Miniport Driver
11561 + RevAdapterSW, // Adapter Software (or NT Simulator)
11562 + RevMonitor, // Monitor for adapter hardware (MON960 for now)
11563 + RevRemoteApi // The remote API.
11564 + // ALWAYS ADD NEW COMPONENTS HERE - AT END
11568 +// Define a structure so that we can create a compatibility table.
11571 + RevComponent A,B;
11572 + unsigned long BuildNumOfB_RequiredByA;
11573 + unsigned long BuildNumOfA_RequiredByB;
11574 +} RevCompareElement;
11577 +// Now, define the table. This table should only be included once,
11578 +// in one program. If it is linked from 2 modules, there will likely
11579 +// be a multiply defined symbol error from the linker.
11581 +// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11582 +// allow access to the revision information table without a redefinition
11585 +extern const int RevCompareTableLength;
11587 +extern const RevCompareElement RevCompareTable[];
11589 +/********************************************************************\
11590 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11592 +* The following routine is used to check compatibility between
11593 +* the calling component and a component that has some dependencies
11594 +* on it. If this routine returns REV_FALSE, it is expected that the caller
11595 +* will send an appropriate incompatibility message and stop.
11597 +* This routine is only meant to check for compatibility in the
11598 +* absolute sense. If code wishes to execute a different path based
11599 +* on the CompB_BuildNumber, then this routine is not useful. The
11600 +* routine RevGetBuildNumber can be used to get the calling module's
11601 +* current build number for a comparison check.
11603 +* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11604 +* if the components are definitely not compatible, or there is an
11605 +* error when trying to figure it out. To be more specific:
11607 +* 1) REV_TRUE if component B is newer than calling component. (In this
11608 +* case, the revision check done by component B with respect to
11609 +* this component will give the real compatibility information.
11610 +* It is the only one with the knowledge, since this component
11611 +* could not look into the future.)
11612 +* 2) REV_TRUE if calling component is more recent and table shows okay
11613 +* 3) REV_FALSE if calling component more recent and table show not okay
11614 +* 4) REV_FALSE if calling component is more recent and table entry to
11615 +* check does not exist.
11617 +* Note that the CompB_BuildNumber must be attained by the calling
11618 +* routine through some mechanism done by the caller.
11622 +* callerComp - Name of component making this call
11623 +* compB - Name of component to check compatibility with
11624 +* compB_BuildNumber - Build number to component B
11632 +* REV_TRUE - Component compatibility is possible, continue as usual. compB
11633 +* must give true compatibility information.
11634 +* REV_FALSE - Incompatible components, notify and end
11636 +\********************************************************************/
11637 +static inline REV_BOOL RevCheckCompatibility(
11638 + RevComponent callerComp,
11639 + RevComponent compB,
11640 + unsigned long compB_BuildNumber)
11643 + unsigned long RevForB;
11646 + // Compatibility check is possible, so we should continue. When
11647 + // compB makes this call in its own component, it will get the
11648 + // true compatibility information, since only it can know.
11650 + if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11653 + // Go through rev table. When the components are found in the
11654 + // same table entry, return the approprate number.
11656 + for (i=0; i<RevCompareTableLength; i++) {
11657 + if (RevCompareTable[i].A == callerComp) {
11658 + if (RevCompareTable[i].B == compB) {
11659 + RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11660 + return (compB_BuildNumber >= RevForB);
11662 + } else if (RevCompareTable[i].B == callerComp) {
11663 + if (RevCompareTable[i].A == compB) {
11664 + RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11665 + return (compB_BuildNumber >= RevForB);
11671 + // Uh oh! No relevant table entry was found (this should never
11674 + return REV_FALSE;
11679 +// Now create a structure that can be used by a FIB to check
11682 +typedef struct _RevCheck {
11683 + RevComponent callingComponent;
11684 + FsaRevision callingRevision;
11687 +typedef struct _RevCheckResp {
11688 + REV_BOOL possiblyCompatible;
11689 + FsaRevision adapterSWRevision;
11693 +#endif /* _REVISION_H */
11696 +// The following allows for inclusion of revision.h in other h
11697 +// files. when you include this file in another h file, simply
11698 +// define REV_REFERENCE_ONLY. This will be undefined later, so that
11699 +// the single C file inclusion in the module will be used to
11700 +// implement the global structures.
11702 +#ifndef REV_REFERENCE_ONLY
11703 +#ifndef _REVISION_H_GLOBAL
11704 +#define _REVISION_H_GLOBAL
11709 +// The following array is the table of compatibility. This table
11710 +// can be modified in two ways:
11712 +// 1) A component which has an incompatible change done to
11713 +// it, can get a new build number.
11715 +// 2) A new component can be added, requiring more entries
11716 +// to be place into this table.
11719 +// In case (1), you must change the revision number in the appropriate
11720 +// column, based on which component absolutely requires an upgrade.
11722 +// Example: A new FIB used by the API, in build number 105
11723 +// {RevApi, RevAdapterSW, 100, 100}
11724 +// ---> would be changed to <---
11725 +// {RevApi, RevAdapterSW, 105, 100}
11727 +// Example: A structure is changed for a FIB that only the API uses
11728 +// {RevApi, RevAdapterSW, 100, 100}
11729 +// ---> would be changed to <---
11730 +// {RevApi, RevAdapterSW, 105, 105}
11733 +// In case (2), the less common case, the enumerated list of
11734 +// components must be changed to include the new component. Then
11735 +// entries need to be placed into this table.
11737 +// Since the revisions must be communicated between the two
11738 +// components, it is likely that you would need to put in the
11739 +// current build number for both columns. That is the recommended
11740 +// way to start revision test.
11742 +const RevCompareElement RevCompareTable[] = {
11743 + // Component A Component B MinBForA MinAForB
11744 + // ----------- ----------- -------- --------
11745 + {RevApplication, RevApi, 2120, 2120 },
11746 + {RevDkiCli, RevApi, 2120, 2120 },
11747 + {RevDkiCli, RevFileSysDriver, 257, 257 },
11748 + {RevDkiCli, RevMiniportDriver, 257, 257 },
11749 + {RevDkiCli, RevAdapterSW, 257, 257 },
11750 + {RevApi, RevFileSysDriver, 2120, 2120 },
11751 + {RevApi, RevMiniportDriver, 2120, 2120 },
11752 + {RevApi, RevAdapterSW, 2120, 2120 },
11753 + {RevApi, RevNetService, 2120, 2120 },
11754 + {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11755 + {RevFileSysDriver, RevAdapterSW, 257, 257 },
11756 + {RevMiniportDriver, RevAdapterSW, 257, 257 },
11757 + {RevMiniportDriver, RevMonitor, 100, 100 },
11758 + {RevApi, RevNetService, 2120, 2120 },
11759 + {RevApi, RevRemoteApi, 2120, 2120 },
11760 + {RevNetService, RevRemoteApi, 2120, 2120 }
11763 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11765 +#endif /* _REVISION_H_GLOBAL */
11766 +#endif /* REV_REFERENCE_ONLY */
11767 +#undef REV_REFERENCE_ONLY
11775 diff -urN linux/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11776 --- linux/drivers/scsi/aacraid/include/rx.h Wed Dec 31 19:00:00 1969
11777 +++ linux/drivers/scsi/aacraid/include/rx.h Thu Dec 21 13:14:30 2000
11780 + * Adaptec aacraid device driver for Linux.
11782 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11784 + * This program is free software; you can redistribute it and/or modify
11785 + * it under the terms of the GNU General Public License as published by
11786 + * the Free Software Foundation; either version 2, or (at your option)
11787 + * any later version.
11789 + * This program is distributed in the hope that it will be useful,
11790 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11791 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11792 + * GNU General Public License for more details.
11794 + * You should have received a copy of the GNU General Public License
11795 + * along with this program; see the file COPYING. If not, write to
11796 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11801 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11806 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11808 +typedef struct _Rx_ADAPTER_EXTENSION {
11811 + // The following must be first.
11813 + PPCI_MINIPORT_COMMON_EXTENSION Common;
11814 + struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11815 + USHORT LocalMaskInterruptControl;
11816 + PRx_DEVICE_REGISTERS Device;
11818 +} Rx_ADAPTER_EXTENSION;
11821 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11830 +#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11834 +#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11835 +#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11838 +#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11840 +#endif /* LINUX */
11844 +RxInterruptAdapter(
11851 + IN HOST_2_ADAP_EVENT AdapterEvent
11860 diff -urN linux/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11861 --- linux/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 19:00:00 1969
11862 +++ linux/drivers/scsi/aacraid/include/rxcommon.h Thu Dec 21 13:14:30 2000
11865 + * Adaptec aacraid device driver for Linux.
11867 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11869 + * This program is free software; you can redistribute it and/or modify
11870 + * it under the terms of the GNU General Public License as published by
11871 + * the Free Software Foundation; either version 2, or (at your option)
11872 + * any later version.
11874 + * This program is distributed in the hope that it will be useful,
11875 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11876 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11877 + * GNU General Public License for more details.
11879 + * You should have received a copy of the GNU General Public License
11880 + * along with this program; see the file COPYING. If not, write to
11881 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11886 + * Abstract: Structures and defines for the i960 Rx chip.
11891 +#ifndef _Rx_COMMON_H_
11892 +#define _Rx_COMMON_H_
11894 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11897 +// Rx Message Unit Registers
11900 +typedef volatile struct _StructRxMURegisters {
11901 + // Local | PCI* | Name
11903 + unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11904 + unsigned reserved0; // 1304h | 04h | Reserved
11905 + unsigned AWR; // 1308h | 08h | APIC Window Register
11906 + unsigned reserved1; // 130Ch | 0Ch | Reserved
11907 + unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11908 + unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11909 + unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11910 + unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11911 + unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11912 + unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11913 + unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11914 + unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11915 + // * Must access trhough ATU Inbound Translation Window
11918 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11920 +typedef volatile struct _Rx_Inbound {
11922 + unsigned Mailbox[8];
11926 +typedef Rx_Inbound *PRx_Inbound;
11928 +#define InboundMailbox0 IndexRegs.Mailbox[0]
11929 +#define InboundMailbox1 IndexRegs.Mailbox[1]
11930 +#define InboundMailbox2 IndexRegs.Mailbox[2]
11931 +#define InboundMailbox3 IndexRegs.Mailbox[3]
11932 +#define InboundMailbox4 IndexRegs.Mailbox[4]
11936 +#define INBOUNDDOORBELL_0 0x00000001
11937 +#define INBOUNDDOORBELL_1 0x00000002
11938 +#define INBOUNDDOORBELL_2 0x00000004
11939 +#define INBOUNDDOORBELL_3 0x00000008
11940 +#define INBOUNDDOORBELL_4 0x00000010
11941 +#define INBOUNDDOORBELL_5 0x00000020
11942 +#define INBOUNDDOORBELL_6 0x00000040
11945 +#define OUTBOUNDDOORBELL_0 0x00000001
11946 +#define OUTBOUNDDOORBELL_1 0x00000002
11947 +#define OUTBOUNDDOORBELL_2 0x00000004
11948 +#define OUTBOUNDDOORBELL_3 0x00000008
11949 +#define OUTBOUNDDOORBELL_4 0x00000010
11952 +#define InboundDoorbellReg MUnit.IDR
11954 +#define OutboundDoorbellReg MUnit.ODR
11957 +typedef struct _Rx_DEVICE_REGISTERS {
11958 + Rx_MU_CONFIG MUnit; // 1300h - 1334h
11959 + unsigned reserved1[6]; // 1338h - 134ch
11960 + Rx_Inbound IndexRegs;
11961 +} Rx_DEVICE_REGISTERS;
11963 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
11966 +#endif // _Rx_COMMON_H_
11969 diff -urN linux/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
11970 --- linux/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 19:00:00 1969
11971 +++ linux/drivers/scsi/aacraid/include/sap1.h Thu Dec 21 13:14:30 2000
11974 + * Adaptec aacraid device driver for Linux.
11976 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11978 + * This program is free software; you can redistribute it and/or modify
11979 + * it under the terms of the GNU General Public License as published by
11980 + * the Free Software Foundation; either version 2, or (at your option)
11981 + * any later version.
11983 + * This program is distributed in the hope that it will be useful,
11984 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11985 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11986 + * GNU General Public License for more details.
11988 + * You should have received a copy of the GNU General Public License
11989 + * along with this program; see the file COPYING. If not, write to
11990 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11995 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12002 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12004 +#define Sa_MINIPORT_REVISION 1
12006 +typedef struct _Sa_ADAPTER_EXTENSION {
12009 + // The following must be first.
12011 + PPCI_MINIPORT_COMMON_EXTENSION Common;
12012 + struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12013 + USHORT LocalMaskInterruptControl;
12014 + PSa_DEVICE_REGISTERS Device;
12016 +} Sa_ADAPTER_EXTENSION;
12018 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12028 +#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12029 +#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12032 +#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12033 +#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12035 +#endif /* LINUX */
12039 +SaInterruptAdapter(
12046 + IN HOST_2_ADAP_EVENT AdapterEvent
12055 +#endif /* _SAP1_H_ */
12058 diff -urN linux/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12059 --- linux/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 19:00:00 1969
12060 +++ linux/drivers/scsi/aacraid/include/sap1common.h Thu Dec 21 13:14:30 2000
12063 + * Adaptec aacraid device driver for Linux.
12065 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12067 + * This program is free software; you can redistribute it and/or modify
12068 + * it under the terms of the GNU General Public License as published by
12069 + * the Free Software Foundation; either version 2, or (at your option)
12070 + * any later version.
12072 + * This program is distributed in the hope that it will be useful,
12073 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12074 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12075 + * GNU General Public License for more details.
12077 + * You should have received a copy of the GNU General Public License
12078 + * along with this program; see the file COPYING. If not, write to
12079 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12084 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12088 +#ifndef _Sa_COMMON_H_
12089 +#define _Sa_COMMON_H_
12091 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12094 +// SaP1 Message Unit Registers
12097 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12099 + unsigned reserved[10]; // 00h-27h | Reserved
12100 + unsigned char LUT_Offset; // 28h | Looup Table Offset
12101 + unsigned char reserved1[3]; // 29h-2bh | Reserved
12102 + unsigned LUT_Data; // 2ch | Looup Table Data
12103 + unsigned reserved2[26]; // 30h-97h | Reserved
12104 + unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12105 + unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12106 + unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12107 + unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12108 + unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12109 + unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12110 + unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12111 + unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12112 + unsigned MAILBOX0; // a8h | Scratchpad 0
12113 + unsigned MAILBOX1; // ach | Scratchpad 1
12114 + unsigned MAILBOX2; // b0h | Scratchpad 2
12115 + unsigned MAILBOX3; // b4h | Scratchpad 3
12116 + unsigned MAILBOX4; // b8h | Scratchpad 4
12117 + unsigned MAILBOX5; // bch | Scratchpad 5
12118 + unsigned MAILBOX6; // c0h | Scratchpad 6
12119 + unsigned MAILBOX7; // c4h | Scratchpad 7
12121 + unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12122 + unsigned ROM_Control_Addr; // cch | Rom Control and Address
12124 + unsigned reserved3[12]; // d0h-ffh | reserved
12125 + unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12129 + // need to add DMA, I2O, UART, etc registers form 80h to 364h
12132 +}Sa_Drawbridge_CSR;
12134 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12137 +#define Mailbox0 SaDbCSR.MAILBOX0
12138 +#define Mailbox1 SaDbCSR.MAILBOX1
12139 +#define Mailbox2 SaDbCSR.MAILBOX2
12140 +#define Mailbox3 SaDbCSR.MAILBOX3
12141 +#define Mailbox4 SaDbCSR.MAILBOX4
12144 +#define Mailbox7 SaDbCSR.MAILBOX7
12146 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12147 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12148 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12151 +#define DOORBELL_0 0x00000001
12152 +#define DOORBELL_1 0x00000002
12153 +#define DOORBELL_2 0x00000004
12154 +#define DOORBELL_3 0x00000008
12155 +#define DOORBELL_4 0x00000010
12156 +#define DOORBELL_5 0x00000020
12157 +#define DOORBELL_6 0x00000040
12160 +#define PrintfReady DOORBELL_5
12161 +#define PrintfDone DOORBELL_5
12163 +typedef struct _Sa_DEVICE_REGISTERS {
12164 + Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12165 +} Sa_DEVICE_REGISTERS;
12167 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12170 +#endif // _Sa_COMMON_H_
12173 diff -urN linux/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12174 --- linux/drivers/scsi/aacraid/include/version.h Wed Dec 31 19:00:00 1969
12175 +++ linux/drivers/scsi/aacraid/include/version.h Thu Dec 21 13:14:30 2000
12178 + * Adaptec aacraid device driver for Linux.
12180 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12182 + * This program is free software; you can redistribute it and/or modify
12183 + * it under the terms of the GNU General Public License as published by
12184 + * the Free Software Foundation; either version 2, or (at your option)
12185 + * any later version.
12187 + * This program is distributed in the hope that it will be useful,
12188 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12189 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12190 + * GNU General Public License for more details.
12192 + * You should have received a copy of the GNU General Public License
12193 + * along with this program; see the file COPYING. If not, write to
12194 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12199 + * Abstract: Keeps track of build number for development purposes.
12202 +#ifndef _VERSION_H_
12203 +#define _VERSION_H_
12205 +static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12207 +#include "build_number.h"
12209 +#define REV_MAJOR 2
12210 +#define REV_MINOR 1
12211 +#define REV_TYPE RevType_Release
12212 +#define REV_DASH 5
12214 +#define FSA_VERSION_STRING "2.1.5.3857\0"
12216 +#endif /* _VERSION_H_ */
12217 diff -urN linux/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12218 --- linux/drivers/scsi/aacraid/linit.c Wed Dec 31 19:00:00 1969
12219 +++ linux/drivers/scsi/aacraid/linit.c Thu Dec 21 14:21:32 2000
12222 + * Adaptec aacraid device driver for Linux.
12224 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12226 + * This program is free software; you can redistribute it and/or modify
12227 + * it under the terms of the GNU General Public License as published by
12228 + * the Free Software Foundation; either version 2, or (at your option)
12229 + * any later version.
12231 + * This program is distributed in the hope that it will be useful,
12232 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12233 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12234 + * GNU General Public License for more details.
12236 + * You should have received a copy of the GNU General Public License
12237 + * along with this program; see the file COPYING. If not, write to
12238 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12243 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12245 + * Provides the following driver entry points:
12246 + * AAC_DetectHostAdapter()
12247 + * AAC_ReleaseHostAdapter()
12248 + * AAC_QueueCommand()
12249 + * AAC_ResetCommand()
12250 + * AAC_BIOSDiskParameters()
12254 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12256 +/*------------------------------------------------------------------------------
12258 + *----------------------------------------------------------------------------*/
12259 +#define AAC_DRIVER_VERSION "0.1.1"
12260 +#define AAC_DRIVER_BUILD_DATE __DATE__
12261 +#define MAX_DRIVER_QUEUE_DEPTH 500
12263 +/*------------------------------------------------------------------------------
12264 + * I N C L U D E S
12265 + *----------------------------------------------------------------------------*/
12266 +#include "osheaders.h"
12268 +#include "AacGenericTypes.h"
12271 +#include <linux/module.h>
12274 +#include "linit.h"
12275 +#include "aac_unix_defs.h"
12276 +#include "fsatypes.h"
12277 +#include "comstruc.h"
12278 +#include "fsaport.h"
12279 +#include "pcisup.h"
12281 +#include "afacomm.h"
12282 +#include "nodetype.h"
12283 +#include "comsup.h"
12284 +#include "adapter.h"
12286 +/*------------------------------------------------------------------------------
12288 + *----------------------------------------------------------------------------*/
12289 +extern FSA_MINIPORT MiniPorts[];
12290 +extern int CommPrinting;
12291 +extern char DescriptionString[];
12292 +extern char devicestr[];
12294 +/*------------------------------------------------------------------------------
12295 + * M O D U L E G L O B A L S
12296 + *----------------------------------------------------------------------------*/
12297 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12299 +char g_DriverName[] = { "aacraid" };
12300 +#define module_options aacraid_options
12301 +static char * aacraid_options = NULL;
12303 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12304 +unsigned g_HostAdapterCount = 0;
12305 +unsigned g_chardev_major = 0;
12307 +int g_single_command_done = FALSE;
12309 +/*------------------------------------------------------------------------------
12310 + * F U N C T I O N P R O T O T Y P E S
12311 + *----------------------------------------------------------------------------*/
12313 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12317 +int AacHba_ProbeContainers(
12318 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12320 +int AacHba_DoScsiCmd(
12321 + Scsi_Cmnd *scsi_cmnd_ptr,
12324 +void AacHba_DetachAdapter(
12325 + IN PVOID AdapterArg );
12327 +int AacHba_ClassDriverInit(
12328 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12330 +void AacHba_AbortScsiCommand(
12331 + Scsi_Cmnd *scsi_cmnd_ptr );
12334 +/*------------------------------------------------------------------------------
12335 + * L O C A L F U N C T I O N P R O T O T Y P E S
12336 + *----------------------------------------------------------------------------*/
12337 +static int parse_keyword(
12339 + char * keyword );
12341 +static void AAC_ParseDriverOptions(
12342 + char * cmnd_line_options_str );
12344 +static void AAC_AnnounceDriver( void );
12346 +int AAC_ChardevIoctl(
12347 + struct inode * inode_ptr,
12348 + struct file * file_ptr,
12349 + unsigned int cmd,
12350 + unsigned long arg );
12352 +int AAC_ChardevOpen(
12353 + struct inode * inode_ptr,
12354 + struct file * file_ptr );
12356 +int AAC_ChardevRelease(
12357 + struct inode * inode_ptr,
12358 + struct file * file_ptr );
12360 +struct file_operations AAC_fops = {
12361 + NULL, // module name
12367 + AAC_ChardevIoctl, // ioctl
12369 + AAC_ChardevOpen, // open
12371 + AAC_ChardevRelease, // release
12374 + NULL, // check media change
12375 + NULL, // revalidate
12379 +/*------------------------------------------------------------------------------
12380 + * F U N C T I O N S
12381 + *----------------------------------------------------------------------------*/
12382 +/*------------------------------------------------------------------------------
12383 + AAC_AnnounceDriver()
12385 + Announce the driver name, version and date.
12386 + *----------------------------------------------------------------------------*/
12387 +static void AAC_AnnounceDriver( void ){
12388 + printk("<1>%s, %s\n",
12389 + "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12394 +/*------------------------------------------------------------------------------
12395 + AAC_DetectHostAdapter()
12397 + Probe for AAC Host Adapters initialize, register, and report the
12398 + configuration of each AAC Host Adapter found.
12402 + - Returns the number of adapters successfully initialized and
12404 + - Initialize all data necessary for this particular SCSI driver.
12406 + The detect routine must not call any of the mid level functions
12407 + to queue commands because things are not guaranteed to be set
12408 + up yet. The detect routine can send commands to the host adapter
12409 + as long as the program control will not be passed to scsi.c in
12410 + the processing of the command. Note especially that
12411 + scsi_malloc/scsi_free must not be called.
12412 + *----------------------------------------------------------------------------*/
12413 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12417 + uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12418 + struct Scsi_Host *host_ptr;
12419 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12420 + struct pci_dev *dev = NULL;
12421 + extern int NumMiniPorts;
12422 + fsadev_t *fsa_dev_ptr;
12423 + char *DeviceName;
12425 + struct pci_dev *devp;
12427 + int first_index, last_index, increment;
12429 + CommPrinting = TRUE;
12432 + EXPORT_NO_SYMBOLS;
12435 + AAC_AnnounceDriver();
12437 + /* setting up the proc directory structure */
12438 + HostTemplate->proc_name = "aacraid";
12440 + if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12442 + // NumMiniPorts & MiniPorts[] defined in aacid.c
12443 + if (g_options.reverse_scan == 0) {
12445 + last_index = NumMiniPorts;
12448 + first_index = NumMiniPorts -1;
12453 + for( index = first_index; index != last_index; index += increment )
12455 + device_id = MiniPorts[index].DeviceId;
12456 + vendor_id = MiniPorts[index].VendorId;
12457 + DeviceName = MiniPorts[index].DeviceName;
12458 + cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12459 + DeviceName, vendor_id, device_id,
12460 + MiniPorts[index].SubVendorId,
12461 + MiniPorts[index].SubSystemId);
12464 + // pci_find_device traverses the pci_devices linked list for devices
12465 + // with matching vendor and device ids.
12467 + dev = NULL; // start from beginning of list
12468 + while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12470 + if (pci_enable_device(dev)) continue;
12472 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12473 + cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12476 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12477 + cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12481 + cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12482 + if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12483 + ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12488 + printk("<1>%s device detected\n", DeviceName );
12489 + cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12491 + // Increment the host adapter count
12492 + g_HostAdapterCount++;
12494 + // scsi_register() allocates memory for a Scsi_Hosts structure and
12495 + // links it into the linked list of host adapters. This linked list
12496 + // contains the data for all possible <supported> scsi hosts.
12497 + // This is similar to the Scsi_Host_Template, except that we have
12498 + // one entry for each actual physical host adapter on the system,
12499 + // stored as a linked list. If there are two AAC boards, then we
12500 + // will need to make two Scsi_Host entries, but there will be only
12501 + // one Scsi_Host_Template entry. The second argument to scsi_register()
12502 + // specifies the size of the extra memory we want to hold any device
12503 + // specific information.
12504 + host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12506 + // These three parameters can be used to allow for wide SCSI
12507 + // and for host adapters that support multiple buses.
12508 + host_ptr->max_id = 17;
12509 + host_ptr->max_lun = 8;
12510 + host_ptr->max_channel = 1;
12513 + host_ptr->irq = dev->irq; // Adapter IRQ number
12514 + /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12515 + host_ptr->base = ( char * )(dev->resource[0].start);
12517 + cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12518 + cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12520 + // The unique_id field is a unique identifier that must be assigned
12521 + // so that we have some way of identifying each host adapter properly
12522 + // and uniquely. For hosts that do not support more than one card in the
12523 + // system, this does not need to be set. It is initialized to zero in
12524 + // scsi_register(). This is the value returned from OsGetDeviceInstance().
12526 + host_ptr->unique_id = g_HostAdapterCount - 1;
12527 + host_ptr->this_id = 16; // SCSI Id for the adapter itself
12529 + // Set the maximum number of simultaneous commands supported by the driver.
12530 + host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12532 + // Define the maximum number of scatter/gather elements supported by
12535 + host_ptr->sg_tablesize = 16;
12536 + host_ptr->cmd_per_lun = 1; // untagged queue depth
12538 + // This function is called after the device list has been built to find
12539 + // tagged queueing depth supported for each device.
12541 + host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12542 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12544 + // attach a pointer back to Scsi_Host
12545 + CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12546 + CommonExtensionPtr->OsDep.MiniPortIndex = index;
12548 + // Initialize the ordinal number of the device to -1
12549 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12550 + for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12551 + fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12553 + // Call initialization routine
12554 + cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12555 + if( ( *MiniPorts[index].InitRoutine )
12556 + ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12558 + // device initialization failed
12559 + cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12560 + scsi_unregister( host_ptr );
12561 + g_HostAdapterCount--;
12565 + cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12566 + AacHba_ClassDriverInit( CommonExtensionPtr );
12567 + cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12568 + AacHba_ProbeContainers( CommonExtensionPtr );
12569 + g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12573 + } /* end while */
12577 + if( g_HostAdapterCount ){
12578 + if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12579 + cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12582 + HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12584 + return( g_HostAdapterCount );
12588 +/*------------------------------------------------------------------------------
12589 + AAC_ReleaseHostAdapter()
12591 + Release all resources previously acquired to support a specific Host
12592 + Adapter and unregister the AAC Host Adapter.
12593 + *----------------------------------------------------------------------------*/
12594 +int AAC_ReleaseHostAdapter(
12595 + struct Scsi_Host *host_ptr )
12596 +/*----------------------------------------------------------------------------*/
12598 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12600 + cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12602 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12604 + // kill any threads we started
12605 + kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12607 + // Call the comm layer to detach from this adapter
12608 + AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12610 + // remove interrupt binding
12611 + OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12613 + SaDetachDevice( CommonExtensionPtr );
12615 + // unregister adapter
12616 + scsi_unregister( host_ptr );
12618 + if( g_chardev_major )
12620 + unregister_chrdev( g_chardev_major, devicestr );
12621 + g_chardev_major = 0;
12624 + return( 0 ); // #REVISIT# return code
12628 +/*------------------------------------------------------------------------------
12629 + AAC_QueueCommand()
12631 + Queues a command for execution by the associated Host Adapter.
12632 + *----------------------------------------------------------------------------*/
12633 +int AAC_QueueCommand(
12634 + Scsi_Cmnd *scsi_cmnd_ptr,
12635 + void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12636 +/*----------------------------------------------------------------------------*/
12638 + scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12640 + // AacHba_DoScsiCmd() handles command processing, setting the
12641 + // result code and calling completion routine.
12643 + if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 ) ) // called with wait = TRUE
12645 + if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 ) ) // called with wait = FALSE
12647 + cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12652 +/*------------------------------------------------------------------------------
12655 + Callback function for a non-queued command.
12658 + Sets g_single_command done to TRUE
12659 + *----------------------------------------------------------------------------*/
12661 + Scsi_Cmnd * scsi_cmnd_ptr )
12662 +/*----------------------------------------------------------------------------*/
12664 + g_single_command_done = TRUE;
12668 +/*------------------------------------------------------------------------------
12671 + Accepts a single command for execution by the associated Host Adapter.
12674 + Returns an int where:
12675 + Byte 0 = SCSI status code
12676 + Byte 1 = SCSI 1 byte message
12677 + Byte 2 = host error return
12678 + Byte 3 = mid level error return
12679 + *----------------------------------------------------------------------------*/
12681 + Scsi_Cmnd *scsi_cmnd_ptr )
12682 +/*----------------------------------------------------------------------------*/
12684 + scsi_cmnd_ptr->scsi_done = AAC_Done;
12686 + cmn_err( CE_DEBUG, "AAC_Command" );
12688 + // AacHba_DoScsiCmd() handles command processing, setting the
12689 + // result code and calling completion routine.
12690 + g_single_command_done = FALSE;
12692 + AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12693 + while( !g_single_command_done );
12694 + return( scsi_cmnd_ptr->result );
12698 +/*------------------------------------------------------------------------------
12699 + AAC_AbortCommand()
12701 + Abort command if possible.
12702 + *----------------------------------------------------------------------------*/
12703 +int AAC_AbortCommand(
12704 + Scsi_Cmnd *scsi_cmnd_ptr )
12705 +/*----------------------------------------------------------------------------*/
12707 + int target = scsi_cmnd_ptr->target;
12708 + int hba = scsi_cmnd_ptr->host->unique_id;
12710 + u_short interrupt_status;
12711 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12712 + char *DeviceName;
12714 + cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12715 + AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12717 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12718 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12721 + cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12722 + "command already completed", DeviceName, hba, target);
12723 + result = SCSI_ABORT_NOT_RUNNING;
12725 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12726 + "no command found\n", DeviceName, hba, target);
12727 + result = SCSI_ABORT_NOT_RUNNING;
12729 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12730 + "command reset\n", DeviceName, hba, target);
12731 + result = SCSI_ABORT_PENDING;
12733 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12734 + "abort tag not supported\n", DeviceName, hba, target);
12735 + result = SCSI_ABORT_SNOOZE;
12737 + cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12738 + DeviceName, hba, target);
12739 + result = SCSI_ABORT_PENDING;
12741 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12742 + DeviceName, hba, target);
12743 + result = SCSI_ABORT_BUSY;
12745 + cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12746 + DeviceName, hba, target);
12747 + result = SCSI_ABORT_SUCCESS;
12750 + // Abort not supported yet
12751 + result = SCSI_ABORT_BUSY;
12756 +/*------------------------------------------------------------------------------
12757 + AAC_ResetCommand()
12759 + Reset command handling.
12760 + *----------------------------------------------------------------------------*/
12761 +int AAC_ResetCommand(
12762 + struct scsi_cmnd *scsi_cmnd_ptr,
12763 + unsigned int reset_flags )
12764 +/*----------------------------------------------------------------------------*/
12766 + int target = scsi_cmnd_ptr->target;
12767 + int hba = scsi_cmnd_ptr->host->unique_id;
12768 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12769 + char *DeviceName;
12771 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12772 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12774 + cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12776 + return SCSI_RESET_PUNT;
12780 +/*------------------------------------------------------------------------------
12783 + Returns the host adapter name
12784 + *----------------------------------------------------------------------------*/
12785 +const char *AAC_DriverInfo(
12786 + struct Scsi_Host *host_ptr )
12787 +/*----------------------------------------------------------------------------*/
12789 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12790 + char *DeviceName;
12792 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12793 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12795 + cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12796 + return (DeviceName);
12800 +/*------------------------------------------------------------------------------
12801 + AAC_BIOSDiskParameters()
12803 + Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12804 + The default disk geometry is 64 heads, 32 sectors, and the appropriate
12805 + number of cylinders so as not to exceed drive capacity. In order for
12806 + disks equal to or larger than 1 GB to be addressable by the BIOS
12807 + without exceeding the BIOS limitation of 1024 cylinders, Extended
12808 + Translation should be enabled. With Extended Translation enabled,
12809 + drives between 1 GB inclusive and 2 GB exclusive are given a disk
12810 + geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12811 + are given a disk geometry of 255 heads and 63 sectors. However, if
12812 + the BIOS detects that the Extended Translation setting does not match
12813 + the geometry in the partition table, then the translation inferred
12814 + from the partition table will be used by the BIOS, and a warning may
12816 + *----------------------------------------------------------------------------*/
12817 +int AAC_BIOSDiskParameters(
12818 + Scsi_Disk *scsi_disk_ptr,
12820 + int *parameter_ptr )
12821 +/*----------------------------------------------------------------------------*/
12823 + AAC_BIOS_DiskParameters_T *disk_parameters =
12824 + ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12825 + struct buffer_head * buffer_head_ptr;
12827 + cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12829 + // Assuming extended translation is enabled - #REVISIT#
12830 + if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12832 + if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12834 + disk_parameters->heads = 255;
12835 + disk_parameters->sectors = 63;
12839 + disk_parameters->heads = 128;
12840 + disk_parameters->sectors = 32;
12845 + disk_parameters->heads = 64;
12846 + disk_parameters->sectors = 32;
12849 + disk_parameters->cylinders = scsi_disk_ptr->capacity
12850 + /( disk_parameters->heads * disk_parameters->sectors );
12852 + // Read the first 1024 bytes from the disk device
12853 + buffer_head_ptr = bread(
12854 + MKDEV( MAJOR( device ),
12855 + MINOR( device ) & ~0x0F ),
12858 + if( buffer_head_ptr == NULL )
12861 + If the boot sector partition table is valid, search for a partition
12862 + table entry whose end_head matches one of the standard geometry
12863 + translations ( 64/32, 128/32, 255/63 ).
12865 + if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12867 + struct partition *first_partition_entry =
12868 + ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12869 + struct partition *partition_entry = first_partition_entry;
12870 + int saved_cylinders = disk_parameters->cylinders;
12871 + int partition_number;
12872 + unsigned char partition_entry_end_head, partition_entry_end_sector;
12874 + for( partition_number = 0; partition_number < 4; partition_number++ )
12876 + partition_entry_end_head = partition_entry->end_head;
12877 + partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12879 + if( partition_entry_end_head == ( 64 - 1 ) )
12881 + disk_parameters->heads = 64;
12882 + disk_parameters->sectors = 32;
12885 + else if( partition_entry_end_head == ( 128 - 1 ) )
12887 + disk_parameters->heads = 128;
12888 + disk_parameters->sectors = 32;
12891 + else if( partition_entry_end_head == ( 255 - 1 ) )
12893 + disk_parameters->heads = 255;
12894 + disk_parameters->sectors = 63;
12897 + partition_entry++;
12900 + if( partition_number == 4 )
12902 + partition_entry_end_head = first_partition_entry->end_head;
12903 + partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12906 + disk_parameters->cylinders = scsi_disk_ptr->capacity
12907 + /( disk_parameters->heads * disk_parameters->sectors );
12909 + if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
12911 + if( disk_parameters->cylinders != saved_cylinders )
12912 + cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12913 + disk_parameters->heads, disk_parameters->sectors, partition_number );
12915 + else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
12917 + cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
12918 + partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
12919 + cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
12920 + disk_parameters->heads, disk_parameters->sectors );
12924 + brelse( buffer_head_ptr );
12930 +/*------------------------------------------------------------------------------
12931 + AAC_SelectQueueDepths()
12933 + Selects queue depths for each target device based on the host adapter's
12934 + total capacity and the queue depth supported by the target device.
12935 + A queue depth of one automatically disables tagged queueing.
12936 + *----------------------------------------------------------------------------*/
12937 +void AAC_SelectQueueDepths(
12938 + struct Scsi_Host * host_ptr,
12939 + Scsi_Device * scsi_device_ptr )
12940 +/*----------------------------------------------------------------------------*/
12942 + Scsi_Device * device_ptr;
12944 + cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
12945 + cmn_err( CE_DEBUG, "Device # Q Depth Online" );
12946 + cmn_err( CE_DEBUG, "---------------------------" );
12947 + for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
12948 + if( device_ptr->host == host_ptr )
12950 + device_ptr->queue_depth = 10;
12951 + cmn_err( CE_DEBUG, " %2d %d %d",
12952 + device_ptr->id, device_ptr->queue_depth, device_ptr->online );
12957 +/*------------------------------------------------------------------------------
12958 + AAC_SearchBiosSignature()
12960 + Locate adapter signature in BIOS
12961 + *----------------------------------------------------------------------------*/
12962 +int AAC_SearchBiosSignature( void )
12963 +/*----------------------------------------------------------------------------*/
12969 + char name_buf[32];
12970 + int result = FALSE;
12972 + for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
12974 + val = readb( base );
12975 + if( val != 0x55 )
12979 + namep = base + 0x1e;
12980 + memcpy_fromio( name_buf, namep, 32 );
12981 + name_buf[31] = '\0';
12983 + return( result );
12987 +/*------------------------------------------------------------------------------
12990 + Handle SCSI ioctls
12991 + *----------------------------------------------------------------------------*/
12993 + Scsi_Device * scsi_dev_ptr,
12996 +/*----------------------------------------------------------------------------*/
12998 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13000 + cmn_err( CE_DEBUG, "AAC_Ioctl" );
13001 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13002 + return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13007 +/*------------------------------------------------------------------------------
13008 + AAC_ChardevOpen()
13010 + Handle character device open
13014 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13015 + *----------------------------------------------------------------------------*/
13016 +int AAC_ChardevOpen(
13017 + struct inode * inode_ptr,
13018 + struct file * file_ptr )
13019 +/*----------------------------------------------------------------------------*/
13021 + unsigned minor_number;
13023 + cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13025 + // check device permissions in file_ptr->f_mode ??
13027 + // extract & check the minor number
13028 + minor_number = MINOR( inode_ptr->i_rdev );
13029 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13031 + cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13032 + return( -ENODEV );
13036 + MOD_INC_USE_COUNT;
13043 +/*------------------------------------------------------------------------------
13044 + AAC_ChardevRelease()
13046 + Handle character device release.
13050 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13051 + *----------------------------------------------------------------------------*/
13052 +int AAC_ChardevRelease(
13053 + struct inode * inode_ptr,
13054 + struct file * file_ptr )
13055 +/*----------------------------------------------------------------------------*/
13057 + cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13060 + MOD_DEC_USE_COUNT;
13067 +/*------------------------------------------------------------------------------
13068 + AAC_ChardevIoctl()
13070 + Handle character device interface ioctls
13074 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13075 + *----------------------------------------------------------------------------*/
13076 +int AAC_ChardevIoctl(
13077 + struct inode * inode_ptr,
13078 + struct file * file_ptr,
13079 + unsigned int cmd,
13080 + unsigned long arg )
13082 + unsigned minor_number;
13083 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13085 + cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13087 + // check device permissions in file_ptr->f_mode ??
13089 + // extract & check the minor number
13090 + minor_number = MINOR( inode_ptr->i_rdev );
13091 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13093 + cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13094 + return( -ENODEV );
13097 + // get device pointer
13098 + CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13100 + // dispatch ioctl - AacHba_Ioctl() returns zero on success
13101 + if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13102 + return( -EINVAL );
13108 +/*------------------------------------------------------------------------------
13111 + Look for the keyword in str_ptr
13116 + - return true and update the pointer str_ptr.
13119 + *----------------------------------------------------------------------------*/
13120 +static int parse_keyword(
13123 +/*----------------------------------------------------------------------------*/
13125 + char * ptr = *str_ptr;
13127 + while( *keyword != '\0' )
13129 + char string_char = *ptr++;
13130 + char keyword_char = *keyword++;
13132 + if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13133 + string_char += 'a' - 'Z';
13134 + if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13135 + keyword_char += 'a' - 'Z';
13136 + if( string_char != keyword_char )
13144 +/*------------------------------------------------------------------------------
13145 + AAC_ParseDriverOptions()
13147 + For modules the usage is:
13148 + insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13149 + *----------------------------------------------------------------------------*/
13150 +static void AAC_ParseDriverOptions(
13151 + char * cmnd_line_options_str )
13152 +/*----------------------------------------------------------------------------*/
13154 + int message_level;
13155 + int reverse_scan;
13159 + cp = cmnd_line_options_str;
13161 + cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13164 + if( parse_keyword( &cp, "message_level:" ) ) {
13165 + message_level = simple_strtoul( cp, 0, 0 );
13166 + if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13167 + g_options.message_level = message_level;
13168 + cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13171 + cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13173 + } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13174 + reverse_scan = simple_strtoul( cp, 0, 0 );
13175 + if (reverse_scan) {
13176 + g_options.reverse_scan = 1;
13177 + cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13181 + cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13185 + * skip to next option, accept " ", ";", and "," as delimiters
13187 + while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13190 + if (*cp) /* skip over the delimiter */
13197 +/*------------------------------------------------------------------------------
13198 + Include Module support if requested.
13200 + To use the low level SCSI driver support using the linux kernel loadable
13201 + module interface we should initialize the global variable driver_interface
13202 + (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13203 + This should also be wrapped in a #ifdef MODULE/#endif
13204 + *----------------------------------------------------------------------------*/
13208 + The Loadable Kernel Module Installation Facility may pass us
13209 + a pointer to a driver specific options string to be parsed,
13210 + we assign this to options string.
13212 +MODULE_PARM( module_options, "s" );
13214 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13216 +#include "scsi_module.c"
13219 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13221 +#include "scsi_module.c"
13224 +/*********************************************************************
13225 + AAC_ProcDirectoryInfo()
13227 + Implement /proc/scsi/<drivername>/<n>.
13228 + Used to export driver statistics and other infos to the world outside
13229 + the kernel using the proc file system. Also provides an interface to
13230 + feed the driver with information.
13234 + - if offset > 0 return 0
13235 + - if offset == 0 write data to proc_buffer and set the start_ptr to
13236 + beginning of proc_buffer, return the number of characters written.
13238 + - writes currently not supported, return 0
13239 +************************************************************/
13240 +int AAC_ProcDirectoryInfo(
13241 + char *proc_buffer, // read/write buffer
13242 + char **start_ptr, // start of valid data in the buffer
13243 + off_t offset, // offset from the beginning of the imaginary file
13244 + int bytes_available, // bytes available
13245 + int host_no, // SCSI host number
13246 + int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13249 + cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13251 + if( ( write ) || ( offset > 0 ) )
13254 + *start_ptr = proc_buffer;
13256 + return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13259 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13261 + void *BaseAddress;
13262 + ULONG PhysAddress;
13267 + AFA_COMM_ADAPTER *Adapter;
13268 + Adapter = CommonExtension->Adapter;
13271 + // Allocate 1 fib for synch fibs
13272 + // Allocate 1 page.
13273 + BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13274 + bzero(BaseAddress, PAGE_SIZE);
13275 + PhysAddress = virt_to_phys (BaseAddress);
13276 + Adapter->SyncFib = BaseAddress;
13277 + Adapter->SyncFibPhysicalAddress = PhysAddress;
13278 + cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13281 diff -urN linux/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13282 --- linux/drivers/scsi/aacraid/osddi.c Wed Dec 31 19:00:00 1969
13283 +++ linux/drivers/scsi/aacraid/osddi.c Thu Dec 21 13:14:30 2000
13286 + * Adaptec aacraid device driver for Linux.
13288 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13290 + * This program is free software; you can redistribute it and/or modify
13291 + * it under the terms of the GNU General Public License as published by
13292 + * the Free Software Foundation; either version 2, or (at your option)
13293 + * any later version.
13295 + * This program is distributed in the hope that it will be useful,
13296 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13297 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13298 + * GNU General Public License for more details.
13300 + * You should have received a copy of the GNU General Public License
13301 + * along with this program; see the file COPYING. If not, write to
13302 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13307 + * Abstract: This file contains all the proceedures which use LINUX specific Device
13308 + * Driver Interfaces.
13312 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13314 +#include "osheaders.h"
13316 +#include <linux/smp_lock.h>
13321 +#include "AacGenericTypes.h"
13322 +#include "aac_unix_defs.h"
13323 +#include "comstruc.h"
13324 +#include "monkerapi.h"
13325 +#include "protocol.h"
13326 +#include "fsafs.h"
13328 +#include "sap1common.h"
13329 +#include "fsaport.h"
13330 +#include "pcisup.h"
13332 +#include "nodetype.h"
13333 +#include "comsup.h"
13334 +#include "afacomm.h"
13335 +#include "adapter.h"
13341 + struct pt_regs *regs);
13346 + struct pt_regs *regs);
13348 +unsigned SaPciIsr (
13349 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13351 +unsigned RxPciIsr (
13352 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13355 +/*----------------------------------------------------------------------------*/
13356 +VOID AfaCommInterruptHost(
13357 + PVOID AdapterArg,
13358 + ADAPTER_EVENT AdapterEvent )
13359 +/*----------------------------------------------------------------------------*/
13361 + PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13362 + PCOMM_REGION CommRegion = Adapter->CommRegion;
13364 + switch (AdapterEvent) {
13366 + case HostNormRespQue:
13367 + OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13369 + // #REVIEW# - what do we do with this
13370 + // if (FsaCommData.HardInterruptModeration)
13371 + // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13375 + case AdapNormCmdNotFull:
13376 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13379 + case HostNormCmdQue:
13380 + OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13383 + case AdapNormRespNotFull:
13384 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13387 + // #REVIEW# - what do we do with these
13388 + case HostHighCmdQue:
13389 + case HostHighRespQue:
13390 + case AdapHighCmdNotFull:
13391 + case AdapHighRespNotFull:
13392 + case SynchCommandComplete:
13393 + case AdapInternalError:
13399 +// get the device name associated with this instance of the device
13400 +/*----------------------------------------------------------------------------*/
13401 +char *OsGetDeviceName(
13402 + void *AdapterExtension )
13403 +/*----------------------------------------------------------------------------*/
13405 + return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13406 + OsDep.scsi_host_ptr->hostt->name );
13410 +/*----------------------------------------------------------------------------*/
13411 +int OsGetDeviceInstance(
13412 + void *AdapterExtension )
13413 +/*----------------------------------------------------------------------------*/
13415 + return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13416 + OsDep.scsi_host_ptr->unique_id );
13420 +/*------------------------------------------------------------------------------
13421 + OsMapDeviceRegisters()
13424 + Return zero on success non-zero otherwise.
13425 + *----------------------------------------------------------------------------*/
13426 +int OsMapDeviceRegisters(
13427 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13428 +/*----------------------------------------------------------------------------*/
13430 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13432 + CommonExtension = AdapterExtension->Common;
13434 + if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13435 + ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13437 + cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13442 + cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13448 +/*------------------------------------------------------------------------------
13449 + OsUnMapDeviceRegisters()
13452 + *----------------------------------------------------------------------------*/
13453 +void OsUnMapDeviceRegisters(
13454 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13455 +/*----------------------------------------------------------------------------*/
13457 + iounmap( ( void * )AdapterExtension->Device );
13461 +/*----------------------------------------------------------------------------*/
13462 +int OsAttachInterrupt(
13463 + Sa_ADAPTER_EXTENSION *AdapterExtension ,
13465 +/*----------------------------------------------------------------------------*/
13467 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13471 + CommonExtension = AdapterExtension->Common;
13472 + irq_data = ( void * )AdapterExtension;
13474 + switch (WhichIsr) {
13476 + Isr = AacSaPciIsr;
13479 + Isr = AacRxPciIsr;
13482 + cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13483 + return( FAILURE );
13488 + if ( OsRegisterInterrupt (
13489 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13490 + Isr, // handler function
13494 + cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13495 + CommonExtension->OsDep.scsi_host_ptr->irq );
13496 + return( FAILURE );
13503 +/*----------------------------------------------------------------------------*/
13507 + struct pt_regs *regs)
13508 +/*----------------------------------------------------------------------------*/
13510 + // call the actual interrupt handler
13511 + SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13514 +/*----------------------------------------------------------------------------*/
13518 + struct pt_regs *regs)
13519 +/*----------------------------------------------------------------------------*/
13521 + // call the actual interrupt handler
13522 + RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13526 +/*----------------------------------------------------------------------------*/
13527 +void OsDetachInterrupt(
13528 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13529 +/*----------------------------------------------------------------------------*/
13531 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13534 + CommonExtension = AdapterExtension->Common;
13535 + irq_data = ( void * )AdapterExtension;
13537 + OsUnregisterInterrupt (
13538 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13543 +/*----------------------------------------------------------------------------*/
13545 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13546 +/*----------------------------------------------------------------------------*/
13551 +/*----------------------------------------------------------------------------*/
13553 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13554 +/*----------------------------------------------------------------------------*/
13559 +/*----------------------------------------------------------------------------*/
13560 +void OsDetachDevice(
13561 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13562 +/*----------------------------------------------------------------------------*/
13564 + OsUnMapDeviceRegisters( AdapterExtension );
13568 +/*----------------------------------------------------------------------------*/
13569 +ULONG *OsAllocCommPhysMem(
13570 + Sa_ADAPTER_EXTENSION *AdapterExtension,
13572 + ULONG **virt_addr_pptr,
13573 + ULONG *phys_addr_ptr )
13574 +/*----------------------------------------------------------------------------*/
13576 + if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13578 + *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13579 + if( !*phys_addr_ptr )
13581 + cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13584 + return( *virt_addr_pptr );
13590 +OsAifKernelThread(
13591 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13594 + struct fs_struct *fs;
13596 + struct task_struct *tsk;
13602 + * set up the name that will appear in 'ps'
13603 + * stored in task_struct.comm[16].
13606 + sprintf(tsk->comm, "AIFd");
13609 + // use_init_fs_context(); only exists in 2.2.13 onward.
13616 + * we were started as a result of loading the module.
13617 + * free all of user space pages
13626 + fs = init_task.fs;
13629 + tsk->session = 1;
13633 + atomic_inc(&fs->count);
13642 + NormCommandThread(AdapterExtension);
13643 + /* NOT REACHED */
13646 +/*----------------------------------------------------------------------------*/
13647 +void OsStartKernelThreads(
13648 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13649 +/*----------------------------------------------------------------------------*/
13651 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13652 + AFA_COMM_ADAPTER *Adapter;
13653 + extern void NormCommandThread(void *Adapter);
13655 + CommonExtension = AdapterExtension->Common;
13656 + Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13659 + // Start thread which will handle interrupts for this adapter
13661 + //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13664 + // Start thread which will handle AdapterInititatedFibs from this adapter
13666 + CommonExtension->OsDep.thread_pid =
13667 + kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13668 +// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13671 +/*----------------------------------------------------------------------------*/
13672 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13674 + IN PMAPFIB_CONTEXT MapFibContext )
13675 +/*----------------------------------------------------------------------------*/
13677 + PVOID BaseAddress;
13678 + ULONG PhysAddress;
13680 + if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13682 + cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13686 + PhysAddress = OsVirtToPhys( BaseAddress );
13688 + MapFibContext->FibVirtualAddress = BaseAddress;
13689 + MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13694 +/*----------------------------------------------------------------------------*/
13695 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13697 + IN PMAPFIB_CONTEXT MapFibContext )
13698 +/*----------------------------------------------------------------------------*/
13700 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13702 + OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13707 +/*----------------------------------------------------------------------------*/
13708 +BOOLEAN AfaPortFreeAdapterCommArea(
13710 +/*----------------------------------------------------------------------------*/
13712 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13714 + OsFreeMemory( CommonExtension->CommAddress, 0 );
13720 +/* ================================================================================ */
13722 + * Not sure if the functions below here ever get called in the current code
13723 + * These probably should be a different file.
13726 +ddi_dma_attr_t AfaPortDmaAttributes = {
13727 + //rpbfix : we may want something different for I/O
13744 +AfaPortBuildSgMap(
13746 + IN PSGMAP_CONTEXT SgMapContext
13751 +Routine Description:
13753 + This routine build a scatter gather map using the information
13754 + in the SgMapContext.
13758 + AdapterExtension - Pointer to adapter extension structure.
13759 + SgMapContext - Pointer to the SgMapContext for the request.
13767 + printk( "<1>AfaPortBuildSgMap: unimplemented function called" );
13768 + return (STATUS_UNSUCCESSFUL);
13772 +AfaPortFreeDmaResources(
13774 + IN PSGMAP_CONTEXT SgMapContext
13779 +Routine Description:
13781 + Given a pointer to the IRP context will free all reserved DMA resources allocated for
13782 + the completed IO operation.
13786 + Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13787 + Context - Pointer to the Irp Context we use to store the dma mapping information
13788 + we need to do and complete the IO.
13797 diff -urN linux/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13798 --- linux/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 19:00:00 1969
13799 +++ linux/drivers/scsi/aacraid/osfuncs.c Thu Dec 21 13:14:30 2000
13802 + * Adaptec aacraid device driver for Linux.
13804 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13806 + * This program is free software; you can redistribute it and/or modify
13807 + * it under the terms of the GNU General Public License as published by
13808 + * the Free Software Foundation; either version 2, or (at your option)
13809 + * any later version.
13811 + * This program is distributed in the hope that it will be useful,
13812 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13813 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13814 + * GNU General Public License for more details.
13816 + * You should have received a copy of the GNU General Public License
13817 + * along with this program; see the file COPYING. If not, write to
13818 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13823 + * Abstract: Holds all of the O/S specific interface functions.
13827 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13829 +#include "osheaders.h"
13831 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13833 +extern aac_options_t g_options;
13835 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13836 +wait_queue_t * g_wait_queue_ptr = NULL;
13837 +wait_queue_t g_wait;
13839 +void OsTimeoutHandler(
13840 + struct semaphore * sem );
13842 +int * OsIdleTask( void * data );
13844 +//-----------------------------------------------------------------------------
13845 +// Memory Allocation functions
13847 +/*----------------------------------------------------------------------------*/
13848 +void * OsAllocMemory(
13850 + unsigned int Flags )
13851 +/*----------------------------------------------------------------------------*/
13855 + if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13856 + cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13857 + return( mem_ptr );
13861 +/*----------------------------------------------------------------------------*/
13862 +void OsFreeMemory(
13865 +/*----------------------------------------------------------------------------*/
13871 +/*----------------------------------------------------------------------------*/
13872 +int OsRegisterInterrupt(
13873 + unsigned int irq, // interrupt number
13874 + void ( *handler )( int, void*, struct pt_regs * ), // handler function
13875 + void *irq_data ) // argument to handler function
13876 +/*----------------------------------------------------------------------------*/
13878 + return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13882 +/*----------------------------------------------------------------------------*/
13883 +void OsUnregisterInterrupt(
13884 + unsigned int irq, // interrupt number
13886 +/*----------------------------------------------------------------------------*/
13889 + irq, // interrupt number
13894 +/*----------------------------------------------------------------------------*/
13895 +unsigned long OsVirtToPhys(
13896 + void * virtual_address )
13897 +/*----------------------------------------------------------------------------*/
13899 + return( virt_to_phys( virtual_address ) );
13903 +//-----------------------------------------------------------------------------
13904 +// MUTEX functions
13906 +/*----------------------------------------------------------------------------*/
13907 +OS_STATUS OsMutexInit(
13909 + OS_SPINLOCK_COOKIE Cookie )
13910 +/*----------------------------------------------------------------------------*/
13912 + Mutex->lock_var = 0;
13913 + // bzero (&Mutex->wq, sizeof (Mutex->wq));
13914 + init_waitqueue_head (&Mutex->wq);
13919 +/*----------------------------------------------------------------------------*/
13920 +void OsMutexDestroy(
13921 + OS_MUTEX *Mutex )
13922 +/*----------------------------------------------------------------------------*/
13927 +/*----------------------------------------------------------------------------*/
13928 +void OsMutexAcquire(
13929 + OS_MUTEX *Mutex )
13930 +/*----------------------------------------------------------------------------*/
13932 + // wait_queue_t wait = { current, NULL };
13933 + unsigned long time_stamp;
13935 + DECLARE_WAITQUEUE (wait, current);
13937 + time_stamp = jiffies;
13939 + if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13941 + if( in_interrupt() )
13942 + panic( "OsMutexAcquire going to sleep at interrupt time\n" );
13943 + current->state = TASK_INTERRUPTIBLE;
13944 + add_wait_queue( &( Mutex->wq ), &wait );
13945 + while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13947 + remove_wait_queue( &( Mutex->wq ), &wait );
13950 + if( ( jiffies - 1 ) > time_stamp )
13951 + cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
13952 + Mutex, jiffies - time_stamp );
13956 +/*----------------------------------------------------------------------------*/
13957 +void OsMutexRelease(
13958 + OS_MUTEX *Mutex )
13959 +/*----------------------------------------------------------------------------*/
13961 + if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
13962 + cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
13963 + wake_up_interruptible( &( Mutex->wq ) );
13966 +// see man hierarchy(D5)
13967 +#define FSA_LOCK 1
13969 +//-----------------------------------------------------------------------------
13970 +// Spinlock functions
13972 +/*----------------------------------------------------------------------------*/
13973 +OS_SPINLOCK * OsSpinLockAlloc( void )
13974 +/*----------------------------------------------------------------------------*/
13976 + OS_SPINLOCK *SpinLock;
13980 + SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
13982 + if (SpinLock == NULL)
13983 + cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
13985 + SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
13986 + for( i = 0; i < NR_CPUS; i++ )
13987 + SpinLock->cpu_lock_count[ i ] = 0;
13988 + return( SpinLock );
13992 +/*----------------------------------------------------------------------------*/
13993 +OS_STATUS OsSpinLockInit(
13994 + OS_SPINLOCK *SpinLock,
13995 + OS_SPINLOCK_COOKIE Cookie )
13996 +/*----------------------------------------------------------------------------*/
14002 +/*----------------------------------------------------------------------------*/
14003 +void OsSpinLockDestroy(
14004 + OS_SPINLOCK *SpinLock )
14005 +/*----------------------------------------------------------------------------*/
14007 + kfree( SpinLock );
14012 +/*----------------------------------------------------------------------------*/
14013 +void OsSpinLockAcquire(
14014 + OS_SPINLOCK *SpinLock )
14015 +/*----------------------------------------------------------------------------*/
14017 + unsigned cpu_id, i;
14022 + cpu_id = smp_processor_id();
14023 + if( SpinLock->cpu_lock_count[ cpu_id ] ){
14024 + cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14025 + cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14028 + spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14029 + SpinLock->cpu_lock_count[ cpu_id ]++;
14032 + cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14037 +/*----------------------------------------------------------------------------*/
14038 +void OsSpinLockRelease(
14039 + OS_SPINLOCK *SpinLock )
14040 +/*----------------------------------------------------------------------------*/
14044 + SpinLock->cpu_lock_count[ smp_processor_id() ]--;
14045 + spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14048 + cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14052 +/*----------------------------------------------------------------------------*/
14053 +int OsSpinLockOwned(
14054 + OS_SPINLOCK *SpinLock )
14055 +/*----------------------------------------------------------------------------*/
14058 + if( SpinLock->spin_lock.lock != 0 )
14066 +//-----------------------------------------------------------------------------
14067 +// CvLock functions
14069 +/*----------------------------------------------------------------------------*/
14070 +OS_CVLOCK *OsCvLockAlloc( void )
14072 + OS_CVLOCK *cv_lock;
14075 +#ifdef CVLOCK_USE_SPINLOCK
14076 + cv_lock = OsSpinLockAlloc();
14078 + cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14079 + cv_lock->wq = NULL;
14080 + cv_lock->lock_var = 0;
14083 + return( cv_lock );
14087 +/*----------------------------------------------------------------------------*/
14088 +OS_STATUS OsCvLockInit(
14089 + OS_CVLOCK *cv_lock,
14090 + OS_SPINLOCK_COOKIE Cookie )
14091 +/*----------------------------------------------------------------------------*/
14097 +/*----------------------------------------------------------------------------*/
14098 +void OsCvLockDestroy(
14099 + OS_CVLOCK *cv_lock )
14100 +/*----------------------------------------------------------------------------*/
14103 + kfree( cv_lock );
14108 +/*----------------------------------------------------------------------------*/
14109 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14111 +#ifdef CVLOCK_USE_SPINLOCK
14112 + OsSpinLockAcquire( cv_lock );
14114 + OsMutexAcquire( cv_lock );
14119 +/*----------------------------------------------------------------------------*/
14120 +void OsCvLockRelease(
14121 + OS_CVLOCK *cv_lock )
14122 +/*----------------------------------------------------------------------------*/
14124 +#ifdef CVLOCK_USE_SPINLOCK
14125 + OsSpinLockRelease( cv_lock );
14127 + OsMutexRelease( cv_lock );
14132 +/*----------------------------------------------------------------------------*/
14133 +int OsCvLockOwned(
14134 + OS_CVLOCK *cv_lock )
14135 +/*----------------------------------------------------------------------------*/
14141 +//-----------------------------------------------------------------------------
14142 +// Conditional variable functions
14144 +/*----------------------------------------------------------------------------*/
14146 + OS_CV_T *cv_ptr )
14147 +/*----------------------------------------------------------------------------*/
14149 + cv_ptr->lock_var = 1;
14150 + init_waitqueue_head (&cv_ptr->wq);
14154 +/*----------------------------------------------------------------------------*/
14155 +void OsCv_destroy(
14156 + OS_CV_T *cv_ptr )
14157 +/*----------------------------------------------------------------------------*/
14162 +/*______________________________________________________________________________
14165 + -----------------------------------------------------------------------------*/
14166 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14168 + unsigned long flags;
14170 + DECLARE_WAITQUEUE (wait, current);
14172 + if( in_interrupt() )
14173 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14175 + cv_ptr->type = TASK_UNINTERRUPTIBLE;
14176 + current->state = TASK_UNINTERRUPTIBLE;
14178 + add_wait_queue( &cv_ptr->wq, &wait );
14180 + OsCvLockRelease( cv_lock_ptr );
14183 + while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14185 + if( in_interrupt() )
14186 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14190 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14192 + OsCvLockAcquire( cv_lock_ptr );
14196 +/*----------------------------------------------------------------------------*/
14197 +int OsCv_wait_sig(
14199 + OS_CVLOCK *cv_lock_ptr )
14200 +/*----------------------------------------------------------------------------*/
14202 + unsigned long flags;
14203 + int signal_state = 1;
14205 + DECLARE_WAITQUEUE (wait, current);
14207 + if( in_interrupt() )
14208 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14210 + cv_ptr->type = TASK_INTERRUPTIBLE;
14211 + current->state = TASK_INTERRUPTIBLE;
14213 + add_wait_queue( &( cv_ptr->wq ), &wait );
14215 + OsCvLockRelease( cv_lock_ptr );
14218 + while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14219 + ( !signal_pending( current ) ) )
14221 + if( in_interrupt() )
14222 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14226 + if( signal_pending( current ) )
14227 + signal_state = 0;
14229 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14231 + OsCvLockAcquire( cv_lock_ptr );
14232 + return( signal_state );
14236 +/*----------------------------------------------------------------------------*/
14238 + OS_CV_T *cv_ptr )
14239 +/*----------------------------------------------------------------------------*/
14242 + clear_bit( 0, &( cv_ptr->lock_var ) );
14243 + if( cv_ptr->type == TASK_INTERRUPTIBLE )
14244 + wake_up_interruptible( &( cv_ptr->wq ) );
14246 + wake_up( &( cv_ptr->wq ) );
14251 +// return time in seconds
14252 +/*----------------------------------------------------------------------------*/
14253 +unsigned long OsGetSeconds( void )
14254 +/*----------------------------------------------------------------------------*/
14256 + return( jiffies/HZ );
14260 +//-----------------------------------------------------------------------------
14261 +// Deferred procedure call functions
14263 +// create a soft interrupt object
14264 +/*----------------------------------------------------------------------------*/
14265 +int OsSoftInterruptAdd(
14266 + OS_SOFTINTR **ptr,
14269 +/*----------------------------------------------------------------------------*/
14271 + OS_SOFTINTR *tmp_ptr;
14273 + if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14275 + tmp_ptr->routine = handler;
14276 + tmp_ptr->data = data;
14277 + tmp_ptr->sync = 0;
14285 + Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14287 +/*----------------------------------------------------------------------------*/
14288 +int * OsIdleTask( void * data )
14289 +/*----------------------------------------------------------------------------*/
14291 + DECLARE_WAITQUEUE (wait, current);
14295 + current->state = TASK_INTERRUPTIBLE;
14296 + add_wait_queue( &g_wait_queue_ptr, &wait );
14298 + remove_wait_queue( &g_wait_queue_ptr, &wait );
14299 + wait.task = current;
14300 + wait.task_list.next = NULL;
14306 +// dispatch a soft interrupt
14307 +/*----------------------------------------------------------------------------*/
14308 +void OsSoftInterruptTrigger(
14309 + OS_SOFTINTR *soft_intr_ptr )
14310 +/*----------------------------------------------------------------------------*/
14312 + // call the completion routine directly
14313 + soft_intr_ptr->routine( soft_intr_ptr->data );
14317 +// delete a soft interrupt object
14318 +/*----------------------------------------------------------------------------*/
14319 +void OsSoftInterruptRemove(
14320 + OS_SOFTINTR *arg )
14321 +/*----------------------------------------------------------------------------*/
14329 +/*----------------------------------------------------------------------------*/
14331 + unsigned time ) // in seconds
14332 +/*----------------------------------------------------------------------------*/
14334 + struct semaphore sem;
14335 + struct timer_list timer_var;
14337 + init_MUTEX_LOCKED (&sem);
14339 + // if( in_interrupt() )
14340 + // panic( "OsSleep going to sleep at interrupt time\n" );
14342 + init_timer( &timer_var );
14343 + timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14344 + timer_var.data = ( unsigned long )&sem;
14345 + timer_var.expires = jiffies + time * HZ;
14347 + add_timer( &timer_var );
14350 + del_timer( &timer_var );
14354 +/*----------------------------------------------------------------------------*/
14355 +void OsTimeoutHandler(
14356 + struct semaphore * sem )
14357 +/*----------------------------------------------------------------------------*/
14359 + if( sem != NULL )
14364 +/*----------------------------------------------------------------------------*/
14369 +/*----------------------------------------------------------------------------*/
14374 + va_start(ap, fmt);
14375 + (void) vsprintf(buf, fmt, ap);
14378 + if( flag <= g_options.message_level )
14379 + printk("<1>%s\n", buf);
14382 +/* void aac_show_tasks (struct list_head *our_tasks){ */
14384 +/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14386 +/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14387 +/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14389 +/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14391 +/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14392 +/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14394 +/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14397 diff -urN linux/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14398 --- linux/drivers/scsi/aacraid/ossup.c Wed Dec 31 19:00:00 1969
14399 +++ linux/drivers/scsi/aacraid/ossup.c Thu Dec 21 13:14:30 2000
14402 + * Adaptec aacraid device driver for Linux.
14404 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14406 + * This program is free software; you can redistribute it and/or modify
14407 + * it under the terms of the GNU General Public License as published by
14408 + * the Free Software Foundation; either version 2, or (at your option)
14409 + * any later version.
14411 + * This program is distributed in the hope that it will be useful,
14412 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14413 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14414 + * GNU General Public License for more details.
14416 + * You should have received a copy of the GNU General Public License
14417 + * along with this program; see the file COPYING. If not, write to
14418 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14427 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14429 +#include "osheaders.h"
14431 +#include "aac_unix_defs.h"
14436 + IN PZONE_HEADER Zone,
14437 + IN ULONG BlockSize,
14438 + IN PVOID InitialSegment,
14439 + IN ULONG InitialSegmentSize
14444 +Routine Description:
14446 + This function initializes a zone header. Once successfully
14447 + initialized, blocks can be allocated and freed from the zone, and
14448 + the zone can be extended.
14452 + Zone - Supplies the address of a zone header to be initialized.
14454 + BlockSize - Supplies the block size of the allocatable unit within
14455 + the zone. The size must be larger that the size of the
14456 + initial segment, and must be 64-bit aligned.
14458 + InitialSegment - Supplies the address of a segment of storage. The
14459 + first ZONE_SEGMENT_HEADER-sized portion of the segment
14460 + is used by the zone allocator. The remainder of
14461 + the segment is carved up into fixed size
14462 + (BlockSize) blocks and is made available for
14463 + allocation and deallocation from the zone. The
14464 + address of the segment must be aligned on a 64-bit
14467 + InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14471 + STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14472 + 64-bit boundaries, or BlockSize was larger than
14473 + the initial segment size.
14475 + STATUS_SUCCESS - The zone was successfully initialized.
14484 + Zone->BlockSize = BlockSize;
14486 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14487 + ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14488 + ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14490 + Zone->FreeList.Next = NULL;
14492 + p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14494 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14495 + i <= InitialSegmentSize - BlockSize;
14498 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14499 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14502 + Zone->TotalSegmentSize = i;
14505 + DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14506 + Zone, InitialSegment, InitialSegmentSize,
14511 + return STATUS_SUCCESS;
14516 + IN PZONE_HEADER Zone,
14517 + IN PVOID Segment,
14518 + IN ULONG SegmentSize
14523 +Routine Description:
14525 + This function extends a zone by adding another segment's worth of
14526 + blocks to the zone.
14530 + Zone - Supplies the address of a zone header to be extended.
14532 + Segment - Supplies the address of a segment of storage. The first
14533 + ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14534 + zone allocator. The remainder of the segment is carved up
14535 + into fixed-size (BlockSize) blocks and is added to the
14536 + zone. The address of the segment must be aligned on a 64-
14539 + SegmentSize - Supplies the size in bytes of Segment.
14543 + STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14544 + 64-bit boundaries, or BlockSize was larger than
14545 + the segment size.
14547 + STATUS_SUCCESS - The zone was successfully extended.
14556 + ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14557 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14559 + p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14561 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14562 + i <= SegmentSize - Zone->BlockSize;
14563 + i += Zone->BlockSize
14566 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14567 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14568 + p += Zone->BlockSize;
14570 + Zone->TotalSegmentSize += i;
14573 + DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14574 + Zone, Segment, SegmentSize, Zone->BlockSize, p
14578 + return STATUS_SUCCESS;
14585 +/* Function: InqStrCopy()
14587 + * Arguments: [2] pointer to char
14589 + * Purpose: Copy a String from one location to another
14590 + * without copying \0
14593 +InqStrCopy(char *a, char *b)
14596 + while(*a != (char)0)
14600 diff -urN linux/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14601 --- linux/drivers/scsi/aacraid/port.c Wed Dec 31 19:00:00 1969
14602 +++ linux/drivers/scsi/aacraid/port.c Thu Dec 21 13:14:30 2000
14605 + * Adaptec aacraid device driver for Linux.
14607 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14609 + * This program is free software; you can redistribute it and/or modify
14610 + * it under the terms of the GNU General Public License as published by
14611 + * the Free Software Foundation; either version 2, or (at your option)
14612 + * any later version.
14614 + * This program is distributed in the hope that it will be useful,
14615 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14616 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14617 + * GNU General Public License for more details.
14619 + * You should have received a copy of the GNU General Public License
14620 + * along with this program; see the file COPYING. If not, write to
14621 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14626 + * Abstract: All support routines for FSA communication which are miniport specific.
14630 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14632 +#include "osheaders.h"
14635 +#include "AacGenericTypes.h"
14637 +#include "aac_unix_defs.h"
14639 +#include "fsatypes.h"
14640 +#include "comstruc.h"
14641 +#include "protocol.h"
14643 +#include "fsaport.h"
14644 +#include "fsaioctl.h"
14646 +#include "pcisup.h"
14649 +int AfaPortPrinting = 1;
14651 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14652 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14653 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14654 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14660 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14661 + IN AAC_STATUS ErrorCode,
14662 + IN PUCHAR StringBuffer,
14663 + IN ULONG StringLength
14667 +Routine Description:
14669 + Does all of the work to log an error log entry
14672 + CommonExtension - Pointer to the adapter that caused the error.
14674 + ErrorCode - Which error is being logged.
14676 + StringBuffer - Pointer to optional String for error log entry.
14678 + StringLength - Length of StringBuffer.
14691 +AfaPortGetNextAdapterNumber(
14692 + IN PDRIVER_OBJECT DriverObject,
14693 + OUT PDEVICE_OBJECT *FsaDeviceObject,
14694 + OUT PFILE_OBJECT *FileObject,
14695 + OUT PULONG AdapterNumber
14700 +AfaPortAllocateAdapterCommArea(
14702 + IN OUT PVOID *CommHeaderAddress,
14703 + IN ULONG CommAreaSize,
14704 + IN ULONG CommAreaAlignment
14707 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14708 + PVOID BaseAddress;
14709 + PHYSICAL_ADDRESS PhysicalBaseAddress;
14710 + ULONG TotalSize, BytesToAlign;
14711 + size_t RealLength;
14713 +// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14714 +// ULONG AdapterFibsSize = PAGE_SIZE;
14715 + ULONG AdapterFibsSize = 4096;
14716 + ULONG PrintfBufferSize = 256;
14717 + PADAPTER_INIT_STRUCT InitStruct;
14718 + extern int MiniPortRevision;
14719 + ULONG PhysAddress;
14721 +// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14722 +// SizeOfFastIoComm + PrintfBufferSize;
14723 + TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14724 + PrintfBufferSize;
14727 + OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14729 + CommonExtension->CommAddress = BaseAddress;
14730 + CommonExtension->CommPhysAddr = PhysAddress;
14731 + CommonExtension->CommSize = TotalSize;
14733 + PhysicalBaseAddress.HighPart = 0;
14734 + PhysicalBaseAddress.LowPart = PhysAddress;
14736 + CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14737 + CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14739 + InitStruct = CommonExtension->InitStruct;
14741 + InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14742 + InitStruct->MiniPortRevision = MiniPortRevision;
14743 + InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14746 + // Adapter Fibs are the first thing allocated so that they start page aligned
14748 + InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14749 + InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14750 + InitStruct->AdapterFibsSize = AdapterFibsSize;
14751 + InitStruct->AdapterFibAlign = sizeof(FIB);
14754 + // Increment the base address by the amount already used
14756 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14757 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14760 + // Align the beginning of Headers to CommAreaAlignment
14762 + BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14763 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14764 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14767 + // Fill in addresses of the Comm Area Headers and Queues
14769 + *CommHeaderAddress = BaseAddress;
14770 + InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14773 + // Increment the base address by the size of the CommArea
14775 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14776 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14780 + // Place the Printf buffer area after the Fast I/O comm area.
14782 + CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14783 + InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14784 + InitStruct->PrintfBufferSize = PrintfBufferSize;
14785 + bzero (BaseAddress, PrintfBufferSize);
14787 + AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14788 + TotalSize, InitStruct->AdapterFibsVirtualAddress,
14789 + (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14791 + AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14798 + IN PDEVICE_OBJECT DeviceObject,
14803 +Routine Description:
14805 + The routine will get called each time a user issues a CreateFile on the DeviceObject
14808 + The main purpose of this routine is to set up any data structures that may be needed
14809 + to handle any requests made on this DeviceObject.
14813 + DeviceObject - Pointer to device object representing adapter
14815 + Irp - Pointer to Irp that caused this open
14820 + Status value returned from File system driver AdapterOpen
14829 + IN PDEVICE_OBJECT DeviceObject,
14834 +Routine Description:
14836 + This routine will get called each time a user issues a CloseHandle on the DeviceObject
14839 + The main purpose of this routine is to cleanup any data structures that have been set up
14840 + while this FileObject has been opened.
14844 + DeviceObject - Pointer to device object representing adapter
14846 + Irp - Pointer to Irp that caused this close
14850 + Status value returned from File system driver AdapterClose
14859 +AfaPortDeviceControl (
14860 + IN PDEVICE_OBJECT DeviceObject,
14868 +AfaPortGetMaxPhysicalPage(
14869 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14873 +Routine Description:
14875 + This routine determines the max physical page in host memory.
14883 + Max physical page in host memory.
14891 diff -urN linux/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14892 --- linux/drivers/scsi/aacraid/rx.c Wed Dec 31 19:00:00 1969
14893 +++ linux/drivers/scsi/aacraid/rx.c Thu Dec 21 13:14:30 2000
14896 + * Adaptec aacraid device driver for Linux.
14898 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14900 + * This program is free software; you can redistribute it and/or modify
14901 + * it under the terms of the GNU General Public License as published by
14902 + * the Free Software Foundation; either version 2, or (at your option)
14903 + * any later version.
14905 + * This program is distributed in the hope that it will be useful,
14906 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14907 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14908 + * GNU General Public License for more details.
14910 + * You should have received a copy of the GNU General Public License
14911 + * along with this program; see the file COPYING. If not, write to
14912 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14917 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
14921 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
14923 +#include "osheaders.h"
14926 +#include "AacGenericTypes.h"
14928 +#include "aac_unix_defs.h"
14930 +#include "fsatypes.h"
14931 +#include "comstruc.h"
14932 +#include "fsact.h"
14933 +#include "protocol.h"
14935 +#define DEFINE_PCI_IDS
14936 +#include "rxcommon.h"
14937 +#include "monkerapi.h"
14939 +#include "fsaport.h"
14940 +#include "fsaioctl.h"
14942 +#include "pcisup.h"
14947 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
14949 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
14951 +#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
14953 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
14957 +// The list of all the Rx adapter structures
14960 +PRx_ADAPTER_EXTENSION RxAdapterList;
14964 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14965 + IN ULONG AdapterNumber,
14973 + ULONG FibPhysicalAddress
14976 +FSA_USER_VAR RxUserVars[] = {
14977 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
14982 +// Declare private use routines for this modual
14987 + IN PRx_ADAPTER_EXTENSION AdapterExtension
14992 +Routine Description:
14994 + The Isr routine for fsa Rx based adapter boards.
15001 + TRUE - if the interrupt was handled by this isr
15002 + FALSE - if the interrupt was not handled by this isr
15007 + ULONG DoorbellBits;
15008 + UCHAR InterruptStatus, Mask;
15009 + u_int OurInterrupt = INTR_UNCLAIMED;
15011 + //cmn_err(CE_WARN, "RxPciIsr entered\n");
15013 + InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15016 + // Read mask and invert because drawbridge is reversed.
15018 + // This allows us to only service interrupts that have been enabled.
15021 + Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15023 + // Check to see if this is our interrupt. If it isn't just return FALSE.
15026 + if (InterruptStatus & Mask) {
15028 + DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15030 + OurInterrupt = INTR_CLAIMED;
15032 + if (DoorbellBits & DoorBellPrintfReady) {
15034 + ULONG Length, Level;
15035 + unsigned char *cp;
15037 + cp = AdapterExtension->Common->PrintfBufferAddress;
15040 + // The size of the Printfbuffer is set in port.c
15041 + // There is no variable or define for it
15043 + if (Length > 255)
15046 + if (cp[Length] != 0) {
15047 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15051 + if (Level == LOG_HIGH_ERROR)
15052 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15054 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15056 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15058 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15060 + Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15063 + } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15065 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15066 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15068 + } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15070 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15071 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15073 + } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15075 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15076 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15078 + } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15080 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15081 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15086 + return(OurInterrupt);
15090 +RxEnableInterrupt(
15092 + ADAPTER_EVENT AdapterEvent,
15093 + BOOLEAN AtDeviceIrq
15097 +Routine Description:
15099 + This routine will enable the corresponding adapter event to cause an interrupt on
15104 + AdapterExtension - Which adapter to enable.
15106 + AdapterEvent - Which adapter event.
15108 + AtDeviceIrq - Whether the system is in DEVICE irql
15116 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15117 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15119 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15120 + switch (AdapterEvent) {
15122 + case HostNormCmdQue:
15124 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15128 + case HostNormRespQue:
15130 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15134 + case AdapNormCmdNotFull:
15136 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15140 + case AdapNormRespNotFull:
15142 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15151 +RxDisableInterrupt(
15153 + ADAPTER_EVENT AdapterEvent,
15154 + BOOLEAN AtDeviceIrq
15158 +Routine Description:
15160 + This routine will disable the corresponding adapter event to cause an interrupt on
15165 + AdapterExtension - Which adapter to enable.
15167 + AdapterEvent - Which adapter event.
15169 + AtDeviceIrq - Whether the system is in DEVICE irql
15177 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15178 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15180 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15182 + switch (AdapterEvent) {
15185 + case HostNormCmdQue:
15187 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15191 + case HostNormRespQue:
15193 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15197 + case AdapNormCmdNotFull:
15199 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15204 + case AdapNormRespNotFull:
15206 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15217 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15220 + PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15223 + // Free the register mapping.
15226 + OsDetachDevice( AdapterExtension);
15228 + OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15234 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15235 + IN ULONG AdapterNumber,
15242 +Routine Description:
15244 + Scans the PCI bus looking for the Rx card. When found all resources for the
15245 + device will be allocated and the interrupt vectors and csrs will be allocated and
15248 + The device_interface in the commregion will be allocated and linked to the comm region.
15255 + TRUE - if the device was setup with not problems
15256 + FALSE - if the device could not be mapped and init successfully
15261 + AAC_STATUS Status;
15262 + PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15263 + FSA_NEW_ADAPTER NewAdapter;
15264 + ULONG StartTime, EndTime, WaitTime;
15265 + ULONG InitStatus;
15270 + AfaPortPrint("In init device.\n");
15272 + //cmn_err(CE_WARN, "In RxInitDevice");
15274 +// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15275 + CommonExtension->AdapterNumber = AdapterNumber;
15278 + CommonExtension->PciBusNumber = PciBus;
15279 + CommonExtension->PciSlotNumber = PciSlot;
15282 + AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15283 + AdapterExtension->Common = CommonExtension;
15284 + CommonExtension->MiniPort = AdapterExtension;
15286 + instance = OsGetDeviceInstance(AdapterExtension);
15287 + name = OsGetDeviceName(AdapterExtension);
15289 + // Map in the registers from the adapter, register space 0 is config space,
15290 + // register space 1 is the memery space.
15293 + if (OsMapDeviceRegisters(AdapterExtension)) {
15295 + cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15296 + OsGetDeviceName(AdapterExtension), instance);
15301 + // Check to see if the board failed any self tests.
15304 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15306 + cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15307 + OsGetDeviceName(AdapterExtension), instance);
15311 + //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15312 + // OsGetDeviceName(AdapterExtension), instance);
15315 + // Check to see if the board panic'd while booting.
15318 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15320 + cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15321 + OsGetDeviceName(AdapterExtension), instance);
15326 + StartTime = OsGetSeconds();
15331 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
15334 + while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15336 + EndTime = OsGetSeconds();
15338 + WaitTime = EndTime - StartTime;
15340 + if ( WaitTime > (3 * 10) ) {
15342 + InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15344 + cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15345 + OsGetDeviceName(AdapterExtension), instance, InitStatus);
15351 + if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15352 + cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15357 + if (OsAttachDMA(AdapterExtension)) {
15358 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15363 + // Fill in the function dispatch table.
15366 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15367 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15368 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15369 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15370 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15371 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15372 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15373 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15374 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15375 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15376 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15377 + AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15378 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15380 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15382 + NewAdapter.AdapterExtension = CommonExtension;
15383 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15384 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15385 + NewAdapter.AdapterUserVars = RxUserVars;
15386 + NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15388 + NewAdapter.Dip = CommonExtension->OsDep.dip;
15391 + if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15393 + cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15394 + return (FAILURE);
15398 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15400 + if (AdapterExtension->Common->Adapter == NULL) {
15402 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15403 + cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15406 + return (FAILURE);
15411 + // Start any kernel threads needed
15413 + OsStartKernelThreads(AdapterExtension);
15416 + // Tell the adapter that all is configure, and it can start accepting requests
15419 + RxStartAdapter(AdapterExtension);
15427 + // Put this adapter into the list of Rx adapters
15430 + AdapterExtension->Next = RxAdapterList;
15431 + RxAdapterList = AdapterExtension;
15433 + AdapterExtension->Common->AdapterConfigured = TRUE;
15438 + // Call the disk layer to initialize itself.
15441 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15447 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15451 + OsAttachHBA(AdapterExtension);
15458 + PRx_ADAPTER_EXTENSION AdapterExtension
15461 + ULONG ReturnStatus;
15462 + LARGE_INTEGER HostTime;
15463 + ULONG ElapsedSeconds;
15464 + PADAPTER_INIT_STRUCT InitStruct;
15466 + //cmn_err(CE_WARN, "RxStartAdapter");
15468 + // Fill in the remaining pieces of the InitStruct.
15471 + InitStruct = AdapterExtension->Common->InitStruct;
15473 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15475 + ElapsedSeconds = OsGetSeconds();
15477 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
15480 + // Tell the adapter we are back and up and running so it will scan its command
15481 + // queues and enable our interrupts
15484 + AdapterExtension->LocalMaskInterruptControl =
15485 + (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15488 + // First clear out all interrupts. Then enable the one's that we can handle.
15491 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15492 + Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15493 +// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15494 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15496 + RxSendSynchCommand(AdapterExtension,
15497 + INIT_STRUCT_BASE_ADDRESS,
15498 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15516 +RxInterruptAdapter(
15521 +Routine Description:
15523 + The will cause the adapter to take a break point.
15535 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15536 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15538 + ULONG ReturnStatus;
15540 + RxSendSynchCommand(AdapterExtension,
15541 + BREAKPOINT_REQUEST,
15553 + IN HOST_2_ADAP_EVENT AdapterEvent
15557 +Routine Description:
15559 + Will read the adapter CSRs to find the reason the adapter has
15564 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15572 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15573 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15574 + ULONG ReturnStatus;
15576 + //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15578 + switch (AdapterEvent) {
15579 + case AdapNormCmdQue:
15581 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15584 + case HostNormRespNotFull:
15586 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15589 + case AdapNormRespQue:
15591 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15594 + case HostNormCmdNotFull:
15596 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15599 + case HostShutdown:
15601 +// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15606 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15609 + case AdapPrintfDone:
15610 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15615 + RxBugCheck(0,0,0);
15616 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15622 +RxSendSynchCommand(
15625 + ULONG Parameter1,
15626 + ULONG Parameter2,
15627 + ULONG Parameter3,
15628 + ULONG Parameter4,
15629 + PULONG ReturnStatus
15633 +Routine Description:
15635 + This routine will send a synchronous comamnd to the adapter and wait for its
15640 + AdapterExtension - Pointer to adapter extension structure.
15641 + Command - Which command to send
15642 + Parameter1 - 4 - Parameters for command
15643 + ReturnStatus - return status from adapter after completion of command
15652 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15653 + ULONG StartTime,EndTime,WaitTime;
15654 + BOOLEAN CommandSucceeded;
15656 + //cmn_err(CE_WARN, "RxSendSyncCommand");
15658 + // Write the Command into Mailbox 0
15661 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15664 + // Write the parameters into Mailboxes 1 - 4
15667 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15668 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15669 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15670 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15673 + // Clear the synch command doorbell to start on a clean slate.
15676 + Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15679 + // disable doorbell interrupts
15682 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15683 + Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15686 + // force the completion of the mask register write before issuing the interrupt.
15689 + Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15692 + // Signal that there is a new synch command
15695 + Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15697 + CommandSucceeded = FALSE;
15699 + StartTime = OsGetSeconds();
15702 + while (WaitTime < 30) { // wait up to 30 seconds
15704 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15707 + // Mon110 will set doorbell0 bit when it has completed the command.
15710 + if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15713 + // clear the doorbell.
15716 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15718 + CommandSucceeded = TRUE;
15722 + EndTime = OsGetSeconds();
15723 + WaitTime = EndTime - StartTime;
15727 + if (CommandSucceeded != TRUE) {
15730 + // restore interrupt mask even though we timed out
15733 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15734 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15736 + return (STATUS_IO_TIMEOUT);
15741 + // Pull the synch status from Mailbox 0.
15744 + *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15747 + // Clear the synch command doorbell.
15750 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15753 + // restore interrupt mask
15756 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15757 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15760 + // Return SUCCESS
15763 + return (STATUS_SUCCESS);
15770 + ULONG FibPhysicalAddress
15774 +Routine Description:
15776 + This routine will send a synchronous fib to the adapter and wait for its
15781 + AdapterExtension - Pointer to adapter extension structure.
15782 + FibPhysicalAddress - Physical address of fib to send.
15791 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15792 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15793 + ULONG returnStatus;
15795 + if (RxSendSynchCommand( AdapterExtension,
15796 + SEND_SYNCHRONOUS_FIB,
15797 + FibPhysicalAddress,
15801 + &returnStatus ) != STATUS_SUCCESS ) {
15812 diff -urN linux/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15813 --- linux/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 19:00:00 1969
15814 +++ linux/drivers/scsi/aacraid/sap1sup.c Thu Dec 21 13:14:30 2000
15817 + * Adaptec aacraid device driver for Linux.
15819 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15821 + * This program is free software; you can redistribute it and/or modify
15822 + * it under the terms of the GNU General Public License as published by
15823 + * the Free Software Foundation; either version 2, or (at your option)
15824 + * any later version.
15826 + * This program is distributed in the hope that it will be useful,
15827 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15828 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15829 + * GNU General Public License for more details.
15831 + * You should have received a copy of the GNU General Public License
15832 + * along with this program; see the file COPYING. If not, write to
15833 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15838 + * Abstract: Drawbridge specific support functions
15842 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15844 +#include "osheaders.h"
15847 +#include "AacGenericTypes.h"
15849 +#include "aac_unix_defs.h"
15851 +#include "fsatypes.h"
15852 +#include "comstruc.h"
15853 +#include "fsact.h"
15854 +#include "protocol.h"
15856 +#define DEFINE_PCI_IDS
15857 +#include "sap1common.h"
15858 +#include "monkerapi.h"
15860 +#include "fsaport.h"
15861 +#include "fsaioctl.h"
15864 +#include "pcisup.h"
15869 +#include "nodetype.h"
15870 +#include "comsup.h"
15871 +#include "afacomm.h"
15872 +#include "adapter.h"
15874 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15876 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15878 +#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15880 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15882 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15886 +// The list of all the Sa adapter structures
15889 +PSa_ADAPTER_EXTENSION SaAdapterList;
15893 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15894 + IN ULONG AdapterNumber,
15902 + ULONG FibPhysicalAddress
15905 +FSA_USER_VAR SaUserVars[] = {
15906 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15911 +// Declare private use routines for this modual
15917 +Routine Description:
15919 + The Isr routine for fsa Sa based adapter boards.
15926 + TRUE - if the interrupt was handled by this isr
15927 + FALSE - if the interrupt was not handled by this isr
15931 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
15933 + USHORT InterruptStatus, Mask;
15934 + u_int OurInterrupt = INTR_UNCLAIMED;
15936 + InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
15939 + // Read mask and invert because drawbridge is reversed.
15941 + // This allows us to only service interrupts that have been enabled.
15944 + Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
15946 + // Check to see if this is our interrupt. If it isn't just return FALSE.
15949 + if (InterruptStatus & Mask) {
15951 + OurInterrupt = INTR_CLAIMED;
15953 + if (InterruptStatus & PrintfReady) {
15955 + ULONG Length, Level;
15956 + unsigned char *cp;
15958 + cp = AdapterExtension->Common->PrintfBufferAddress;
15961 + // The size of the Printbuffer is set in port.c
15962 + // There is no variable or define for it
15964 + if (Length > 255)
15967 + if (cp[Length] != 0) {
15968 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15972 + if (Level == LOG_HIGH_ERROR)
15973 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15975 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15977 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15979 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
15981 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
15983 + } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
15985 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15986 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
15988 + } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
15990 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15991 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
15993 + } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
15995 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15996 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
15998 + } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
16000 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16001 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16006 + return(OurInterrupt);
16012 +Routine Description:
16014 + This routine will enable the corresponding adapter event to cause an interrupt on
16019 + AdapterExtension - Which adapter to enable.
16021 + AdapterEvent - Which adapter event.
16023 + AtDeviceIrq - Whether the system is in DEVICE irql
16031 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16033 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16034 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16036 + switch (AdapterEvent) {
16038 + case HostNormCmdQue:
16040 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16044 + case HostNormRespQue:
16046 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16050 + case AdapNormCmdNotFull:
16052 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16056 + case AdapNormRespNotFull:
16058 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16070 +Routine Description:
16072 + This routine will disable the corresponding adapter event to cause an interrupt on
16077 + AdapterExtension - Which adapter to enable.
16079 + AdapterEvent - Which adapter event.
16081 + AtDeviceIrq - Whether the system is in DEVICE irql
16089 +SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16091 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16092 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16094 + switch (AdapterEvent) {
16097 + case HostNormCmdQue:
16099 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16103 + case HostNormRespQue:
16105 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16109 + case AdapNormCmdNotFull:
16111 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16116 + case AdapNormRespNotFull:
16118 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16127 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16129 + PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16132 + // Free the register mapping.
16135 + OsDetachDevice(AdapterExtension);
16137 + OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16144 +Routine Description:
16146 + Scans the PCI bus looking for the Sa card. When found all resources for the
16147 + device will be allocated and the interrupt vectors and csrs will be allocated and
16150 + The device_interface in the commregion will be allocated and linked to the comm region.
16157 + TRUE - if the device was setup with not problems
16158 + FALSE - if the device could not be mapped and init successfully
16162 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16163 + IN ULONG AdapterNumber, IN ULONG PciBus,
16164 + IN ULONG PciSlot)
16166 + AAC_STATUS Status;
16167 + PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16168 + FSA_NEW_ADAPTER NewAdapter;
16169 + ULONG StartTime, EndTime, WaitTime;
16170 + ULONG InitStatus;
16174 + AfaPortPrint("In init device.\n");
16176 + CommonExtension->AdapterNumber = AdapterNumber;
16178 + CommonExtension->PciBusNumber = PciBus;
16179 + CommonExtension->PciSlotNumber = PciSlot;
16181 + AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16182 + AdapterExtension->Common = CommonExtension;
16183 + CommonExtension->MiniPort = AdapterExtension;
16185 + instance = OsGetDeviceInstance(AdapterExtension);
16186 + name = OsGetDeviceName(AdapterExtension);
16189 + // Map in the registers from the adapter, register space 0 is config space,
16190 + // register space 1 is the memery space.
16193 + if (OsMapDeviceRegisters(AdapterExtension)){
16194 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16200 + // Check to see if the board failed any self tests.
16203 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16205 + cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16211 + // Check to see if the board panic'd while booting.
16214 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16216 + cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16222 + StartTime = OsGetSeconds();
16227 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
16230 + while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16232 + EndTime = OsGetSeconds();
16234 + WaitTime = EndTime - StartTime;
16236 + if ( WaitTime > (3 * 60) ) {
16238 + InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16240 + cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16241 + name, instance, InitStatus);
16247 + if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16248 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16252 + if (OsAttachDMA(AdapterExtension)) {
16253 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16259 + // Fill in the function dispatch table.
16262 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16263 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16264 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16265 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16266 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16267 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16268 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16269 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16270 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16271 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16272 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16273 + AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16274 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16276 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16278 + NewAdapter.AdapterExtension = CommonExtension;
16279 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16280 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16281 + NewAdapter.AdapterUserVars = SaUserVars;
16282 + NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16284 + NewAdapter.Dip = CommonExtension->OsDep.dip;
16287 + if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16288 + cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16289 + return (FAILURE);
16293 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16295 + if (AdapterExtension->Common->Adapter == NULL) {
16297 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16298 + cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16300 + return (FAILURE);
16305 + // Start any kernel threads needed
16306 + OsStartKernelThreads(AdapterExtension);
16309 + // Tell the adapter that all is configure, and it can start accepting requests
16312 + SaStartAdapter(AdapterExtension);
16317 + // Put this adapter into the list of Sa adapters
16320 + AdapterExtension->Next = SaAdapterList;
16321 + SaAdapterList = AdapterExtension;
16323 + AdapterExtension->Common->AdapterConfigured = TRUE;
16328 + // Call the disk layer to initialize itself.
16331 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16337 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16339 + OsAttachHBA(AdapterExtension);
16345 + return (FAILURE);
16351 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16353 + ULONG ReturnStatus;
16354 + LARGE_INTEGER HostTime;
16355 + ULONG ElapsedSeconds;
16356 + PADAPTER_INIT_STRUCT InitStruct;
16359 + // Fill in the remaining pieces of the InitStruct.
16362 + InitStruct = AdapterExtension->Common->InitStruct;
16364 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16366 + ElapsedSeconds = OsGetSeconds();
16368 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
16371 + // Tell the adapter we are back and up and running so it will scan its command
16372 + // queues and enable our interrupts
16375 + AdapterExtension->LocalMaskInterruptControl =
16376 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16380 + // First clear out all interrupts. Then enable the one's that we can handle.
16383 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16384 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16385 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16387 + SaSendSynchCommand(AdapterExtension,
16388 + INIT_STRUCT_BASE_ADDRESS,
16389 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16399 +SaResetDevice (PVOID Arg1){
16406 +Routine Description:
16408 + The will cause the adapter to take a break point.
16420 +SaInterruptAdapter (PVOID Arg1)
16422 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16423 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16425 + ULONG ReturnStatus;
16427 + SaSendSynchCommand(AdapterExtension,
16428 + BREAKPOINT_REQUEST,
16440 +Routine Description:
16442 + Will read the adapter CSRs to find the reason the adapter has
16447 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16455 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16457 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16458 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16459 + ULONG ReturnStatus;
16461 + switch (AdapterEvent) {
16462 + case AdapNormCmdQue:
16464 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16467 + case HostNormRespNotFull:
16469 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16472 + case AdapNormRespQue:
16474 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16477 + case HostNormCmdNotFull:
16479 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16482 + case HostShutdown:
16484 +// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16489 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16492 + case AdapPrintfDone:
16493 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16498 + SaBugCheck(0,0,0);
16499 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16507 +Routine Description:
16509 + This routine will send a synchronous comamnd to the adapter and wait for its
16514 + AdapterExtension - Pointer to adapter extension structure.
16515 + Command - Which command to send
16516 + Parameter1 - 4 - Parameters for command
16517 + ReturnStatus - return status from adapter after completion of command
16526 +SaSendSynchCommand(
16529 + ULONG Parameter1,
16530 + ULONG Parameter2,
16531 + ULONG Parameter3,
16532 + ULONG Parameter4,
16533 + PULONG ReturnStatus
16536 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16537 + ULONG StartTime,EndTime,WaitTime;
16538 + BOOLEAN CommandSucceeded;
16541 + // Write the Command into Mailbox 0
16544 + Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16547 + // Write the parameters into Mailboxes 1 - 4
16550 + Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16551 + Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16552 + Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16553 + Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16556 + // Clear the synch command doorbell to start on a clean slate.
16559 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16562 + // Signal that there is a new synch command
16565 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16567 + CommandSucceeded = FALSE;
16569 + StartTime = OsGetSeconds();
16572 + while (WaitTime < 30) { // wait up to 30 seconds
16574 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16577 + // Mon110 will set doorbell0 bit when it has completed the command.
16580 + if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16582 + CommandSucceeded = TRUE;
16586 + EndTime = OsGetSeconds();
16587 + WaitTime = EndTime - StartTime;
16591 + if (CommandSucceeded != TRUE) {
16593 + return (STATUS_IO_TIMEOUT);
16598 + // Clear the synch command doorbell.
16601 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16604 + // Pull the synch status from Mailbox 0.
16607 + *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16610 + // Return SUCCESS
16613 + return (STATUS_SUCCESS);
16620 +Routine Description:
16622 + This routine will send a synchronous fib to the adapter and wait for its
16627 + AdapterExtension - Pointer to adapter extension structure.
16628 + FibPhysicalAddress - Physical address of fib to send.
16637 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16639 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16640 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16641 + ULONG returnStatus;
16643 + if (SaSendSynchCommand( AdapterExtension,
16644 + SEND_SYNCHRONOUS_FIB,
16645 + FibPhysicalAddress,
16649 + &returnStatus ) != STATUS_SUCCESS ) {
16661 + PVOID AdapterExtension,
16662 + ULONG *MappedBuffer)
16669 + PVOID AdapterExtension,
16670 + ULONG *MappedBuffer)