1 diff -burN linux-2.4.4/MAINTAINERS linux/MAINTAINERS
2 --- linux-2.4.4/MAINTAINERS Wed Apr 25 16:35:25 2001
3 +++ linux/MAINTAINERS Mon Apr 30 09:43:33 2001
5 W: http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
8 +AACRAID SCSI RAID DRIVER
9 +P: Adaptec OEM Raid Solutions
10 +M: linux-aacraid-devel@domsch.com
11 +L: linux-aacraid-devel@domsch.com
12 +L: linux-aacraid-announce@domsch.com
13 +W: http://domsch.com/linux
18 M: andrew.grover@intel.com
19 diff -burN linux-2.4.4/arch/i386/defconfig linux/arch/i386/defconfig
20 --- linux-2.4.4/arch/i386/defconfig Fri Apr 27 16:41:16 2001
21 +++ linux/arch/i386/defconfig Mon Apr 30 09:43:33 2001
23 # CONFIG_SCSI_AHA152X is not set
24 # CONFIG_SCSI_AHA1542 is not set
25 # CONFIG_SCSI_AHA1740 is not set
26 +# CONFIG_SCSI_AACRAID is not set
27 # CONFIG_SCSI_AIC7XXX is not set
28 # CONFIG_SCSI_AIC7XXX_OLD is not set
29 # CONFIG_SCSI_ADVANSYS is not set
30 diff -burN linux-2.4.4/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31 --- linux-2.4.4/drivers/scsi/Config.in Sun Mar 4 16:30:18 2001
32 +++ linux/drivers/scsi/Config.in Mon Apr 30 09:43:33 2001
34 dep_tristate 'Adaptec AHA152X/2825 support' CONFIG_SCSI_AHA152X $CONFIG_SCSI
35 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 $CONFIG_SCSI
36 dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
37 +dep_tristate 'Adaptec AACRAID support' CONFIG_SCSI_AACRAID $CONFIG_SCSI
38 source drivers/scsi/aic7xxx/Config.in
39 if [ "$CONFIG_SCSI_AIC7XXX" != "y" ]; then
40 dep_tristate 'Old Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX_OLD $CONFIG_SCSI
41 diff -burN linux-2.4.4/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42 --- linux-2.4.4/drivers/scsi/Makefile Mon Mar 26 17:36:30 2001
43 +++ linux/drivers/scsi/Makefile Mon Apr 30 09:43:33 2001
45 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
46 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx_drv.o
48 +obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
49 obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o
50 obj-$(CONFIG_SCSI_IPS) += ips.o
51 obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
53 sim710_u.h: sim710_d.h
60 diff -burN linux-2.4.4/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
61 --- linux-2.4.4/drivers/scsi/aacraid/ChangeLog Wed Dec 31 18:00:00 1969
62 +++ linux/drivers/scsi/aacraid/ChangeLog Mon Apr 30 09:46:47 2001
64 +2001-04-30 Matt Domsch <Matt_Domsch@dell.com>
65 +* Started with linux-2.4.3-aacraid-030101.patch
66 +* Applied against 2.4.4.
67 +* Added scsi_set_pci_device() call in linit.c
69 diff -burN linux-2.4.4/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
70 --- linux-2.4.4/drivers/scsi/aacraid/Makefile Wed Dec 31 18:00:00 1969
71 +++ linux/drivers/scsi/aacraid/Makefile Mon Apr 30 09:43:33 2001
74 +# Makefile aacraid Raid Controller
77 +###############################################################################
78 +### SOURCE FILES DEFINES
79 +###############################################################################
97 + ./include/AacGenericTypes.h \
98 + ./include/aac_unix_defs.h \
99 + ./include/adapter.h \
100 + ./include/afacomm.h \
101 + ./include/aifstruc.h \
102 + ./include/build_number.h \
103 + ./include/commdata.h \
104 + ./include/commerr.h \
105 + ./include/commfibcontext.h \
106 + ./include/comprocs.h \
107 + ./include/comproto.h \
108 + ./include/comstruc.h \
109 + ./include/comsup.h \
110 + ./include/fsact.h \
111 + ./include/fsafs.h \
112 + ./include/fsaioctl.h \
113 + ./include/fsaport.h \
114 + ./include/fsatypes.h \
115 + ./include/linit.h \
116 + ./include/monkerapi.h \
117 + ./include/nodetype.h \
118 + ./include/nvramioctl.h \
119 + ./include/osheaders.h \
120 + ./include/ostypes.h \
121 + ./include/pcisup.h \
122 + ./include/perfpack.h \
124 + ./include/protocol.h \
125 + ./include/revision.h \
126 + ./include/rxcommon.h \
128 + ./include/sap1common.h \
130 + ./include/version.h
136 +###############################################################################
137 +### OBJECT FILES DEFINES
138 +###############################################################################
155 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
157 +###############################################################################
159 +###############################################################################
161 +# Remember that we're doing a chdir one level lower, so we need an extra ../
164 + -I../../../include -I..
166 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
170 + -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
174 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
176 +###############################################################################
177 +### DO GENERAL STUFF
178 +###############################################################################
181 +.SUFFIXES: .c .o .h .a
183 +all: source ${TARGET_OFILES} aacraid.o
185 +source: ${ALL_SOURCE}
190 +###############################################################################
192 +###############################################################################
194 +aacraid.o: source ${TARGET_OFILES}
195 + ld -r -o $@ $(TARGET_OFILES)
196 + cp -r aacraid.o ../
198 +###############################################################################
200 +###############################################################################
203 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
205 +aachba.o: ./aachba.c
206 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
209 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
211 +osfuncs.o: ./osfuncs.c
212 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
214 +commctrl.o: ./commctrl.c
215 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
217 +comminit.o: ./comminit.c
218 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
220 +commsup.o: ./commsup.c
221 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
223 +dpcsup.o: ./dpcsup.c
224 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
227 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
230 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
233 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
236 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
238 +sap1sup.o: ./sap1sup.c
239 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
242 diff -burN linux-2.4.4/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
243 --- linux-2.4.4/drivers/scsi/aacraid/README Wed Dec 31 18:00:00 1969
244 +++ linux/drivers/scsi/aacraid/README Mon Apr 30 09:43:33 2001
246 + AACRAID Driver for Linux
249 +-------------------------
250 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
251 +OEM based RAID controllers.
253 +It is important to note the amount of test time the 2.4.x driver
254 +received. Though not a great deal has changed between 2.2 and 2.4
255 +for this version, it has not recevied a great deal of test time.
257 +A new driver version is in the works and that version will be
258 +submitted to the standard distribution kernel. The previous
259 +2.2 version was submitted but rejected due to the large
260 +amount of code reduncdancy and NTisms. This driver was
261 +initially ported from NT to Solaris and then to Linux.
263 +The new version is being written on Unix for Unix and
264 +should be much easier to read and a great deal cleaner.
266 +Supported Cards/Chipsets
267 +-------------------------
268 + Dell Computer Corporation PERC 2 Quad Channel
269 + Dell Computer Corporation PERC 2/Si
270 + Dell Computer Corporation PERC 3/Si
271 + Dell Computer Corporation PERC 3/Di
274 +Not Supported Devices
275 +-------------------------
276 + Any and All Adaptec branded raid controllers.
279 +-------------------------
280 + Adaptec Unix OEM Product Group
283 +-------------------------
284 +please see http://domsch.com/linux for information
285 +on mailing lists. There is both a development and
286 +an announcment list. Due to the overwhelming amount
287 +of mail I receive about this driver, I can not
288 +answer questions individually and requests should
289 +be directed to the list server. Thanks.
291 +Modified by Brian Boerner February 2001
292 diff -burN linux-2.4.4/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
293 --- linux-2.4.4/drivers/scsi/aacraid/aachba.c Wed Dec 31 18:00:00 1969
294 +++ linux/drivers/scsi/aacraid/aachba.c Mon Apr 30 09:43:34 2001
297 + * Adaptec aacraid device driver for Linux.
299 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
301 + * This program is free software; you can redistribute it and/or modify
302 + * it under the terms of the GNU General Public License as published by
303 + * the Free Software Foundation; either version 2, or (at your option)
304 + * any later version.
306 + * This program is distributed in the hope that it will be useful,
307 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
308 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
309 + * GNU General Public License for more details.
311 + * You should have received a copy of the GNU General Public License
312 + * along with this program; see the file COPYING. If not, write to
313 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
318 + * Abstract: driver...
322 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
324 +/*------------------------------------------------------------------------------
326 + *----------------------------------------------------------------------------*/
327 +#include "osheaders.h"
328 +#include "AacGenericTypes.h"
329 +#include "aac_unix_defs.h"
330 +#include "comstruc.h"
331 +#include "monkerapi.h"
332 +#include "protocol.h"
335 +#include "fsaioctl.h"
337 +#include "sap1common.h"
338 +#include "fsaport.h"
341 +#include "nodetype.h"
343 +#include "afacomm.h"
344 +#include "adapter.h"
346 +/*------------------------------------------------------------------------------
348 + *----------------------------------------------------------------------------*/
350 +#define SS_TEST 0x00 /* Test unit ready */
351 +#define SS_REZERO 0x01 /* Rezero unit */
352 +#define SS_REQSEN 0x03 /* Request Sense */
353 +#define SS_REASGN 0x07 /* Reassign blocks */
354 +#define SS_READ 0x08 /* Read 6 */
355 +#define SS_WRITE 0x0A /* Write 6 */
356 +#define SS_INQUIR 0x12 /* inquiry */
357 +#define SS_ST_SP 0x1B /* Start/Stop unit */
358 +#define SS_LOCK 0x1E /* prevent/allow medium removal */
359 +#define SS_RESERV 0x16 /* Reserve */
360 +#define SS_RELES 0x17 /* Release */
361 +#define SS_MODESEN 0x1A /* Mode Sense 6 */
362 +#define SS_RDCAP 0x25 /* Read Capacity */
363 +#define SM_READ 0x28 /* Read 10 */
364 +#define SM_WRITE 0x2A /* Write 10 */
365 +#define SS_SEEK 0x2B /* Seek */
367 +/* values for inqd_pdt: Peripheral device type in plain English */
368 +#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
369 +#define INQD_PDT_PROC 0x03 /* Processor device */
370 +#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
371 +#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
372 +#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
373 +#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
375 +#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
376 +#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
378 +#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
379 +#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
380 +#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
382 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
384 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
386 +// ------------------------------------------------------
389 +#define SENKEY_NO_SENSE 0x00 //
390 +#define SENKEY_UNDEFINED 0x01 //
391 +#define SENKEY_NOT_READY 0x02 //
392 +#define SENKEY_MEDIUM_ERR 0x03 //
393 +#define SENKEY_HW_ERR 0x04 //
394 +#define SENKEY_ILLEGAL 0x05 //
395 +#define SENKEY_ATTENTION 0x06 //
396 +#define SENKEY_PROTECTED 0x07 //
397 +#define SENKEY_BLANK 0x08 //
398 +#define SENKEY_V_UNIQUE 0x09 //
399 +#define SENKEY_CPY_ABORT 0x0A //
400 +#define SENKEY_ABORT 0x0B //
401 +#define SENKEY_EQUAL 0x0C //
402 +#define SENKEY_VOL_OVERFLOW 0x0D //
403 +#define SENKEY_MISCOMP 0x0E //
404 +#define SENKEY_RESERVED 0x0F //
406 +// ------------------------------------------------------
409 +#define SENCODE_NO_SENSE 0x00
410 +#define SENCODE_END_OF_DATA 0x00
411 +#define SENCODE_BECOMING_READY 0x04
412 +#define SENCODE_INIT_CMD_REQUIRED 0x04
413 +#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
414 +#define SENCODE_INVALID_COMMAND 0x20
415 +#define SENCODE_LBA_OUT_OF_RANGE 0x21
416 +#define SENCODE_INVALID_CDB_FIELD 0x24
417 +#define SENCODE_LUN_NOT_SUPPORTED 0x25
418 +#define SENCODE_INVALID_PARAM_FIELD 0x26
419 +#define SENCODE_PARAM_NOT_SUPPORTED 0x26
420 +#define SENCODE_PARAM_VALUE_INVALID 0x26
421 +#define SENCODE_RESET_OCCURRED 0x29
422 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
423 +#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
424 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
425 +#define SENCODE_DIAGNOSTIC_FAILURE 0x40
426 +#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
427 +#define SENCODE_INVALID_MESSAGE_ERROR 0x49
428 +#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
429 +#define SENCODE_OVERLAPPED_COMMAND 0x4E
431 +// ------------------------------------------------------
432 +// Additional sense codes
434 +#define ASENCODE_NO_SENSE 0x00
435 +#define ASENCODE_END_OF_DATA 0x05
436 +#define ASENCODE_BECOMING_READY 0x01
437 +#define ASENCODE_INIT_CMD_REQUIRED 0x02
438 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
439 +#define ASENCODE_INVALID_COMMAND 0x00
440 +#define ASENCODE_LBA_OUT_OF_RANGE 0x00
441 +#define ASENCODE_INVALID_CDB_FIELD 0x00
442 +#define ASENCODE_LUN_NOT_SUPPORTED 0x00
443 +#define ASENCODE_INVALID_PARAM_FIELD 0x00
444 +#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
445 +#define ASENCODE_PARAM_VALUE_INVALID 0x02
446 +#define ASENCODE_RESET_OCCURRED 0x00
447 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
448 +#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
449 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
450 +#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
451 +#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
452 +#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
453 +#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
454 +#define ASENCODE_OVERLAPPED_COMMAND 0x00
456 +#define BYTE0( x ) ( unsigned char )( x )
457 +#define BYTE1( x ) ( unsigned char )( x >> 8 )
458 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
459 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
461 +/*------------------------------------------------------------------------------
462 + * S T R U C T S / T Y P E D E F S
463 + *----------------------------------------------------------------------------*/
464 +/* SCSI inquiry data */
465 +struct inquiry_data {
466 + unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
467 + unchar inqd_dtq; /* RMB | Device Type Qualifier */
468 + unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
469 + unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
470 + unchar inqd_len; /* Additional length (n-4) */
471 + unchar inqd_pad1[2]; /* Reserved - must be zero */
472 + unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
473 + unchar inqd_vid[8]; /* Vendor ID */
474 + unchar inqd_pid[16]; /* Product ID */
475 + unchar inqd_prl[4]; /* Product Revision Level */
479 + unchar error_code; // 70h (current errors), 71h(deferred errors)
480 + unchar valid:1; // A valid bit of one indicates that the information
481 + // field contains valid information as defined in the
482 + // SCSI-2 Standard.
484 + unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
487 + unchar sense_key:4; // Sense Key
489 + unchar ILI:1; // Incorrect Length Indicator
490 + unchar EOM:1; // End Of Medium - reserved for random access devices
491 + unchar filemark:1; // Filemark - reserved for random access devices
493 + unchar information[4]; // for direct-access devices, contains the unsigned
494 + // logical block address or residue associated with
496 + unchar add_sense_len; // number of additional sense bytes to follow this field
497 + unchar cmnd_info[4]; // not used
498 + unchar ASC; // Additional Sense Code
499 + unchar ASCQ; // Additional Sense Code Qualifier
500 + unchar FRUC; // Field Replaceable Unit Code - not used
502 + unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
504 + unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
505 + // the bit_ptr field has valid value
506 + unchar reserved2:2;
507 + unchar CD:1; // command data bit: 1- illegal parameter in CDB.
508 + // 0- illegal parameter in data.
511 + unchar field_ptr[2]; // byte of the CDB or parameter data in error
514 +/*------------------------------------------------------------------------------
516 + *----------------------------------------------------------------------------*/
517 +/*------------------------------------------------------------------------------
518 + * M O D U L E G L O B A L S
519 + *----------------------------------------------------------------------------*/
520 +static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
521 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
523 +/*------------------------------------------------------------------------------
524 + * F U N C T I O N P R O T O T Y P E S
525 + *----------------------------------------------------------------------------*/
526 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
527 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
528 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
529 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
530 + PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
532 +void AacHba_CompleteScsi(
533 + Scsi_Cmnd *scsi_cmnd_ptr );
535 +void AacHba_CompleteScsiNoLock(
536 + Scsi_Cmnd *scsi_cmnd_ptr );
538 +static void AacHba_ReadCallback(
540 + PFIB_CONTEXT FibContext,
543 +static void AacHba_WriteCallback(
545 + PFIB_CONTEXT FibContext,
548 +int AacHba_DoScsiRead(
549 + Scsi_Cmnd *scsi_cmnd_ptr,
553 +int AacHba_DoScsiWrite(
554 + Scsi_Cmnd *scsi_cmnd_ptr,
558 +int AacHba_QueryDisk(
559 + PVOID AdapterArg, // CommonExtensionPtr
560 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
562 +int AacHba_ForceDeleteDisk(
563 + PVOID AdapterArg, // CommonExtensionPtr
564 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
566 +int AacHba_DeleteDisk(
568 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
570 +void AacHba_DetachAdapter(
571 + IN PVOID AdapterArg );
573 +BOOLEAN AacCommDetachAdapter(
574 + IN PAFA_COMM_ADAPTER Adapter );
576 +void AacHba_SetSenseData(
580 + unchar a_sense_code,
581 + unchar incorrect_length,
582 + unchar bit_pointer,
583 + unsigned field_pointer,
584 + unsigned long residue );
586 +static void get_sd_devname(
590 +// Keep these here for the time being - #REVIEW#
592 +AfaCommAdapterDeviceControl (
593 + IN PVOID AdapterArg,
594 + IN PAFA_IOCTL_CMD IoctlCmdPtr
598 +AfaCommRegisterNewClassDriver(
599 + IN PAFA_COMM_ADAPTER Adapter,
600 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
601 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
605 +SetInqDataStr (int, void *, int);
606 +/*------------------------------------------------------------------------------
607 + * F U N C T I O N S
608 + *----------------------------------------------------------------------------*/
610 +/*------------------------------------------------------------------------------
611 + AacHba_ClassDriverInit()
613 + Setup 'core' class driver to answer ioctl's
614 + *----------------------------------------------------------------------------*/
615 +int AacHba_ClassDriverInit(
616 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
617 +/*----------------------------------------------------------------------------*/
619 + AFA_NEW_CLASS_DRIVER NewClassDriver;
620 + AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
621 + PAFA_COMM_ADAPTER Adapter;
623 + Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
625 + RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
627 + // ClassDriverExtension is the first argument passed to class driver functions below
628 + NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
630 + NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
631 + NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
632 + NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
633 + NewClassDriver.HandleAif = AacHba_HandleAif;
634 + AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
640 +/*------------------------------------------------------------------------------
641 + AacHba_ProbeContainers()
643 + Make a list of all containers in the system.
644 +------------------------------------------------------------------------------*/
645 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
647 + fsadev_t *fsa_dev_ptr;
650 + PMNTINFORESPONSE DiskInfoResponse;
651 + PFIB_CONTEXT FibContext;
652 + AFA_COMM_ADAPTER *Adapter;
658 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
659 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
660 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
662 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
664 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
665 + return( STATUS_UNSUCCESSFUL );
668 + for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
670 + Adapter->CommFuncs.InitializeFib( FibContext );
672 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
674 + DiskInfo->Command = VM_NameServe;
675 + DiskInfo->MntCount = Index;
676 + DiskInfo->MntType = FT_FILESYS;
678 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
689 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
693 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
696 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
697 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
701 + fsa_dev_ptr->ContainerValid[Index] = TRUE;
702 + fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
703 + fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
705 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
706 + fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
709 + Adapter->CommFuncs.CompleteFib( FibContext );
711 + // If there are no more containers, then stop asking.
712 + if ((Index + 1) >= DiskInfoResponse->MntRespCount)
716 + Adapter->CommFuncs.FreeFib( FibContext );
718 + g_fsa_dev_array[instance] = fsa_dev_ptr;
723 +/*------------------------------------------------------------------------------
724 + AacHba_ProbeContainer()
726 + Probe a single container.
727 + *----------------------------------------------------------------------------*/
728 +int AacHba_ProbeContainer(
729 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
731 +/*----------------------------------------------------------------------------*/
733 + fsadev_t *fsa_dev_ptr;
736 + PMNTINFORESPONSE DiskInfoResponse;
737 + PFIB_CONTEXT FibContext;
738 + AFA_COMM_ADAPTER *Adapter;
741 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
742 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
743 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
745 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
747 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
748 + return( STATUS_UNSUCCESSFUL );
751 + Adapter->CommFuncs.InitializeFib( FibContext );
753 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
755 + DiskInfo->Command = VM_NameServe;
756 + DiskInfo->MntCount = ContainerId;
757 + DiskInfo->MntType = FT_FILESYS;
759 + Status = Adapter->CommFuncs.SendFib (ContainerCommand,
770 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
771 + Adapter->CommFuncs.CompleteFib( FibContext );
772 + Adapter->CommFuncs.FreeFib( FibContext );
776 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
779 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
780 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
783 + fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
784 + fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
785 + fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
786 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
787 + fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
790 + Adapter->CommFuncs.CompleteFib( FibContext );
791 + Adapter->CommFuncs.FreeFib( FibContext );
797 +/*------------------------------------------------------------------------------
798 + AacHba_CompleteScsi()
800 + Call SCSI completion routine after acquiring io_request_lock
804 + *----------------------------------------------------------------------------*/
805 +void AacHba_CompleteScsi(
806 + Scsi_Cmnd *scsi_cmnd_ptr )
808 + unsigned long cpu_flags;
810 + spin_lock_irqsave( &io_request_lock, cpu_flags );
811 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
812 + spin_unlock_irqrestore( &io_request_lock, cpu_flags );
816 +/*------------------------------------------------------------------------------
817 + AacHba_CompleteScsiNoLock()
819 + Call SCSI completion routine
823 + *----------------------------------------------------------------------------*/
824 +void AacHba_CompleteScsiNoLock(
825 + Scsi_Cmnd *scsi_cmnd_ptr )
827 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
830 +/*------------------------------------------------------------------------------
833 + Process SCSI command
837 + Returns 0 on success, -1 on failure
838 + *----------------------------------------------------------------------------*/
839 +int AacHba_DoScsiCmd(
840 + Scsi_Cmnd *scsi_cmnd_ptr,
843 + int ContainerId = 0;
844 + fsadev_t *fsa_dev_ptr;
845 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
848 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
849 + MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
851 + fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
853 + // If the bus, target or lun is out of range, return fail
854 + // Test does not apply to ID 16, the pseudo id for the controller itself.
855 + if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
857 + if( ( scsi_cmnd_ptr->channel > 0 ) ||
858 + ( scsi_cmnd_ptr->target > 15 ) ||
859 + ( scsi_cmnd_ptr->lun > 7 ) )
861 + cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
862 + scsi_cmnd_ptr->channel,
863 + scsi_cmnd_ptr->target,
864 + scsi_cmnd_ptr->lun );
865 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
867 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
872 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
875 + // If the target container doesn't exist, it may have been newly created
876 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
878 + switch( scsi_cmnd_ptr->cmnd[0] )
883 + spin_unlock_irq( &io_request_lock );
884 + AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
885 + spin_lock_irq( &io_request_lock );
891 + // If the target container still doesn't exist, return failure
892 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
895 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
896 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
901 + else // the command is for the controller itself
902 + if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
903 + ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
905 + cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
906 + scsi_cmnd_ptr->cmnd[0] );
908 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
910 + AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
911 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
914 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
919 + // Handle commands here that don't really require going out to the adapter
920 + switch ( scsi_cmnd_ptr->cmnd[0] )
924 + struct inquiry_data *inq_data_ptr;
926 + cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
927 + inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
928 + bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
930 + inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
932 + inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
933 + // that the medium is removable
934 + inq_data_ptr->inqd_rdf = 2; // A response data format value of
935 + // two indicates that the data shall
936 + // be in the format specified in SCSI-2
937 + inq_data_ptr->inqd_len = 31;
939 + // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
940 + SetInqDataStr( MiniPortIndex,
941 + (void *)(inq_data_ptr->inqd_vid),
942 + fsa_dev_ptr->ContainerType[ContainerId]);
944 + if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
945 + inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
947 + inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
949 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
950 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
960 + cmn_err( CE_DEBUG, "READ CAPACITY command" );
961 + capacity = fsa_dev_ptr->ContainerSize[ContainerId];
962 + cp = scsi_cmnd_ptr->request_buffer;
963 + cp[0] = ( capacity >> 24 ) & 0xff;
964 + cp[1] = ( capacity >> 16 ) & 0xff;
965 + cp[2] = ( capacity >> 8 ) & 0xff;
966 + cp[3] = ( capacity >> 0 ) & 0xff;
972 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
973 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
982 + cmn_err( CE_DEBUG, "MODE SENSE command" );
983 + mode_buf = scsi_cmnd_ptr->request_buffer;
984 + mode_buf[0] = 0; // Mode data length (MSB)
985 + mode_buf[1] = 6; // Mode data length (LSB)
986 + mode_buf[2] = 0; // Medium type - default
987 + mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
988 + mode_buf[4] = 0; // reserved
989 + mode_buf[5] = 0; // reserved
990 + mode_buf[6] = 0; // Block descriptor length (MSB)
991 + mode_buf[7] = 0; // Block descriptor length (LSB)
993 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
994 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1000 + // These commands are all No-Ops
1002 + cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1003 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1004 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1008 + cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1010 + memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1011 + sizeof( struct sense_data ) );
1012 + bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1014 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1015 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1019 + cmn_err(CE_DEBUG, "LOCK command");
1021 + if( scsi_cmnd_ptr->cmnd[4] )
1022 + fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1024 + fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1026 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1027 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1031 + cmn_err( CE_DEBUG, "RESERVE command" );
1032 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1033 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1037 + cmn_err( CE_DEBUG, "RELEASE command" );
1038 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1039 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1043 + cmn_err( CE_DEBUG, "REZERO command" );
1044 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1045 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1049 + cmn_err( CE_DEBUG, "REASSIGN command" );
1050 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1051 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1055 + cmn_err( CE_DEBUG, "SEEK command" );
1056 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1057 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1061 + cmn_err( CE_DEBUG, "START/STOP command" );
1062 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1063 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1067 + switch ( scsi_cmnd_ptr->cmnd[0] )
1071 + // Hack to keep track of ordinal number of the device that corresponds
1072 + // to a container. Needed to convert containers to /dev/sd device names
1073 + fsa_dev_ptr->ContainerDevNo[ContainerId] =
1074 + DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1076 + return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1082 + return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1086 + // Unhandled commands
1088 + cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1089 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1091 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1092 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1095 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1100 +/*------------------------------------------------------------------------------
1101 + AacHba_DoScsiRead()
1103 + Handles SCSI READ requests
1107 + Returns 0 on success, -1 on failure
1108 + *----------------------------------------------------------------------------*/
1109 +int AacHba_DoScsiRead(
1110 + Scsi_Cmnd *scsi_cmnd_ptr,
1113 +/*----------------------------------------------------------------------------*/
1117 + u_long byte_count;
1120 + PBLOCKREAD BlockReadDisk;
1121 + PBLOCKREADRESPONSE BlockReadResponse;
1123 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1124 + AFA_COMM_ADAPTER *Adapter;
1125 + PFIB_CONTEXT cmd_fibcontext;
1127 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1128 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1130 + // Get block address and transfer length
1131 + if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1133 + cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1135 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1136 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1137 + scsi_cmnd_ptr->cmnd[3];
1138 + count = scsi_cmnd_ptr->cmnd[4];
1145 + cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1147 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1148 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1150 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1152 + cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1154 + //-------------------------------------------------------------------------
1155 + // Alocate and initialize a Fib
1156 + // Setup BlockRead command
1157 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1159 + cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1160 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1161 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1165 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1167 + BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1168 + BlockReadDisk->Command = VM_CtBlockRead;
1169 + BlockReadDisk->ContainerId = ContainerId;
1170 + BlockReadDisk->BlockNumber = lba;
1171 + BlockReadDisk->ByteCount = count * 512;
1172 + BlockReadDisk->SgMap.SgCount = 1;
1174 + if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1176 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1177 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1179 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1180 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1186 + //-------------------------------------------------------------------------
1187 + // Build Scatter/Gather list
1189 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1191 + struct scatterlist *scatterlist_ptr;
1194 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1197 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1199 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1200 + ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1201 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1202 + scatterlist_ptr[segment].length;
1204 +#ifdef DEBUG_SGBUFFER
1205 + memset( scatterlist_ptr[segment].address, 0xa5,
1206 + scatterlist_ptr[segment].length );
1209 + byte_count += scatterlist_ptr[segment].length;
1211 + if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1213 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1214 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1216 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1217 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1223 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1225 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1226 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1229 + BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1231 + if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1233 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1234 + MAX_DRIVER_SG_SEGMENT_COUNT );
1235 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1239 + else // one piece of contiguous phys mem
1241 + BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1242 + ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1243 + BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1245 + byte_count = scsi_cmnd_ptr->request_bufflen;
1247 + if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1249 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1250 + cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1251 + cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1252 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1254 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1255 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1262 + if( byte_count != BlockReadDisk->ByteCount )
1263 + cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1265 + //-------------------------------------------------------------------------
1266 + // Now send the Fib to the adapter
1268 + FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1272 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1282 + BlockReadResponse = ( PBLOCKREADRESPONSE )
1283 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1285 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1286 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1288 + if( BlockReadResponse->Status != ST_OK )
1290 + cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1291 + BlockReadResponse->Status );
1292 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1294 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1295 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1298 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1302 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1304 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1309 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1316 + ( PFIB_CALLBACK )AacHba_ReadCallback,
1317 + ( void *)scsi_cmnd_ptr );
1318 + // don't call done func here
1323 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1325 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1326 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1332 +/*------------------------------------------------------------------------------
1333 + AacHba_DoScsiWrite()
1335 + Handles SCSI WRITE requests
1339 + Returns 0 on success, -1 on failure
1340 + *----------------------------------------------------------------------------*/
1341 +int AacHba_DoScsiWrite(
1342 + Scsi_Cmnd *scsi_cmnd_ptr,
1345 +/*----------------------------------------------------------------------------*/
1349 + u_long byte_count;
1352 + PBLOCKWRITE BlockWriteDisk;
1353 + PBLOCKWRITERESPONSE BlockWriteResponse;
1355 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1356 + AFA_COMM_ADAPTER *Adapter;
1357 + PFIB_CONTEXT cmd_fibcontext;
1359 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1360 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1362 + // Get block address and transfer length
1363 + if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1365 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1366 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1367 + scsi_cmnd_ptr->cmnd[3];
1368 + count = scsi_cmnd_ptr->cmnd[4];
1375 + cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1377 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1378 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1380 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1383 + cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1385 + //-------------------------------------------------------------------------
1386 + // Alocate and initialize a Fib
1387 + // Setup BlockWrite command
1388 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1390 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1391 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1392 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1396 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1398 + BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1399 + BlockWriteDisk->Command = VM_CtBlockWrite;
1400 + BlockWriteDisk->ContainerId = ContainerId;
1401 + BlockWriteDisk->BlockNumber = lba;
1402 + BlockWriteDisk->ByteCount = count * 512;
1403 + BlockWriteDisk->SgMap.SgCount = 1;
1406 + if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1408 + struct scatterlist *scatterlist_ptr;
1410 + scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1412 + cmn_err( CE_WARN, "\n");
1413 + cmn_err( CE_WARN, "AacHba_`DoScsiWrite: WRITE request is larger than 64K");
1414 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1415 +/* cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1416 +/* cmn_err( CE_WARN, "Dump SG Element Size..."); */
1417 +/* for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) */
1419 +/* cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1421 +/* cmn_err (CE_WARN, "\n"); */
1423 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1425 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1426 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1432 + //-------------------------------------------------------------------------
1433 + // Build Scatter/Gather list
1435 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1437 + struct scatterlist *scatterlist_ptr;
1440 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1443 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1445 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1446 + ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1447 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1448 + scatterlist_ptr[segment].length;
1450 + byte_count += scatterlist_ptr[segment].length;
1452 + if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1454 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1455 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1457 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1458 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1465 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1467 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1468 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1471 + BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1473 + if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1475 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1476 + MAX_DRIVER_SG_SEGMENT_COUNT );
1477 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1481 + else // one piece of contiguous phys mem
1483 + BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1484 + ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1485 + BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1487 + byte_count = scsi_cmnd_ptr->request_bufflen;
1489 + if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1491 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1493 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1494 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1495 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1502 + if( byte_count != BlockWriteDisk->ByteCount )
1503 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1505 + //-------------------------------------------------------------------------
1506 + // Now send the Fib to the adapter
1508 + FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1512 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1522 + BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1523 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1525 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1526 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1528 + if( BlockWriteResponse->Status != ST_OK )
1530 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1531 + BlockWriteResponse->Status );
1532 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1533 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1534 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1536 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1540 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1542 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1547 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1554 + ( PFIB_CALLBACK )AacHba_WriteCallback,
1555 + ( void * )scsi_cmnd_ptr );
1557 + // don't call done func here - it should be called by the WriteCallback
1562 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1564 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1565 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1571 +/*------------------------------------------------------------------------------
1572 + AacHba_ReadCallback()
1573 + *----------------------------------------------------------------------------*/
1574 +void AacHba_ReadCallback(
1576 + PFIB_CONTEXT FibContext,
1578 +/*----------------------------------------------------------------------------*/
1580 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1581 + AFA_COMM_ADAPTER *Adapter;
1582 + BLOCKREADRESPONSE *BlockReadResponse;
1583 + Scsi_Cmnd * scsi_cmnd_ptr;
1587 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1589 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1590 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1592 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1594 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1595 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1596 + scsi_cmnd_ptr->cmnd[3];
1597 + cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1599 + if( FibContext == 0 )
1601 + cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1602 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1603 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1607 + BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1609 + if ( BlockReadResponse->Status == ST_OK )
1610 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1613 + cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1614 + BlockReadResponse->Status );
1615 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1616 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1617 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1621 +#ifdef DEBUG_SGBUFFER
1622 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1624 + struct scatterlist *scatterlist_ptr;
1625 + int i, segment, count;
1628 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1630 + for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1633 + ptr = scatterlist_ptr[segment].address;
1634 + for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1636 + if( *( ptr++ ) == 0xa5 )
1639 + if( count == scatterlist_ptr[segment].length )
1640 + cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1646 + Adapter->CommFuncs.CompleteFib( FibContext );
1647 + Adapter->CommFuncs.FreeFib( FibContext );
1649 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1652 +/*------------------------------------------------------------------------------
1653 + AacHba_WriteCallback()
1654 + *----------------------------------------------------------------------------*/
1655 +void AacHba_WriteCallback(
1657 + PFIB_CONTEXT FibContext,
1659 +/*----------------------------------------------------------------------------*/
1661 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1662 + AFA_COMM_ADAPTER *Adapter;
1663 + BLOCKWRITERESPONSE *BlockWriteResponse;
1664 + Scsi_Cmnd *scsi_cmnd_ptr;
1668 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1670 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1671 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1673 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1675 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1676 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1677 + scsi_cmnd_ptr->cmnd[3];
1678 + cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1679 + if( FibContext == 0 )
1681 + cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1682 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1683 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1687 + BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1688 + if (BlockWriteResponse->Status == ST_OK)
1689 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1692 + cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1693 + BlockWriteResponse->Status );
1694 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1695 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1696 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1700 + Adapter->CommFuncs.CompleteFib( FibContext );
1701 + Adapter->CommFuncs.FreeFib( FibContext );
1703 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1707 +/*------------------------------------------------------------------------------
1710 + Handle IOCTL requests
1714 + *----------------------------------------------------------------------------*/
1716 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1719 +/*----------------------------------------------------------------------------*/
1721 + Sa_ADAPTER_EXTENSION *AdapterExtension;
1722 + AFA_IOCTL_CMD IoctlCmd;
1725 + AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1727 + cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1730 + case FSACTL_SENDFIB:
1731 + cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1734 + case FSACTL_AIF_THREAD:
1735 + cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1738 + case FSACTL_NULL_IO_TEST:
1739 + cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1742 + case FSACTL_SIM_IO_TEST:
1743 + cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1746 + case FSACTL_GET_FIBTIMES:
1747 + cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1750 + case FSACTL_ZERO_FIBTIMES:
1751 + cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1754 + case FSACTL_GET_VAR:
1755 + cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1758 + case FSACTL_SET_VAR:
1759 + cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1762 + case FSACTL_OPEN_ADAPTER_CONFIG:
1763 + cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1766 + case FSACTL_CLOSE_ADAPTER_CONFIG:
1767 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1770 + case FSACTL_QUERY_ADAPTER_CONFIG:
1771 + cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1774 + case FSACTL_OPEN_GET_ADAPTER_FIB:
1775 + cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1778 + case FSACTL_GET_NEXT_ADAPTER_FIB:
1779 + cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1782 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
1783 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1786 + case FSACTL_MINIPORT_REV_CHECK:
1787 + cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1790 + case FSACTL_OPENCLS_COMM_PERF_DATA:
1791 + cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1794 + case FSACTL_GET_COMM_PERF_DATA:
1795 + cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1798 + case FSACTL_QUERY_DISK:
1799 + cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1802 + case FSACTL_DELETE_DISK:
1803 + cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1807 + cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1810 + IoctlCmd.cmd = cmd;
1811 + IoctlCmd.arg = ( intptr_t )arg;
1812 + IoctlCmd.flag = 0;
1813 + IoctlCmd.cred_p = 0;
1814 + IoctlCmd.rval_p = 0;
1816 + status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1817 + cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1822 +/*------------------------------------------------------------------------------
1823 + AacHba_AdapterDeviceControl()
1827 + Returns TRUE if ioctl handled, FALSE otherwise
1828 + *ReturnStatus set to completion status
1829 + *----------------------------------------------------------------------------*/
1830 +BOOLEAN AacHba_AdapterDeviceControl (
1831 + PVOID AdapterArg, // CommonExtensionPtr
1832 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
1833 + OUT int * ReturnStatus )
1834 +/*----------------------------------------------------------------------------*/
1836 + BOOLEAN Handled = TRUE; // start out handling it.
1837 + int Status = EFAULT;
1839 + switch( IoctlCmdPtr->cmd )
1841 + case FSACTL_QUERY_DISK:
1842 + Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1845 + case FSACTL_DELETE_DISK:
1846 + Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1849 + case FSACTL_FORCE_DELETE_DISK:
1850 + Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1854 + if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1863 + *ReturnStatus = Status;
1865 + return( Handled );
1869 +/*------------------------------------------------------------------------------
1870 + AacHba_QueryDisk()
1875 + -EFAULT = Bad address
1876 + -EINVAL = Bad container number
1877 + *----------------------------------------------------------------------------*/
1878 +int AacHba_QueryDisk(
1879 + PVOID AdapterArg, // CommonExtensionPtr
1880 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
1881 +/*----------------------------------------------------------------------------*/
1883 + UNIX_QUERY_DISK QueryDisk;
1884 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1885 + fsadev_t *fsa_dev_ptr;
1887 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1888 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1890 + if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1891 + return( -EFAULT );
1893 + if (QueryDisk.ContainerNumber == -1)
1894 + QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1896 + if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1898 + if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1899 + return( -EINVAL );
1901 + QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1902 + QueryDisk.Bus = 0;
1903 + QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1904 + QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1907 + return( -EINVAL );
1909 + QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1910 + QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1911 + QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1913 + if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1914 + QueryDisk.UnMapped = TRUE;
1916 + QueryDisk.UnMapped = FALSE;
1918 + get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1919 + QueryDisk.diskDeviceName );
1921 + if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1922 + return( -EFAULT );
1928 +/*------------------------------------------------------------------------------
1930 + *----------------------------------------------------------------------------*/
1931 +static void get_sd_devname(
1934 +/*----------------------------------------------------------------------------*/
1938 + sprintf(buffer, "%s", "");
1942 + if( disknum < 26 )
1943 + sprintf(buffer, "sd%c", 'a' + disknum);
1945 + unsigned int min1;
1946 + unsigned int min2;
1948 + * For larger numbers of disks, we need to go to a new
1951 + min1 = disknum / 26;
1952 + min2 = disknum % 26;
1953 + sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1958 +/*------------------------------------------------------------------------------
1959 + AacHba_ForceDeleteDisk()
1964 + -EFAULT = Bad address
1965 + -EINVAL = Bad container number
1966 + *----------------------------------------------------------------------------*/
1967 +int AacHba_ForceDeleteDisk(
1968 + PVOID AdapterArg, // CommonExtensionPtr
1969 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
1970 +/*----------------------------------------------------------------------------*/
1972 + DELETE_DISK DeleteDisk;
1973 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1974 + fsadev_t *fsa_dev_ptr;
1976 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1977 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1979 + if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
1980 + return( -EFAULT );
1982 + if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1983 + return( -EINVAL );
1985 + // Mark this container as being deleted.
1986 + fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
1988 + // Mark the container as no longer valid
1989 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
1995 +/*------------------------------------------------------------------------------
1996 + AacHba_DeleteDisk()
2001 + -EFAULT = Bad address
2002 + -EINVAL = Bad container number
2003 + -EBUSY = Device locked
2004 + *----------------------------------------------------------------------------*/
2005 +int AacHba_DeleteDisk(
2007 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
2008 +/*----------------------------------------------------------------------------*/
2010 + DELETE_DISK DeleteDisk;
2011 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2012 + fsadev_t *fsa_dev_ptr;
2014 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2015 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2017 + if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2018 + return( -EFAULT );
2020 + if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2021 + return( -EINVAL );
2023 + // If the container is locked, it can not be deleted by the API.
2024 + if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2028 + // Mark the container as no longer being valid.
2029 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2030 + fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2036 +/*------------------------------------------------------------------------------
2037 + AacHba_OpenAdapter()
2038 + *----------------------------------------------------------------------------*/
2039 +AAC_STATUS AacHba_OpenAdapter(
2040 + IN PVOID AdapterArg )
2041 +/*----------------------------------------------------------------------------*/
2043 + return( STATUS_SUCCESS );
2047 +/*------------------------------------------------------------------------------
2048 + AacHba_CloseAdapter()
2049 + *----------------------------------------------------------------------------*/
2050 +AAC_STATUS AacHba_CloseAdapter(
2051 + IN PVOID AdapterArg )
2052 +/*----------------------------------------------------------------------------*/
2054 + return( STATUS_SUCCESS );
2058 +/*------------------------------------------------------------------------------
2059 + AacHba_DetachAdapter()
2060 + *----------------------------------------------------------------------------*/
2061 +void AacHba_DetachAdapter(
2062 + IN PVOID AdapterArg )
2063 +/*----------------------------------------------------------------------------*/
2065 + AacCommDetachAdapter( AdapterArg );
2069 +/*------------------------------------------------------------------------------
2070 + AacHba_AbortScsiCommand()
2071 + *----------------------------------------------------------------------------*/
2072 +void AacHba_AbortScsiCommand(
2073 + Scsi_Cmnd *scsi_cmnd_ptr )
2074 +/*----------------------------------------------------------------------------*/
2076 + u_short interrupt_status;
2077 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2079 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2080 + interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2082 + cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2084 + if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2085 + cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2088 + if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2089 + cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2092 + if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2093 + cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2096 + if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2097 + cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2103 +/*------------------------------------------------------------------------------
2104 + AacHba_HandleAif()
2105 + *----------------------------------------------------------------------------*/
2106 +BOOLEAN AacHba_HandleAif(
2107 + IN PVOID AdapterArg,
2108 + IN PFIB_CONTEXT FibContext )
2109 +/*----------------------------------------------------------------------------*/
2115 +/*------------------------------------------------------------------------------
2116 + AacHba_SetSenseData()
2117 + Fill in the sense data.
2120 + *----------------------------------------------------------------------------*/
2121 +void AacHba_SetSenseData(
2124 + unchar sense_code,
2125 + unchar a_sense_code,
2126 + unchar incorrect_length,
2127 + unchar bit_pointer,
2128 + unsigned field_pointer,
2129 + unsigned long residue )
2130 +/*----------------------------------------------------------------------------*/
2132 + sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2133 + sense_buf[1] = 0; // Segment number, always zero
2135 + if( incorrect_length )
2137 + sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2138 + sense_buf[3] = BYTE3(residue);
2139 + sense_buf[4] = BYTE2(residue);
2140 + sense_buf[5] = BYTE1(residue);
2141 + sense_buf[6] = BYTE0(residue);
2144 + sense_buf[2] = sense_key; // Sense key
2146 + if( sense_key == SENKEY_ILLEGAL )
2147 + sense_buf[7] = 10; // Additional sense length
2149 + sense_buf[7] = 6; // Additional sense length
2151 + sense_buf[12] = sense_code; // Additional sense code
2152 + sense_buf[13] = a_sense_code; // Additional sense code qualifier
2153 + if( sense_key == SENKEY_ILLEGAL )
2155 + sense_buf[15] = 0;
2157 + if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2158 + sense_buf[15] = 0x80; // Std sense key specific field
2159 + // Illegal parameter is in the parameter block
2161 + if( sense_code == SENCODE_INVALID_CDB_FIELD )
2162 + sense_buf[15] = 0xc0; // Std sense key specific field
2163 + // Illegal parameter is in the CDB block
2164 + sense_buf[15] |= bit_pointer;
2165 + sense_buf[16] = field_pointer >> 8; // MSB
2166 + sense_buf[17] = field_pointer; // LSB
2170 diff -burN linux-2.4.4/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2171 --- linux-2.4.4/drivers/scsi/aacraid/aacid.c Wed Dec 31 18:00:00 1969
2172 +++ linux/drivers/scsi/aacraid/aacid.c Mon Apr 30 09:43:34 2001
2175 + * Adaptec aacraid device driver for Linux.
2177 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2179 + * This program is free software; you can redistribute it and/or modify
2180 + * it under the terms of the GNU General Public License as published by
2181 + * the Free Software Foundation; either version 2, or (at your option)
2182 + * any later version.
2184 + * This program is distributed in the hope that it will be useful,
2185 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2186 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2187 + * GNU General Public License for more details.
2189 + * You should have received a copy of the GNU General Public License
2190 + * along with this program; see the file COPYING. If not, write to
2191 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2196 + * Abstract: Data structures for controller specific info.
2200 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2202 +#include "osheaders.h"
2204 +#include "AacGenericTypes.h"
2206 +#include "aac_unix_defs.h"
2208 +#include "fsatypes.h"
2209 +#include "comstruc.h"
2210 +#include "fsaport.h"
2211 +#include "pcisup.h"
2213 +#include "version.h"
2216 +/* Function Prototypes */
2217 +void InqStrCopy(char *a, char *b); /* ossup.c */
2219 +/* Device name used to register and unregister
2220 + the device in linit.c */
2221 +char devicestr[]="aac";
2223 +char *container_types[] = {
2242 +/* Local Structure to set SCSI inquiry data strings */
2243 +typedef struct _INQSTR {
2244 + char vid[8]; /* Vendor ID */
2245 + char pid[16]; /* Product ID */
2246 + char prl[4]; /* Product Revision Level */
2247 +} INQSTR, *INQSTRP;
2249 +FSA_MINIPORT MiniPorts[];
2251 +/* Function: SetInqDataStr
2253 + * Arguments: [1] pointer to void [1] int
2255 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2256 + * and revision level. Allows strings to be set in platform dependant
2257 + * files instead of in OS dependant driver source.
2261 + int MiniPortIndex,
2265 + INQSTRP InqStrPtr;
2269 + mp = &MiniPorts[MiniPortIndex];
2271 + InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2273 + InqStrCopy (mp->Vendor, InqStrPtr->vid);
2274 + InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2276 + findit = InqStrPtr->pid;
2278 + for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2281 + if (tindex < (sizeof(container_types)/sizeof(char *))){
2282 + InqStrCopy (container_types[tindex], findit);
2284 + InqStrCopy ("0001", InqStrPtr->prl);
2289 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2290 + IN ULONG AdapterNumber,
2297 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2298 + IN ULONG AdapterNumber,
2305 + * Because of the way Linux names scsi devices, the order in this table has
2306 + * become important. Check for on-board Raid first, add-in cards second.
2309 +FSA_MINIPORT MiniPorts[] = {
2310 + { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2311 + { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2312 + { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2313 + { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2314 + { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2315 + { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2316 + { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2317 + { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel */
2318 + { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2322 +#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2324 +int NumMiniPorts = NUM_MINIPORTS;
2326 +char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2327 diff -burN linux-2.4.4/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2328 --- linux-2.4.4/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2329 +++ linux/drivers/scsi/aacraid/commctrl.c Mon Apr 30 09:43:34 2001
2332 + * Adaptec aacraid device driver for Linux.
2334 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2336 + * This program is free software; you can redistribute it and/or modify
2337 + * it under the terms of the GNU General Public License as published by
2338 + * the Free Software Foundation; either version 2, or (at your option)
2339 + * any later version.
2341 + * This program is distributed in the hope that it will be useful,
2342 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2343 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2344 + * GNU General Public License for more details.
2346 + * You should have received a copy of the GNU General Public License
2347 + * along with this program; see the file COPYING. If not, write to
2348 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2353 + * Abstract: Contains all routines for control of the AFA comm layer
2357 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2359 +#include "comprocs.h"
2360 +#include "osheaders.h"
2361 +#include "ostypes.h"
2367 +typedef BOOLEAN BOOL;
2368 +#define inline /* _inline */
2370 +#include <revision.h>
2372 +FsaCtlCheckRevision(
2373 + IN PAFA_COMM_ADAPTER Adapter,
2374 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2378 +Routine Description:
2380 + This routine validates the revision of the caller with the current revision
2381 + of the filesystem.
2385 + Adapter - Supplies which adapter is being processed.
2387 + Irp - Supplies the Irp being processed.
2389 + IrpContext - Supplies the IrpContext.
2398 + RevCheck APIRevCheck;
2399 + RevCheckResp APIRevCheckResp;
2400 + RevComponent APICallingComponent;
2401 + ULONG APIBuildNumber;
2403 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2407 + APICallingComponent = APIRevCheck.callingComponent;
2408 + APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2410 + APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2412 + APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2413 + APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2415 + if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2424 +AfaCommAdapterDeviceControl(
2425 + IN PVOID AdapterArg,
2426 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2429 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2430 + int Status = ENOTTY;
2431 +// PIO_STACK_LOCATION IrpSp;
2432 + PAFA_CLASS_DRIVER ClassDriver;
2435 + // First loop through all of the class drivers to give them a chance to handle
2436 + // the Device control first.
2439 + ClassDriver = Adapter->ClassDriverList;
2441 + while (ClassDriver) {
2443 + if (ClassDriver->DeviceControl) {
2445 + if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2452 + ClassDriver = ClassDriver->Next;
2455 + switch (IoctlCmdPtr->cmd) {
2458 + case FSACTL_SENDFIB:
2460 + Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2463 + case FSACTL_AIF_THREAD:
2465 + Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2469 + case FSACTL_OPEN_GET_ADAPTER_FIB:
2471 + Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2474 + case FSACTL_GET_NEXT_ADAPTER_FIB:
2476 + Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2479 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
2481 + Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2484 + case FSACTL_MINIPORT_REV_CHECK:
2486 + Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2502 +AfaCommRegisterNewClassDriver(
2503 + IN PAFA_COMM_ADAPTER Adapter,
2504 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2505 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2509 +Routine Description:
2511 + This routine registers a new class driver for the comm layer.
2513 + It will return a pointer to the communication functions for the class driver
2518 + Adapter - Supplies which adapter is being processed.
2520 + Irp - Supplies the Irp being processed.
2524 + STATUS_SUCCESS - Everything OK.
2528 + AAC_STATUS Status;
2529 + PAFA_CLASS_DRIVER ClassDriver;
2532 + ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2534 + if (ClassDriver == NULL) {
2536 + Status = STATUS_INSUFFICIENT_RESOURCES;
2542 + // If the class driver has sent in user Vars, then copy them into the global
2546 + if (NewClassDriver->NumUserVars) {
2548 + PFSA_USER_VAR NewUserVars;
2550 + NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2551 + NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2554 + // First copy the existing into the new area.
2557 + RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2560 + // Next copy the new vars passed in from class driver.
2563 + RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2564 + NewClassDriver->UserVars,
2565 + NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2568 + // Free up the old user vars.
2571 + OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2574 + // Point the global to the new area.
2577 + FsaCommData.UserVars = NewUserVars;
2580 + // Update the total count.
2583 + FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2587 + ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2588 + ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2589 + ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2590 + ClassDriver->HandleAif = NewClassDriver->HandleAif;
2591 + ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2593 + ClassDriver->Next = Adapter->ClassDriverList;
2594 + Adapter->ClassDriverList = ClassDriver;
2597 + // Now return the information needed by the class driver to communicate to us.
2600 + NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2601 + NewClassDriverResponse->CommPortExtension = Adapter;
2602 + NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2603 + NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2604 + NewClassDriverResponse->Dip = Adapter->Dip;
2606 + return (STATUS_SUCCESS);
2613 + IN PAFA_COMM_ADAPTER Adapter,
2614 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2618 +Routine Description:
2620 + This routine sends a fib to the adapter on behalf of a user level
2625 + Adapter - Supplies which adapter is being processed.
2627 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2631 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2633 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2635 + STATUS_SUCCESS - Everything OK.
2640 +// PMDL DmaMdl = NULL;
2641 + PCOMM_FIB_CONTEXT FibContext;
2642 + PSGMAP_CONTEXT SgMapContext;
2643 + SGMAP_CONTEXT _SgMapContext;
2644 + QUEUE_TYPES WhichQueue;
2645 + PVOID UsersAddress;
2646 + AAC_STATUS Status;
2648 + FibContext = AllocateFib( Adapter );
2650 + KFib = FibContext->Fib;
2653 + // First copy in the header so that we can check the size field.
2656 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2657 + FreeFib( FibContext );
2663 + // Since we copy based on the fib header size, make sure that we
2664 + // will not overrun the buffer when we copy the memory. Return
2665 + // an error if we would.
2668 + if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2669 + FreeFib( FibContext );
2675 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2676 + FreeFib( FibContext );
2681 + WhichQueue = AdapNormCmdQueue;
2684 + if (KFib->Header.Command == TakeABreakPt) {
2686 + InterruptAdapter(Adapter);
2689 + // Since we didn't really send a fib, zero out the state to allow
2690 + // cleanup code not to assert.
2693 + KFib->Header.XferState = 0;
2698 + if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2699 + TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2700 + FsaCommPrint("User SendFib failed!.\n");
2703 + FreeFib( FibContext );
2707 + if (CompleteFib(FibContext) != FSA_SUCCESS) {
2708 + FsaCommPrint("User Complete FIB failed.\n");
2710 + FreeFib( FibContext );
2719 + // Make sure that the size returned by the adapter (which includes
2720 + // the header) is less than or equal to the size of a fib, so we
2721 + // don't corrupt application data. Then copy that size to the user
2722 + // buffer. (Don't try to add the header information again, since it
2723 + // was already included by the adapter.)
2725 + ASSERT(KFib->Header.Size <= sizeof(FIB));
2727 + if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2728 + FreeFib( FibContext );
2733 + FreeFib( FibContext );
2740 +AfaCommCtlAifThread(
2741 + IN PAFA_COMM_ADAPTER Adapter,
2742 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2746 +Routine Description:
2748 + This routine will act as the AIF thread for this adapter.
2752 + Adapter - Supplies which adapter is being processed.
2754 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2758 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2760 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2762 + STATUS_SUCCESS - Everything OK.
2766 + return (NormCommandThread(Adapter));
2771 +#ifdef GATHER_FIB_TIMES
2773 +AfaCommGetFibTimes(
2774 + IN PAFA_COMM_ADAPTER Adapter,
2779 +Routine Description:
2781 + This routine returns the gathered fibtimes to the user.
2785 + Adapter - Supplies which adapter is being processed.
2787 + Irp - Supplies the Irp being processed.
2791 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2793 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2795 + STATUS_SUCCESS - Everything OK.
2799 + PALL_FIB_TIMES AllFibTimes;
2800 + PLARGE_INTEGER FreqPtr;
2801 + PIO_STACK_LOCATION IrpSp;
2804 + // Get a pointer to the current Irp stack location
2807 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2809 + FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2811 + *FreqPtr = Adapter->FibTimesFrequency;
2813 + AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2815 + RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2817 + Irp->IoStatus.Information = 0;
2819 + return (STATUS_SUCCESS);
2824 +AfaCommZeroFibTimes(
2825 + IN PAFA_COMM_ADAPTER Adapter,
2830 +Routine Description:
2832 + This routine zero's the FibTimes structure within the adapter structure.
2836 + Adapter - Supplies which adapter is being processed.
2838 + Irp - Supplies the Irp being processed.
2842 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2844 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2846 + STATUS_SUCCESS - Everything OK.
2850 + PFIB_TIMES FibTimesPtr;
2852 + PIO_STACK_LOCATION IrpSp;
2855 + // Get a pointer to the current Irp stack location
2858 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2861 + // Initialize the Fib timing data structures
2863 + RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2865 + for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2867 + FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2869 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2870 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2871 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2872 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2874 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2876 + FibTimesPtr = &Adapter->FibTimes->Read[i];
2878 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2879 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2880 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2881 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2883 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2885 + FibTimesPtr = &Adapter->FibTimes->Write[i];
2887 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2888 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2889 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2890 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2893 + FibTimesPtr = &Adapter->FibTimes->Other;
2895 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2896 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2897 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2898 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2900 + Irp->IoStatus.Information = 0;
2902 + return (STATUS_SUCCESS);
2905 +#endif // GATHER_FIB_TIMES
2909 +FsaCtlOpenGetAdapterFib(
2910 + IN PAFA_COMM_ADAPTER Adapter,
2911 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2915 +Routine Description:
2917 + This routine will get the next Fib, if available, from the AdapterFibContext
2918 + passed in from the user.
2922 + Adapter - Supplies which adapter is being processed.
2924 + Irp - Supplies the Irp being processed.
2928 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2930 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2932 + STATUS_SUCCESS - Everything OK.
2936 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2938 +// PKEVENT eventObject = (PKEVENT) NULL;
2942 + // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2945 + AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2947 + if (AdapterFibContext == NULL) {
2953 + AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2954 + AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2958 + // Initialize the conditional variable use to wait for the next AIF.
2961 + OsCv_init( &AdapterFibContext->UserEvent);
2964 + // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
2967 + AdapterFibContext->WaitingForFib = FALSE;
2970 + // Initialize the FibList and set the count of fibs on the list to 0.
2973 + AdapterFibContext->FibCount = 0;
2974 + InitializeListHead(&AdapterFibContext->FibList);
2977 + // Overload FileObject with a time stamp.
2979 + AdapterFibContext->FileObject = (void *)OsGetSeconds();
2982 + // Now add this context onto the adapter's AdapterFibContext list.
2985 + OsCvLockAcquire(Adapter->AdapterFibMutex);
2987 + InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
2989 + OsCvLockRelease(Adapter->AdapterFibMutex);
2991 + if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
2992 + IoctlCmdPtr->flag )) {
3008 +FsaCtlGetNextAdapterFib(
3009 + IN PAFA_COMM_ADAPTER Adapter,
3010 + IN PAFA_IOCTL_CMD IoctlCmdPtr
3014 +Routine Description:
3016 + This routine will get the next Fib, if available, from the AdapterFibContext
3017 + passed in from the user.
3021 + Adapter - Supplies which adapter is being processed.
3023 + Irp - Supplies the Irp being processed.
3027 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3029 + STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3031 + STATUS_SUCCESS - Everything OK.
3035 + GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3036 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3039 + PLIST_ENTRY Entry;
3042 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3043 + sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3048 + // Extract the AdapterFibContext from the Input parameters.
3051 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3054 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3056 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3057 + // this is a valid address
3060 + Entry = Adapter->AdapterFibContextList.Flink;
3062 + while ( Entry != &Adapter->AdapterFibContextList ) {
3063 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3064 + if ( AdapterFibContext == aifcp ) { // We found a winner
3068 + Entry = Entry->Flink;
3071 + if ( found == 0 ) {
3072 + return ( EINVAL );;
3075 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3076 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3078 + return ( EINVAL );
3082 + Status = STATUS_SUCCESS;
3084 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3087 + // If there are no fibs to send back, then either wait or return EAGAIN
3091 + if (!IsListEmpty(&AdapterFibContext->FibList)) {
3093 + PLIST_ENTRY Entry;
3096 + // Pull the next fib from the FibList
3098 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3100 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3102 + AdapterFibContext->FibCount--;
3104 + if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3106 + OsCvLockRelease( Adapter->AdapterFibMutex );
3107 + OsFreeMemory( Fib, sizeof(Fib) );
3113 + // Free the space occupied by this copy of the fib.
3116 + OsFreeMemory(Fib, sizeof(FIB));
3121 + // Overload FileObject with a time stamp
3123 + AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3127 + if (AdapterFibIoctl.Wait) {
3129 + if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3145 + OsCvLockRelease( Adapter->AdapterFibMutex );
3151 +FsaCtlCloseGetAdapterFib(
3152 + IN PAFA_COMM_ADAPTER Adapter,
3153 + IN PAFA_IOCTL_CMD IoctlCmdPtr
3157 +Routine Description:
3159 + This routine will close down the AdapterFibContext passed in from the user.
3163 + Adapter - Supplies which adapter is being processed.
3165 + Irp - Supplies the Irp being processed.
3169 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3171 + STATUS_SUCCESS - Everything OK.
3175 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3176 + AAC_STATUS Status;
3178 + PLIST_ENTRY Entry;
3182 + // Extract the AdapterFibContext from the Input parameters
3185 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3187 + if (AdapterFibContext == 0) {
3188 + cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3193 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3195 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3196 + // this is a valid address
3199 + Entry = Adapter->AdapterFibContextList.Flink;
3201 + while ( Entry != &Adapter->AdapterFibContextList ) {
3202 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3203 + if ( AdapterFibContext == aifcp ) { // We found a winner
3207 + Entry = Entry->Flink;
3210 + if ( found == 0 ) {
3211 + return ( 0 ); // Already Gone
3214 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3215 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3221 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3223 + Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3225 + OsCvLockRelease(Adapter->AdapterFibMutex);
3231 +FsaCloseAdapterFibContext(
3232 + IN PAFA_COMM_ADAPTER Adapter,
3233 + IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3240 + // First free any FIBs that have not been consumed yet.
3243 + while (!IsListEmpty(&AdapterFibContext->FibList)) {
3245 + PLIST_ENTRY Entry;
3248 + // Pull the next fib from the FibList
3251 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3253 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3255 + AdapterFibContext->FibCount--;
3258 + // Free the space occupied by this copy of the fib.
3261 + OsFreeMemory(Fib, sizeof(FIB));
3265 + // Remove the Context from the AdapterFibContext List
3268 + RemoveEntryList(&AdapterFibContext->NextContext);
3270 + OsCv_destroy( &AdapterFibContext->UserEvent );
3273 + // Invalidate context
3276 + AdapterFibContext->NodeTypeCode = 0;
3279 + // Free the space occupied by the Context
3282 + OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3284 + Status = STATUS_SUCCESS;
3291 +AfaCommOpenAdapter(
3296 +Routine Description:
3298 + The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3301 + The main purpose of this routine is to set up any data structures that may be needed
3302 + to handle any requests made on this DeviceObject.
3306 + Adapter - Pointer to which adapter miniport was opened.
3316 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3317 + AAC_STATUS Status = STATUS_SUCCESS;
3318 + PAFA_CLASS_DRIVER ClassDriver;
3320 + ClassDriver = Adapter->ClassDriverList;
3322 + while (ClassDriver) {
3324 + if (ClassDriver->OpenAdapter) {
3326 + Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3328 + if (Status != STATUS_SUCCESS)
3332 + ClassDriver = ClassDriver->Next;
3335 + return ( Status );
3339 +AfaCommCloseAdapter(
3344 +Routine Description:
3346 + This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3349 + The main purpose of this routine is to cleanup any data structures that have been set up
3350 + while this FileObject has been opened.
3352 + This routine loops through all of the AdapterFibContext structures to determine if any need
3353 + to be deleted for this FileObject.
3357 + Adapter - Pointer to adapter miniport
3359 + Irp - Pointer to Irp that caused this close
3363 + Status value returned from File system driver AdapterClose
3367 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3368 + PLIST_ENTRY Entry, NextEntry;
3369 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3370 + AAC_STATUS Status = STATUS_SUCCESS;
3371 + PAFA_CLASS_DRIVER ClassDriver;
3373 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3375 + Entry = Adapter->AdapterFibContextList.Flink;
3378 + // Loop through all of the AdapterFibContext, looking for any that
3379 + // were created with the FileObject that is being closed.
3381 + while (Entry != &Adapter->AdapterFibContextList) {
3384 + // Extract the AdapterFibContext
3386 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3389 + // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3391 + NextEntry = Entry->Flink;
3393 + Entry = NextEntry;
3397 +#ifdef unix_config_file
3399 + // If this FileObject had the adapter open for configuration, then release it.
3401 + if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3403 + Adapter->AdapterConfigFileObject = NULL;
3408 + OsCvLockRelease(Adapter->AdapterFibMutex);
3410 + ClassDriver = Adapter->ClassDriverList;
3412 + while (ClassDriver) {
3414 + if (ClassDriver->CloseAdapter) {
3416 + Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3418 + if (Status != STATUS_SUCCESS)
3422 + ClassDriver = ClassDriver->Next;
3425 + return ( Status );
3429 diff -burN linux-2.4.4/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3430 --- linux-2.4.4/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3431 +++ linux/drivers/scsi/aacraid/comminit.c Mon Apr 30 09:43:34 2001
3434 + * Adaptec aacraid device driver for Linux.
3436 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3438 + * This program is free software; you can redistribute it and/or modify
3439 + * it under the terms of the GNU General Public License as published by
3440 + * the Free Software Foundation; either version 2, or (at your option)
3441 + * any later version.
3443 + * This program is distributed in the hope that it will be useful,
3444 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3445 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3446 + * GNU General Public License for more details.
3448 + * You should have received a copy of the GNU General Public License
3449 + * along with this program; see the file COPYING. If not, write to
3450 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3455 + * Abstract: This supports the initialization of the host adapter commuication interface.
3456 + * This is a platform dependent module for the pci cyclone board.
3460 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3462 +#include "comprocs.h"
3464 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3467 +AfaCommBugcheckHandler(
3473 +ThrottlePeriodEndDpcRtn(
3475 + IN PVOID DeferredContext,
3476 + IN PVOID SystemArgument1,
3477 + IN PVOID SystemArgument2);
3479 +FSA_COMM_DATA FsaCommData;
3482 +HardInterruptModeration1Changed(
3483 + IN PVOID AdapterContext,
3487 + PAFA_COMM_ADAPTER Adapter = AdapterContext;
3490 + // If we are using interrupt moderation, then disable the interrupt
3491 + // until we need to use it.
3493 + if (FsaCommData.HardInterruptModeration1)
3494 + DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3496 + EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3498 + return (STATUS_SUCCESS);
3502 +FsaFibTimeoutChanged(
3503 + IN PVOID AdapterContext,
3508 + // scale the new timeout from seconds to 100 nsec units
3510 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3512 + return (STATUS_SUCCESS);
3515 +#ifdef GATHER_FIB_TIMES
3516 +extern int GatherFibTimes;
3519 +FSA_USER_VAR FsaCommUserVars[] = {
3520 +#ifdef FIB_CHECKSUMS
3521 + { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3523 +#ifdef GATHER_FIB_TIMES
3524 + { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3526 + { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3527 + { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3528 + { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3529 + { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3530 + { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3531 + { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3532 + { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3533 + { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3534 + { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3535 + { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3538 +#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3542 +AacCommDriverEntry(
3547 +Routine Description:
3549 + This is the initialization routine for the FileArray Comm layer device driver.
3553 + DriverObject - Pointer to driver object created by the system.
3557 + AAC_STATUS - The function value is the final status from the initialization
3563 + AAC_STATUS Status;
3564 + PVOID BugCheckBuffer;
3566 + RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3570 + // Load the global timeout value for the adapter timeout
3571 + // Also init the global that enables or disables adapter timeouts
3574 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3576 + FsaCommData.FibTimeoutSeconds = 180;
3578 + FsaCommData.EnableAdapterTimeouts = TRUE;
3580 +// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3582 +#ifdef unix_fib_timeout
3583 + FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3586 + FsaCommData.EnableInterruptModeration = FALSE;
3589 + // Preload UserVars with all variables from the comm layer. The class layers will
3590 + // include theirs when they register.
3593 + FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3594 + FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3596 + RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3601 + // Call the disk driver to initialize itself.
3604 + AacDiskDriverEntry();
3610 + return (STATUS_SUCCESS);
3616 + IN PAFA_COMM_ADAPTER Adapter,
3617 + IN OUT PCOMM_QUE Queue,
3618 + IN QUEUE_TYPES WhichQueue
3622 +Routine Description:
3624 + This routine will release all of the resources used by a given queue.
3628 + Adapter - Which adapter the queue belongs to
3629 + Queue - Pointer to the queue itself
3630 + WhichQueue - Identifies which of the host queues this is.
3638 + switch (WhichQueue) {
3640 + case HostNormCmdQueue:
3642 + Os_remove_softintr( Queue->ConsumerRoutine );
3643 + OsSpinLockDestroy( Queue->QueueLock );
3644 + OsCv_destroy( &Queue->CommandReady );
3648 + case HostHighCmdQueue:
3650 + Os_remove_softintr( Queue->ConsumerRoutine );
3651 + OsSpinLockDestroy( Queue->QueueLock );
3652 + OsCv_destroy( &Queue->CommandReady );
3656 + case HostNormRespQueue:
3658 + Os_remove_softintr( Queue->ConsumerRoutine );
3659 + OsSpinLockDestroy( Queue->QueueLock );
3662 + case HostHighRespQueue:
3664 + Os_remove_softintr( Queue->ConsumerRoutine );
3665 + OsSpinLockDestroy( Queue->QueueLock );
3668 + case AdapNormCmdQueue:
3669 + case AdapHighCmdQueue:
3670 + case AdapNormRespQueue:
3671 + case AdapHighRespQueue:
3672 + OsCv_destroy( &Queue->QueueFull );
3679 + IN PAFA_COMM_ADAPTER Adapter,
3680 + IN OUT PCOMM_QUE Queue,
3681 + IN QUEUE_TYPES WhichQueue
3685 +Routine Description:
3687 + Will initialize all entries in the queue that is NT specific.
3693 + Nothing there is nothing to allocate so nothing should fail
3698 + Queue->NumOutstandingIos = 0;
3701 + // Store a pointer to the adapter structure.
3704 + Queue->Adapter = Adapter;
3706 + InitializeListHead( &Queue->OutstandingIoQueue );
3708 + switch (WhichQueue) {
3710 + case HostNormCmdQueue:
3712 + OsCv_init( &Queue->CommandReady);
3713 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3714 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3715 + NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3716 + (caddr_t)Queue ) != DDI_SUCCESS) {
3718 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3721 + InitializeListHead(&Queue->CommandQueue);
3725 + case HostHighCmdQueue:
3727 + OsCv_init( &Queue->CommandReady);
3728 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3729 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3730 + NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3731 + (caddr_t) Queue ) != DDI_SUCCESS) {
3733 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3736 + InitializeListHead(&Queue->CommandQueue);
3739 + case HostNormRespQueue:
3741 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3742 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3743 + NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3744 + (caddr_t) Queue ) != DDI_SUCCESS) {
3746 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3750 + case HostHighRespQueue:
3753 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3754 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3755 + NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3756 + (caddr_t) Queue ) != DDI_SUCCESS) {
3758 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3762 + case AdapNormCmdQueue:
3763 + case AdapHighCmdQueue:
3764 + case AdapNormRespQueue:
3765 + case AdapHighRespQueue:
3767 + OsCv_init( &Queue->QueueFull);
3773 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3776 +Routine Description:
3778 + Create and start the command receiver threads.
3797 +Routine Description:
3799 + This routine gets called to detach all resources that have been allocated for
3804 + Adapter - Pointer to the adapter structure to detach.
3808 + TRUE - All resources have been properly released.
3809 + FALSE - An error occured while trying to release resources.
3812 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3814 + PAFA_CLASS_DRIVER ClassDriver;
3816 + // First remove this adapter from the list of adapters.
3819 + if (FsaCommData.AdapterList == Adapter) {
3821 + FsaCommData.AdapterList = Adapter->NextAdapter;
3825 + PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3827 + CurrentAdapter = FsaCommData.AdapterList;
3828 + NextAdapter = CurrentAdapter->NextAdapter;
3830 + while (NextAdapter) {
3832 + if (NextAdapter == Adapter) {
3834 + CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3839 + CurrentAdapter = NextAdapter;
3840 + NextAdapter = CurrentAdapter->NextAdapter;
3845 + // First send a shutdown to the adapter.
3848 + AfaCommShutdown( Adapter );
3851 + // Destroy the FibContextZone for this adapter. This will free up all
3852 + // of the fib space used by this adapter.
3855 + FsaFreeFibContextZone( Adapter );
3858 + // Destroy the mutex used for synch'ing adapter fibs.
3861 + OsCvLockDestroy( Adapter->AdapterFibMutex );
3864 + // Detach all of the host queues.
3867 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3868 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3869 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3870 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3871 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3872 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3873 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3874 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3877 + // Destroy the mutex used to protect the FibContextZone
3880 + OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3883 + // Call the miniport to free the space allocated for the shared comm queues
3884 + // between the host and the adapter.
3887 + FsaFreeAdapterCommArea( Adapter );
3890 + // Free the memory used by the comm region for this adapter
3893 + OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3896 + // Free the memory used by the adapter structure.
3898 + ClassDriver = Adapter->ClassDriverList;
3899 + Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3900 + OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3902 + OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3908 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3910 + PVOID BugCheckBuffer;
3911 + PAFA_COMM_ADAPTER Adapter;
3912 + MAPFIB_CONTEXT MapFibContext;
3913 + LARGE_INTEGER Time;
3914 + char ErrorBuffer[60];
3916 + Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3918 + if (Adapter == NULL)
3921 + RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3925 + // Save the current adapter number and increment the total number.
3928 + Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3932 + // Fill in the pointer back to the device specific structures.
3933 + // The device specific driver has also passed a pointer for us to
3934 + // fill in with the Adapter object that we have created.
3937 + Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3938 + Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3939 + Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3940 + Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3941 + Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3943 + Adapter->Dip = NewAdapter->Dip;
3946 + // Fill in Our address into the function dispatch table
3949 + NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3950 + NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3951 + NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3952 + NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3955 + // Ok now init the communication subsystem
3958 + Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3959 + if (Adapter->CommRegion == NULL) {
3960 + cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3963 + RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
3966 + // Get a pointer to the iblock_cookie
3969 + ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
3971 + if (!CommInit(Adapter)) {
3972 + FsaCommPrint("Failed to init the commuication subsystem.\n");
3978 + // Initialize the list of AdapterFibContext's.
3981 + InitializeListHead(&Adapter->AdapterFibContextList);
3984 + // Initialize the fast mutex used for synchronization of the adapter fibs
3987 + Adapter->AdapterFibMutex = OsCvLockAlloc();
3988 + OsCvLockInit(Adapter->AdapterFibMutex, NULL);
3991 + // Allocate and start the FSA command threads. These threads will handle
3992 + // command requests from the adapter. They will wait on an event then pull
3993 + // all CDBs off the thread's queue. Each CDB will be given to a worker thread
3994 + // upto a defined limit. When that limit is reached wait a event will be waited
3995 + // on till a worker thread is finished.
3998 + if (!StartFsaCommandThreads(Adapter)) {
3999 + FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4003 +#ifdef unix_crash_dump
4005 + // Allocate and map a fib for use by the synch path, which is used for crash
4008 + // Allocate an entire page so that alignment is correct.
4011 + Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4012 + MapFibContext.Fib = Adapter->SyncFib;
4013 + MapFibContext.Size = sizeof(FIB);
4014 + MapFib( Adapter, &MapFibContext );
4015 + Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4018 + Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4020 + Adapter->CommFuncs.AllocateFib = AllocateFib;
4022 + Adapter->CommFuncs.FreeFib = FreeFib;
4023 + Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4024 + Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4026 + Adapter->CommFuncs.InitializeFib = InitializeFib;
4027 + Adapter->CommFuncs.GetFibData = FsaGetFibData;
4028 + Adapter->CommFuncs.SendFib = SendFib;
4029 + Adapter->CommFuncs.CompleteFib = CompleteFib;
4030 + Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4032 + Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4034 + Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4035 + Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4038 + // Add this adapter in to our Adapter List.
4041 + Adapter->NextAdapter = FsaCommData.AdapterList;
4042 + FsaCommData.AdapterList = Adapter;
4044 + NewAdapter->Adapter = Adapter;
4046 +// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4053 + PAFA_COMM_ADAPTER Adapter
4057 + // Now allocate and initialize the zone structures used as our pool
4058 + // of FIB context records. The size of the zone is based on the
4059 + // system memory size. We also initialize the mutex used to protect
4062 + Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4063 + OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4065 + Adapter->FibContextZoneExtendSize = 64;
4067 + return (STATUS_SUCCESS);
4074 +Routine Description:
4076 + Initializes the data structures that are required for the FSA commuication
4077 + interface to operate.
4081 + None - all global or allocated data.
4085 + TRUE - if we were able to init the commuication interface.
4086 + FALSE - If there were errors initing. This is a fatal error.
4089 +CommInit(PAFA_COMM_ADAPTER Adapter)
4092 + ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4093 + ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4094 + PQUEUE_INDEX Headers;
4095 + PQUEUE_ENTRY Queues;
4097 + PCOMM_REGION CommRegion = Adapter->CommRegion;
4099 + CommInitialize( Adapter );
4101 + FsaCommPrint("CommInit: Queue entry size is 0x%x, Queue index size is 0x%x, Number of total entries is 0x%x, # queues = 0x%x.\n",
4102 + sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4105 + // Allocate the physically contigous space for the commuication queue
4109 + TotalSize = SizeOfHeaders + SizeOfQueues;
4111 + if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4114 + Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4116 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4117 + NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4118 + (caddr_t)CommRegion ) != DDI_SUCCESS) {
4120 + cmn_err(CE_CONT, "Os_addr_intr failed\n");
4124 + // Adapter to Host normal priority Command queue
4127 + CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4128 + CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4129 + *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4130 + *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4132 + CommRegion->HostNormCmdQue.SavedIrql = 0;
4133 + CommRegion->HostNormCmdQue.BaseAddress = Queues;
4134 + CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4136 + CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4137 + if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4140 + InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4143 + Queues += HOST_NORM_CMD_ENTRIES;
4145 + // Adapter to Host high priority command queue
4147 + CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4148 + CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4149 + *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4150 + *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4152 + CommRegion->HostHighCmdQue.SavedIrql = 0;
4153 + CommRegion->HostHighCmdQue.BaseAddress = Queues;
4154 + CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4155 +// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4156 + CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4157 + if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4160 + InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4162 + Queues += HOST_HIGH_CMD_ENTRIES;
4164 + // Host to adapter normal priority command queue
4166 + CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4167 + CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4168 + *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4169 + *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4171 + CommRegion->AdapNormCmdQue.SavedIrql = 0;
4172 + CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4173 + CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4174 + InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4176 + Queues += ADAP_NORM_CMD_ENTRIES;
4178 + // host to adapter high priority command queue
4180 + CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4181 + CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4182 + *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4183 + *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4185 + CommRegion->AdapHighCmdQue.SavedIrql = 0;
4186 + CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4187 + CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4188 + InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4190 + Queues += ADAP_HIGH_CMD_ENTRIES;
4192 + // adapter to host normal priority response queue
4194 + CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4195 + CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4196 + *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4197 + *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4199 + CommRegion->HostNormRespQue.SavedIrql = 0;
4200 + CommRegion->HostNormRespQue.BaseAddress = Queues;
4201 + CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4202 +// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4203 + CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4204 + if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4207 + InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4209 + Queues += HOST_NORM_RESP_ENTRIES;
4211 + // adapter to host high priority response queue
4213 + CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4214 + CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4215 + *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4216 + *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4218 + CommRegion->HostHighRespQue.SavedIrql = 0;
4219 + CommRegion->HostHighRespQue.BaseAddress = Queues;
4220 + CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4221 +// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4222 + CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4223 + if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4226 + InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4228 + Queues += HOST_HIGH_RESP_ENTRIES;
4230 + // host to adapter normal priority response queue
4232 + CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4233 + CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4234 + *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4235 + *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4237 + CommRegion->AdapNormRespQue.SavedIrql = 0;
4238 + CommRegion->AdapNormRespQue.BaseAddress = Queues;
4239 + CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4240 + InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4242 + Queues += ADAP_NORM_RESP_ENTRIES;
4244 + // host to adapter high priority response queue
4246 + CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4247 + CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4248 + *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4249 + *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4251 + CommRegion->AdapHighRespQue.SavedIrql = 0;
4252 + CommRegion->AdapHighRespQue.BaseAddress = Queues;
4253 + CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4254 + InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4256 + CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4257 + CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4258 + CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4259 + CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4266 + PAFA_COMM_ADAPTER Adapter
4270 +Routine Description:
4272 + This routine will send a shutdown request to each adapter.
4276 + Adapter - which adapter to send the shutdown to.
4280 + NT Status success.
4285 + PFIB_CONTEXT FibContext;
4286 + PCLOSECOMMAND CloseCommand;
4287 + AAC_STATUS Status;
4289 + FibContext = AllocateFib( Adapter );
4291 + InitializeFib( FibContext );
4293 + CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4295 + CloseCommand->Command = VM_CloseAll;
4296 + CloseCommand->ContainerId = 0xffffffff;
4298 + Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4300 + if (Status != STATUS_SUCCESS) {
4302 + FreeFib( FibContext );
4308 + CompleteFib( FibContext );
4310 + FreeFib( FibContext );
4313 + Status = STATUS_SUCCESS;
4322 +AfaCommBugcheckHandler(
4328 +Routine Description:
4330 + This routine will shutdown the adapter if there is a bugcheck and
4331 + copy the shutdown data from the adapter response into the buffer
4332 + so it will show up in the host dump file.
4336 + Buffer - This buffer will be written to the host dump by nt for us.
4338 + Length - The size of the buffer.
4346 + PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4350 + NotifyAdapter(Adapter, HostShutdown);
4352 + Adapter = Adapter->NextAdapter;
4360 + PFIB_CONTEXT FibContext,
4361 + PDEVICE_OBJECT DeviceObject,
4362 + AAC_STATUS FsaStatus,
4363 + AAC_STATUS AacStatus,
4364 + ULONG LocationCode,
4373 + PAFA_COMM_ADAPTER Adapter
4376 + PMNTINFO DiskInfo;
4377 + PMNTINFORESPONSE DiskInfoResponse;
4378 + AAC_STATUS Status;
4379 + PCOMM_FIB_CONTEXT FibContext;
4381 + FibContext = AllocateFib( Adapter );
4383 + InitializeFib( FibContext );
4385 + DiskInfo = (PMNTINFO) FibContext->Fib->data;
4386 + DiskInfo->Command = VM_NameServe;
4387 + DiskInfo->MntCount = 0;
4388 + DiskInfo->MntType = FT_FILESYS;
4390 + Status = SendFib(ContainerCommand,
4400 + DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4402 + if (DiskInfoResponse->MntRespCount) {
4404 + cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4405 + DiskInfoResponse->MntTable[0].Capacity);
4409 + cmn_err(CE_CONT, "no containers found on adapter\n");
4413 + CompleteFib( FibContext );
4415 + FreeFib( FibContext );
4419 diff -burN linux-2.4.4/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4420 --- linux-2.4.4/drivers/scsi/aacraid/commsup.c Wed Dec 31 18:00:00 1969
4421 +++ linux/drivers/scsi/aacraid/commsup.c Mon Apr 30 09:43:34 2001
4424 + * Adaptec aacraid device driver for Linux.
4426 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4428 + * This program is free software; you can redistribute it and/or modify
4429 + * it under the terms of the GNU General Public License as published by
4430 + * the Free Software Foundation; either version 2, or (at your option)
4431 + * any later version.
4433 + * This program is distributed in the hope that it will be useful,
4434 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4435 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4436 + * GNU General Public License for more details.
4438 + * You should have received a copy of the GNU General Public License
4439 + * along with this program; see the file COPYING. If not, write to
4440 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4445 + * Abstract: Contain all routines that are required for FSA host/adapter
4451 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4453 +#include "comprocs.h"
4455 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4460 +ThrottleExceptionHandler(
4461 + IN PCOMM_REGION CommRegion,
4465 +void ThrottlePeriodEndDpcRtn(
4467 + IN PVOID DeferredContext,
4468 + IN PVOID SystemArgument1,
4469 + IN PVOID SystemArgument2
4475 +Routine Description:
4477 + This routine will free all resources used by a given FibContextSegment.
4481 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4482 + ZoneSegment - The segment to release resources from.
4486 + TRUE - All resources were properly freed.
4487 + FALSE - An Error occured while freeing resources.
4491 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4492 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4494 + PCOMM_FIB_CONTEXT FibContext;
4497 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4499 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4500 + i < ZoneSegment->ExtendSize; i++, FibContext++) {
4502 + OsCvLockDestroy( FibContext->FsaEventMutex );
4503 + OsCv_destroy( &FibContext->FsaEvent );
4507 + UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4509 + OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4511 + OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4517 +FsaFreeFibContextZone(
4518 + PAFA_COMM_ADAPTER Adapter
4522 +Routine Description:
4524 + This routine will walk through the FibContextSegmentList and free up all
4525 + resources used by the FibContextZone.
4529 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4533 + TRUE - All resources were properly freed.
4534 + FALSE - An Error occured while freeing resources.
4539 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4541 + ZoneSegment = Adapter->FibContextSegmentList;
4543 + while (ZoneSegment) {
4545 + NextZoneSegment = ZoneSegment->Next;
4547 + FsaFreeFibContextSegment( Adapter, ZoneSegment );
4549 + ZoneSegment = NextZoneSegment;
4558 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4562 + ULONG ZoneSegmentAllocSize, FibAllocSize;
4563 + PVOID FibContextSegment;
4564 + PCOMM_FIB_CONTEXT FibContext;
4566 + PVOID FibPhysicalAddress;
4568 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4571 + // Allocate space to describe this zone segment.
4574 + cmn_err (CE_DEBUG, "Entered FsaExtendFibConextZone");
4575 + ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4577 + ExtendSize = Adapter->FibContextZoneExtendSize;
4578 + ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4580 + FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4582 + if (FibContextSegment == NULL) {
4586 + RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4588 + ZoneSegment->FibContextSegment = FibContextSegment;
4589 + ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4590 + ZoneSegment->ExtendSize = ExtendSize;
4592 + FibAllocSize = ExtendSize * sizeof(FIB);
4595 + ZoneSegment->MapFibContext.Size = FibAllocSize;
4597 + AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4599 + Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4600 + FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4602 + RtlZeroMemory( Fib, FibAllocSize );
4604 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4606 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4607 + i < ExtendSize; i++, FibContext++) {
4609 + FibContext->Adapter = Adapter;
4611 + FibContext->Fib = Fib;
4612 + FibContext->FibData = (PVOID) FibContext->Fib->data;
4614 + OsCv_init( &FibContext->FsaEvent);
4615 + FibContext->FsaEventMutex = OsCvLockAlloc();
4616 + OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4618 + Fib->Header.XferState = 0xffffffff;
4619 + Fib->Header.SenderSize = sizeof(FIB);
4621 + FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4623 + Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4624 + FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4628 + // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4629 + // initialized, we just need to extend it.
4632 + if (Adapter->FibContextZone.TotalSegmentSize) {
4634 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4636 + ExExtendZone( &Adapter->FibContextZone,
4637 + FibContextSegment,
4638 + ZoneSegmentAllocSize );
4640 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4644 + if (ExInitializeZone( &Adapter->FibContextZone,
4645 + sizeof(COMM_FIB_CONTEXT),
4646 + FibContextSegment,
4647 + ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4648 + FsaBugCheck(0,0,0);
4653 + // Add this segment to the adapter's list of segments
4656 + ZoneSegment->Next = Adapter->FibContextSegmentList;
4657 + Adapter->FibContextSegmentList = ZoneSegment;
4666 +Routine Description:
4668 + This routine creates a new COMM_FIB_CONTEXT record
4672 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4676 + PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4680 +AllocateFib (IN PVOID AdapterArg)
4682 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4684 + PCOMM_FIB_CONTEXT FibContext;
4685 + int FullZoneLoopCounter = 0;
4689 + // Acquire the zone spin lock, and check to see if the zone is full.
4690 + // If it is, then release the spin lock and allocate more fibs for the
4691 + // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4692 + // the new fibs onto the zone.
4695 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4697 + while (ExIsFullZone( &Adapter->FibContextZone )) {
4699 + if (++FullZoneLoopCounter > 10)
4700 + FsaBugCheck(0,0,0);
4702 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4705 + cmn_err (CE_DEBUG, "Extending FibContextZone");
4706 + if (FsaExtendFibContextZone(Adapter) == FALSE) {
4710 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4715 + // At this point we now know that the zone has at least one more
4716 + // IRP context record available. So allocate from the zone and
4717 + // then release the mutex.
4720 + FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4722 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4725 + // Set the proper node type code and node byte size
4728 + FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4729 + FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4732 + // Null out fields that depend on being zero at the start of each I/O
4735 + FibContext->Fib->Header.XferState = 0;
4736 + FibContext->FibCallback = NULL;
4737 + FibContext->FibCallbackContext = NULL;
4741 + // return and tell the caller
4744 + return ((PFIB_CONTEXT) FibContext);
4750 +Routine Description:
4752 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4753 + from the Fsafs in memory data structures. It should only be called
4754 + by FsaCompleteRequest.
4758 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4766 +FreeFib (IN PFIB_CONTEXT Context)
4769 + PCOMM_FIB_CONTEXT FibContext = Context;
4771 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4773 + OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4775 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4777 + FsaCommData.TimedOutFibs++;
4779 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4780 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4784 + ASSERT(FibContext->Fib->Header.XferState == 0);
4786 + if (FibContext->Fib->Header.XferState != 0) {
4787 + cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4788 + FibContext, FibContext->Fib->Header.XferState);
4791 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4795 + OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4798 + // return and tell the caller
4807 +Routine Description:
4809 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4810 + from the Fsafs in memory data structures. It should only be called
4811 + from the dpc routines to from dpc to free an FibContext from an async or
4816 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4824 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4826 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4828 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4830 + OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4832 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4834 + FsaCommData.TimedOutFibs++;
4836 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4837 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4841 + ASSERT(FibContext->Fib->Header.XferState == 0);
4843 + if (FibContext->Fib->Header.XferState != 0) {
4844 + cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4845 + FibContext, FibContext->Fib->Header.XferState);
4849 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4853 + OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4856 + // return and tell the caller
4865 +Routine Description:
4867 + Will initialize a FIB of the requested size.
4871 + Fib is a pointer to a location which will receive the address of the allocated
4874 + Size is the size of the Fib to allocate.
4878 + NT_SUCCESS if a Fib was returned to the caller.
4879 + NT_ERROR if event was an invalid event.
4883 +InitializeFib (IN PFIB_CONTEXT Context)
4885 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4886 + PFIB Fib = FibContext->Fib;
4888 + Fib->Header.StructType = TFib;
4889 + Fib->Header.Size = sizeof(FIB);
4890 +// if (Fib->Header.XferState & AllocatedFromPool)
4891 +// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4893 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4894 + Fib->Header.SenderFibAddress = 0;
4895 + Fib->Header.ReceiverFibAddress = 0;
4896 + Fib->Header.SenderSize = sizeof(FIB);
4898 + return(STATUS_SUCCESS);
4904 +Routine Description:
4906 + Will allocate and initialize a FIB of the requested size and return a
4907 + pointer to the structure. The size allocated may be larger than the size
4908 + requested due to allocation performace optimizations.
4912 + Fib is a pointer to a location which will receive the address of the allocated
4915 + Size is the size of the Fib to allocate.
4917 + JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4918 + imbedded structure the FS always allocates. So just initiaize it and return.
4922 + NT_SUCCESS if a Fib was returned to the caller.
4923 + NT_ERROR if event was an invalid event.
4927 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4933 +Routine Description:
4935 + Will deallocate and return to the free pool the FIB pointed to by the
4936 + caller. Upon return accessing locations pointed to by the FIB parameter
4937 + could cause system access faults.
4941 + Fib is a pointer to the FIB that caller wishes to deallocate.
4945 + NT_SUCCESS if a Fib was returned to the caller.
4946 + NT_ERROR if event was an invalid event.
4950 +DeallocateFib (PFIB_CONTEXT Context)
4952 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4953 + PFIB Fib = FibContext->Fib;
4955 + if ( Fib->Header.StructType != TFib ) {
4956 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4957 + return(STATUS_UNSUCCESSFUL);
4961 + Fib->Header.XferState = 0;
4963 + return(STATUS_SUCCESS);
4970 + IN PCOMM_QUE ResponseQueue,
4975 +Routine Description:
4977 + Gets a QE off the requested response queue and gets the response FIB into
4978 + host memory. The FIB may already be in host memory depending on the bus
4979 + interface, or may require the host to DMA it over from the adapter. The routine
4980 + will return the FIB to the caller.
4984 + ResponseQueue - Is the queue the caller wishes to have the response gotten from.
4985 + Fib - Is the Fib which was the response from the adapter
4989 + NT_SUCCESS if a Fib was returned to the caller.
4990 + NT_ERROR if there was no Fib to return to the caller.
4991 + bkpfix - add in all the other possible errors ect
4995 +return(STATUS_UNSUCCESSFUL);
4999 +// Commuication primitives define and support the queuing method we use to
5000 +// support host to adapter commuication. All queue accesses happen through
5001 +// these routines and are the only routines which have a knowledge of the
5002 +// how these queues are implemented.
5008 +Routine Description:
5010 + With a priority the routine returns a queue entry if the queue has free entries. If the queue
5011 + is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5016 + Priority is an enumerated type which determines which priority level
5017 + command queue the QE is going to be queued on.
5019 + Entry is a pointer to the address of where to return the address of
5020 + the queue entry from the requested command queue.
5022 + Index is a pointer to the address of where to store the index of the new
5023 + queue entry returned.
5025 + DontInterrupt - We set this true if the queue state is such that we don't
5026 + need to interrupt the adapter for this queue entry.
5030 + TRUE - If a queue entry is returned
5031 + FALSE - If there are no free queue entries on the requested command queue.
5035 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5036 + OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5037 + OUT ULONG *DontInterrupt)
5039 + ULONG QueueOffset;
5041 + PCOMM_REGION CommRegion;
5043 + CommRegion = Adapter->CommRegion;
5046 + // All of the queues wrap when they reach the end, so we check to see if they
5047 + // have reached the end and if they have we just set the index back to zero.
5048 + // This is a wrap. You could or off the high bits in all updates but this is
5049 + // a bit faster I think.
5052 + if (WhichQueue == AdapHighCmdQueue) {
5053 + *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5055 + if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5056 + *DontInterrupt = TRUE;
5058 + if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5061 + if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5063 + cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5064 + CommRegion->AdapHighCmdQue.NumOutstandingIos);
5066 + QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5067 + *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5071 + } else if (WhichQueue == AdapNormCmdQueue) {
5073 + *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5075 + if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5076 + *DontInterrupt = TRUE;
5079 + // If we are at the end of the QUEUE then wrap back to
5083 + if (*Index >= ADAP_NORM_CMD_ENTRIES)
5084 + *Index = 0; // Wrap to front of the Producer Queue.
5087 + // The IEEE spec says that it the producer is one behind the consumer then
5088 + // the queue is full.
5091 + ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5093 + if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5094 + cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5095 + CommRegion->AdapNormCmdQue.NumOutstandingIos);
5099 + // The success case just falls through and returns the a valid queue entry.
5103 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5104 + FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5105 + *Index, QueueOffset, Entry, *Entry);
5107 + *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5111 + } else if (WhichQueue == AdapHighRespQueue) {
5113 + *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5115 + if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5116 + *DontInterrupt = TRUE;
5118 + if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5121 + if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5123 + cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5124 + CommRegion->AdapHighRespQue.NumOutstandingIos);
5126 + *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5129 + } else if (WhichQueue == AdapNormRespQueue) {
5131 + *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5133 + if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5134 + *DontInterrupt = TRUE;
5137 + // If we are at the end of the QUEUE then wrap back to
5141 + if (*Index >= ADAP_NORM_RESP_ENTRIES)
5142 + *Index = 0; // Wrap to front of the Producer Queue.
5145 + // The IEEE spec says that it the producer is one behind the consumer then
5146 + // the queue is full.
5149 + if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5151 + cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5152 + CommRegion->AdapNormRespQue.NumOutstandingIos);
5155 + // The success case just falls through and returns the a valid queue entry.
5158 + *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5161 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5162 + FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5167 + cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5176 +#ifdef API_THROTTLE
5178 +void ThrottleCheck(
5179 + IN PAFA_COMM_ADAPTER Adapter,
5184 +Routine Description:
5186 + This routine implements data I/O throttling. Throttling occurs when
5187 + a CLI FIB is detected. To ensure the CLI responds quickly (the user
5188 + is waiting for the response), this mechanism restricts the queue
5189 + depth of data IOs at the adapter for a period of time (called the
5190 + Throttle Period, default 5 seconds).
5192 + The mechanism uses a counted semaphore to place threads into a wait
5193 + state should there be too many data I/Os outstanding.
5195 + At the start of a throttle period (indicated by the first CLI FIB)
5196 + a timer is started. When the timer expires, new requests can go to
5197 + the adapter freely. Throttled requests gradually drain to the
5198 + adapter as each outstanding throttle I/O completes.
5200 + To avoid hurting regular I/O performance, we use a flag in the FIB
5201 + header to mark FIBs involved in throttling. This means we only need
5202 + take the extra spinlock in the response DPC routine for FIBs who
5203 + were subject to throttling. If no throttling is occurring, the cost
5204 + to the regular code paths is a handful of instructions.
5208 + Adapter - Pointer to per-adapter context. This is used to locate the
5209 + throttle information for this adapter.
5211 + Fib - Pointer to the header for the fib being sent.
5219 + PCOMM_REGION CommRegion = Adapter->CommRegion;
5220 + AAC_STATUS Status;
5223 + // This routine is called under protection of the queue spinlock.
5224 + // As such we are allowed to check and change the counts for the
5226 + // Check the FIB. If its not a data operation, send it on without
5227 + // throttle check. If it is a data operation, check for throttle.
5230 + CommRegion->TotalFibs++; // Keep statistics
5232 + if ((Fib->Header.XferState & ApiFib) != 0) {
5234 + CommRegion->ApiFibs++; // Keep statistics
5237 + // Its an API fib. If the throttle is not already active,
5238 + // make it so. This will prevent new data Fibs being sent
5239 + // if they exceed the throttle check.
5242 + if (!CommRegion->ThrottleActive) {
5245 + CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5248 + // Schedule a timer for the throttle active period. When
5249 + // it expires, we'll be called back at routine ThrottleDpcRoutine
5250 + // above. This will signify the throttle active period ended
5251 + // and any waiting threads will be signalled to restart.
5254 + FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5255 + CommRegion->ThrottleTimerSets++;
5256 + InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5257 + CommRegion->ThrottleTimeout,
5258 + &CommRegion->ThrottleDpc);
5259 + ASSERT(InQue == FALSE);
5266 + // Its a non-API fib, so subject to throttle checks.
5267 + // The following are exempt from throttling:
5268 + // o FIBs marked as "throttle exempt" by upper layers.
5269 + // o I/Os issued from a raised IRQL. We can't suspend
5270 + // a thread when at raised IRQL so throttling is exempt.
5273 + if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5275 + CommRegion->NonPassiveFibs++;
5276 + FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5281 + if (CommRegion->ThrottleActive) {
5284 + // Throttle is active.
5285 + // Check if the FIB is a read or write. If so, and its to the
5286 + // file system information area, let it through without throttling.
5289 + if (Fib->Header.Command == ContainerCommand) {
5290 + PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5293 + // *** Note *** We are using read and write command formats
5294 + // interchangably here. This is ok for this purpose as the
5295 + // command is in the same place for both. Read and write command
5296 + // formats are different at higher offsets though.
5299 + if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5300 + (BlockDisk->Command == VM_CtBlockWrite)) &&
5301 + (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5303 + CommRegion->FSInfoFibs++; // Keep statistics
5311 + // Throttle the FIB.
5312 + // Mark it as throttle active so that it can signal a waiter
5313 + // when it completes.
5315 + CommRegion->ThrottledFibs++;
5316 + Fib->Header.Flags |= ThrottledFib;
5319 + // Release the spinlock so we can wait the thread if necessary.
5320 + // Since we specify a timeout, check the caller is at passive level.
5323 + OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5325 + FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5327 + Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5328 + Executive, // Don't allow user APCs to wake us
5329 + KernelMode, // Wait in kernel mode
5330 + FALSE, // Not alertable
5331 + &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5334 + // Check the signal status. If we've timed out, clear the throttle
5335 + // flag on the FIB to avoid us signalling the semaphore on completion.
5336 + // We never acquired the semaphore.
5338 + if (Status == STATUS_TIMEOUT) {
5340 + CommRegion->ThrottleTimedoutFibs++;
5341 + FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5342 + Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5346 + ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5351 + // We've been woken up and can now send the FIB to the adapter.
5352 + // Acquire the spinlock again so we can get a queue entry. This
5353 + // returns to GetQueueEntry.
5356 + FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5357 + KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5358 + CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5364 +#endif //#ifdef API_THROTTLE
5366 +int GetQueueEntryTimeouts = 0;
5371 +Routine Description:
5373 + Gets the next free QE off the requested priorty adapter command queue and
5374 + associates the Fib with the QE. The QE represented by index is ready to
5375 + insert on the queue when this routine returns success.
5379 + Index is the returned value which represents the QE which is ready to
5380 + insert on the adapter's command queue.
5382 + Priority is an enumerated type which determines which priority level
5383 + command queue the QE is going to be queued on.
5385 + Fib is a pointer to the FIB the caller wishes to have associated with the
5388 + Wait is a boolean which determines if the routine will wait if there are
5389 + no free QEs on the requested priority command queue.
5391 + FibContext is where the driver stores all system resources required to execute the
5392 + command requested from the calling thread. This includes mapping resources for
5393 + the FIB and the 'users' buffer.
5395 + DontInterrupt - We set this true if the queue state is such that we don't
5396 + need to interrupt the adapter for this queue entry.
5400 + NT_SUCCESS if a Fib was returned to the caller.
5401 + NT_ERROR if event was an invalid event.
5405 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5406 + IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5407 + IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5409 + PQUEUE_ENTRY QueueEntry = NULL;
5410 + BOOLEAN MapAddress = FALSE;
5412 + AAC_STATUS Status;
5413 + PCOMM_REGION CommRegion;
5415 + CommRegion = Adapter->CommRegion;
5418 + // Get the spinlock for the queue we are putting a command on
5421 + if (WhichQueue == AdapHighCmdQueue)
5422 + OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5423 + else if (WhichQueue == AdapNormCmdQueue)
5424 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5425 + else if (WhichQueue == AdapHighRespQueue)
5426 + OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5427 + else if (WhichQueue == AdapNormRespQueue)
5428 + OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5430 + FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5431 + return(FSA_INVALID_QUEUE);
5435 + // Get the pointers to a queue entry on the queue the caller wishes to queue
5436 + // a command request on. If there are no entries then wait if that is what the
5437 + // caller requested.
5440 + if (WhichQueue == AdapHighCmdQueue) {
5441 + // if no entries wait for some if caller wants to
5442 + while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5443 + cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5447 + // Setup queue entry with a command, status and Fib mapped
5450 + QueueEntry->Size = Fib->Header.Size;
5451 + MapAddress = TRUE;
5453 + } else if (WhichQueue == AdapNormCmdQueue) {
5454 + // if no entries wait for some if caller wants to
5455 + while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5456 + cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5460 + // Setup queue entry with command, status and Fib mapped
5463 + QueueEntry->Size = Fib->Header.Size;
5464 + MapAddress = TRUE;
5466 + } else if (WhichQueue == AdapHighRespQueue) {
5468 + while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5472 + // Setup queue entry with command, status and Fib mapped
5475 + QueueEntry->Size = Fib->Header.Size;
5476 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5477 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5478 + MapAddress = FALSE;
5480 + } else if (WhichQueue == AdapNormRespQueue) {
5481 + while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5485 + // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5488 + QueueEntry->Size = Fib->Header.Size;
5489 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5490 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5491 + MapAddress = FALSE;
5495 + // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5499 + QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5506 + FsaCommPrint("Queue Entry contents:.\n");
5507 + FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5508 + FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5509 + FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5510 + FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5513 + return(FSA_SUCCESS);
5519 +Routine Description:
5521 + Gets the next free QE off the requested priorty adapter command queue and
5522 + associates the Fib with the QE. The QE represented by index is ready to
5523 + insert on the queue when this routine returns success.
5527 + Index is the returned value which represents the QE which is ready to
5528 + insert on the adapter's command queue.
5530 + WhichQueue tells us which queue the caller wishes to have the entry put.
5534 + NT_SUCCESS if a Fib was returned to the caller.
5535 + NT_ERROR if event was an invalid event.
5540 + IN PAFA_COMM_ADAPTER Adapter,
5541 + IN QUEUE_INDEX Index,
5542 + IN QUEUE_TYPES WhichQueue,
5543 + IN ULONG DontInterrupt
5546 + PCOMM_REGION CommRegion;
5548 + CommRegion = Adapter->CommRegion;
5551 + // We have already verified the queue in getentry, but we still have to make
5552 + // sure we don't wrap here too.
5555 + if (WhichQueue == AdapHighCmdQueue) {
5557 + *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5559 + OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5561 + if (!DontInterrupt)
5562 + NotifyAdapter(Adapter, AdapHighCmdQue);
5564 + } else if (WhichQueue == AdapNormCmdQueue) {
5567 + FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5569 + *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5571 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5573 + if (!DontInterrupt)
5574 + NotifyAdapter(Adapter, AdapNormCmdQue);
5576 + } else if (WhichQueue == AdapHighRespQueue) {
5578 + *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5580 + OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5582 + if (!DontInterrupt)
5583 + NotifyAdapter(Adapter, AdapHighRespQue);
5585 + } else if (WhichQueue == AdapNormRespQueue) {
5587 + *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5589 + OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5591 + if (!DontInterrupt)
5592 + NotifyAdapter(Adapter, AdapNormRespQue);
5595 + FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5596 + return(FSA_INVALID_QUEUE_PRIORITY);
5599 + return(FSA_SUCCESS);
5602 +extern int GatherFibTimes;
5607 + FIB_COMMAND Command,
5611 + USHORT *ResponseSize
5615 +Routine Description:
5617 + This routine will send a synchronous FIB to the adapter and wait for its
5622 + DeviceExtension - Pointer to adapter extension structure.
5631 + PAFA_COMM_ADAPTER Adapter = Arg;
5633 + ULONG returnStatus;
5635 + Fib = Adapter->SyncFib;
5637 + Fib->Header.StructType = TFib;
5638 + Fib->Header.Size = sizeof(FIB);
5639 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5640 + Fib->Header.ReceiverFibAddress = 0;
5641 + Fib->Header.SenderSize = sizeof(FIB);
5642 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5643 + Fib->Header.Command = Command;
5646 + // Copy the Data portion into the Fib.
5649 + RtlCopyMemory( Fib->data, Data, Size );
5652 + Fib->Header.XferState |= (SentFromHost | NormalPriority);
5655 + // Set the size of the Fib we want to send to the adapter
5658 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5660 + if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5661 + Adapter->SyncFibPhysicalAddress )) {
5668 + // Copy the response back to the caller's buffer.
5671 + RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5673 + *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5676 + // Indicate success
5683 +// Define the highest level of host to adapter communication routines. These
5684 +// routines will support host to adapter FS commuication. These routines have
5685 +// no knowledge of the commuication method used. This level sends and receives
5686 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5693 +Routine Description:
5695 + Sends the requested FIB to the adapter and optionally will wait for a
5696 + response FIB. If the caller does not wish to wait for a response than
5697 + an event to wait on must be supplied. This event will be set when a
5698 + response FIB is received from the adapter.
5702 + Fib is a pointer to the FIB the caller wishes to send to the adapter.
5704 + Size - Size of the data portion of the Fib.
5706 + Priority is an enumerated type which determines which priority level
5707 + the caller wishes to send this command at.
5709 + Wait is a boolean which determines if the routine will wait for the
5710 + completion Fib to be returned(TRUE), or return when the Fib has been
5711 + successfully received by the adapter(FALSE).
5713 + WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5714 + FIB has been returned by the adapter.
5716 + ReturnFib is an optional pointer to a FIB that if present the response FIB will
5721 + NT_SUCCESS if a Fib was returned to the caller.
5722 + NT_ERROR if event was an invalid event.
5726 +SendFib (IN FIB_COMMAND Command,
5727 + IN PFIB_CONTEXT Context,
5729 + IN COMM_PRIORITIES Priority,
5732 + IN BOOLEAN ResponseExpected,
5733 + IN PFIB_CALLBACK FibCallback,
5734 + IN PVOID FibCallbackContext)
5736 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5737 + QUEUE_INDEX Index;
5738 + QUEUE_TYPES WhichQueue;
5739 + LARGE_INTEGER Timeout;
5740 + AAC_STATUS Status;
5741 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5742 + ULONG DontInterrupt = FALSE;
5743 + PFIB Fib = FibContext->Fib;
5744 + IN PCOMM_QUE OurQueue;
5746 + Timeout = FsaCommData.AdapterTimeout;
5748 + if (!(Fib->Header.XferState & HostOwned)) {
5749 + FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5750 + FsaCommLogEvent(FibContext,
5751 + FsaCommData.DeviceObject,
5752 + FSAFS_FIB_INVALID,
5753 + STATUS_UNSUCCESSFUL,
5754 + BugCheckFileId | __LINE__,
5755 + FACILITY_FSAFS_ERROR_CODE,
5759 + return(STATUS_UNSUCCESSFUL);
5764 + // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5765 + // are if the caller requests to wait and does not request a response and if the
5766 + // caller does not want a response and the Fib is not allocated from pool. If a response
5767 + // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5768 + // comes back from the adapter. No further processing will be done besides deleting the
5769 + // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5770 + // and the host can log that fact.
5772 + if (Wait && !ResponseExpected) {
5774 + FsaCommLogEvent(FibContext,
5775 + FsaCommData.DeviceObject,
5776 + FSAFS_FIB_INVALID,
5777 + STATUS_UNSUCCESSFUL,
5778 + BugCheckFileId | __LINE__,
5779 + FACILITY_FSAFS_ERROR_CODE,
5783 + return(STATUS_UNSUCCESSFUL);
5785 + } else if (!Wait && ResponseExpected) {
5786 + Fib->Header.XferState |= (Async | ResponseExpected);
5787 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5788 + } else if (!Wait && !ResponseExpected) {
5789 + Fib->Header.XferState |= NoResponseExpected;
5790 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5791 + } else if (Wait && ResponseExpected) {
5792 + Fib->Header.XferState |= ResponseExpected;
5793 + FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5796 + Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5799 + // Set FIB state to indicate where it came from and if we want a response from the
5800 + // adapter. Also load the command from the caller.
5803 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5804 + Fib->Header.Command = Command;
5805 + Fib->Header.XferState |= SentFromHost;
5806 + FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5809 + // Set the size of the Fib we want to send to the adapter
5812 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5813 + if (Fib->Header.Size > Fib->Header.SenderSize) {
5814 + return(STATUS_BUFFER_OVERFLOW);
5818 + // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5821 + if (Priority == FsaHigh) {
5822 + Fib->Header.XferState |= HighPriority;
5823 + WhichQueue = AdapHighCmdQueue;
5824 + OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5826 + Fib->Header.XferState |= NormalPriority;
5827 + WhichQueue = AdapNormCmdQueue;
5828 + OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5832 + OsCvLockAcquire( FibContext->FsaEventMutex );
5835 + if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5836 + return(STATUS_UNSUCCESSFUL);
5840 + cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5841 + cmn_err (CE_DEBUG,"Fib contents:.\n");
5842 + cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5843 + cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5846 + // Fill in the Callback and CallbackContext if we are not going to wait.
5851 + FibContext->FibCallback = FibCallback;
5852 + FibContext->FibCallbackContext = FibCallbackContext;
5856 + FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5858 + InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5859 + OurQueue->NumOutstandingIos++;
5861 + FibContext->FibComplete = 0;
5865 + if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5866 + return(STATUS_UNSUCCESSFUL);
5869 + // If the caller wanted us to wait for response wait now.
5870 + // If Timeouts are enabled than set the timeout otherwise wait forever.
5874 + while (FibContext->FibComplete == 0) {
5875 + OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5878 + OsCvLockRelease( FibContext->FsaEventMutex );
5880 + if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5881 + return(STATUS_IO_TIMEOUT);
5883 + return(STATUS_SUCCESS);
5888 + // If the user does not want a response than return success otherwise return pending
5891 + ASSERT( FibCallback );
5893 + if (ResponseExpected)
5894 + return(STATUS_PENDING);
5896 + return(STATUS_SUCCESS);
5901 + IN PAFA_COMM_ADAPTER Adapter,
5902 + PCOMM_QUE OurQueue,
5903 + OUT PQUEUE_ENTRY *Entry
5907 +Routine Description:
5909 + Will return a pointer to the entry on the top of the queue requested that we are a consumer
5910 + of, and return the address of the queue entry. It does not change the state of the queue.
5914 + OurQueue - is the queue the queue entry should be removed from.
5916 + Entry - is a pointer where the address of the queue entry should be returned.
5920 + TRUE if there was a queue entry on the response queue for the host to consume.
5921 + FALSE if there were no queue entries to consume.
5926 + QUEUE_INDEX Index;
5929 + if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5934 + // The consumer index must be wrapped if we have reached the end of
5936 + // Else we just use the entry pointed to by the header index
5939 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5942 + Index = *OurQueue->Headers.ConsumerIndex;
5944 + *Entry = OurQueue->BaseAddress + Index;
5947 + FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5956 +ConsumerEntryAvailable(
5957 + IN PAFA_COMM_ADAPTER Adapter,
5958 + PCOMM_QUE OurQueue
5961 + return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
5966 + IN PAFA_COMM_ADAPTER Adapter,
5967 + PCOMM_QUE OurQueue,
5968 + QUEUE_TYPES WhichQueue
5972 +Routine Description:
5974 + Frees up the current top of the queue we are a consumer of. If the queue was full
5975 + notify the producer that the queue is no longer full.
5979 + OurQueue - is the queue we will free the current consumer entry on.
5983 + TRUE if there was a queue entry on the response queue for the host to consume.
5984 + FALSE if there were no queue entries to consume.
5989 + BOOLEAN WasFull = FALSE;
5990 + HOST_2_ADAP_EVENT Notify;
5992 + if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
5995 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5996 + *OurQueue->Headers.ConsumerIndex = 1;
5998 + *OurQueue->Headers.ConsumerIndex += 1;
6001 + switch (WhichQueue) {
6003 + case HostNormCmdQueue:
6004 + Notify = HostNormCmdNotFull;
6006 + case HostHighCmdQueue:
6007 + Notify = HostHighCmdNotFull;
6010 + case HostNormRespQueue:
6011 + Notify = HostNormRespNotFull;
6014 + case HostHighRespQueue:
6015 + Notify = HostHighRespNotFull;
6019 + NotifyAdapter(Adapter, Notify);
6025 +CompleteAdapterFib(
6026 + IN PFIB_CONTEXT Context,
6031 +Routine Description:
6033 + Will do all necessary work to complete a FIB that was sent from the adapter.
6037 + Fib is a pointer to the FIB that caller wishes to complete processing on.
6039 + Size - Size of the completion Packet(Opitional). If not present than the current
6040 + largest size in the Fib will be used
6042 + Adapter - Pointer to which adapter sent this FIB
6046 + NT_SUCCESS if a Fib was returned to the caller.
6047 + NT_ERROR if event was an invalid event.
6051 + PCOMM_FIB_CONTEXT FibContext = Context;
6052 + PFIB Fib = FibContext->Fib;
6053 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6054 + ULONG DontInterrupt = FALSE;
6056 + if (Fib->Header.XferState == 0)
6057 + return(STATUS_SUCCESS);
6060 + // If we plan to do anything check the structure type first.
6063 + if ( Fib->Header.StructType != TFib ) {
6064 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6065 + return(STATUS_UNSUCCESSFUL);
6069 + // This block handles the case where the adapter had sent us a command and we
6070 + // have finished processing the command. We call completeFib when we are done
6071 + // processing the command and want to send a response back to the adapter. This
6072 + // will send the completed cdb to the adapter.
6075 + if (Fib->Header.XferState & SentFromAdapter) {
6076 + Fib->Header.XferState |= HostProcessed;
6077 + if (Fib->Header.XferState & HighPriority) {
6078 + QUEUE_INDEX Index;
6081 + Size += sizeof(FIB_HEADER);
6082 + if (Size > Fib->Header.SenderSize)
6083 + return(STATUS_BUFFER_OVERFLOW);
6084 + Fib->Header.Size = Size;
6087 + if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6088 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6089 + return(FSA_FATAL);
6091 + if (InsertQueueEntry(Adapter,
6093 + AdapHighRespQueue,
6094 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6095 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6097 + } else if (Fib->Header.XferState & NormalPriority) {
6098 + QUEUE_INDEX Index;
6101 + Size += sizeof(FIB_HEADER);
6102 + if (Size > Fib->Header.SenderSize)
6103 + return(STATUS_BUFFER_OVERFLOW);
6104 + Fib->Header.Size = Size;
6107 + if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6108 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6109 + return(FSA_FATAL);
6111 + if (InsertQueueEntry(Adapter,
6113 + AdapNormRespQueue,
6114 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6115 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6119 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6120 + FsaBugCheck(0,0,0);
6122 + return(STATUS_SUCCESS);
6127 + IN PFIB_CONTEXT Context
6131 +Routine Description:
6133 + Will do all necessary work to complete a FIB. If the caller wishes to
6134 + reuse the FIB after post processing has been completed Reinitialize
6135 + should be called set to TRUE, otherwise the FIB will be returned to the
6136 + free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6137 + reinitialzied and is ready for reuse on return from this routine.
6141 + Fib is a pointer to the FIB that caller wishes to complete processing on.
6143 + Size - Size of the completion Packet(Opitional). If not present than the current
6144 + largest size in the Fib will be used
6146 + Reinitialize is a boolean which determines if the routine will ready the
6147 + completed FIB for reuse(TRUE) or not(FALSE).
6151 + NT_SUCCESS if a Fib was returned to the caller.
6152 + NT_ERROR if event was an invalid event.
6156 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6157 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6158 + PFIB Fib = FibContext->Fib;
6161 + // Check for a fib which has already been completed
6164 +// ASSERT(Fib->Header.XferState & AdapterProcessed);
6165 + if (Fib->Header.XferState == 0)
6166 + return(STATUS_SUCCESS);
6169 + // If we plan to do anything check the structure type first.
6172 + if ( Fib->Header.StructType != TFib ) {
6173 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6174 + return(STATUS_UNSUCCESSFUL);
6178 +//#if FSA_ADAPTER_METER
6180 + // Meter the completion
6182 + fsaMeterEnd( // meter the end of an operation
6183 + &(Adapter->FibMeter), // .. the meter
6184 + IrpContext->FibMeterType, // .. type of operation
6185 + &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6186 + FibGetMeterSize(Fib, // .. number of bytes in operation
6187 + IrpContext->FibMeterType,
6188 + IrpContext->FibSubCommand));
6189 +#endif // FSA_ADAPTER_METER
6192 + // This block completes a cdb which orginated on the host and we just need
6193 + // to deallocate the cdb or reinit it. At this point the command is complete
6194 + // that we had sent to the adapter and this cdb could be reused.
6197 + if ( (Fib->Header.XferState & SentFromHost) &&
6198 + (Fib->Header.XferState & AdapterProcessed)) {
6200 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6202 + return( DeallocateFib(FibContext) );
6205 + // This handles the case when the host has aborted the I/O to the
6206 + // adapter because the adapter is not responding
6209 + } else if (Fib->Header.XferState & SentFromHost) {
6211 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6214 + return( DeallocateFib(FibContext) );
6216 + } else if (Fib->Header.XferState & HostOwned) {
6218 + return(DeallocateFib(FibContext));
6221 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6222 + FsaBugCheck(0,0,0);
6224 + return(STATUS_SUCCESS);
6229 + IN PAFA_COMM_ADAPTER Adapter,
6230 + IN PCOMM_FIB_CONTEXT FibContext
6234 +Routine Description:
6236 + This routine handles a driver notify fib from the adapter and dispatches it to
6237 + the appropriate routine for handling.
6241 + Adapter - Which adapter this fib is from
6242 + FibContext - Pointer to FibContext from adapter.
6250 + PFIB Fib = FibContext->Fib;
6251 + PAFA_CLASS_DRIVER ClassDriver;
6252 + BOOLEAN Handled = FALSE;
6256 + // First loop through all of the class drivers to give them a chance to handle
6260 + ClassDriver = Adapter->ClassDriverList;
6262 + while (ClassDriver) {
6264 + if (ClassDriver->HandleAif) {
6266 + if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6274 + ClassDriver = ClassDriver->Next;
6280 + // Set the status of this FIB to be Invalid parameter.
6283 +// *(FSASTATUS *)Fib->data = ST_INVAL;
6284 + *(FSASTATUS *)Fib->data = ST_OK;
6287 + CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6294 + IN PAFA_COMM_ADAPTER Adapter
6298 +Routine Description:
6300 + Waits on the commandready event in it's queue. When the event gets set it will
6301 + pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6302 + When the queue is empty it will wait for more FIBs.
6306 + Context is used. All data os global
6314 + COMM_FIB_CONTEXT FibContext; // for error logging
6316 + PCOMM_REGION CommRegion = Adapter->CommRegion;
6317 + PLIST_ENTRY Entry;
6318 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6321 + // We can only have one thread per adapter for AIF's.
6324 + if (Adapter->AifThreadStarted) {
6328 +// cmn_err(CE_DEBUG, "AIF thread started");
6331 + // Let the DPC know it has a place to send the AIF's to.
6334 + Adapter->AifThreadStarted = TRUE;
6336 + RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6338 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6343 + // NOTE : the QueueLock is held at the top of each loop.
6346 + ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6348 + while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6349 + PLIST_ENTRY Entry;
6350 + PAIFCOMMANDTOHOST AifCommandToHost;
6352 + Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6354 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6356 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6359 + // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6360 + // can't do anything at this point since we don't have anything defined for this thread to
6364 + // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6366 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6369 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6370 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6371 + FibContext.Fib = Fib;
6372 + FibContext.FibData = Fib->data;
6373 + FibContext.Adapter = Adapter;
6377 + // We only handle AifRequest fibs from the adapter.
6380 + ASSERT(Fib->Header.Command == AifRequest);
6383 + AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6385 + if (AifCommandToHost->command == AifCmdDriverNotify) {
6389 + HandleDriverAif( Adapter, &FibContext );
6392 + AAC_UINT32 time_now, time_last;
6393 + time_now = (AAC_UINT32)OsGetSeconds();
6396 + OsCvLockAcquire(Adapter->AdapterFibMutex);
6398 + Entry = Adapter->AdapterFibContextList.Flink;
6401 + // For each Context that is on the AdapterFibContextList, make a copy of the
6402 + // fib, and then set the event to wake up the thread that is waiting for it.
6405 + while (Entry != &Adapter->AdapterFibContextList) {
6408 + // Extract the AdapterFibContext
6411 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6414 + // Check if the queue is getting backlogged
6416 + if ( AdapterFibContext->FibCount > 20 ) {
6417 + time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6420 + // has it been > 2 minutes since the last read off the queue?
6422 + if ((time_now - time_last) > 120) {
6423 + Entry = Entry->Flink;
6424 + // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6425 + // time_now - time_last,
6426 + // AdapterFibContext->FibCount);
6427 + FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6432 +// Warning: sleep possible while holding spinlock
6433 + NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6438 + // Make the copy of the FIB
6441 + RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6444 + // Put the FIB onto the AdapterFibContext's FibList
6447 + InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6448 + AdapterFibContext->FibCount++;
6451 + // Set the event to wake up the thread that will waiting.
6454 + OsCv_signal(&AdapterFibContext->UserEvent);
6461 + Entry = Entry->Flink;
6465 + // Set the status of this FIB
6468 + *(FSASTATUS *)Fib->data = ST_OK;
6470 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6472 + OsCvLockRelease(Adapter->AdapterFibMutex);
6476 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6481 + // There are no more AIF's, call cv_wait_sig to wait for more
6485 + // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6487 + if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6488 + CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6490 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6492 + Adapter->AifThreadStarted = FALSE;
6494 + // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6500 + // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6508 + IN PFIB_CONTEXT Context
6511 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6513 + return ((PVOID)FibContext->Fib->data);
6517 +#ifdef API_THROTTLE
6519 +void ThrottlePeriodEndDpcRtn(
6521 + IN PVOID DeferredContext,
6522 + IN PVOID SystemArgument1,
6523 + IN PVOID SystemArgument2
6527 +Routine Description:
6529 + This routine is called as a DPC when a throttle period expires. It
6530 + restarts all threads suspended due to the throttling flow control.
6532 + The throttling counted semaphore is signalled for all waiting threads
6533 + and the indicator of throttling active is cleared.
6537 + Dpc - Pointer to Dpc structure. Not used.
6538 + DefferedContext - Pointer to per-adapter context. This is used to locate the
6539 + throttle information for this adapter.
6540 + SystemArgument1 - Not used
6541 + SystemArgument2 - Not used
6549 + PCOMM_REGION CommRegion;
6550 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6552 + CommRegion = Adapter->CommRegion;
6555 + // Acquire the spinlock protecting the throttle status.
6557 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6559 + FsaCommPrint("ThrottlePeriodEndDpc\n");
6562 + // Check that the timer has fired as many times as it was set !
6565 + CommRegion->ThrottleTimerFires++;
6566 + ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6569 + // The throttle period is now over. Restart all threads waiting
6570 + // on the throttle being released.
6571 + // Clear the throttle active indicator. This will allow new FIBs
6572 + // to be sent to the adapter once we release the spinlock on exiting
6573 + // the DPC. This means all restarted threads will be runnable
6574 + // threads by then.
6577 + ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6578 + CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6580 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6583 +#endif // #ifdef API_THROTTLE
6586 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6587 + * Emacs will notice this stuff at the end of the file and automatically
6588 + * adjust the settings for this buffer only. This must remain at the end
6590 + * ---------------------------------------------------------------------------
6591 + * Local variables:
6592 + * c-indent-level: 4
6593 + * c-brace-imaginary-offset: 0
6594 + * c-brace-offset: -4
6595 + * c-argdecl-indent: 4
6596 + * c-label-offset: -4
6597 + * c-continued-statement-offset: 4
6598 + * c-continued-brace-offset: 0
6599 + * indent-tabs-mode: nil
6603 diff -burN linux-2.4.4/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6604 --- linux-2.4.4/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 18:00:00 1969
6605 +++ linux/drivers/scsi/aacraid/dpcsup.c Mon Apr 30 09:43:34 2001
6608 + * Adaptec aacraid device driver for Linux.
6610 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6612 + * This program is free software; you can redistribute it and/or modify
6613 + * it under the terms of the GNU General Public License as published by
6614 + * the Free Software Foundation; either version 2, or (at your option)
6615 + * any later version.
6617 + * This program is distributed in the hope that it will be useful,
6618 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6619 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6620 + * GNU General Public License for more details.
6622 + * You should have received a copy of the GNU General Public License
6623 + * along with this program; see the file COPYING. If not, write to
6624 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6629 + * Abstract: All DPC processing routines for the cyclone board occur here.
6634 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6636 +#include "comprocs.h"
6640 +// The Bug check file id for this module
6643 +#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6645 +#define Dbg (DEBUG_TRACE_DPCSUP)
6649 + IN PCOMM_REGION CommRegion
6653 +Routine Description:
6655 + This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6656 + no longer full. The Isr will pass the queue that we will set the not full event.
6660 + Dpc - Pointer to this routine.
6662 + Dummy - is a pointer to the comm region which is global so we don't need it anyway
6664 + Queue is a pointer to the queue structure we will operate on.
6666 + MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6675 +#ifdef unix_queue_full
6676 + KeSetEvent(&Queue->QueueFull, 0, FALSE);
6681 +int GatherFibTimes = 0;
6683 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6694 +Routine Description:
6696 + This DPC routine will be queued when the adapter interrupts us to let us know there
6697 + is a response on our normal priority queue. We will pull off all QE there are and wake
6698 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6703 + Dpc - Pointer to this routine.
6705 + OurQueue is a pointer to the queue structure we will operate on.
6707 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6715 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6717 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6718 + PQUEUE_ENTRY QueueEntry;
6720 + PCOMM_FIB_CONTEXT FibContext;
6724 + LARGE_INTEGER ResponseAllocSize;
6727 + FsaCommPrint("entering the host normal reponse dpc routine.\n");
6730 + OsSpinLockAcquire( OurQueue->QueueLock );
6733 + // Keep pulling response QEs off the response queue and waking
6734 + // up the waiters until there are no more QEs. We then return
6735 + // back to the system. If no response was requesed we just
6736 + // deallocate the Fib here and continue.
6740 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6742 + int IsFastResponse;
6744 + IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6745 + Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6747 + FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6749 + FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6751 + ASSERT(FibContext->Fib == Fib);
6754 + // Remove this FibContext from the Outstanding I/O queue.
6755 + // But only if it has not already been timed out.
6757 + // If the fib has been timed out already, then just continue.
6758 + // The caller has already been notified that the fib timed out.
6761 + if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6763 + RemoveEntryList( &FibContext->QueueEntry );
6764 + Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6768 + FsaCommLogEvent(FibContext,
6769 + FsaCommData.DeviceObject,
6770 + FSAFS_TIMED_OUT_FIB_COMPLETED,
6771 + STATUS_UNSUCCESSFUL,
6772 + BugCheckFileId | __LINE__,
6773 + FACILITY_FSAFS_ERROR_CODE,
6781 + OsSpinLockRelease( OurQueue->QueueLock );
6783 + if (IsFastResponse) {
6789 + *(FSASTATUS *)Fib->data = ST_OK;
6791 + Fib->Header.XferState |= AdapterProcessed;
6795 + ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6797 + FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6799 + ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6802 + if (Fib->Header.Command == NuFileSystem) {
6804 + FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6806 + if (*pStatus & 0xffff0000) {
6808 + ULONG Hint = *pStatus;
6813 + DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6814 + IrpContext->NonPaged->FileId.fid_driveno,
6815 + IrpContext->NonPaged->FileId.fid_f1,
6816 + IrpContext->NonPaged->FileId.fid_f2,
6817 + IrpContext->NonPaged->FileId.fid_hint,
6825 + if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6827 + ASSERT(FibContext->FibCallback);
6829 + if (Fib->Header.XferState & NoResponseExpected)
6830 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6832 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6835 + // NOTE: we can not touch the FibContext after this call, because it may have been
6839 + FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6843 + OsCvLockAcquire( FibContext->FsaEventMutex);
6845 + FibContext->FibComplete = 1;
6847 + OsCv_signal( &FibContext->FsaEvent );
6849 + OsCvLockRelease( FibContext->FsaEventMutex );
6851 + FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6858 + OsSpinLockAcquire( OurQueue->QueueLock );
6862 + if (Consumed > FsaCommData.PeakFibsConsumed)
6863 + FsaCommData.PeakFibsConsumed = Consumed;
6865 + if (Consumed == 0)
6866 + FsaCommData.ZeroFibsConsumed++;
6868 + if (FsaCommData.HardInterruptModeration) {
6871 + // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6872 + // been put on the queue. This removes the race condition that exists between the
6873 + // last time we checked the queue, and when we re-enabled the interrupt.
6875 + // If there is something on the queue, then go handle it.
6878 + EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6880 + if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6882 + DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6890 + FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6893 + OsSpinLockRelease( OurQueue->QueueLock );
6899 +Routine Description:
6901 + This DPC routine wiol be queued when the adapter interrupts us to let us know there
6902 + is a response on our high priority queue. We will pull off all QE there are and wake
6903 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6908 + Dpc - Pointer to this routine.
6910 + OurQueue is a pointer to the queue structure we will operate on.
6912 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6920 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6926 +Routine Description:
6928 + This DPC routine will be queued when the adapter interrupts us to let us know there
6929 + is a command on our high priority queue. We will pull off all QE there are and wake
6930 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6935 + Dpc - Pointer to this routine.
6937 + OurQueue is a pointer to the queue structure we will operate on.
6939 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6947 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6953 +Routine Description:
6955 + This DPC routine will be queued when the adapter interrupts us to let us know there
6956 + is a command on our normal priority queue. We will pull off all QE there are and wake
6957 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6962 + Dpc - Pointer to this routine.
6964 + OurQueue is a pointer to the queue structure we will operate on.
6966 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6974 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
6976 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6977 + PQUEUE_ENTRY QueueEntry;
6979 + OsSpinLockAcquire( OurQueue->QueueLock );
6982 + // Keep pulling response QEs off the response queue and waking
6983 + // up the waiters until there are no more QEs. We then return
6984 + // back to the system.
6987 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6991 + Fib = (PFIB)QueueEntry->FibAddress;
6994 + if (Adapter->AifThreadStarted) {
6997 +// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
7000 + InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7001 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7002 + OsCv_signal(&OurQueue->CommandReady);
7010 + COMM_FIB_CONTEXT FibContext;
7014 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7018 + OsSpinLockRelease( OurQueue->QueueLock );
7022 +// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7025 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7027 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7028 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7029 + FibContext.Fib = Fib;
7030 + FibContext.FibData = Fib->data;
7031 + FibContext.Adapter = Adapter;
7034 + // Set the status of this FIB
7037 + *(FSASTATUS *)Fib->data = ST_OK;
7039 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7043 + OsSpinLockAcquire( OurQueue->QueueLock );
7047 + OsSpinLockRelease( OurQueue->QueueLock );
7050 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7051 --- linux-2.4.4/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 18:00:00 1969
7052 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Mon Apr 30 09:43:34 2001
7055 + * Adaptec aacraid device driver for Linux.
7057 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7059 + * This program is free software; you can redistribute it and/or modify
7060 + * it under the terms of the GNU General Public License as published by
7061 + * the Free Software Foundation; either version 2, or (at your option)
7062 + * any later version.
7064 + * This program is distributed in the hope that it will be useful,
7065 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7066 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7067 + * GNU General Public License for more details.
7069 + * You should have received a copy of the GNU General Public License
7070 + * along with this program; see the file COPYING. If not, write to
7071 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7075 + * AacGenericTypes.h
7079 + * The module defines the generic data types that all of the other header files
7083 +#ifndef _AAC_GENERIC_TYPES
7084 +#define _AAC_GENERIC_TYPES
7086 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7088 +typedef char AAC_INT8, *PAAC_INT8;
7089 +typedef short AAC_INT16, *PAAC_INT16;
7090 +typedef int AAC_INT32, *PAAC_INT32;
7091 +typedef long long AAC_INT64, *PAAC_INT64;
7093 +typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7094 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7095 +typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7096 +typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7098 +typedef void AAC_VOID, *PAAC_VOID;
7101 +// this compiler uses 32 bit enum data types
7104 +#define AAC_32BIT_ENUMS 1
7106 +#define INTR_UNCLAIMED 1
7107 +#define INTR_CLAIMED 0
7109 +#endif // _AAC_GENERIC_TYPES
7111 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7112 --- linux-2.4.4/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 18:00:00 1969
7113 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Mon Apr 30 09:43:34 2001
7116 + * Adaptec aacraid device driver for Linux.
7118 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7120 + * This program is free software; you can redistribute it and/or modify
7121 + * it under the terms of the GNU General Public License as published by
7122 + * the Free Software Foundation; either version 2, or (at your option)
7123 + * any later version.
7125 + * This program is distributed in the hope that it will be useful,
7126 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7127 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7128 + * GNU General Public License for more details.
7130 + * You should have received a copy of the GNU General Public License
7131 + * along with this program; see the file COPYING. If not, write to
7132 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7140 + * Macro definition and typedefs
7144 +#ifndef _AAC_UNIX_DEFS
7145 +#define _AAC_UNIX_DEFS
7147 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7149 +#define AAC_MAX_ADAPTERS 64
7156 +#define PAGE_SIZE 4096
7159 +typedef VOID *PVOID;
7161 +typedef char CHAR, *PCHAR;
7162 +typedef unsigned char UCHAR, *PUCHAR;
7163 +typedef short SHORT, *PSHORT;
7164 +typedef short CSHORT, *PCSHORT;
7165 +typedef unsigned short USHORT, *PUSHORT;
7166 +typedef unsigned long ULONG, *PULONG;
7167 +typedef long LONG, *PLONG;
7169 +typedef unsigned long BOOLEAN;
7171 +typedef unsigned long AAC_STATUS, *PNT_STATUS;
7174 + unsigned long LowPart;
7175 + unsigned long HighPart;
7178 +typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7181 +typedef struct _AFA_IOCTL_CMD {
7187 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7191 +// Singly linked list structure. Can be used as either a list head, or
7195 +typedef struct _SINGLE_LIST_ENTRY {
7196 + struct _SINGLE_LIST_ENTRY *Next;
7197 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7201 +// Calculate the address of the base of the structure given its type, and an
7202 +// address of a field within the structure.
7205 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7206 + (PCHAR)(address) - \
7207 + (PCHAR)(&((type *)0)->field)))
7209 +typedef PVOID PMDL;
7210 +typedef PVOID PDEVICE_OBJECT;
7211 +typedef PVOID PADAPTER_OBJECT;
7212 +typedef ULONG KIRQL;
7213 +typedef PVOID HANDLE;
7214 +typedef PVOID KDPC, *PKDPC;
7215 +typedef PVOID PFILE_OBJECT;
7216 +typedef PVOID PIRP;
7217 +typedef PVOID PDRIVER_OBJECT;
7218 +typedef ULONG KTIMER;
7221 +#define STATUS_SUCCESS 0x00000000
7222 +#define STATUS_PENDING 0x40000001
7223 +#define STATUS_IO_TIMEOUT 0xc0000001
7224 +#define STATUS_UNSUCCESSFUL 0xc0000002
7225 +#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7226 +#define STATUS_BUFFER_OVERFLOW 0xc0000003
7234 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7240 +typedef struct _ZONE_SEGMENT_HEADER {
7241 + SINGLE_LIST_ENTRY SegmentList;
7243 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7245 +typedef struct _ZONE_HEADER {
7246 + SINGLE_LIST_ENTRY FreeList;
7247 + SINGLE_LIST_ENTRY SegmentList;
7249 + ULONG TotalSegmentSize;
7250 +} ZONE_HEADER, *PZONE_HEADER;
7256 +// ExAllocateFromZone(
7257 +// IN PZONE_HEADER Zone
7260 +// Routine Description:
7262 +// This routine removes an entry from the zone and returns a pointer to it.
7266 +// Zone - Pointer to the zone header controlling the storage from which the
7267 +// entry is to be allocated.
7271 +// The function value is a pointer to the storage allocated from the zone.
7275 +#define ExAllocateFromZone(Zone) \
7276 + (PVOID)((Zone)->FreeList.Next); \
7277 + if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7283 +// IN PZONE_HEADER Zone,
7287 +// Routine Description:
7289 +// This routine places the specified block of storage back onto the free
7290 +// list in the specified zone.
7294 +// Zone - Pointer to the zone header controlling the storage to which the
7295 +// entry is to be inserted.
7297 +// Block - Pointer to the block of storage to be freed back to the zone.
7301 +// Pointer to previous block of storage that was at the head of the free
7302 +// list. NULL implies the zone went from no available free blocks to
7303 +// at least one free block.
7307 +#define ExFreeToZone(Zone,Block) \
7308 + ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7309 + (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7310 + ((PSINGLE_LIST_ENTRY)(Block))->Next \
7317 +// IN PZONE_HEADER Zone
7320 +// Routine Description:
7322 +// This routine determines if the specified zone is full or not. A zone
7323 +// is considered full if the free list is empty.
7327 +// Zone - Pointer to the zone header to be tested.
7331 +// TRUE if the zone is full and FALSE otherwise.
7335 +#define ExIsFullZone(Zone) \
7336 + ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7339 +#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7340 +#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7343 +// Doubly-linked list manipulation routines. Implemented as macros
7344 +// but logically these are procedures.
7349 +// InitializeListHead(
7350 +// PLIST_ENTRY ListHead
7354 +#define InitializeListHead(ListHead) (\
7355 + (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7360 +// PLIST_ENTRY ListHead
7364 +#define IsListEmpty(ListHead) \
7365 + ((ListHead)->Flink == (ListHead))
7370 +// PLIST_ENTRY ListHead
7374 +#define RemoveHeadList(ListHead) \
7375 + (ListHead)->Flink;\
7376 + {RemoveEntryList((ListHead)->Flink)}
7381 +// RemoveEntryList(
7382 +// PLIST_ENTRY Entry
7386 +#define RemoveEntryList(Entry) {\
7387 + PLIST_ENTRY _EX_Blink;\
7388 + PLIST_ENTRY _EX_Flink;\
7389 + _EX_Flink = (Entry)->Flink;\
7390 + _EX_Blink = (Entry)->Blink;\
7391 + _EX_Blink->Flink = _EX_Flink;\
7392 + _EX_Flink->Blink = _EX_Blink;\
7398 +// PLIST_ENTRY ListHead,
7399 +// PLIST_ENTRY Entry
7403 +#define InsertTailList(ListHead,Entry) {\
7404 + PLIST_ENTRY _EX_Blink;\
7405 + PLIST_ENTRY _EX_ListHead;\
7406 + _EX_ListHead = (ListHead);\
7407 + _EX_Blink = _EX_ListHead->Blink;\
7408 + (Entry)->Flink = _EX_ListHead;\
7409 + (Entry)->Blink = _EX_Blink;\
7410 + _EX_Blink->Flink = (Entry);\
7411 + _EX_ListHead->Blink = (Entry);\
7414 +#endif /* AAC_UNIX_DEFS */
7415 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7416 --- linux-2.4.4/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 18:00:00 1969
7417 +++ linux/drivers/scsi/aacraid/include/adapter.h Mon Apr 30 09:43:34 2001
7420 + * Adaptec aacraid device driver for Linux.
7422 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7424 + * This program is free software; you can redistribute it and/or modify
7425 + * it under the terms of the GNU General Public License as published by
7426 + * the Free Software Foundation; either version 2, or (at your option)
7427 + * any later version.
7429 + * This program is distributed in the hope that it will be useful,
7430 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7431 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7432 + * GNU General Public License for more details.
7434 + * You should have received a copy of the GNU General Public License
7435 + * along with this program; see the file COPYING. If not, write to
7436 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7443 + * The module contains the definitions for a comm layer view of the adapter.
7452 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7454 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7456 + NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7457 + NODE_BYTE_SIZE NodeByteSize;
7458 + PFILE_OBJECT FileObject; // used for cleanup
7459 + LIST_ENTRY NextContext; // used to link context's into a linked list
7460 + OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7461 + BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7462 + ULONG FibCount; // total number of FIBs on FibList
7463 + LIST_ENTRY FibList;
7464 +} GET_ADAPTER_FIB_CONTEXT;
7465 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7468 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7470 + struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7471 + ULONG FibContextSegmentSize;
7472 + PVOID FibContextSegment;
7474 + MAPFIB_CONTEXT MapFibContext;
7476 +} FIB_CONTEXT_ZONE_SEGMENT;
7477 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7479 +typedef struct _AFA_COMM_ADAPTER {
7481 + struct _AFA_COMM_ADAPTER *NextAdapter;
7484 + // The following fields are used to allocate FIB context structures
7485 + // using the zone allocator, and other fixed sized structures from a
7486 + // small cache. The mutex protects access to the zone/lists
7489 + ZONE_HEADER FibContextZone;
7490 + OS_SPINLOCK *FibContextZoneSpinLock;
7491 + int FibContextZoneExtendSize;
7493 + PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7495 + PVOID FibContextTimedOutList;
7498 + ULONG SyncFibPhysicalAddress;
7500 + PCOMM_REGION CommRegion;
7502 + OS_SPINLOCK_COOKIE SpinLockCookie;
7505 + // The user API will use an IOCTL to register itself to receive FIBs
7506 + // from the adapter. The following list is used to keep track of all
7507 + // the threads that have requested these FIBs. The mutex is used to
7508 + // synchronize access to all data associated with the adapter fibs.
7510 + LIST_ENTRY AdapterFibContextList;
7511 + OS_CVLOCK *AdapterFibMutex;
7514 + // The following holds which FileObject is allow to send configuration
7515 + // commands to the adapter that would modify the configuration.
7517 + // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7520 + PFILE_OBJECT AdapterConfigFileObject;
7523 + // The following is really here because of the simulator
7525 + BOOLEAN InterruptsBelowDpc;
7528 + // The following is the device specific extension.
7530 + PVOID AdapterExtension;
7531 + PFSAPORT_FUNCS AdapterFuncs;
7535 + // The following are user variables that are specific to the mini port.
7537 + PFSA_USER_VAR AdapterUserVars;
7538 + ULONG AdapterUserVarsSize;
7541 + // The following is the number of the individual adapter..i.e. \Device\Afa0
7543 + LONG AdapterNumber;
7545 + AFACOMM_FUNCS CommFuncs;
7547 + PAFA_CLASS_DRIVER ClassDriverList;
7549 + BOOLEAN AifThreadStarted;
7551 +} AFA_COMM_ADAPTER;
7553 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7556 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7557 + Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7559 +#define FsaFreeAdapterCommArea(Adapter) \
7560 + Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7563 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7564 + Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7566 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7567 + Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7569 +#define InterruptAdapter(Adapter) \
7570 + Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7572 +#define NotifyAdapter(Adapter, AdapterEvent) \
7573 + Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7575 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7576 + Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7578 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7579 + Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7582 +#endif // _ADAPTER_
7583 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7584 --- linux-2.4.4/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 18:00:00 1969
7585 +++ linux/drivers/scsi/aacraid/include/afacomm.h Mon Apr 30 09:43:34 2001
7588 + * Adaptec aacraid device driver for Linux.
7590 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7592 + * This program is free software; you can redistribute it and/or modify
7593 + * it under the terms of the GNU General Public License as published by
7594 + * the Free Software Foundation; either version 2, or (at your option)
7595 + * any later version.
7597 + * This program is distributed in the hope that it will be useful,
7598 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7599 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7600 + * GNU General Public License for more details.
7602 + * You should have received a copy of the GNU General Public License
7603 + * along with this program; see the file COPYING. If not, write to
7604 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7610 + * This module defines all of the external interfaces to the AFA comm layer.
7618 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7620 +#include "fsaport.h"
7622 +typedef void *PFIB_CONTEXT;
7626 + PVOID FibCallbackContext,
7627 + PFIB_CONTEXT FibContext,
7632 +typedef PFIB_CONTEXT
7633 +(*PAFA_COMM_ALLOCATE_FIB) (
7634 + IN PVOID AdapterExtension
7638 +(*PAFA_COMM_FREE_FIB) (
7639 + IN PFIB_CONTEXT FibContext
7644 +(*PAFA_COMM_DEALLOCATE_FIB) (
7645 + IN PFIB_CONTEXT FibContext
7650 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7651 + IN PFIB_CONTEXT FibContext
7655 +(*PAFA_COMM_INITIALIZE_FIB) (
7656 + IN PFIB_CONTEXT FibContext
7660 +(*PAFA_COMM_GET_FIB_DATA) (
7661 + IN PFIB_CONTEXT FibContext
7665 +(*PAFA_COMM_SEND_FIB) (
7666 + IN FIB_COMMAND Command,
7667 + IN PFIB_CONTEXT FibContext,
7669 + IN COMM_PRIORITIES Priority,
7672 + IN BOOLEAN ResponseExpected,
7673 + IN PFIB_CALLBACK FibCallback,
7674 + IN PVOID FibCallbackContext
7678 +(*PAFA_COMM_COMPLETE_FIB) (
7679 + IN PFIB_CONTEXT FibContext
7683 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7684 + IN PFIB_CONTEXT FibContext,
7689 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7690 + PVOID AdapterExtension,
7691 + FIB_COMMAND Command,
7695 + USHORT *ResponseSize
7699 +typedef struct _AFACOMM_FUNCS {
7700 + ULONG SizeOfAfaCommFuncs;
7701 + PAFA_COMM_ALLOCATE_FIB AllocateFib;
7702 + PAFA_COMM_FREE_FIB FreeFib;
7703 + PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7704 + PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7705 + PAFA_COMM_INITIALIZE_FIB InitializeFib;
7706 + PAFA_COMM_GET_FIB_DATA GetFibData;
7707 + PAFA_COMM_SEND_FIB SendFib;
7708 + PAFA_COMM_COMPLETE_FIB CompleteFib;
7709 + PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7710 + PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7711 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7712 + PFSA_BUILD_SGMAP BuildSgMap;
7713 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7715 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7719 +(*PAFA_CLASS_OPEN_ADAPTER) (
7725 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7731 +(*PAFA_CLASS_DEV_CONTROL) (
7733 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
7738 +(*PAFA_CLASS_HANDLE_AIF) (
7740 + IN PFIB_CONTEXT FibContext
7744 +typedef struct _AFA_NEW_CLASS_DRIVER {
7745 + PVOID ClassDriverExtension;
7746 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7747 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7748 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7749 + PAFA_CLASS_HANDLE_AIF HandleAif;
7750 + PFSA_USER_VAR UserVars;
7751 + ULONG NumUserVars;
7752 +} AFA_NEW_CLASS_DRIVER;
7753 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7756 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7757 + PAFACOMM_FUNCS CommFuncs;
7758 + PVOID CommPortExtension;
7759 + PVOID MiniPortExtension;
7760 + OS_SPINLOCK_COOKIE SpinLockCookie;
7762 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7763 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7766 +typedef struct _AFA_CLASS_DRIVER {
7767 + struct _AFA_CLASS_DRIVER *Next;
7768 + PVOID ClassDriverExtension;
7769 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7770 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7771 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7772 + PAFA_CLASS_HANDLE_AIF HandleAif;
7773 +} AFA_CLASS_DRIVER;
7774 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7777 +#endif // _AFACOMM_
7778 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7779 --- linux-2.4.4/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7780 +++ linux/drivers/scsi/aacraid/include/aifstruc.h Mon Apr 30 09:43:34 2001
7783 + * Adaptec aacraid device driver for Linux.
7785 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7787 + * This program is free software; you can redistribute it and/or modify
7788 + * it under the terms of the GNU General Public License as published by
7789 + * the Free Software Foundation; either version 2, or (at your option)
7790 + * any later version.
7792 + * This program is distributed in the hope that it will be useful,
7793 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7794 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7795 + * GNU General Public License for more details.
7797 + * You should have received a copy of the GNU General Public License
7798 + * along with this program; see the file COPYING. If not, write to
7799 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7805 + * Define all shared data types relating to
7806 + * the set of features utilizing Adapter
7812 +#ifndef _AIFSTRUC_H
7813 +#define _AIFSTRUC_H
7815 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7817 +#include <protocol.h>
7820 +// Progress report structure definitions
7823 + AifJobStsSuccess = 1,
7824 + AifJobStsFinished,
7827 + AifJobStsLastReportMarker = 100, // All before mean last report
7828 + AifJobStsSuspended,
7832 +#ifdef AAC_32BIT_ENUMS
7833 +typedef _E_AifJobStatus AifJobStatus;
7835 +typedef AAC_UINT32 AifJobStatus;
7840 + AifJobScsiMin = 1, // Minimum value for Scsi operation
7841 + AifJobScsiZero, // SCSI device clear operation
7842 + AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7843 + AifJobScsiExercise, // SCSI device Exercise operation
7844 + AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7845 + // Add new SCSI task types above this line
7846 + AifJobScsiMax = 99, // Max Scsi value
7847 + AifJobCtrMin, // Min Ctr op value
7848 + AifJobCtrZero, // Container clear operation
7849 + AifJobCtrCopy, // Container copy operation
7850 + AifJobCtrCreateMirror, // Container Create Mirror operation
7851 + AifJobCtrMergeMirror, // Container Merge Mirror operation
7852 + AifJobCtrScrubMirror, // Container Scrub Mirror operation
7853 + AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7854 + AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7855 + AifJobCtrMorph, // Container morph operation
7856 + AifJobCtrPartCopy, // Container Partition copy operation
7857 + AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7858 + AifJobCtrCrazyCache, // crazy cache
7859 + // Add new container task types above this line
7860 + AifJobCtrMax = 199, // Max Ctr type operation
7861 + AifJobFsMin, // Min Fs type operation
7862 + AifJobFsCreate, // File System Create operation
7863 + AifJobFsVerify, // File System Verify operation
7864 + AifJobFsExtend, // File System Extend operation
7865 + // Add new file system task types above this line
7866 + AifJobFsMax = 299, // Max Fs type operation
7867 + // Add new API task types here
7868 + AifJobApiFormatNTFS, // Format a drive to NTFS
7869 + AifJobApiFormatFAT, // Format a drive to FAT
7870 + AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7871 + AifJobApiFormatFAT32, // Format a drive to FAT32
7872 + AifJobApiMax = 399, // Max API type operation
7873 + AifJobCtlContinuousCtrVerify, // Controller operation
7874 + AifJobCtlMax = 499 // Max Controller type operation
7878 +#ifdef AAC_32BIT_ENUMS
7879 +typedef _E_AifJobType AifJobType;
7881 +typedef AAC_UINT32 AifJobType;
7884 +union SrcContainer {
7886 + AAC_UINT32 master;
7887 + AAC_UINT32 container;
7890 +union DstContainer {
7893 + AAC_UINT32 container;
7897 +struct AifContainers {
7898 + union SrcContainer src;
7899 + union DstContainer dst;
7902 +union AifJobClient {
7904 + struct AifContainers container; // For Container nd file system progress ops;
7905 + AAC_INT32 scsi_dh; // For SCSI progress ops
7908 +struct AifJobDesc {
7909 + AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7910 + AifJobType type; // Operation that is being performed
7911 + union AifJobClient client; // Details
7914 +struct AifJobProgressReport {
7915 + struct AifJobDesc jd;
7916 + AifJobStatus status;
7917 + AAC_UINT32 finalTick;
7918 + AAC_UINT32 currentTick;
7919 + AAC_UINT32 jobSpecificData1;
7920 + AAC_UINT32 jobSpecificData2;
7924 +// Notification of events structure definition starts here
7927 + // General application notifies start here
7928 + AifEnGeneric = 1, // Generic notification
7929 + AifEnTaskComplete, // Task has completed
7930 + AifEnConfigChange, // Adapter configuration change occurred
7931 + AifEnContainerChange, // Adapter specific container configuration change
7932 + AifEnDeviceFailure, // SCSI device failed
7933 + AifEnMirrorFailover, // Mirror failover started
7934 + AifEnContainerEvent, // Significant container event
7935 + AifEnFileSystemChange, // File system changed
7936 + AifEnConfigPause, // Container pause event
7937 + AifEnConfigResume, // Container resume event
7938 + AifEnFailoverChange, // Failover space assignment changed
7939 + AifEnRAID5RebuildDone, // RAID5 rebuild finished
7940 + AifEnEnclosureManagement, // Enclosure management event
7941 + AifEnBatteryEvent, // Significant NV battery event
7942 + AifEnAddContainer, // A new container was created.
7943 + AifEnDeleteContainer, // A container was deleted.
7944 + AifEnSMARTEvent, // SMART Event
7945 + AifEnBatteryNeedsRecond, // The battery needs reconditioning
7946 + AifEnClusterEvent, // Some cluster event
7947 + AifEnDiskSetEvent, // A disk set event occured.
7948 + // Add general application notifies above this comment
7949 + AifDriverNotifyStart=199, // Notifies for host driver go here
7950 + // Host driver notifications start here
7951 + AifDenMorphComplete, // A morph operation completed
7952 + AifDenVolumeExtendComplete // A volume expand operation completed
7953 + // Add host driver notifications above this comment
7954 +} _E_AifEventNotifyType;
7956 +#ifdef AAC_32BIT_ENUMS
7957 +typedef _E_AifEventNotifyType AifEventNotifyType;
7959 +typedef AAC_UINT32 AifEventNotifyType;
7962 +struct AifEnsGeneric {
7963 + AAC_INT8 text[132]; // Generic text
7966 +struct AifEnsDeviceFailure {
7967 + AAC_INT32 deviceHandle; // SCSI device handle
7970 +struct AifEnsMirrorFailover {
7971 + AAC_UINT32 container; // Container with failed element
7972 + AAC_UINT32 failedSlice; // Old slice which failed
7973 + AAC_UINT32 creatingSlice; // New slice used for auto-create
7976 +struct AifEnsContainerChange {
7977 + AAC_UINT32 container[2]; // container that changed, -1 if no container
7980 +struct AifEnsContainerEvent {
7981 + AAC_UINT32 container; // container number
7982 + AAC_UINT32 eventType; // event type
7985 +struct AifEnsEnclosureEvent {
7986 + AAC_UINT32 empID; // enclosure management processor number
7987 + AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
7988 + AAC_UINT32 eventType; // event type
7992 +struct AifEnsBatteryEvent {
7993 + NVBATT_TRANSITION transition_type; // e.g. from low to ok
7994 + NVBATTSTATUS current_state; // current battery state
7995 + NVBATTSTATUS prior_state; // previous battery state
7998 +struct AifEnsDiskSetEvent {
7999 + AAC_UINT32 eventType;
8000 + AAC_UINT32 DsNum[2];
8001 + AAC_UINT32 CreatorId[2];
8006 +typedef enum _CLUSTER_AIF_EVENT {
8007 + CLUSTER_NULL_EVENT = 0,
8008 + CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
8009 + // (partner's agent may be up)
8010 + CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8011 + // (partner has rebooted)
8012 +} _E_CLUSTER_AIF_EVENT;
8014 +#ifdef AAC_32BIT_ENUMS
8015 +typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
8017 +typedef AAC_UINT32 CLUSTER_AIF_EVENT;
8020 +struct AifEnsClusterEvent {
8021 + CLUSTER_AIF_EVENT eventType;
8024 +struct AifEventNotify {
8025 + AifEventNotifyType type;
8027 + struct AifEnsGeneric EG;
8028 + struct AifEnsDeviceFailure EDF;
8029 + struct AifEnsMirrorFailover EMF;
8030 + struct AifEnsContainerChange ECC;
8031 + struct AifEnsContainerEvent ECE;
8032 + struct AifEnsEnclosureEvent EEE;
8033 + struct AifEnsBatteryEvent EBE;
8034 + struct AifEnsDiskSetEvent EDS;
8036 + struct AifEnsSMARTEvent ES;
8038 + struct AifEnsClusterEvent ECLE;
8043 +// Generic API structure
8045 +#define AIF_API_REPORT_MAX_SIZE 64
8046 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8051 +// For FIB communication, we need all of the following things
8052 +// to send back to the user.
8055 + AifCmdEventNotify = 1, // Notify of event
8056 + AifCmdJobProgress, // Progress report
8057 + AifCmdAPIReport, // Report from other user of API
8058 + AifCmdDriverNotify, // Notify host driver of event
8059 + AifReqJobList = 100, // Gets back complete job list
8060 + AifReqJobsForCtr, // Gets back jobs for specific container
8061 + AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8062 + AifReqJobReport, // Gets back a specific job report or list of them
8063 + AifReqTerminateJob, // Terminates job
8064 + AifReqSuspendJob, // Suspends a job
8065 + AifReqResumeJob, // Resumes a job
8066 + AifReqSendAPIReport, // API generic report requests
8067 + AifReqAPIJobStart, // Start a job from the API
8068 + AifReqAPIJobUpdate, // Update a job report from the API
8069 + AifReqAPIJobFinish // Finish a job from the API
8072 +#ifdef AAC_32BIT_ENUMS
8073 +typedef _E_AIFCOMMAND AIFCOMMAND;
8075 +typedef AAC_UINT32 AIFCOMMAND;
8081 +// Adapter Initiated FIB command structures. Start with the adapter
8082 +// initiated FIBs that really come from the adapter, and get responded
8085 +typedef struct _AIFCOMMANDTOHOST {
8086 + AIFCOMMAND command; // Tell host what type of notify this is
8087 + AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8089 + // First define data going to the adapter
8090 + struct AifEventNotify EN; // Event notify structure
8091 + struct AifJobProgressReport PR[1]; // Progress report
8094 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8097 +#endif // _AIFSTRUC_H
8101 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8102 --- linux-2.4.4/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 18:00:00 1969
8103 +++ linux/drivers/scsi/aacraid/include/build_number.h Mon Apr 30 09:43:34 2001
8106 + * Adaptec aacraid device driver for Linux.
8108 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8110 + * This program is free software; you can redistribute it and/or modify
8111 + * it under the terms of the GNU General Public License as published by
8112 + * the Free Software Foundation; either version 2, or (at your option)
8113 + * any later version.
8115 + * This program is distributed in the hope that it will be useful,
8116 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8117 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8118 + * GNU General Public License for more details.
8120 + * You should have received a copy of the GNU General Public License
8121 + * along with this program; see the file COPYING. If not, write to
8122 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8128 + * DThis module contains the single location where the build number
8134 +#ifndef _BUILD_NUMBER_H
8135 +#define _BUILD_NUMBER_H
8137 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8139 +#define REV_BUILD_NUMBER 3911
8142 +#endif // _BUILD_NUMBER_H
8144 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8145 --- linux-2.4.4/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8146 +++ linux/drivers/scsi/aacraid/include/commdata.h Mon Apr 30 09:43:34 2001
8149 + * Adaptec aacraid device driver for Linux.
8151 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8153 + * This program is free software; you can redistribute it and/or modify
8154 + * it under the terms of the GNU General Public License as published by
8155 + * the Free Software Foundation; either version 2, or (at your option)
8156 + * any later version.
8158 + * This program is distributed in the hope that it will be useful,
8159 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8160 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8161 + * GNU General Public License for more details.
8163 + * You should have received a copy of the GNU General Public License
8164 + * along with this program; see the file COPYING. If not, write to
8165 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8170 + * Abstract: Define the communication layer of the adapter
8178 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8180 +typedef struct _FSA_COMM_DATA {
8183 + // A pointer to the Driver and Device object we were initialized with
8186 + PDRIVER_OBJECT DriverObject;
8187 + PDEVICE_OBJECT DeviceObject;
8190 + // A list of all adapters we have configured.
8193 + PAFA_COMM_ADAPTER AdapterList;
8194 + ULONG TotalAdapters;
8197 + // Adapter timeout support. This is the default timeout to wait for the
8198 + // adapter to respond(setup in initfs.c), and a boolean to indicate if
8199 + // we should timeout requests to the adapter or not.
8202 + LARGE_INTEGER QueueFreeTimeout;
8203 + LARGE_INTEGER AdapterTimeout;
8204 + BOOLEAN EnableAdapterTimeouts;
8206 + ULONG FibTimeoutIncrement;
8210 + ULONG NoResponseSent;
8211 + ULONG NoResponseRecved;
8213 + ULONG AsyncRecved;
8215 + ULONG NormalRecved;
8217 + ULONG TimedOutFibs;
8220 + KTIMER TimeoutTimer;
8223 + // If this value is set to 1 then interrupt moderation will occur
8224 + // in the base commuication support.
8227 + ULONG EnableInterruptModeration;
8229 + int HardInterruptModeration;
8230 + int HardInterruptModeration1;
8231 + int PeakFibsConsumed;
8232 + int ZeroFibsConsumed;
8233 + int EnableFibTimeoutBreak;
8234 + ULONG FibTimeoutSeconds;
8237 + // The following holds all of the available user settable variables.
8238 + // This includes all for the comm layer as well as any from the class
8239 + // drivers as well.
8242 + FSA_USER_VAR *UserVars;
8243 + ULONG NumUserVars;
8248 +#ifdef FIB_CHECKSUMS
8249 + int do_fib_checksums;
8253 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8255 +extern FSA_COMM_DATA FsaCommData;
8258 +#endif // _COMMDATA_
8260 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8261 --- linux-2.4.4/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 18:00:00 1969
8262 +++ linux/drivers/scsi/aacraid/include/commerr.h Mon Apr 30 09:43:34 2001
8265 + * Adaptec aacraid device driver for Linux.
8267 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8269 + * This program is free software; you can redistribute it and/or modify
8270 + * it under the terms of the GNU General Public License as published by
8271 + * the Free Software Foundation; either version 2, or (at your option)
8272 + * any later version.
8274 + * This program is distributed in the hope that it will be useful,
8275 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8276 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8277 + * GNU General Public License for more details.
8279 + * You should have received a copy of the GNU General Public License
8280 + * along with this program; see the file COPYING. If not, write to
8281 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8286 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8295 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8298 +// Note: comments in the .mc file must use both ";" and "//".
8300 +// Status values are 32 bit values layed out as follows:
8302 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8303 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8304 +// +---+-+-------------------------+-------------------------------+
8305 +// |Sev|C| Facility | Code |
8306 +// +---+-+-------------------------+-------------------------------+
8310 +// Sev - is the severity code
8313 +// 01 - Informational
8317 +// C - is the Customer code flag
8319 +// Facility - is the facility code
8321 +// Code - is the facility's status code
8326 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8327 +// called with a device, the name of the device will be inserted into
8328 +// the message at %1. Otherwise, the place of %1 will be left empty.
8329 +// In either case, the insertion strings from the driver's error log
8330 +// entry starts at %2. In other words, the first insertion string goes
8331 +// to %2, the second to %3 and so on.
8335 +// Values are 32 bit values layed out as follows:
8337 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8338 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
8339 +// +---+-+-+-----------------------+-------------------------------+
8340 +// |Sev|C|R| Facility | Code |
8341 +// +---+-+-+-----------------------+-------------------------------+
8345 +// Sev - is the severity code
8348 +// 01 - Informational
8352 +// C - is the Customer code flag
8354 +// R - is a reserved bit
8356 +// Facility - is the facility code
8358 +// Code - is the facility's status code
8361 +// Define the facility codes
8365 +#define FACILITY_FSAFS_ERROR_CODE 0x7
8370 +// MessageId: FSAFS_FIB_INVALID
8374 +// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8376 +#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8380 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8384 +// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8386 +#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8389 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8390 --- linux-2.4.4/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 18:00:00 1969
8391 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Mon Apr 30 09:43:34 2001
8394 + * Adaptec aacraid device driver for Linux.
8396 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8398 + * This program is free software; you can redistribute it and/or modify
8399 + * it under the terms of the GNU General Public License as published by
8400 + * the Free Software Foundation; either version 2, or (at your option)
8401 + * any later version.
8403 + * This program is distributed in the hope that it will be useful,
8404 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8405 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8406 + * GNU General Public License for more details.
8408 + * You should have received a copy of the GNU General Public License
8409 + * along with this program; see the file COPYING. If not, write to
8410 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8413 + * commfibcontext.h
8415 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8420 +#ifndef _COMM_FIB_CONTEXT_
8421 +#define _COMM_FIB_CONTEXT_
8423 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8425 +typedef struct _COMM_FIB_CONTEXT {
8427 + PVOID Next; // this is used by the zone allocation
8430 + // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8432 + // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8433 + // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8437 + NODE_TYPE_CODE NodeTypeCode;
8438 + NODE_BYTE_SIZE NodeByteSize;
8441 + // The Adapter that this I/O is destined for.
8444 + PAFA_COMM_ADAPTER Adapter;
8446 + PHYSICAL_ADDRESS LogicalFibAddress;
8449 + // This is the event the sendfib routine will wait on if the
8450 + // caller did not pass one and this is synch io.
8454 + OS_CVLOCK *FsaEventMutex;
8456 + ULONG FibComplete; // gets set to 1 when fib is complete
8458 + PFIB_CALLBACK FibCallback;
8459 + PVOID FibCallbackContext;
8464 +#ifdef GATHER_FIB_TIMES
8465 + LARGE_INTEGER FibTimeStamp;
8466 + PFIB_TIMES FibTimesPtr;
8470 + // The following is used to put this fib context onto the Outstanding I/O queue.
8473 + LIST_ENTRY QueueEntry;
8476 + // The following is used to timeout a fib to the adapter.
8479 + LARGE_INTEGER TimeoutValue;
8485 +} COMM_FIB_CONTEXT;
8486 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8488 +#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8490 +#endif /* _COMM_FIB_CONTEXT_ */
8491 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8492 --- linux-2.4.4/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8493 +++ linux/drivers/scsi/aacraid/include/comprocs.h Mon Apr 30 09:43:34 2001
8496 + * Adaptec aacraid device driver for Linux.
8498 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8500 + * This program is free software; you can redistribute it and/or modify
8501 + * it under the terms of the GNU General Public License as published by
8502 + * the Free Software Foundation; either version 2, or (at your option)
8503 + * any later version.
8505 + * This program is distributed in the hope that it will be useful,
8506 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8507 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8508 + * GNU General Public License for more details.
8510 + * You should have received a copy of the GNU General Public License
8511 + * along with this program; see the file COPYING. If not, write to
8512 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8517 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8525 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8527 +#include "osheaders.h"
8529 +#include "AacGenericTypes.h"
8531 +#include "aac_unix_defs.h"
8533 +#include "nodetype.h"
8535 +// #define GATHER_FIB_TIMES
8537 +#include "fsatypes.h"
8539 +#include "perfpack.h"
8541 +#include "comstruc.h"
8543 +//#include "unix_protocol.h"
8547 +#include "protocol.h"
8549 +#include "fsaioctl.h"
8551 +#undef GATHER_FIB_TIMES
8553 +#include "aifstruc.h"
8555 +#include "fsaport.h"
8556 +#include "comsup.h"
8557 +#include "afacomm.h"
8558 +#include "adapter.h"
8560 +#include "commfibcontext.h"
8561 +#include "comproto.h"
8562 +#include "commdata.h"
8563 +#include "commerr.h"
8569 +// The following macro is used when sending and receiving FIBs. It is only used for
8573 +#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8575 +#define FIB_COUNTER_INCREMENT(Counter)
8581 +AfaCommAdapterDeviceControl (
8582 + IN PVOID AdapterArg,
8583 + IN PAFA_IOCTL_CMD IoctlCmdPtr
8587 +#endif // _COMPROCS_
8588 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8589 --- linux-2.4.4/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8590 +++ linux/drivers/scsi/aacraid/include/comproto.h Mon Apr 30 09:43:34 2001
8593 + * Adaptec aacraid device driver for Linux.
8595 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8597 + * This program is free software; you can redistribute it and/or modify
8598 + * it under the terms of the GNU General Public License as published by
8599 + * the Free Software Foundation; either version 2, or (at your option)
8600 + * any later version.
8602 + * This program is distributed in the hope that it will be useful,
8603 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8604 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8605 + * GNU General Public License for more details.
8607 + * You should have received a copy of the GNU General Public License
8608 + * along with this program; see the file COPYING. If not, write to
8609 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8614 + * Abstract: Global routines for the commuication interface that are device
8620 +#ifndef _COMM_PROTO
8621 +#define _COMM_PROTO
8623 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8626 +// define the routines we need so we can commuicate with the
8631 +// The following 4 dpc routines will support commuication from the adapter to the
8632 +// host. There is one DPC routine to deal with each type of queue that supports
8633 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8634 +// These routines will simply pull off the QE and set an event. In the case of a
8635 +// adapter to host command they will also put the FIB on a queue to be processed by
8636 +// a FS thread running at passive level.
8639 +// Handle queue not full notification to the file system thread waiting for a queue entry
8643 + IN PCOMM_REGION CommRegion
8646 +// Adapter to host normal priority responses
8649 +HostResponseNormalDpc(
8650 + IN PCOMM_QUE OurQueue
8653 +// Adapter to host high priority responses
8655 +HostResponseHighDpc(
8656 + IN PCOMM_QUE OurQueue
8659 +// Adapter to host high priority commands
8661 +HostCommandHighDpc(
8662 + IN PCOMM_QUE OurQueue
8666 +// Adapter to host normal priority commands
8668 +HostCommandNormDpc(
8669 + IN PCOMM_QUE OurQueue
8677 + FIB_COMMAND Command,
8681 + USHORT *ResponseSize
8691 + IN PFIB_CONTEXT FibContext
8696 + IN PFIB_CONTEXT FibContext
8701 + IN PFIB_CONTEXT FibContext
8708 + IN FIB_COMMAND Command,
8709 + IN PFIB_CONTEXT FibContext,
8711 + IN COMM_PRIORITIES Priority,
8714 + IN BOOLEAN ResponseExpected,
8715 + IN PFIB_CALLBACK FibCallback,
8716 + IN PVOID FibCallbackContext
8721 + IN PFIB_CONTEXT FibContext
8725 +CompleteAdapterFib(
8726 + IN PFIB_CONTEXT FibContext,
8732 + IN PFIB_CONTEXT FibContext
8738 + IN PFIB_CONTEXT FibContext
8744 +AfaCommOpenAdapter (
8745 + IN PVOID AdapterArg
8749 +AfaCommCloseAdapter (
8750 + IN PVOID AdapterArg
8755 +AfaCommInterruptHost(
8757 + ADAPTER_EVENT AdapterEvent
8761 +#endif // _COMM_PROTO
8762 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8763 --- linux-2.4.4/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8764 +++ linux/drivers/scsi/aacraid/include/comstruc.h Mon Apr 30 09:43:34 2001
8767 + * Adaptec aacraid device driver for Linux.
8769 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8771 + * This program is free software; you can redistribute it and/or modify
8772 + * it under the terms of the GNU General Public License as published by
8773 + * the Free Software Foundation; either version 2, or (at your option)
8774 + * any later version.
8776 + * This program is distributed in the hope that it will be useful,
8777 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8778 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8779 + * GNU General Public License for more details.
8781 + * You should have received a copy of the GNU General Public License
8782 + * along with this program; see the file COPYING. If not, write to
8783 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8788 + * Abstract: This module defines the data structures that make up the communication
8789 + * region for the FSA filesystem. This region is how the host based code
8790 + * communicates both control and data to the adapter based code.
8795 +#ifndef _COMM_STRUCT
8796 +#define _COMM_STRUCT
8798 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8801 +// Define all the constants needed for the communication interface
8804 +// Define how many queue entries each queue will have and the total number of
8805 +// entries for the entire communication interface. Also define how many queues
8808 +#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8809 +#define HOST_HIGH_CMD_ENTRIES 4
8810 +#define HOST_NORM_CMD_ENTRIES 8
8811 +#define ADAP_HIGH_CMD_ENTRIES 4
8812 +#define ADAP_NORM_CMD_ENTRIES 512
8813 +#define HOST_HIGH_RESP_ENTRIES 4
8814 +#define HOST_NORM_RESP_ENTRIES 512
8815 +#define ADAP_HIGH_RESP_ENTRIES 4
8816 +#define ADAP_NORM_RESP_ENTRIES 8
8818 +#define TOTAL_QUEUE_ENTRIES \
8819 + (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8820 + HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8825 +// Set the queues on a 16 byte alignment
8826 +#define QUEUE_ALIGNMENT 16
8830 +// The queue headers define the Communication Region queues. These
8831 +// are physically contiguous and accessible by both the adapter and the
8832 +// host. Even though all queue headers are in the same contiguous block they will be
8833 +// represented as individual units in the data structures.
8836 +typedef AAC_UINT32 QUEUE_INDEX;
8838 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8840 +typedef struct _QUEUE_ENTRY {
8842 + AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8843 + AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8847 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8851 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8852 +// adjacently and in that order.
8854 +typedef struct _QUEUE_HEADERS {
8856 + PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8857 + PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8858 + PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8861 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8864 +// Define all the events which the adapter would like to notify
8867 +typedef enum _ADAPTER_EVENT {
8868 + HostNormCmdQue = 1, // Change in host normal priority command queue
8869 + HostHighCmdQue, // Change in host high priority command queue
8870 + HostNormRespQue, // Change in host normal priority response queue
8871 + HostHighRespQue, // Change in host high priority response queue
8872 + AdapNormRespNotFull,
8873 + AdapHighRespNotFull,
8874 + AdapNormCmdNotFull,
8875 + AdapHighCmdNotFull,
8876 + SynchCommandComplete,
8877 + AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8879 +} _E_ADAPTER_EVENT;
8881 +#ifdef AAC_32BIT_ENUMS
8882 +typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8884 +typedef AAC_UINT32 ADAPTER_EVENT;
8888 +// Define all the events the host wishes to notify the
8891 +typedef enum _HOST_2_ADAP_EVENT {
8892 + AdapNormCmdQue = 1,
8899 + HostNormRespNotFull,
8900 + HostHighRespNotFull,
8901 + HostNormCmdNotFull,
8902 + HostHighCmdNotFull,
8905 +} _E_HOST_2_ADAP_EVENT;
8907 +#ifdef AAC_32BIT_ENUMS
8908 +typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8910 +typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8914 +// Define all the queues that the adapter and host use to communicate
8917 +typedef enum _QUEUE_TYPES {
8918 + HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8919 + HostHighCmdQueue, // Adapter to host high priority command traffic
8920 + AdapNormRespQueue, // Host to adapter normal priority response traffic
8921 + AdapHighRespQueue, // Host to adapter high priority response traffic
8922 + AdapNormCmdQueue, // Host to adapter normal priority command traffic
8923 + AdapHighCmdQueue, // Host to adapter high priority command traffic
8924 + HostNormRespQueue, // Adapter to host normal priority response traffic
8925 + HostHighRespQueue // Adapter to host high priority response traffic
8928 +#ifdef AAC_32BIT_ENUMS
8929 +typedef _E_QUEUE_TYPES QUEUE_TYPES;
8931 +typedef AAC_UINT32 QUEUE_TYPES;
8936 +// Assign type values to the FSA communication data structures
8939 +typedef enum _STRUCT_TYPES {
8945 +#ifdef AAC_32BIT_ENUMS
8946 +typedef _E_STRUCT_TYPES STRUCT_TYPES;
8948 +typedef AAC_UINT32 STRUCT_TYPES;
8952 +// Define the priority levels the FSA communication routines support.
8955 +typedef enum _COMM_PRIORITIES {
8958 +} _E_COMM_PRIORITIES;
8960 +#ifdef AAC_32BIT_ENUMS
8961 +typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
8963 +typedef AAC_UINT32 COMM_PRIORITIES;
8969 +// Define the LIST_ENTRY structure. This structure is used on the NT side to link
8970 +// the FIBs together in a linked list. Since this structure gets compiled on the adapter
8971 +// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
8972 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
8973 +// is already defined.
8974 +#if !defined(_NTDEF_) && !defined(_WINNT_)
8975 +typedef struct _LIST_ENTRY {
8976 + struct _LIST_ENTRY *Flink;
8977 + struct _LIST_ENTRY *Blink;
8979 +typedef LIST_ENTRY *PLIST_ENTRY;
8984 +// Define the FIB. The FIB is the where all the requested data and
8985 +// command information are put to the application on the FSA adapter.
8988 +typedef struct _FIB_HEADER {
8989 + AAC_UINT32 XferState; // Current transfer state for this CCB
8990 + AAC_UINT16 Command; // Routing information for the destination
8991 + AAC_UINT8 StructType; // Type FIB
8992 + AAC_UINT8 Flags; // Flags for FIB
8993 + AAC_UINT16 Size; // Size of this FIB in bytes
8994 + AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
8995 + AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
8996 + AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
8997 + AAC_UINT32 SenderData; // Place holder for the sender to store data
9001 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9002 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9004 + LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
9006 +#else // The MIDL compiler does not support unions without a discriminant.
9007 + struct { // Since nothing during the midl compile actually looks into this
9008 + struct { // structure, this shoudl be ok.
9009 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9010 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9017 +#define FibLinks _u._FibLinks
9020 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9023 +typedef struct _FIB {
9025 +#ifdef BRIDGE //rma
9028 + FIB_HEADER Header;
9030 + AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
9041 +typedef enum _FIB_COMMANDS {
9042 + TestCommandResponse = 1,
9043 + TestAdapterCommand = 2,
9045 + // Lowlevel and comm commands
9047 + LastTestCommand = 100,
9048 + ReinitHostNormCommandQueue = 101,
9049 + ReinitHostHighCommandQueue = 102,
9050 + ReinitHostHighRespQueue = 103,
9051 + ReinitHostNormRespQueue = 104,
9052 + ReinitAdapNormCommandQueue = 105,
9053 + ReinitAdapHighCommandQueue = 107,
9054 + ReinitAdapHighRespQueue = 108,
9055 + ReinitAdapNormRespQueue = 109,
9056 + InterfaceShutdown = 110,
9057 + DmaCommandFib = 120,
9058 + StartProfile = 121,
9059 + TermProfile = 122,
9061 + TakeABreakPt = 124,
9062 + RequestPerfData = 125,
9063 + SetInterruptDefTimer= 126,
9064 + SetInterruptDefCount= 127,
9065 + GetInterruptDefStatus= 128,
9066 + LastCommCommand = 129,
9068 + // Filesystem commands
9070 + NuFileSystem = 300,
9072 + HostFileSystem = 302,
9073 + LastFileSystemCommand = 303,
9075 + // Container Commands
9077 + ContainerCommand = 500,
9078 + ContainerCommand64 = 501,
9080 + // Cluster Commands
9082 + ClusterCommand = 550,
9084 + // Scsi Port commands (scsi passthrough)
9086 + ScsiPortCommand = 600,
9088 + // misc house keeping and generic adapter initiated commands
9091 + CheckRevision = 701,
9092 + FsaHostShutdown = 702,
9093 + RequestAdapterInfo = 703,
9094 + IsAdapterPaused = 704,
9095 + SendHostTime = 705,
9096 + LastMiscCommand = 706
9102 +typedef AAC_UINT16 FIB_COMMAND;
9105 +// Commands that will target the failover level on the FSA adapter
9108 +typedef enum _FIB_XFER_STATE {
9109 + HostOwned = (1<<0),
9110 + AdapterOwned = (1<<1),
9111 + FibInitialized = (1<<2),
9112 + FibEmpty = (1<<3),
9113 + AllocatedFromPool = (1<<4),
9114 + SentFromHost = (1<<5),
9115 + SentFromAdapter = (1<<6),
9116 + ResponseExpected = (1<<7),
9117 + NoResponseExpected = (1<<8),
9118 + AdapterProcessed = (1<<9),
9119 + HostProcessed = (1<<10),
9120 + HighPriority = (1<<11),
9121 + NormalPriority = (1<<12),
9123 + AsyncIo = (1<<13), // rpbfix: remove with new regime
9124 + PageFileIo = (1<<14), // rpbfix: remove with new regime
9125 + ShutdownRequest = (1<<15),
9126 + LazyWrite = (1<<16), // rpbfix: remove with new regime
9127 + AdapterMicroFib = (1<<17),
9128 + BIOSFibPath = (1<<18),
9129 + FastResponseCapable = (1<<19),
9130 + ApiFib = (1<<20) // Its an API Fib.
9132 +} _E_FIB_XFER_STATE;
9135 +typedef enum _FSA_ERRORS {
9138 + FSA_PENDING = 0x01,
9140 + FSA_INVALID_QUEUE = 0x03,
9141 + FSA_NOENTRIES = 0x04,
9142 + FSA_SENDFAILED = 0x05,
9143 + FSA_INVALID_QUEUE_PRIORITY = 0x06,
9144 + FSA_FIB_ALLOCATION_FAILED = 0x07,
9145 + FSA_FIB_DEALLOCATION_FAILED = 0x08
9151 +// The following defines needs to be updated any time there is an incompatible change made
9152 +// to the ADAPTER_INIT_STRUCT structure.
9154 +#define ADAPTER_INIT_STRUCT_REVISION 3
9156 +typedef struct _ADAPTER_INIT_STRUCT {
9157 + AAC_UINT32 InitStructRevision;
9158 + AAC_UINT32 MiniPortRevision;
9159 + AAC_UINT32 FilesystemRevision;
9160 + PAAC_VOID CommHeaderAddress;
9161 + PAAC_VOID FastIoCommAreaAddress;
9162 + PAAC_VOID AdapterFibsPhysicalAddress;
9163 + PAAC_VOID AdapterFibsVirtualAddress;
9164 + AAC_UINT32 AdapterFibsSize;
9165 + AAC_UINT32 AdapterFibAlign;
9166 + PAAC_VOID PrintfBufferAddress;
9167 + AAC_UINT32 PrintfBufferSize;
9168 + AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9169 + AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9170 +} ADAPTER_INIT_STRUCT;
9171 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9173 +#ifdef AAC_32BIT_ENUMS
9174 +typedef _E_FSA_ERRORS FSA_ERRORS;
9176 +typedef AAC_UINT32 FSA_ERRORS;
9179 +typedef enum _LOG_LEVEL {
9181 + LOG_INFORMATIONAL = 20,
9183 + LOG_LOW_ERROR = 40,
9184 + LOG_MEDIUM_ERROR = 50,
9185 + LOG_HIGH_ERROR = 60,
9188 + LOG_WINDBG_PRINT = 90
9191 +#ifdef AAC_32BIT_ENUMS
9192 +typedef _E_LOG_LEVEL LOG_LEVEL;
9194 +typedef AAC_UINT32 LOG_LEVEL;
9198 +#endif //_COMM_STRUCT
9201 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9202 --- linux-2.4.4/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 18:00:00 1969
9203 +++ linux/drivers/scsi/aacraid/include/comsup.h Mon Apr 30 09:43:34 2001
9206 + * Adaptec aacraid device driver for Linux.
9208 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9210 + * This program is free software; you can redistribute it and/or modify
9211 + * it under the terms of the GNU General Public License as published by
9212 + * the Free Software Foundation; either version 2, or (at your option)
9213 + * any later version.
9215 + * This program is distributed in the hope that it will be useful,
9216 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9217 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9218 + * GNU General Public License for more details.
9220 + * You should have received a copy of the GNU General Public License
9221 + * along with this program; see the file COPYING. If not, write to
9222 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9227 + * Abstract: This module defines the data structures that make up the
9228 + * commuication region for the FSA filesystem. This region is
9229 + * how the host based code commuicates both control and data
9230 + * to the adapter based code.
9235 +#ifndef _COMM_SUP_DEF
9236 +#define _COMM_SUP_DEF
9238 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9241 +// The adapter interface specs all queues to be located in the same physically
9242 +// contigous block. The host structure that defines the commuication queues will
9243 +// assume they are each a seperate physically contigous memory region that will
9244 +// support them all being one big contigous block.
9245 +// There is a command and response queue for each level and direction of
9246 +// commuication. These regions are accessed by both the host and adapter.
9248 +typedef struct _COMM_QUE {
9250 + PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9252 + PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9253 + QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9254 + ULONG QueueEntries; // Number of queue entries on this queue
9255 + OS_CV_T QueueFull; // Event to wait on if the queue is full
9256 + OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9257 + // This is only valid for adapter to host command queues.
9258 + OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9259 + KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9260 + ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9261 + // Only queues which the host will be the consumer will this field be valid
9262 + LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9263 + // only valid for command queues which receive entries from the adapter.
9264 + LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9265 + ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9267 + PVOID Adapter; // Back pointer to adapter structure
9270 +typedef COMM_QUE *PCOMM_QUE;
9273 +typedef struct _COMM_REGION {
9275 + COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9276 + COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9278 + COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9279 + COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9281 + COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9282 + COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9284 + COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9285 + COMM_QUE AdapHighRespQue; // A response for high priority host responses
9288 + // The 2 threads below are the threads which handle command traffic from the
9289 + // the adapter. There is one for normal priority and one for high priority queues.
9290 + // These threads will wait on the commandready event for it's queue.
9293 + HANDLE NormCommandThread;
9294 + HANDLE HighCommandThread;
9297 + // This dpc routine will handle the setting the of not full event when the adapter
9298 + // lets us know the queue is not longer full via interrupt
9301 + KDPC QueueNotFullDpc;
9303 +#ifdef API_THROTTLE
9305 + // Support for data I/O throttling to improve CLI performance
9306 + // while the system is under load.
9307 + // This is the throttling mechanism built into the COMM layer.
9308 + // Look in commsup.c, dpcsup.c and comminit.c for use.
9311 + int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9312 + int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9313 + LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9314 + LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9315 + BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9316 + KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9317 + KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9318 + KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9320 + unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9321 + unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9322 + unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9324 + unsigned int ThrottledFibs;
9325 + unsigned int ThrottleTimedoutFibs;
9326 + unsigned int ApiFibs;
9327 + unsigned int NonPassiveFibs;
9328 + unsigned int TotalFibs;
9329 + unsigned int FSInfoFibs;
9331 +#endif // #ifdef API_THROTTLE
9334 +typedef COMM_REGION *PCOMM_REGION;
9336 +#endif // _COMM_SUP
9337 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9338 --- linux-2.4.4/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 18:00:00 1969
9339 +++ linux/drivers/scsi/aacraid/include/fsact.h Mon Apr 30 09:43:34 2001
9342 + * Adaptec aacraid device driver for Linux.
9344 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9346 + * This program is free software; you can redistribute it and/or modify
9347 + * it under the terms of the GNU General Public License as published by
9348 + * the Free Software Foundation; either version 2, or (at your option)
9349 + * any later version.
9351 + * This program is distributed in the hope that it will be useful,
9352 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9353 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9354 + * GNU General Public License for more details.
9356 + * You should have received a copy of the GNU General Public License
9357 + * along with this program; see the file COPYING. If not, write to
9358 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9363 + * Abstract: Common container structures that are required to be
9364 + * known on both the host and adapter.
9371 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9373 +//#include <comstruc.h>
9374 +//#include <fsatypes.h>
9375 +#include <protocol.h> // definitions for FSASTATUS
9379 + * Object-Server / Volume-Manager Dispatch Classes
9381 +typedef enum _VM_COMMANDS {
9384 + VM_ContainerConfig,
9386 + VM_FilesystemIoctl,
9388 + VM_CtBlockRead, // see protocol.h for BlockRead command layout
9389 + VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9390 + VM_SliceBlockRead, // raw access to configured "storage objects"
9391 + VM_SliceBlockWrite,
9392 + VM_DriveBlockRead, // raw access to physical devices
9393 + VM_DriveBlockWrite,
9394 + VM_EnclosureMgt, // enclosure management
9395 + VM_Unused, // used to be diskset management
9396 + VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9397 + VM_CtPerf, // performance test
9398 + VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9399 + VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9400 + VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9401 + MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9404 +#ifdef AAC_32BIT_ENUMS
9405 +typedef _E_VMCOMMAND VMCOMMAND;
9407 +typedef AAC_UINT32 VMCOMMAND;
9413 +// Descriptive information (eg, vital stats)
9414 +// that a content manager might report. The
9415 +// FileArray filesystem component is one example
9416 +// of a content manager. Raw mode might be
9420 +struct FileSysInfo {
9422 + a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9423 + b) FSA usage (implemented by ObjType and ContentState fields)
9426 + e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9427 + f) I-node density - (computed from other fields)
9429 + AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9430 + AAC_UINT32 fsBlockSize;
9431 + AAC_UINT32 fsFragSize;
9432 + AAC_UINT32 fsMaxExtendSize;
9433 + AAC_UINT32 fsSpaceUnits;
9434 + AAC_UINT32 fsMaxNumFiles;
9435 + AAC_UINT32 fsNumFreeFiles;
9436 + AAC_UINT32 fsInodeDensity;
9437 +}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9439 +union ContentManagerInfo {
9440 + struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9444 +// Query for "mountable" objects, ie, objects that are typically
9445 +// associated with a drive letter on the client (host) side.
9448 +typedef struct _MNTOBJ {
9450 + AAC_UINT32 ObjectId;
9451 + FSASTRING FileSystemName; // if applicable
9452 + ContainerCreationInfo CreateInfo; // if applicable
9453 + AAC_UINT32 Capacity;
9454 + FSAVOLTYPE VolType; // substrate structure
9455 + FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9456 + AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9458 + union ContentManagerInfo
9459 + ObjExtension; // Info specific to content manager (eg, filesystem)
9461 + AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9466 +#define FSCS_READONLY 0x0002 // possible result of broken mirror
9470 +typedef struct _MNTINFO {
9472 + VMCOMMAND Command;
9474 + AAC_UINT32 MntCount;
9477 +typedef MNTINFO *PMNTINFO;
9479 +typedef struct _MNTINFORESPONSE {
9482 + FTYPE MntType; // should be same as that requested
9483 + AAC_UINT32 MntRespCount;
9484 + MNTOBJ MntTable[1];
9487 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9491 +// The following command is sent to shut down each container.
9494 +typedef struct _CLOSECOMMAND {
9496 + VMCOMMAND Command;
9497 + AAC_UINT32 ContainerId;
9500 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9503 +#endif /* _FSACT_H_ */
9506 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9507 --- linux-2.4.4/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 18:00:00 1969
9508 +++ linux/drivers/scsi/aacraid/include/fsafs.h Mon Apr 30 09:43:34 2001
9511 + * Adaptec aacraid device driver for Linux.
9513 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9515 + * This program is free software; you can redistribute it and/or modify
9516 + * it under the terms of the GNU General Public License as published by
9517 + * the Free Software Foundation; either version 2, or (at your option)
9518 + * any later version.
9520 + * This program is distributed in the hope that it will be useful,
9521 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9522 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9523 + * GNU General Public License for more details.
9525 + * You should have received a copy of the GNU General Public License
9526 + * along with this program; see the file COPYING. If not, write to
9527 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9532 + * Abstract: Common file system structures that are required to be
9533 + * known on both the host and adapter
9540 +#define _FSAFS_H_ 1
9542 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9544 +#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9547 + * Maximum number of filesystems.
9549 +#define NFILESYS 24
9552 + * File identifier.
9553 + * These are unique and self validating within a filesystem
9554 + * on a single machine and can persist across reboots.
9555 + * The hint field may be volatile and is not guaranteed to persist
9556 + * across reboots but is used to speed up the FID to file object translation
9557 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9558 + * the file object (assuming a filesystem context, i.e. driveno).
9561 + AAC_UINT32 hint; // last used hint for fast reclaim
9562 + AAC_UINT32 f1; // opaque
9563 + AAC_UINT32 f2; // opaque
9564 + } fileid_t; /* intra-filesystem file ID type */
9568 + * Generic file handle
9571 + fsid_t fh_fsid; /* File system id of mount point */
9572 + fileid_t fh_fid; /* File sys specific file id */
9574 +typedef struct fhandle fhandle_t;
9576 +#define FIDSIZE sizeof(fhandle_t)
9580 + AAC_INT8 fid_data[FIDSIZE];
9581 + struct fhandle fsafid;
9583 +} FSAFID; /* FSA File ID type */
9586 +#endif /* _FSAFS_H_ */
9588 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9589 --- linux-2.4.4/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9590 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h Mon Apr 30 09:43:34 2001
9593 + * Adaptec aacraid device driver for Linux.
9595 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9597 + * This program is free software; you can redistribute it and/or modify
9598 + * it under the terms of the GNU General Public License as published by
9599 + * the Free Software Foundation; either version 2, or (at your option)
9600 + * any later version.
9602 + * This program is distributed in the hope that it will be useful,
9603 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9604 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9605 + * GNU General Public License for more details.
9607 + * You should have received a copy of the GNU General Public License
9608 + * along with this program; see the file COPYING. If not, write to
9609 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9614 + * Abstract: Defines the interface structures between user mode applications
9615 + * and the fsa driver. This structures are used in
9616 + * DeviceIoControl() calls.
9621 +#ifndef _FSAIOCTL_H_
9622 +#define _FSAIOCTL_H_
9624 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9626 +#ifndef IOTRACEUSER
9631 +#define FILE_DEVICE_CONTROLLER 0x00000004
9634 +// Macro definition for defining IOCTL and FSCTL function control codes. Note
9635 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9636 +// 2048-4095 are reserved for customers.
9639 +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9640 + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9644 +// Define the method codes for how buffers are passed for I/O and FS controls
9647 +#define METHOD_BUFFERED 0
9650 +#define METHOD_NEITHER 3
9653 +// Define the access check value for any access
9656 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9657 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9658 +// constants *MUST* always be in sync.
9660 +#define FILE_ANY_ACCESS 0
9668 +typedef struct _UNIX_QUERY_DISK {
9669 + AAC_INT32 ContainerNumber;
9673 + AAC_BOOLEAN Valid;
9674 + AAC_BOOLEAN Locked;
9675 + AAC_BOOLEAN Deleted;
9676 + AAC_INT32 Instance;
9677 + AAC_INT8 diskDeviceName[10];
9678 + AAC_BOOLEAN UnMapped;
9680 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9683 +typedef struct _DELETE_DISK {
9684 + AAC_UINT32 NtDiskNumber;
9685 + AAC_UINT32 ContainerNumber;
9687 +typedef DELETE_DISK *PDELETE_DISK;
9690 +#endif /*IOTRACEUSER*/
9692 +#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9693 +#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9696 +#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9699 +#define FSACTL_GET_VAR 0x93
9700 +#define FSACTL_SET_VAR 0xa3
9701 +#define FSACTL_GET_FIBTIMES 0xb3
9702 +#define FSACTL_ZERO_FIBTIMES 0xc3
9705 +#define FSACTL_DELETE_DISK 0x163
9706 +#define FSACTL_QUERY_DISK 0x173
9709 +// AfaComm perfmon ioctls
9710 +#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9713 +#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9716 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9717 + char *AdapterFibContext;
9720 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9723 +// filesystem ioctls
9725 +#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9727 +#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9729 +#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9731 +#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9733 +#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9736 +#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9739 +#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9742 +#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9745 +#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9748 +#endif // _FSAIOCTL_H_
9751 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9752 --- linux-2.4.4/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 18:00:00 1969
9753 +++ linux/drivers/scsi/aacraid/include/fsaport.h Mon Apr 30 09:43:34 2001
9756 + * Adaptec aacraid device driver for Linux.
9758 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9760 + * This program is free software; you can redistribute it and/or modify
9761 + * it under the terms of the GNU General Public License as published by
9762 + * the Free Software Foundation; either version 2, or (at your option)
9763 + * any later version.
9765 + * This program is distributed in the hope that it will be useful,
9766 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9767 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9768 + * GNU General Public License for more details.
9770 + * You should have received a copy of the GNU General Public License
9771 + * along with this program; see the file COPYING. If not, write to
9772 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9777 + * Abstract: This module defines all of the globally used procedures in the FSA
9786 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9789 +// The scatter/gather map context is the information we
9790 +// we need to keep the map and transfer data to and from the
9794 +typedef struct _SGMAP_CONTEXT {
9796 + caddr_t BaseAddress;
9798 + ULONG NumberMapRegs;
9800 + ULONG ByteCount; // Used to check the Mdl length.
9801 + BOOLEAN WriteToDevice;
9807 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9809 +typedef struct _MAPFIB_CONTEXT {
9812 + ULONG NumberMapRegs;
9813 + PVOID FibVirtualAddress;
9815 + PVOID FibPhysicalAddress;
9819 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9822 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9823 + PVOID AdapterExtension,
9824 + IN OUT PVOID *BaseAddress,
9826 + IN ULONG Alignment
9830 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9831 + PVOID AdapterExtension
9835 +(*PFSA_FREE_DMA_RESOURCES)(
9836 + IN PVOID AdapterExtension,
9837 + IN PSGMAP_CONTEXT SgMapContext
9841 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9842 + IN PVOID AdapterExtension,
9843 + IN PMAPFIB_CONTEXT MapFibContext
9847 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9848 + IN PVOID AdapterExtension,
9849 + IN PMAPFIB_CONTEXT MapFibContext
9853 +(*PFSA_INTERRUPT_ADAPTER)(
9854 + IN PVOID AdapterExtension
9858 +(*PFSA_NOTIFY_ADAPTER)(
9859 + IN PVOID AdapterExtension,
9860 + IN HOST_2_ADAP_EVENT AdapterEvent
9864 +(*PFSA_RESET_DEVICE)(
9865 + PVOID AdapterExtension
9869 +(*PFSA_BUILD_SGMAP)(
9870 + IN PVOID AdapterExtension,
9871 + IN PSGMAP_CONTEXT SgMapContext
9875 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9876 + IN PVOID AdapterExtension,
9877 + IN PVOID AdapterAddress
9881 +(*PFSA_INTERRUPT_HOST)(
9883 + ADAPTER_EVENT AdapterEvent
9887 +(*PFSA_ENABLE_INTERRUPT)(
9889 + ADAPTER_EVENT AdapterEvent,
9890 + BOOLEAN AtDeviceIrq
9895 +(*PFSA_DISABLE_INTERRUPT)(
9897 + ADAPTER_EVENT AdapterEvent,
9898 + BOOLEAN AtDeviceIrq
9902 +(*PFSA_OPEN_ADAPTER) (
9907 +(*PFSA_DEVICE_CONTROL) (
9909 + IN PAFA_IOCTL_CMD IoctlCmdPtr
9913 +(*PFSA_CLOSE_ADAPTER) (
9918 +(*PFSA_SEND_SYNCH_FIB) (
9920 + IN ULONG FibPhysicalAddress
9923 +typedef struct _FSAPORT_FUNCS {
9924 + ULONG SizeOfFsaPortFuncs;
9926 + PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9927 + PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9928 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9929 + PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9930 + PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9931 + PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9932 + PFSA_NOTIFY_ADAPTER NotifyAdapter;
9933 + PFSA_ENABLE_INTERRUPT EnableInterrupt;
9934 + PFSA_DISABLE_INTERRUPT DisableInterrupt;
9935 + PFSA_RESET_DEVICE ResetDevice;
9936 + PFSA_BUILD_SGMAP BuildSgMap;
9937 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9939 + PFSA_INTERRUPT_HOST InterruptHost;
9940 + PFSA_OPEN_ADAPTER OpenAdapter;
9941 + PFSA_DEVICE_CONTROL DeviceControl;
9942 + PFSA_CLOSE_ADAPTER CloseAdapter;
9944 + PFSA_SEND_SYNCH_FIB SendSynchFib;
9947 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9950 +(*PFSA_SETVAR_CALLBACK) (
9955 +typedef struct _FSA_USER_VAR {
9958 + PFSA_SETVAR_CALLBACK SetVarCallback;
9961 +typedef FSA_USER_VAR *PFSA_USER_VAR;
9963 +typedef struct _FSA_NEW_ADAPTER {
9964 + PVOID AdapterExtension;
9965 + PFSAPORT_FUNCS AdapterFuncs;
9967 + BOOLEAN AdapterInterruptsBelowDpc;
9968 + PFSA_USER_VAR AdapterUserVars;
9969 + ULONG AdapterUserVarsSize;
9972 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
9974 +#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9975 +#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9978 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
9979 --- linux-2.4.4/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
9980 +++ linux/drivers/scsi/aacraid/include/fsatypes.h Mon Apr 30 09:43:34 2001
9983 + * Adaptec aacraid device driver for Linux.
9985 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9987 + * This program is free software; you can redistribute it and/or modify
9988 + * it under the terms of the GNU General Public License as published by
9989 + * the Free Software Foundation; either version 2, or (at your option)
9990 + * any later version.
9992 + * This program is distributed in the hope that it will be useful,
9993 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9994 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9995 + * GNU General Public License for more details.
9997 + * You should have received a copy of the GNU General Public License
9998 + * along with this program; see the file COPYING. If not, write to
9999 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10004 + * Abstract: Define all shared data types here, ie, those
10005 + * types shared among several components, such
10006 + * as host (driver + apps), adapter, and BIOS.
10010 +#ifndef _FSATYPES_H
10011 +#define _FSATYPES_H
10013 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10015 +typedef AAC_UINT32 AAC_BOOLEAN;
10018 +// Define a 64-bit address structure for use on
10019 +// a 32-bit processor architecture.
10024 +} AAC_UINT64S, *PAAC_UINT64S;
10029 +// Container Types
10032 + AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
10033 + // know what it looks like. Note, BIOS sees this
10034 + // definition and it must be coded in such a way
10035 + // that it appears to be 64 bits. ints are 16 bits
10036 + // in BIOS land; fortunately, longs are 32 bits.
10042 +// ***********************
10043 +// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10044 +// ***********************
10045 +// drivers for CT_NONE to CT_PASSTHRU
10047 +typedef enum _FSAVOLTYPE {
10058 + CT_RAID10, // stripe of mirror
10059 + CT_RAID00, // stripe of stripe
10060 + CT_VOLUME_OF_MIRRORS, // volume of mirror
10061 + CT_PSEUDO_RAID3, // really raid4
10063 + CT_LAST_VOLUME_TYPE
10067 +#ifdef AAC_32BIT_ENUMS
10068 +typedef _E_FSAVOLTYPE FSAVOLTYPE;
10070 +typedef AAC_UINT32 FSAVOLTYPE;
10075 +// Types of objects addressable in some fashion by the client.
10076 +// This is a superset of those objects handled just by the filesystem
10077 +// and includes "raw" objects that an administrator would use to
10078 +// configure containers and filesystems.
10080 +typedef enum _FTYPE {
10081 + FT_REG = 1, // regular file
10082 + FT_DIR, // directory
10083 + FT_BLK, // "block" device - reserved
10084 + FT_CHR, // "character special" device - reserved
10085 + FT_LNK, // symbolic link
10086 + FT_SOCK, // socket
10088 + FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10089 + FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10090 + FT_SLICE, // virtual disk - raw volume - slice
10091 + FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10092 + FT_VOLUME, // Container - Volume Set
10093 + FT_STRIPE, // Container - Stripe Set
10094 + FT_MIRROR, // Container - Mirror Set
10095 + FT_RAID5, // Container - Raid 5 Set
10096 + FT_DATABASE // Storage object with "foreign" content manager
10099 +#ifdef AAC_32BIT_ENUMS
10100 +typedef _E_FTYPE FTYPE;
10102 +typedef AAC_UINT32 FTYPE;
10108 +// Host side memory scatter gather list
10109 +// Used by the adapter for read, write, and readdirplus operations
10111 +typedef PAAC_UINT8 HOSTADDRESS;
10113 +typedef struct _SGENTRY {
10114 + HOSTADDRESS SgAddress; /* 32-bit Base address. */
10115 + AAC_UINT32 SgByteCount; /* Length. */
10117 +typedef SGENTRY *PSGENTRY;
10124 +// This is the SGMAP structure for all commands that use
10125 +// 32-bit addressing.
10127 +// Note that the upper 16 bits of SgCount are used as flags.
10128 +// Only the lower 16 bits of SgCount are actually used as the
10129 +// SG element count.
10131 +typedef struct _SGMAP {
10132 + AAC_UINT32 SgCount;
10133 + SGENTRY SgEntry[1];
10135 +typedef SGMAP *PSGMAP;
10142 +// This is the SGMAP structure for 64-bit container commands.
10144 +typedef struct _SGMAP64 {
10145 + AAC_UINT8 SgCount;
10146 + AAC_UINT8 SgSectorsPerPage;
10147 + AAC_UINT16 SgByteOffset; // For the first page
10148 + AAC_UINT64S SgEntry[1]; // Must be last entry
10150 +typedef SGMAP64 *PSGMAP64;
10156 +// attempt at common time structure across host and adapter
10158 +typedef struct __TIME_T {
10160 + AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10161 + AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10164 +typedef TIME_T *PTIME_T;
10167 +#define timespec __TIME_T
10168 +#define ts_sec tv_sec
10169 +#define ts_nsec tv_usec
10175 +typedef struct _ContainerCreationInfo
10178 + AAC_UINT8 ViaBuildNumber; // e.g., 588
10179 + AAC_UINT8 MicroSecond; // e.g., 588
10180 + AAC_UINT8 Via; // e.g., 1 = FSU,
10182 + AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10183 + AAC_UINT32 Date; //
10184 + // unsigned Month :4; // 1 - 12
10185 + // unsigned Day :6; // 1 - 32
10186 + // unsigned Hour :6; // 0 - 23
10187 + // unsigned Minute :6; // 0 - 60
10188 + // unsigned Second :6; // 0 - 60
10189 + SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10190 +} ContainerCreationInfo;
10193 +#endif // _FSATYPES_H
10196 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10197 --- linux-2.4.4/drivers/scsi/aacraid/include/linit.h Wed Dec 31 18:00:00 1969
10198 +++ linux/drivers/scsi/aacraid/include/linit.h Mon Apr 30 09:43:34 2001
10201 + * Adaptec aacraid device driver for Linux.
10203 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10205 + * This program is free software; you can redistribute it and/or modify
10206 + * it under the terms of the GNU General Public License as published by
10207 + * the Free Software Foundation; either version 2, or (at your option)
10208 + * any later version.
10210 + * This program is distributed in the hope that it will be useful,
10211 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10212 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10213 + * GNU General Public License for more details.
10215 + * You should have received a copy of the GNU General Public License
10216 + * along with this program; see the file COPYING. If not, write to
10217 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10222 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10225 +/*------------------------------------------------------------------------------
10226 + * I N C L U D E S
10227 + *----------------------------------------------------------------------------*/
10232 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10234 +#include <linux/config.h>
10236 +/*------------------------------------------------------------------------------
10238 + *----------------------------------------------------------------------------*/
10239 +/* Define the AAC SCSI Host Template structure. */
10240 +#define AAC_HOST_TEMPLATE_ENTRY \
10241 + { name: "AAC", /* Driver Name */ \
10242 + proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10243 + detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10244 + release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10245 + info: AAC_DriverInfo, /* Driver Info Function */ \
10246 + ioctl: AAC_Ioctl, /* ioctl Interface */ \
10247 + command: AAC_Command, /* unqueued command */ \
10248 + queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10249 + abort: AAC_AbortCommand, /* Abort Command Function */ \
10250 + reset: AAC_ResetCommand, /* Reset Command Function */ \
10251 + bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10252 + can_queue: 1, /* Default initial value */ \
10253 + this_id: 0, /* Default initial value */ \
10254 + sg_tablesize: 0, /* Default initial value */ \
10255 + max_sectors: 128, /* max xfer size of 64k */ \
10256 + cmd_per_lun: 0, /* Default initial value */ \
10257 + present: 0, /* Default initial value */ \
10258 + unchecked_isa_dma: 0, /* Default Initial Value */ \
10259 + use_new_eh_code: 0, /* Default initial value */ \
10260 + eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10261 + eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10262 + eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10263 + eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10264 + eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10265 + use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10269 +/*------------------------------------------------------------------------------
10270 + * T Y P E D E F S / S T R U C T S
10271 + *----------------------------------------------------------------------------*/
10272 +typedef struct AAC_BIOS_DiskParameters
10277 +} AAC_BIOS_DiskParameters_T;
10280 +/*------------------------------------------------------------------------------
10281 + * P R O G R A M G L O B A L S
10282 + *----------------------------------------------------------------------------*/
10284 +const char *AAC_DriverInfo( struct Scsi_Host * );
10287 +/*------------------------------------------------------------------------------
10288 + * F U N C T I O N P R O T O T Y P E S
10289 + *----------------------------------------------------------------------------*/
10290 +/* Define prototypes for the AAC Driver Interface Functions. */
10291 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10292 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10293 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10294 +int AAC_Command( Scsi_Cmnd * );
10295 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10296 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10297 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10298 +int AAC_Ioctl( Scsi_Device *, int, void * );
10301 +void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10304 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10306 +#endif /* _LINIT_H_ */
10307 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10308 --- linux-2.4.4/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 18:00:00 1969
10309 +++ linux/drivers/scsi/aacraid/include/monkerapi.h Mon Apr 30 09:43:34 2001
10312 + * Adaptec aacraid device driver for Linux.
10314 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10316 + * This program is free software; you can redistribute it and/or modify
10317 + * it under the terms of the GNU General Public License as published by
10318 + * the Free Software Foundation; either version 2, or (at your option)
10319 + * any later version.
10321 + * This program is distributed in the hope that it will be useful,
10322 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10323 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10324 + * GNU General Public License for more details.
10326 + * You should have received a copy of the GNU General Public License
10327 + * along with this program; see the file COPYING. If not, write to
10328 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10333 + * Abstract: This module contains the definitions used by the Host Adapter
10334 + * Communications interface.
10335 + * This is the interface used for by host programs and the Adapter
10336 + * to communicate via synchronous commands via a shared set of registers
10337 + * on a platform (typically doorbells and mailboxes).
10340 +//**********************************************************************
10342 +// Monitor / Kernel API
10344 +// 03/24/1998 Bob Peret Initial creation
10346 +//**********************************************************************
10351 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10353 +#define BREAKPOINT_REQUEST 0x00000004
10354 +#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10357 +#define SEND_SYNCHRONOUS_FIB 0x0000000c
10362 +// Adapter Status Register
10364 +// Phase Staus mailbox is 32bits:
10365 +// <31:16> = Phase Status
10368 +// The adapter reports is present state through the phase. Only
10369 +// a single phase should be ever be set. Each phase can have multiple
10370 +// phase status bits to provide more detailed information about the
10371 +// state of the board. Care should be taken to ensure that any phase status
10372 +// bits that are set when changing the phase are also valid for the new phase
10373 +// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10374 +// for properly maintining the phase status mailbox when it is running.
10377 +// MONKER_API Phases
10379 +// Phases are bit oriented. It is NOT valid
10380 +// to have multiple bits set
10384 +#define SELF_TEST_FAILED 0x00000004
10387 +#define KERNEL_UP_AND_RUNNING 0x00000080
10388 +#define KERNEL_PANIC 0x00000100
10393 +// Doorbell bit defines
10397 +#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10400 +#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10401 +#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10402 +#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10403 +#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10404 +#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10407 +#endif // MONKER_H
10409 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10410 --- linux-2.4.4/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10411 +++ linux/drivers/scsi/aacraid/include/nodetype.h Mon Apr 30 09:43:34 2001
10414 + * Adaptec aacraid device driver for Linux.
10416 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10418 + * This program is free software; you can redistribute it and/or modify
10419 + * it under the terms of the GNU General Public License as published by
10420 + * the Free Software Foundation; either version 2, or (at your option)
10421 + * any later version.
10423 + * This program is distributed in the hope that it will be useful,
10424 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10425 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10426 + * GNU General Public License for more details.
10428 + * You should have received a copy of the GNU General Public License
10429 + * along with this program; see the file COPYING. If not, write to
10430 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10435 + * Abstract: This module defines all of the node type codes used in this development
10436 + * shell. Every major data structure in the file system is assigned a node
10437 + * type code that is. This code is the first CSHORT in the structure and is
10438 + * followed by a CSHORT containing the size, in bytes, of the structure.
10441 +#ifndef _NODETYPE_
10442 +#define _NODETYPE_
10444 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10446 +typedef CSHORT NODE_TYPE_CODE;
10449 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10450 +#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10453 +typedef CSHORT NODE_BYTE_SIZE;
10457 +// The following definitions are used to generate meaningful blue bugcheck
10458 +// screens. On a bugcheck the file system can output 4 ulongs of useful
10459 +// information. The first ulong will have encoded in it a source file id
10460 +// (in the high word) and the line number of the bugcheck (in the low word).
10461 +// The other values can be whatever the caller of the bugcheck routine deems
10464 +// Each individual file that calls bugcheck needs to have defined at the
10465 +// start of the file a constant called BugCheckFileId with one of the
10466 +// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10471 +#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10472 +#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10475 +#define FsaBugCheck(A,B,C) { cmn_err( CE_PANIC, "aacdisk: module %x, line %x, 0x%x, 0x%x, 0x%x ", BugCheckFileId, __LINE__, A, B, C); }
10478 +#endif // _NODETYPE_
10480 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10481 --- linux-2.4.4/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 18:00:00 1969
10482 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h Mon Apr 30 09:43:34 2001
10485 + * Adaptec aacraid device driver for Linux.
10487 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10489 + * This program is free software; you can redistribute it and/or modify
10490 + * it under the terms of the GNU General Public License as published by
10491 + * the Free Software Foundation; either version 2, or (at your option)
10492 + * any later version.
10494 + * This program is distributed in the hope that it will be useful,
10495 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10496 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10497 + * GNU General Public License for more details.
10499 + * You should have received a copy of the GNU General Public License
10500 + * along with this program; see the file COPYING. If not, write to
10501 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10506 + * Abstract: This file defines the data structures related to querying
10507 + * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10510 +#ifndef _NVRAMIOCTL_H_
10511 +#define _NVRAMIOCTL_H_ 1
10513 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10516 + * NVRAM/Write Cache subsystem states
10518 +typedef enum _NVSTATUS {
10519 + NVSTATUS_DISABLED = 0, // present, clean, not being used
10520 + NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10521 + NVSTATUS_ERROR, // present, dirty, contains dirty data
10522 + // for bad/missing device
10523 + NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10524 + // for bad/missing device
10525 + NVSTATUS_UNKNOWN // present?????
10528 +#ifdef AAC_32BIT_ENUMS
10529 +typedef _E_NVSTATUS NVSTATUS;
10531 +typedef AAC_UINT32 NVSTATUS;
10535 + * NVRAM/Write Cache subsystem battery component states
10538 +//NB: this enum should be identical to battery_status in nvram.h
10539 +// or else collapsed into one enum someday
10540 +typedef enum _NVBATTSTATUS {
10541 + NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10542 + NVBATTSTATUS_LOW, // battery is low on power
10543 + NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10544 + NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10545 +} _E_NVBATTSTATUS;
10547 +#ifdef AAC_32BIT_ENUMS
10548 +typedef _E_NVBATTSTATUS NVBATTSTATUS;
10550 +typedef AAC_UINT32 NVBATTSTATUS;
10554 + * battery transition type
10556 +typedef enum _NVBATT_TRANSITION {
10557 + NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10558 + NVBATT_TRANSITION_LOW, // battery is now low on power
10559 + NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10560 +} _E_NVBATT_TRANSITION;
10562 +#ifdef AAC_32BIT_ENUMS
10563 +typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10565 +typedef AAC_UINT32 NVBATT_TRANSITION;
10569 + * NVRAM Info structure returned for NVRAM_GetInfo call
10571 +typedef struct _NVRAMDEVINFO {
10572 + AAC_UINT32 NV_Enabled; /* write caching enabled */
10573 + AAC_UINT32 NV_Error; /* device in error state */
10574 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10575 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10576 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10578 +typedef struct _NVRAMINFO {
10579 + NVSTATUS NV_Status; /* nvram subsystem status */
10580 + NVBATTSTATUS NV_BattStatus; /* battery status */
10581 + AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10582 + AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10583 + AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10584 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10585 + AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10586 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10587 + AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10588 + NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10589 + AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10590 + AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10591 +} NVRAMINFO, *PNVRAMINFO;
10593 +#endif /* !_NVRAMIOCTL_H_ */
10596 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10597 --- linux-2.4.4/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 18:00:00 1969
10598 +++ linux/drivers/scsi/aacraid/include/osheaders.h Mon Apr 30 09:43:34 2001
10601 + * Adaptec aacraid device driver for Linux.
10603 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10605 + * This program is free software; you can redistribute it and/or modify
10606 + * it under the terms of the GNU General Public License as published by
10607 + * the Free Software Foundation; either version 2, or (at your option)
10608 + * any later version.
10610 + * This program is distributed in the hope that it will be useful,
10611 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10612 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10613 + * GNU General Public License for more details.
10615 + * You should have received a copy of the GNU General Public License
10616 + * along with this program; see the file COPYING. If not, write to
10617 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10622 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10625 +#ifndef _OSHEADERS_H_
10626 +#define _OSHEADERS_H_
10628 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10630 +#include <linux/autoconf.h> // retrieve the kernel configuration info
10631 +#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10632 +#define MODVERSIONS // force it on
10635 +#include <linux/version.h>
10637 +#if defined( MODVERSIONS ) && defined( MODULE )
10638 +#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10640 +#include <linux/modversions-smp.h>
10641 +#elif defined( BOOT_DRIVER )
10642 +#include <linux/modversions-BOOT.h>
10644 +#include <linux/modversions-up.h>
10645 +#endif // ifdef __SMP__
10647 +#include <linux/modversions.h>
10652 +#include <linux/kernel.h>
10653 +#include <linux/config.h>
10654 +#include <linux/init.h>
10655 +#include <linux/types.h>
10656 +#include <linux/blk.h>
10657 +#include <linux/blkdev.h>
10658 +#include <linux/delay.h>
10659 +#include <linux/ioport.h>
10660 +#include <linux/mm.h>
10661 +#include <linux/sched.h>
10662 +#include <linux/stat.h>
10663 +#include <linux/pci.h>
10664 +#include <linux/interrupt.h>
10665 +#include <asm/dma.h>
10666 +#include <asm/io.h>
10667 +#include <linux/spinlock.h>
10668 +#include <asm/system.h>
10669 +#include <asm/bitops.h>
10670 +#include <asm/uaccess.h>
10671 +#include <linux/wait.h>
10672 +#include <linux/malloc.h>
10673 +#include <linux/tqueue.h>
10675 +#include <linux/tasks.h>
10677 +#include <ostypes.h>
10679 +#include "hosts.h"
10682 +#define intptr_t void *
10686 +#define cred_t void
10690 +#define paddr32_t unsigned
10694 +#define bzero(b,len) memset(b,0,len)
10698 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10702 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10705 +typedef unsigned uint_t;
10718 +#define CMN_ERR_LEVEL CE_NOTE
10724 +// usage of READ & WRITE as a typedefs in protocol.h
10725 +// conflicts with <linux/fs.h> definition.
10734 +typedef struct aac_options
10736 + int message_level;
10737 + int reverse_scan;
10740 +#endif // _OSHEADERS_H_
10750 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10751 --- linux-2.4.4/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 18:00:00 1969
10752 +++ linux/drivers/scsi/aacraid/include/ostypes.h Mon Apr 30 09:43:34 2001
10755 + * Adaptec aacraid device driver for Linux.
10757 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10759 + * This program is free software; you can redistribute it and/or modify
10760 + * it under the terms of the GNU General Public License as published by
10761 + * the Free Software Foundation; either version 2, or (at your option)
10762 + * any later version.
10764 + * This program is distributed in the hope that it will be useful,
10765 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10766 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10767 + * GNU General Public License for more details.
10769 + * You should have received a copy of the GNU General Public License
10770 + * along with this program; see the file COPYING. If not, write to
10771 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10776 + * Abstract: Holds all of the O/S specific types.
10779 +/*------------------------------------------------------------------------------
10781 + *----------------------------------------------------------------------------*/
10782 +#ifndef _OSTYPES_H_
10783 +#define _OSTYPES_H_
10785 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10787 +#include <linux/types.h>
10789 +#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10790 +#define MAXIMUM_NUM_ADAPTERS 8
10792 +#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10794 +#define Os_remove_softintr OsSoftInterruptRemove
10795 +#define OsPrintf printk
10796 +#define FsaCommPrint
10798 +// the return values for copy_from_user & copy_to_user is the
10799 +// number of bytes not transferred. Thus if an internal error
10800 +// occurs, the return value is greater than zero.
10801 +#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10802 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10804 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10805 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10807 +/*------------------------------------------------------------------------------
10808 + * S T R U C T S / T Y P E D E F S
10809 + *----------------------------------------------------------------------------*/
10810 +typedef struct OS_MUTEX
10812 + unsigned long lock_var;
10813 + wait_queue_head_t wq;
10817 +typedef struct OS_SPINLOCK
10819 + spinlock_t spin_lock;
10820 + unsigned cpu_lock_count[NR_CPUS];
10822 + long lockout_count;
10825 +#ifdef CVLOCK_USE_SPINLOCK
10826 + typedef OS_SPINLOCK OS_CVLOCK;
10828 + typedef OS_MUTEX OS_CVLOCK;
10831 +typedef size_t OS_SIZE_T;
10833 +typedef struct OS_CV_T
10835 + unsigned long lock_var;
10836 + unsigned long type;
10837 + wait_queue_head_t wq;
10840 +struct fsa_scsi_hba {
10841 + void *CommonExtension;
10842 + unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10843 + unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10844 + unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10845 + unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10846 + unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10847 + unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10848 + long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10851 +typedef struct fsa_scsi_hba fsadev_t;
10853 +typedef struct OsKI
10855 + struct Scsi_Host *scsi_host_ptr;
10856 + void * dip; // #REVISIT#
10857 + fsadev_t fsa_dev;
10859 + int MiniPortIndex;
10862 +#define dev_info_t fsadev_t
10864 +typedef int OS_SPINLOCK_COOKIE;
10866 +typedef unsigned int OS_STATUS;
10868 +typedef struct tq_struct OS_SOFTINTR;
10870 +typedef OS_SOFTINTR *ddi_softintr_t;
10874 +//-----------------------------------------------------------------------------
10875 +// Conditional variable functions
10878 + OS_CV_T *cv_ptr );
10881 +//-----------------------------------------------------------------------------
10882 +// Printing functions
10883 +void printk_err(int flag, char *fmt, ...);
10885 +#define cmn_err printk_err
10889 +// just ignore these solaris ddi functions in the code
10891 +#define DDI_SUCCESS 0
10893 +#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10896 +#define ddi_remove_softintr(A) 0
10897 +#define ddi_get_soft_iblock_cookie(A, B, C) 0
10899 +#define ASSERT(expr) ((void) 0)
10900 +#define drv_usecwait udelay
10902 +#endif // _OSTYPES_H_
10903 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10904 --- linux-2.4.4/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 18:00:00 1969
10905 +++ linux/drivers/scsi/aacraid/include/pcisup.h Mon Apr 30 09:43:34 2001
10908 + * Adaptec aacraid device driver for Linux.
10910 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10912 + * This program is free software; you can redistribute it and/or modify
10913 + * it under the terms of the GNU General Public License as published by
10914 + * the Free Software Foundation; either version 2, or (at your option)
10915 + * any later version.
10917 + * This program is distributed in the hope that it will be useful,
10918 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10919 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10920 + * GNU General Public License for more details.
10922 + * You should have received a copy of the GNU General Public License
10923 + * along with this program; see the file COPYING. If not, write to
10924 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10929 + * Abstract: This module defines functions that are defined in PciSup.c
10935 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10939 + * define which interrupt handler needs to be installed
10945 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10946 + ULONG AdapterNumber; // Which FSA# this miniport is
10948 + ULONG PciBusNumber; // Which PCI bus we are located on
10949 + ULONG PciSlotNumber; // Whiat PCI slot we are in
10951 + PVOID Adapter; // Back pointer to Fsa adapter object
10952 + ULONG AdapterIndex; // Index into PlxAdapterTypes array
10953 + PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10955 + FSAPORT_FUNCS AdapterFuncs;
10956 + ULONG FilesystemRevision; // Main driver's revision number
10959 + PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
10960 + PVOID PhysicalInitStruct; // Holds physical address of the init struct
10963 + PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
10965 + BOOLEAN AdapterPrintfsToScreen;
10966 + BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
10970 + caddr_t CommAddress; // Base address of Comm area
10971 + paddr32_t CommPhysAddr; // Physical Address of Comm area
10974 + OsKI_t OsDep; // OS dependent kernel interfaces
10977 +} PCI_MINIPORT_COMMON_EXTENSION;
10979 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
10982 +(*PFSA_MINIPORT_INIT) (
10983 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
10984 + IN ULONG AdapterNumber,
10989 +typedef struct _FSA_MINIPORT {
10992 + USHORT SubVendorId;
10993 + USHORT SubSystemId;
10994 + PCHAR DevicePrefix;
10995 + PFSA_MINIPORT_INIT InitRoutine;
10996 + PCHAR DeviceName;
11000 +typedef FSA_MINIPORT *PFSA_MINIPORT;
11003 +#endif // _PCISUP_
11004 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11005 --- linux-2.4.4/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11006 +++ linux/drivers/scsi/aacraid/include/perfpack.h Mon Apr 30 09:43:34 2001
11009 + * Adaptec aacraid device driver for Linux.
11011 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11013 + * This program is free software; you can redistribute it and/or modify
11014 + * it under the terms of the GNU General Public License as published by
11015 + * the Free Software Foundation; either version 2, or (at your option)
11016 + * any later version.
11018 + * This program is distributed in the hope that it will be useful,
11019 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11020 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11021 + * GNU General Public License for more details.
11023 + * You should have received a copy of the GNU General Public License
11024 + * along with this program; see the file COPYING. If not, write to
11025 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11030 + * Abstract: This file defines the layout of the performance data that is passed
11031 + * back from the FSA filesystem driver.
11036 +#ifndef _FSA_PERFPACK_H_
11037 +#define _FSA_PERFPACK_H_ 1
11039 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11041 +//#define FSA_DO_PERF 1 /* enable the engineering counters */
11043 +#ifdef FSA_DO_PERF
11045 +// engineering counters
11047 +typedef struct _FSA_PERF_DATA {
11055 + ULONG CreateFibs;
11057 + ULONG RemoveFibs;
11058 + ULONG RemoveDirs;
11059 + ULONG RenameFibs;
11060 + ULONG ReadDirPlus;
11062 + ULONG WriteBytes;
11064 +// NT FSA entry points
11065 + ULONG FsaFsdCreateCount;
11066 + ULONG FsaFsdCloseCount;
11067 + ULONG FsaFsdReadCount;
11068 + ULONG FsaFsdWriteCount;
11069 + ULONG FsaFsdQueryInformationCount;
11071 + struct _FsaFsdSetInfomation{
11072 + ULONG FsaSetAllocationInfoCount;
11073 + ULONG FsaSetBasicInfoCount;
11074 + ULONG FsaSetDispositionInfoCount;
11075 + ULONG FsaSetEndOfFileInfoCount;
11076 + ULONG FsaSetPositionInfoCount;
11077 + ULONG FsaSetRenameInfoCount;
11078 + ULONG FsaClearArchiveBitCount;
11081 + ULONG FsaFsdFlushBuffersCount;
11082 + ULONG FsaFsdQueryVolumeInfoCount;
11083 + ULONG FsaFsdSetVolumeInfoCount;
11084 + ULONG FsaFsdCleanupCount;
11085 + ULONG FsaFsdDirectoryControlCount;
11086 + ULONG FsaFsdFileSystemControlCount;
11087 + ULONG FsaFsdLockControlCount;
11088 + ULONG FsaFsdDeviceControlCount;
11089 + ULONG FsaFsdShutdownCount;
11090 + ULONG FsaFsdQuerySecurityInfo;
11091 + ULONG FsaFsdSetSecurityInfo;
11092 + ULONG FastIoCheckIfPossibleCount;
11093 + ULONG FastIoReadCount;
11094 + ULONG FastIoWriteCount;
11095 + ULONG FastIoQueryBasicInfoCount;
11096 + ULONG FastIoQueryStandardInfoCount;
11097 + ULONG FastIoLockCount;
11098 + ULONG FastIoUnlockSingleCount;
11099 + ULONG FastIoUnlockAllCount;
11100 + ULONG FastIoUnlockAllByKeyCount;
11101 + ULONG FastIoDeviceControlCount;
11104 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11107 +#else /* FSA_DO_PERF */
11110 +// engineering performance counters are disabled
11112 +#define FSA_DO_PERF_INC(Counter) /* */
11113 +#define FSA_DO_FSP_PERF_INC(Counter) /* */
11115 +#endif /* FSA_DO_PERF */
11117 +#endif // _FSA_PERFPACK_H_
11118 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11119 --- linux-2.4.4/drivers/scsi/aacraid/include/port.h Wed Dec 31 18:00:00 1969
11120 +++ linux/drivers/scsi/aacraid/include/port.h Mon Apr 30 09:43:34 2001
11123 + * Adaptec aacraid device driver for Linux.
11125 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11127 + * This program is free software; you can redistribute it and/or modify
11128 + * it under the terms of the GNU General Public License as published by
11129 + * the Free Software Foundation; either version 2, or (at your option)
11130 + * any later version.
11132 + * This program is distributed in the hope that it will be useful,
11133 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11134 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11135 + * GNU General Public License for more details.
11137 + * You should have received a copy of the GNU General Public License
11138 + * along with this program; see the file COPYING. If not, write to
11139 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11144 + * Abstract: This module defines functions and structures that are in common among all miniports
11152 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11155 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11156 +extern int AfaPortPrinting;
11158 +#define AfaPortPrint
11161 +extern int AfaPortPrinting;
11165 +AfaPortAllocateAdapterCommArea(
11167 + IN OUT PVOID *CommHeaderAddress,
11168 + IN ULONG CommAreaSize,
11169 + IN ULONG CommAreaAlignment
11174 +AfaPortFreeAdapterCommArea(
11180 +AfaPortBuildSgMap(
11182 + IN PSGMAP_CONTEXT SgMapContext
11187 +AfaPortFreeDmaResources(
11189 + IN PSGMAP_CONTEXT SgMapContext
11194 +AfaPortAllocateAndMapFibSpace(
11196 + IN PMAPFIB_CONTEXT MapFibContext
11201 +AfaPortUnmapAndFreeFibSpace(
11203 + IN PMAPFIB_CONTEXT MapFibContext
11209 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11210 --- linux-2.4.4/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11211 +++ linux/drivers/scsi/aacraid/include/protocol.h Mon Apr 30 09:43:34 2001
11214 + * Adaptec aacraid device driver for Linux.
11216 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11218 + * This program is free software; you can redistribute it and/or modify
11219 + * it under the terms of the GNU General Public License as published by
11220 + * the Free Software Foundation; either version 2, or (at your option)
11221 + * any later version.
11223 + * This program is distributed in the hope that it will be useful,
11224 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11225 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11226 + * GNU General Public License for more details.
11228 + * You should have received a copy of the GNU General Public License
11229 + * along with this program; see the file COPYING. If not, write to
11230 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11235 + * Abstract: Defines the commands and command data which enables the nt
11236 + * filesystem driver to be the client of the fsa adapter
11237 + * filesystem. This protocol is largely modeled after the NFS
11238 + * V3 protocol with modifications allowed due to the unique
11239 + * client/server model FSA works under.
11245 +#ifndef _PROTOCOL_H_
11246 +#define _PROTOCOL_H_
11248 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11250 +#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11251 +#include <nvramioctl.h> // for NVRAMINFO definition
11253 +// #define MDL_READ_WRITE
11256 +// Define the command values
11258 +typedef enum _FSA_COMMANDS {
11271 + RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11275 + ReadDirectoryPlus,
11276 + FileSystemStatus,
11286 + SetFileSystemStatus,
11292 +#ifdef MDL_READ_WRITE
11294 + MdlWriteComplete,
11295 + MdlRead, // these are used solely for stats, Mdl really controlled by
11296 + MdlWrite, // flags field in Fib.
11301 + FaultInsertion, // Fault Insertion Command
11302 + CrazyCache, // crazycache
11303 + MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11306 +#ifdef AAC_32BIT_ENUMS
11307 +typedef _E_FSACOMMAND FSACOMMAND;
11309 +typedef AAC_UINT32 FSACOMMAND;
11315 +// Define the status returns
11317 +// See include\comm\errno.h for adapter kernel errno's
11318 +typedef enum _FSASTATUS {
11336 + ST_WOULDBLOCK = 35,
11337 + ST_NAMETOOLONG = 63,
11338 + ST_NOTEMPTY = 66,
11342 + ST_BADHANDLE = 10001,
11343 + ST_NOT_SYNC = 10002,
11344 + ST_BAD_COOKIE = 10003,
11345 + ST_NOTSUPP = 10004,
11346 + ST_TOOSMALL = 10005,
11347 + ST_SERVERFAULT = 10006,
11348 + ST_BADTYPE = 10007,
11349 + ST_JUKEBOX = 10008,
11350 + ST_NOTMOUNTED = 10009,
11351 + ST_MAINTMODE = 10010,
11352 + ST_STALEACL = 10011
11355 +#ifdef AAC_32BIT_ENUMS
11356 +typedef _E_FSASTATUS FSASTATUS;
11358 +typedef AAC_UINT32 FSASTATUS;
11362 +// On writes how does the client want the data written.
11365 +typedef enum _CACHELEVEL {
11370 +#ifdef AAC_32BIT_ENUMS
11371 +typedef _E_CACHELEVEL CACHELEVEL;
11373 +typedef AAC_UINT32 CACHELEVEL;
11377 +// Lets the client know at which level the data was commited on a write request
11380 +typedef enum _COMMITLEVEL {
11381 + CMFILE_SYNCH_NVRAM = 1,
11382 + CMDATA_SYNCH_NVRAM,
11388 +#ifdef AAC_32BIT_ENUMS
11389 +typedef _E_COMMITLEVEL COMMITLEVEL;
11391 +typedef AAC_UINT32 COMMITLEVEL;
11397 +// The following are all the different commands or FIBs which can be sent to the
11398 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11399 +// but others outside that subset are allowed to return not implemented. The client is then
11400 +// responsible for dealing with the fact it is not implemented.
11402 +typedef AAC_INT8 FSASTRING[16];
11405 +typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11413 +typedef struct _BLOCKREAD { // variable size struct
11415 + FSACOMMAND Command;
11416 + AAC_UINT32 ContainerId;
11417 + BYTECOUNT BlockNumber;
11418 + BYTECOUNT ByteCount;
11419 + SGMAP SgMap; // Must be last in struct because it is variable
11422 +typedef BLOCKREAD *PBLOCKREAD;
11424 +typedef struct _BLOCKREADRESPONSE {
11426 + FSASTATUS Status;
11427 + BYTECOUNT ByteCount;
11429 +} BLOCKREADRESPONSE;
11430 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11436 +typedef struct _BLOCKWRITE { // variable size struct
11438 + FSACOMMAND Command;
11439 + AAC_UINT32 ContainerId;
11440 + BYTECOUNT BlockNumber;
11441 + BYTECOUNT ByteCount;
11442 + CACHELEVEL Stable;
11443 + SGMAP SgMap; // Must be last in struct because it is variable
11446 +typedef BLOCKWRITE *PBLOCKWRITE;
11449 +typedef struct _BLOCKWRITERESPONSE {
11451 + FSASTATUS Status;
11452 + BYTECOUNT ByteCount;
11453 + COMMITLEVEL Committed;
11455 +} BLOCKWRITERESPONSE;
11456 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11460 +#endif // _PROTOCOL_H_
11462 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11463 --- linux-2.4.4/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11464 +++ linux/drivers/scsi/aacraid/include/revision.h Mon Apr 30 09:43:34 2001
11467 + * Adaptec aacraid device driver for Linux.
11469 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11471 + * This program is free software; you can redistribute it and/or modify
11472 + * it under the terms of the GNU General Public License as published by
11473 + * the Free Software Foundation; either version 2, or (at your option)
11474 + * any later version.
11476 + * This program is distributed in the hope that it will be useful,
11477 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11478 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11479 + * GNU General Public License for more details.
11481 + * You should have received a copy of the GNU General Public License
11482 + * along with this program; see the file COPYING. If not, write to
11483 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11488 + * Abstract: This module contains all of the revision information for
11489 + * the FSA product, as well as the support routines for
11490 + * checking module compatibility.
11492 + * Before editing anything in this module, make sure that
11493 + * you read the comments. Some lines are changed automatically
11494 + * as part of the build, and should never be changed by hand.
11496 + * Routines (all inlines):
11498 + * RevGetBuildNumber - Retrieve current build number
11499 + * RevGetExternalRev - Retrieve revision for external use
11500 + * RevGetFullRevision - Retrieve full revision structure
11502 + * RevCheckCompatibility - Checks compatibility base on internal table
11504 + * RevCheckCompatibilityFullInfo - Check for static component
11505 + * RevGetCompInfoTableSize - Get size for static component table
11506 + * RevGetCompInfoTable - Get actual table to place on static component
11507 + * RevGetBuildNumberFromInfo - Get build number for static component.
11513 +#ifndef _REVISION_H
11514 +#define _REVISION_H
11516 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11518 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11520 +typedef int REV_BOOL;
11522 +#define REV_TRUE 1
11523 +#define REV_FALSE 0
11526 +// Define Revision Levels for this product
11528 +// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11529 +// automatically by the build.
11531 +// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11533 +// IMPORTANT: Don't access these revisions directly. They can be
11534 +// accessed via, the RevGetXxxxx rouines.
11538 +#define REV_AS_LONGWORD \
11539 + ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11546 +// Enumerate the types of product levels we can have
11549 + RevType_Devo=1, // Development mode, testing all of latest
11550 + RevType_Alpha, // Alpha - Internal field test
11551 + RevType_Beta, // Beta - External field test
11552 + RevType_Release // Release - Retail version
11556 +// Define the basic structure for all revision information. Note
11557 +// that the ordering of the components is such that they should
11558 +// always increase. dash will be updated the most, then the version
11559 +// type, then minor and major.
11564 + unsigned char dash; // Dash version number
11565 + unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11566 + unsigned char minor;// Minor version minor
11567 + unsigned char major;// Major version number
11568 + } comp; // Components to external viewed rev number
11569 + unsigned long ul; // External revision as single 32-bit value
11570 + } external; // External revision number (union)
11571 + unsigned long buildNumber; // Automatically generated build number
11576 +// Define simple routines to get basic revision information. The
11577 +// definitions should never be accessed directly. These routines
11578 +// are meant to be used to access all relevant information no matter
11581 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11583 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11587 +// Enumerate different components that may have to check
11588 +// compatibility. This list of components can be changed
11591 +// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11592 +// incompatibilities between component rev checking will
11593 +// cause wrong checking results.
11596 + RevApplication = 1, // Any user End application
11597 + RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11598 + RevNetService, // Network Service Revision (under API)
11599 + RevApi, // ADAPTEC User mode API
11600 + RevFileSysDriver, // FSA File System Driver
11601 + RevMiniportDriver, // FSA File System Miniport Driver
11602 + RevAdapterSW, // Adapter Software (or NT Simulator)
11603 + RevMonitor, // Monitor for adapter hardware (MON960 for now)
11604 + RevRemoteApi // The remote API.
11605 + // ALWAYS ADD NEW COMPONENTS HERE - AT END
11609 +// Define a structure so that we can create a compatibility table.
11612 + RevComponent A,B;
11613 + unsigned long BuildNumOfB_RequiredByA;
11614 + unsigned long BuildNumOfA_RequiredByB;
11615 +} RevCompareElement;
11618 +// Now, define the table. This table should only be included once,
11619 +// in one program. If it is linked from 2 modules, there will likely
11620 +// be a multiply defined symbol error from the linker.
11622 +// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11623 +// allow access to the revision information table without a redefinition
11626 +extern const int RevCompareTableLength;
11628 +extern const RevCompareElement RevCompareTable[];
11630 +/********************************************************************\
11631 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11633 +* The following routine is used to check compatibility between
11634 +* the calling component and a component that has some dependencies
11635 +* on it. If this routine returns REV_FALSE, it is expected that the caller
11636 +* will send an appropriate incompatibility message and stop.
11638 +* This routine is only meant to check for compatibility in the
11639 +* absolute sense. If code wishes to execute a different path based
11640 +* on the CompB_BuildNumber, then this routine is not useful. The
11641 +* routine RevGetBuildNumber can be used to get the calling module's
11642 +* current build number for a comparison check.
11644 +* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11645 +* if the components are definitely not compatible, or there is an
11646 +* error when trying to figure it out. To be more specific:
11648 +* 1) REV_TRUE if component B is newer than calling component. (In this
11649 +* case, the revision check done by component B with respect to
11650 +* this component will give the real compatibility information.
11651 +* It is the only one with the knowledge, since this component
11652 +* could not look into the future.)
11653 +* 2) REV_TRUE if calling component is more recent and table shows okay
11654 +* 3) REV_FALSE if calling component more recent and table show not okay
11655 +* 4) REV_FALSE if calling component is more recent and table entry to
11656 +* check does not exist.
11658 +* Note that the CompB_BuildNumber must be attained by the calling
11659 +* routine through some mechanism done by the caller.
11663 +* callerComp - Name of component making this call
11664 +* compB - Name of component to check compatibility with
11665 +* compB_BuildNumber - Build number to component B
11673 +* REV_TRUE - Component compatibility is possible, continue as usual. compB
11674 +* must give true compatibility information.
11675 +* REV_FALSE - Incompatible components, notify and end
11677 +\********************************************************************/
11678 +static inline REV_BOOL RevCheckCompatibility(
11679 + RevComponent callerComp,
11680 + RevComponent compB,
11681 + unsigned long compB_BuildNumber)
11684 + unsigned long RevForB;
11687 + // Compatibility check is possible, so we should continue. When
11688 + // compB makes this call in its own component, it will get the
11689 + // true compatibility information, since only it can know.
11691 + if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11694 + // Go through rev table. When the components are found in the
11695 + // same table entry, return the approprate number.
11697 + for (i=0; i<RevCompareTableLength; i++) {
11698 + if (RevCompareTable[i].A == callerComp) {
11699 + if (RevCompareTable[i].B == compB) {
11700 + RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11701 + return (compB_BuildNumber >= RevForB);
11703 + } else if (RevCompareTable[i].B == callerComp) {
11704 + if (RevCompareTable[i].A == compB) {
11705 + RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11706 + return (compB_BuildNumber >= RevForB);
11712 + // Uh oh! No relevant table entry was found (this should never
11715 + return REV_FALSE;
11720 +// Now create a structure that can be used by a FIB to check
11723 +typedef struct _RevCheck {
11724 + RevComponent callingComponent;
11725 + FsaRevision callingRevision;
11728 +typedef struct _RevCheckResp {
11729 + REV_BOOL possiblyCompatible;
11730 + FsaRevision adapterSWRevision;
11734 +#endif /* _REVISION_H */
11737 +// The following allows for inclusion of revision.h in other h
11738 +// files. when you include this file in another h file, simply
11739 +// define REV_REFERENCE_ONLY. This will be undefined later, so that
11740 +// the single C file inclusion in the module will be used to
11741 +// implement the global structures.
11743 +#ifndef REV_REFERENCE_ONLY
11744 +#ifndef _REVISION_H_GLOBAL
11745 +#define _REVISION_H_GLOBAL
11750 +// The following array is the table of compatibility. This table
11751 +// can be modified in two ways:
11753 +// 1) A component which has an incompatible change done to
11754 +// it, can get a new build number.
11756 +// 2) A new component can be added, requiring more entries
11757 +// to be place into this table.
11760 +// In case (1), you must change the revision number in the appropriate
11761 +// column, based on which component absolutely requires an upgrade.
11763 +// Example: A new FIB used by the API, in build number 105
11764 +// {RevApi, RevAdapterSW, 100, 100}
11765 +// ---> would be changed to <---
11766 +// {RevApi, RevAdapterSW, 105, 100}
11768 +// Example: A structure is changed for a FIB that only the API uses
11769 +// {RevApi, RevAdapterSW, 100, 100}
11770 +// ---> would be changed to <---
11771 +// {RevApi, RevAdapterSW, 105, 105}
11774 +// In case (2), the less common case, the enumerated list of
11775 +// components must be changed to include the new component. Then
11776 +// entries need to be placed into this table.
11778 +// Since the revisions must be communicated between the two
11779 +// components, it is likely that you would need to put in the
11780 +// current build number for both columns. That is the recommended
11781 +// way to start revision test.
11783 +const RevCompareElement RevCompareTable[] = {
11784 + // Component A Component B MinBForA MinAForB
11785 + // ----------- ----------- -------- --------
11786 + {RevApplication, RevApi, 2120, 2120 },
11787 + {RevDkiCli, RevApi, 2120, 2120 },
11788 + {RevDkiCli, RevFileSysDriver, 257, 257 },
11789 + {RevDkiCli, RevMiniportDriver, 257, 257 },
11790 + {RevDkiCli, RevAdapterSW, 257, 257 },
11791 + {RevApi, RevFileSysDriver, 2120, 2120 },
11792 + {RevApi, RevMiniportDriver, 2120, 2120 },
11793 + {RevApi, RevAdapterSW, 2120, 2120 },
11794 + {RevApi, RevNetService, 2120, 2120 },
11795 + {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11796 + {RevFileSysDriver, RevAdapterSW, 257, 257 },
11797 + {RevMiniportDriver, RevAdapterSW, 257, 257 },
11798 + {RevMiniportDriver, RevMonitor, 100, 100 },
11799 + {RevApi, RevNetService, 2120, 2120 },
11800 + {RevApi, RevRemoteApi, 2120, 2120 },
11801 + {RevNetService, RevRemoteApi, 2120, 2120 }
11804 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11806 +#endif /* _REVISION_H_GLOBAL */
11807 +#endif /* REV_REFERENCE_ONLY */
11808 +#undef REV_REFERENCE_ONLY
11816 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11817 --- linux-2.4.4/drivers/scsi/aacraid/include/rx.h Wed Dec 31 18:00:00 1969
11818 +++ linux/drivers/scsi/aacraid/include/rx.h Mon Apr 30 09:43:34 2001
11821 + * Adaptec aacraid device driver for Linux.
11823 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11825 + * This program is free software; you can redistribute it and/or modify
11826 + * it under the terms of the GNU General Public License as published by
11827 + * the Free Software Foundation; either version 2, or (at your option)
11828 + * any later version.
11830 + * This program is distributed in the hope that it will be useful,
11831 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11832 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11833 + * GNU General Public License for more details.
11835 + * You should have received a copy of the GNU General Public License
11836 + * along with this program; see the file COPYING. If not, write to
11837 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11842 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11847 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11849 +typedef struct _Rx_ADAPTER_EXTENSION {
11852 + // The following must be first.
11854 + PPCI_MINIPORT_COMMON_EXTENSION Common;
11855 + struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11856 + USHORT LocalMaskInterruptControl;
11857 + PRx_DEVICE_REGISTERS Device;
11859 +} Rx_ADAPTER_EXTENSION;
11862 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11871 +#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11875 +#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11876 +#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11879 +#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11881 +#endif /* LINUX */
11885 +RxInterruptAdapter(
11892 + IN HOST_2_ADAP_EVENT AdapterEvent
11901 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11902 --- linux-2.4.4/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11903 +++ linux/drivers/scsi/aacraid/include/rxcommon.h Mon Apr 30 09:43:34 2001
11906 + * Adaptec aacraid device driver for Linux.
11908 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11910 + * This program is free software; you can redistribute it and/or modify
11911 + * it under the terms of the GNU General Public License as published by
11912 + * the Free Software Foundation; either version 2, or (at your option)
11913 + * any later version.
11915 + * This program is distributed in the hope that it will be useful,
11916 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11917 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11918 + * GNU General Public License for more details.
11920 + * You should have received a copy of the GNU General Public License
11921 + * along with this program; see the file COPYING. If not, write to
11922 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11927 + * Abstract: Structures and defines for the i960 Rx chip.
11932 +#ifndef _Rx_COMMON_H_
11933 +#define _Rx_COMMON_H_
11935 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11938 +// Rx Message Unit Registers
11941 +typedef volatile struct _StructRxMURegisters {
11942 + // Local | PCI* | Name
11944 + unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11945 + unsigned reserved0; // 1304h | 04h | Reserved
11946 + unsigned AWR; // 1308h | 08h | APIC Window Register
11947 + unsigned reserved1; // 130Ch | 0Ch | Reserved
11948 + unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11949 + unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11950 + unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11951 + unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11952 + unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11953 + unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11954 + unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11955 + unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11956 + // * Must access trhough ATU Inbound Translation Window
11959 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
11961 +typedef volatile struct _Rx_Inbound {
11963 + unsigned Mailbox[8];
11967 +typedef Rx_Inbound *PRx_Inbound;
11969 +#define InboundMailbox0 IndexRegs.Mailbox[0]
11970 +#define InboundMailbox1 IndexRegs.Mailbox[1]
11971 +#define InboundMailbox2 IndexRegs.Mailbox[2]
11972 +#define InboundMailbox3 IndexRegs.Mailbox[3]
11973 +#define InboundMailbox4 IndexRegs.Mailbox[4]
11977 +#define INBOUNDDOORBELL_0 0x00000001
11978 +#define INBOUNDDOORBELL_1 0x00000002
11979 +#define INBOUNDDOORBELL_2 0x00000004
11980 +#define INBOUNDDOORBELL_3 0x00000008
11981 +#define INBOUNDDOORBELL_4 0x00000010
11982 +#define INBOUNDDOORBELL_5 0x00000020
11983 +#define INBOUNDDOORBELL_6 0x00000040
11986 +#define OUTBOUNDDOORBELL_0 0x00000001
11987 +#define OUTBOUNDDOORBELL_1 0x00000002
11988 +#define OUTBOUNDDOORBELL_2 0x00000004
11989 +#define OUTBOUNDDOORBELL_3 0x00000008
11990 +#define OUTBOUNDDOORBELL_4 0x00000010
11993 +#define InboundDoorbellReg MUnit.IDR
11995 +#define OutboundDoorbellReg MUnit.ODR
11998 +typedef struct _Rx_DEVICE_REGISTERS {
11999 + Rx_MU_CONFIG MUnit; // 1300h - 1334h
12000 + unsigned reserved1[6]; // 1338h - 134ch
12001 + Rx_Inbound IndexRegs;
12002 +} Rx_DEVICE_REGISTERS;
12004 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12007 +#endif // _Rx_COMMON_H_
12010 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12011 --- linux-2.4.4/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 18:00:00 1969
12012 +++ linux/drivers/scsi/aacraid/include/sap1.h Mon Apr 30 09:43:34 2001
12015 + * Adaptec aacraid device driver for Linux.
12017 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12019 + * This program is free software; you can redistribute it and/or modify
12020 + * it under the terms of the GNU General Public License as published by
12021 + * the Free Software Foundation; either version 2, or (at your option)
12022 + * any later version.
12024 + * This program is distributed in the hope that it will be useful,
12025 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12026 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12027 + * GNU General Public License for more details.
12029 + * You should have received a copy of the GNU General Public License
12030 + * along with this program; see the file COPYING. If not, write to
12031 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12036 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12043 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12045 +#define Sa_MINIPORT_REVISION 1
12047 +typedef struct _Sa_ADAPTER_EXTENSION {
12050 + // The following must be first.
12052 + PPCI_MINIPORT_COMMON_EXTENSION Common;
12053 + struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12054 + USHORT LocalMaskInterruptControl;
12055 + PSa_DEVICE_REGISTERS Device;
12057 +} Sa_ADAPTER_EXTENSION;
12059 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12069 +#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12070 +#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12073 +#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12074 +#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12076 +#endif /* LINUX */
12080 +SaInterruptAdapter(
12087 + IN HOST_2_ADAP_EVENT AdapterEvent
12096 +#endif /* _SAP1_H_ */
12099 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12100 --- linux-2.4.4/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 18:00:00 1969
12101 +++ linux/drivers/scsi/aacraid/include/sap1common.h Mon Apr 30 09:43:34 2001
12104 + * Adaptec aacraid device driver for Linux.
12106 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12108 + * This program is free software; you can redistribute it and/or modify
12109 + * it under the terms of the GNU General Public License as published by
12110 + * the Free Software Foundation; either version 2, or (at your option)
12111 + * any later version.
12113 + * This program is distributed in the hope that it will be useful,
12114 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12115 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12116 + * GNU General Public License for more details.
12118 + * You should have received a copy of the GNU General Public License
12119 + * along with this program; see the file COPYING. If not, write to
12120 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12125 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12129 +#ifndef _Sa_COMMON_H_
12130 +#define _Sa_COMMON_H_
12132 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12135 +// SaP1 Message Unit Registers
12138 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12140 + unsigned reserved[10]; // 00h-27h | Reserved
12141 + unsigned char LUT_Offset; // 28h | Looup Table Offset
12142 + unsigned char reserved1[3]; // 29h-2bh | Reserved
12143 + unsigned LUT_Data; // 2ch | Looup Table Data
12144 + unsigned reserved2[26]; // 30h-97h | Reserved
12145 + unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12146 + unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12147 + unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12148 + unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12149 + unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12150 + unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12151 + unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12152 + unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12153 + unsigned MAILBOX0; // a8h | Scratchpad 0
12154 + unsigned MAILBOX1; // ach | Scratchpad 1
12155 + unsigned MAILBOX2; // b0h | Scratchpad 2
12156 + unsigned MAILBOX3; // b4h | Scratchpad 3
12157 + unsigned MAILBOX4; // b8h | Scratchpad 4
12158 + unsigned MAILBOX5; // bch | Scratchpad 5
12159 + unsigned MAILBOX6; // c0h | Scratchpad 6
12160 + unsigned MAILBOX7; // c4h | Scratchpad 7
12162 + unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12163 + unsigned ROM_Control_Addr; // cch | Rom Control and Address
12165 + unsigned reserved3[12]; // d0h-ffh | reserved
12166 + unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12170 + // need to add DMA, I2O, UART, etc registers form 80h to 364h
12173 +}Sa_Drawbridge_CSR;
12175 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12178 +#define Mailbox0 SaDbCSR.MAILBOX0
12179 +#define Mailbox1 SaDbCSR.MAILBOX1
12180 +#define Mailbox2 SaDbCSR.MAILBOX2
12181 +#define Mailbox3 SaDbCSR.MAILBOX3
12182 +#define Mailbox4 SaDbCSR.MAILBOX4
12185 +#define Mailbox7 SaDbCSR.MAILBOX7
12187 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12188 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12189 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12192 +#define DOORBELL_0 0x00000001
12193 +#define DOORBELL_1 0x00000002
12194 +#define DOORBELL_2 0x00000004
12195 +#define DOORBELL_3 0x00000008
12196 +#define DOORBELL_4 0x00000010
12197 +#define DOORBELL_5 0x00000020
12198 +#define DOORBELL_6 0x00000040
12201 +#define PrintfReady DOORBELL_5
12202 +#define PrintfDone DOORBELL_5
12204 +typedef struct _Sa_DEVICE_REGISTERS {
12205 + Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12206 +} Sa_DEVICE_REGISTERS;
12208 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12211 +#endif // _Sa_COMMON_H_
12214 diff -burN linux-2.4.4/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12215 --- linux-2.4.4/drivers/scsi/aacraid/include/version.h Wed Dec 31 18:00:00 1969
12216 +++ linux/drivers/scsi/aacraid/include/version.h Mon Apr 30 09:43:34 2001
12219 + * Adaptec aacraid device driver for Linux.
12221 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12223 + * This program is free software; you can redistribute it and/or modify
12224 + * it under the terms of the GNU General Public License as published by
12225 + * the Free Software Foundation; either version 2, or (at your option)
12226 + * any later version.
12228 + * This program is distributed in the hope that it will be useful,
12229 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12230 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12231 + * GNU General Public License for more details.
12233 + * You should have received a copy of the GNU General Public License
12234 + * along with this program; see the file COPYING. If not, write to
12235 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12240 + * Abstract: Keeps track of build number for development purposes.
12243 +#ifndef _VERSION_H_
12244 +#define _VERSION_H_
12246 +static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12248 +#include "build_number.h"
12250 +#define REV_MAJOR 2
12251 +#define REV_MINOR 1
12252 +#define REV_TYPE RevType_Release
12253 +#define REV_DASH 5
12255 +#define FSA_VERSION_STRING "2.1.5.3857\0"
12257 +#endif /* _VERSION_H_ */
12258 diff -burN linux-2.4.4/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12259 --- linux-2.4.4/drivers/scsi/aacraid/linit.c Wed Dec 31 18:00:00 1969
12260 +++ linux/drivers/scsi/aacraid/linit.c Mon Apr 30 09:47:34 2001
12263 + * Adaptec aacraid device driver for Linux.
12265 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12267 + * This program is free software; you can redistribute it and/or modify
12268 + * it under the terms of the GNU General Public License as published by
12269 + * the Free Software Foundation; either version 2, or (at your option)
12270 + * any later version.
12272 + * This program is distributed in the hope that it will be useful,
12273 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12274 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12275 + * GNU General Public License for more details.
12277 + * You should have received a copy of the GNU General Public License
12278 + * along with this program; see the file COPYING. If not, write to
12279 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12284 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12286 + * Provides the following driver entry points:
12287 + * AAC_DetectHostAdapter()
12288 + * AAC_ReleaseHostAdapter()
12289 + * AAC_QueueCommand()
12290 + * AAC_ResetCommand()
12291 + * AAC_BIOSDiskParameters()
12295 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12297 +/*------------------------------------------------------------------------------
12299 + *----------------------------------------------------------------------------*/
12300 +#define AAC_DRIVER_VERSION "0.1.1"
12301 +#define AAC_DRIVER_BUILD_DATE __DATE__
12302 +#define MAX_DRIVER_QUEUE_DEPTH 500
12304 +/*------------------------------------------------------------------------------
12305 + * I N C L U D E S
12306 + *----------------------------------------------------------------------------*/
12307 +#include "osheaders.h"
12309 +#include "AacGenericTypes.h"
12312 +#include <linux/module.h>
12315 +#include "linit.h"
12316 +#include "aac_unix_defs.h"
12317 +#include "fsatypes.h"
12318 +#include "comstruc.h"
12319 +#include "fsaport.h"
12320 +#include "pcisup.h"
12322 +#include "afacomm.h"
12323 +#include "nodetype.h"
12324 +#include "comsup.h"
12325 +#include "adapter.h"
12327 +/*------------------------------------------------------------------------------
12329 + *----------------------------------------------------------------------------*/
12330 +extern FSA_MINIPORT MiniPorts[];
12331 +extern int CommPrinting;
12332 +extern char DescriptionString[];
12333 +extern char devicestr[];
12335 +/*------------------------------------------------------------------------------
12336 + * M O D U L E G L O B A L S
12337 + *----------------------------------------------------------------------------*/
12338 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12340 +char g_DriverName[] = { "aacraid" };
12341 +#define module_options aacraid_options
12342 +static char * aacraid_options = NULL;
12344 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12345 +unsigned g_HostAdapterCount = 0;
12346 +unsigned g_chardev_major = 0;
12348 +int g_single_command_done = FALSE;
12350 +/*------------------------------------------------------------------------------
12351 + * F U N C T I O N P R O T O T Y P E S
12352 + *----------------------------------------------------------------------------*/
12354 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12358 +int AacHba_ProbeContainers(
12359 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12361 +int AacHba_DoScsiCmd(
12362 + Scsi_Cmnd *scsi_cmnd_ptr,
12365 +void AacHba_DetachAdapter(
12366 + IN PVOID AdapterArg );
12368 +int AacHba_ClassDriverInit(
12369 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12371 +void AacHba_AbortScsiCommand(
12372 + Scsi_Cmnd *scsi_cmnd_ptr );
12375 +/*------------------------------------------------------------------------------
12376 + * L O C A L F U N C T I O N P R O T O T Y P E S
12377 + *----------------------------------------------------------------------------*/
12378 +static int parse_keyword(
12380 + char * keyword );
12382 +static void AAC_ParseDriverOptions(
12383 + char * cmnd_line_options_str );
12385 +static void AAC_AnnounceDriver( void );
12387 +int AAC_ChardevIoctl(
12388 + struct inode * inode_ptr,
12389 + struct file * file_ptr,
12390 + unsigned int cmd,
12391 + unsigned long arg );
12393 +int AAC_ChardevOpen(
12394 + struct inode * inode_ptr,
12395 + struct file * file_ptr );
12397 +int AAC_ChardevRelease(
12398 + struct inode * inode_ptr,
12399 + struct file * file_ptr );
12401 +struct file_operations AAC_fops = {
12402 + NULL, // module name
12408 + AAC_ChardevIoctl, // ioctl
12410 + AAC_ChardevOpen, // open
12412 + AAC_ChardevRelease, // release
12415 + NULL, // check media change
12416 + NULL, // revalidate
12420 +/*------------------------------------------------------------------------------
12421 + * F U N C T I O N S
12422 + *----------------------------------------------------------------------------*/
12423 +/*------------------------------------------------------------------------------
12424 + AAC_AnnounceDriver()
12426 + Announce the driver name, version and date.
12427 + *----------------------------------------------------------------------------*/
12428 +static void AAC_AnnounceDriver( void ){
12429 + printk("<1>%s, %s\n",
12430 + "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12435 +/*------------------------------------------------------------------------------
12436 + AAC_DetectHostAdapter()
12438 + Probe for AAC Host Adapters initialize, register, and report the
12439 + configuration of each AAC Host Adapter found.
12443 + - Returns the number of adapters successfully initialized and
12445 + - Initialize all data necessary for this particular SCSI driver.
12447 + The detect routine must not call any of the mid level functions
12448 + to queue commands because things are not guaranteed to be set
12449 + up yet. The detect routine can send commands to the host adapter
12450 + as long as the program control will not be passed to scsi.c in
12451 + the processing of the command. Note especially that
12452 + scsi_malloc/scsi_free must not be called.
12453 + *----------------------------------------------------------------------------*/
12454 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12458 + uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12459 + struct Scsi_Host *host_ptr;
12460 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12461 + struct pci_dev *dev = NULL;
12462 + extern int NumMiniPorts;
12463 + fsadev_t *fsa_dev_ptr;
12464 + char *DeviceName;
12466 + struct pci_dev *devp;
12468 + int first_index, last_index, increment;
12470 + CommPrinting = TRUE;
12473 + EXPORT_NO_SYMBOLS;
12476 + AAC_AnnounceDriver();
12478 + /* setting up the proc directory structure */
12479 + HostTemplate->proc_name = "aacraid";
12481 + if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12483 + // NumMiniPorts & MiniPorts[] defined in aacid.c
12484 + if (g_options.reverse_scan == 0) {
12486 + last_index = NumMiniPorts;
12489 + first_index = NumMiniPorts -1;
12494 + for( index = first_index; index != last_index; index += increment )
12496 + device_id = MiniPorts[index].DeviceId;
12497 + vendor_id = MiniPorts[index].VendorId;
12498 + DeviceName = MiniPorts[index].DeviceName;
12499 + cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12500 + DeviceName, vendor_id, device_id,
12501 + MiniPorts[index].SubVendorId,
12502 + MiniPorts[index].SubSystemId);
12505 + // pci_find_device traverses the pci_devices linked list for devices
12506 + // with matching vendor and device ids.
12508 + dev = NULL; // start from beginning of list
12509 + while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12511 + if (pci_enable_device(dev)) continue;
12513 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12514 + cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12517 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12518 + cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12522 + cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12523 + if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12524 + ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12529 + printk("<1>%s device detected\n", DeviceName );
12530 + cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12532 + // Increment the host adapter count
12533 + g_HostAdapterCount++;
12535 + // scsi_register() allocates memory for a Scsi_Hosts structure and
12536 + // links it into the linked list of host adapters. This linked list
12537 + // contains the data for all possible <supported> scsi hosts.
12538 + // This is similar to the Scsi_Host_Template, except that we have
12539 + // one entry for each actual physical host adapter on the system,
12540 + // stored as a linked list. If there are two AAC boards, then we
12541 + // will need to make two Scsi_Host entries, but there will be only
12542 + // one Scsi_Host_Template entry. The second argument to scsi_register()
12543 + // specifies the size of the extra memory we want to hold any device
12544 + // specific information.
12545 + host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12547 + // These three parameters can be used to allow for wide SCSI
12548 + // and for host adapters that support multiple buses.
12549 + host_ptr->max_id = 17;
12550 + host_ptr->max_lun = 8;
12551 + host_ptr->max_channel = 1;
12554 + host_ptr->irq = dev->irq; // Adapter IRQ number
12555 + /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12556 + host_ptr->base = ( char * )(dev->resource[0].start);
12557 + scsi_set_pci_device(host_ptr, dev);
12559 + cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12560 + cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12562 + // The unique_id field is a unique identifier that must be assigned
12563 + // so that we have some way of identifying each host adapter properly
12564 + // and uniquely. For hosts that do not support more than one card in the
12565 + // system, this does not need to be set. It is initialized to zero in
12566 + // scsi_register(). This is the value returned from OsGetDeviceInstance().
12568 + host_ptr->unique_id = g_HostAdapterCount - 1;
12569 + host_ptr->this_id = 16; // SCSI Id for the adapter itself
12571 + // Set the maximum number of simultaneous commands supported by the driver.
12572 + host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12574 + // Define the maximum number of scatter/gather elements supported by
12577 + host_ptr->sg_tablesize = 16;
12578 + host_ptr->max_sectors = 128;
12579 + host_ptr->cmd_per_lun = 1; // untagged queue depth
12581 + // This function is called after the device list has been built to find
12582 + // tagged queueing depth supported for each device.
12584 + host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12585 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12587 + // attach a pointer back to Scsi_Host
12588 + CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12589 + CommonExtensionPtr->OsDep.MiniPortIndex = index;
12591 + // Initialize the ordinal number of the device to -1
12592 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12593 + for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12594 + fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12596 + // Call initialization routine
12597 + cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12598 + if( ( *MiniPorts[index].InitRoutine )
12599 + ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12601 + // device initialization failed
12602 + cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12603 + scsi_unregister( host_ptr );
12604 + g_HostAdapterCount--;
12608 + cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12609 + AacHba_ClassDriverInit( CommonExtensionPtr );
12610 + cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12611 + AacHba_ProbeContainers( CommonExtensionPtr );
12612 + g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12616 + } /* end while */
12620 + if( g_HostAdapterCount ){
12621 + if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12622 + cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12625 + HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12627 + return( g_HostAdapterCount );
12631 +/*------------------------------------------------------------------------------
12632 + AAC_ReleaseHostAdapter()
12634 + Release all resources previously acquired to support a specific Host
12635 + Adapter and unregister the AAC Host Adapter.
12636 + *----------------------------------------------------------------------------*/
12637 +int AAC_ReleaseHostAdapter(
12638 + struct Scsi_Host *host_ptr )
12639 +/*----------------------------------------------------------------------------*/
12641 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12643 + cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12645 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12647 + // kill any threads we started
12648 + kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12650 + // Call the comm layer to detach from this adapter
12651 + AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12653 + // remove interrupt binding
12654 + OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12656 + SaDetachDevice( CommonExtensionPtr );
12658 + // unregister adapter
12659 + scsi_unregister( host_ptr );
12661 + if( g_chardev_major )
12663 + unregister_chrdev( g_chardev_major, devicestr );
12664 + g_chardev_major = 0;
12667 + return( 0 ); // #REVISIT# return code
12671 +/*------------------------------------------------------------------------------
12672 + AAC_QueueCommand()
12674 + Queues a command for execution by the associated Host Adapter.
12675 + *----------------------------------------------------------------------------*/
12676 +int AAC_QueueCommand(
12677 + Scsi_Cmnd *scsi_cmnd_ptr,
12678 + void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12679 +/*----------------------------------------------------------------------------*/
12681 + scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12683 + // AacHba_DoScsiCmd() handles command processing, setting the
12684 + // result code and calling completion routine.
12686 + if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 ) ) // called with wait = TRUE
12688 + if( AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 ) ) // called with wait = FALSE
12690 + cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12695 +/*------------------------------------------------------------------------------
12698 + Callback function for a non-queued command.
12701 + Sets g_single_command done to TRUE
12702 + *----------------------------------------------------------------------------*/
12704 + Scsi_Cmnd * scsi_cmnd_ptr )
12705 +/*----------------------------------------------------------------------------*/
12707 + g_single_command_done = TRUE;
12711 +/*------------------------------------------------------------------------------
12714 + Accepts a single command for execution by the associated Host Adapter.
12717 + Returns an int where:
12718 + Byte 0 = SCSI status code
12719 + Byte 1 = SCSI 1 byte message
12720 + Byte 2 = host error return
12721 + Byte 3 = mid level error return
12722 + *----------------------------------------------------------------------------*/
12724 + Scsi_Cmnd *scsi_cmnd_ptr )
12725 +/*----------------------------------------------------------------------------*/
12727 + scsi_cmnd_ptr->scsi_done = AAC_Done;
12729 + cmn_err( CE_DEBUG, "AAC_Command" );
12731 + // AacHba_DoScsiCmd() handles command processing, setting the
12732 + // result code and calling completion routine.
12733 + g_single_command_done = FALSE;
12735 + AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12736 + while( !g_single_command_done );
12737 + return( scsi_cmnd_ptr->result );
12741 +/*------------------------------------------------------------------------------
12742 + AAC_AbortCommand()
12744 + Abort command if possible.
12745 + *----------------------------------------------------------------------------*/
12746 +int AAC_AbortCommand(
12747 + Scsi_Cmnd *scsi_cmnd_ptr )
12748 +/*----------------------------------------------------------------------------*/
12750 + int target = scsi_cmnd_ptr->target;
12751 + int hba = scsi_cmnd_ptr->host->unique_id;
12753 + u_short interrupt_status;
12754 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12755 + char *DeviceName;
12757 + cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12758 + AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12760 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12761 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12764 + cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12765 + "command already completed", DeviceName, hba, target);
12766 + result = SCSI_ABORT_NOT_RUNNING;
12768 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12769 + "no command found\n", DeviceName, hba, target);
12770 + result = SCSI_ABORT_NOT_RUNNING;
12772 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12773 + "command reset\n", DeviceName, hba, target);
12774 + result = SCSI_ABORT_PENDING;
12776 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12777 + "abort tag not supported\n", DeviceName, hba, target);
12778 + result = SCSI_ABORT_SNOOZE;
12780 + cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12781 + DeviceName, hba, target);
12782 + result = SCSI_ABORT_PENDING;
12784 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12785 + DeviceName, hba, target);
12786 + result = SCSI_ABORT_BUSY;
12788 + cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12789 + DeviceName, hba, target);
12790 + result = SCSI_ABORT_SUCCESS;
12793 + // Abort not supported yet
12794 + result = SCSI_ABORT_BUSY;
12799 +/*------------------------------------------------------------------------------
12800 + AAC_ResetCommand()
12802 + Reset command handling.
12803 + *----------------------------------------------------------------------------*/
12804 +int AAC_ResetCommand(
12805 + struct scsi_cmnd *scsi_cmnd_ptr,
12806 + unsigned int reset_flags )
12807 +/*----------------------------------------------------------------------------*/
12809 + int target = scsi_cmnd_ptr->target;
12810 + int hba = scsi_cmnd_ptr->host->unique_id;
12811 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12812 + char *DeviceName;
12814 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12815 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12817 + cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12819 + return SCSI_RESET_PUNT;
12823 +/*------------------------------------------------------------------------------
12826 + Returns the host adapter name
12827 + *----------------------------------------------------------------------------*/
12828 +const char *AAC_DriverInfo(
12829 + struct Scsi_Host *host_ptr )
12830 +/*----------------------------------------------------------------------------*/
12832 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12833 + char *DeviceName;
12835 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12836 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12838 + cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12839 + return (DeviceName);
12843 +/*------------------------------------------------------------------------------
12844 + AAC_BIOSDiskParameters()
12846 + Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12847 + The default disk geometry is 64 heads, 32 sectors, and the appropriate
12848 + number of cylinders so as not to exceed drive capacity. In order for
12849 + disks equal to or larger than 1 GB to be addressable by the BIOS
12850 + without exceeding the BIOS limitation of 1024 cylinders, Extended
12851 + Translation should be enabled. With Extended Translation enabled,
12852 + drives between 1 GB inclusive and 2 GB exclusive are given a disk
12853 + geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12854 + are given a disk geometry of 255 heads and 63 sectors. However, if
12855 + the BIOS detects that the Extended Translation setting does not match
12856 + the geometry in the partition table, then the translation inferred
12857 + from the partition table will be used by the BIOS, and a warning may
12859 + *----------------------------------------------------------------------------*/
12860 +int AAC_BIOSDiskParameters(
12861 + Scsi_Disk *scsi_disk_ptr,
12863 + int *parameter_ptr )
12864 +/*----------------------------------------------------------------------------*/
12866 + AAC_BIOS_DiskParameters_T *disk_parameters =
12867 + ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12868 + struct buffer_head * buffer_head_ptr;
12870 + cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12872 + // Assuming extended translation is enabled - #REVISIT#
12873 + if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12875 + if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12877 + disk_parameters->heads = 255;
12878 + disk_parameters->sectors = 63;
12882 + disk_parameters->heads = 128;
12883 + disk_parameters->sectors = 32;
12888 + disk_parameters->heads = 64;
12889 + disk_parameters->sectors = 32;
12892 + disk_parameters->cylinders = scsi_disk_ptr->capacity
12893 + /( disk_parameters->heads * disk_parameters->sectors );
12895 + // Read the first 1024 bytes from the disk device
12896 + buffer_head_ptr = bread(
12897 + MKDEV( MAJOR( device ),
12898 + MINOR( device ) & ~0x0F ),
12901 + if( buffer_head_ptr == NULL )
12904 + If the boot sector partition table is valid, search for a partition
12905 + table entry whose end_head matches one of the standard geometry
12906 + translations ( 64/32, 128/32, 255/63 ).
12908 + if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12910 + struct partition *first_partition_entry =
12911 + ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12912 + struct partition *partition_entry = first_partition_entry;
12913 + int saved_cylinders = disk_parameters->cylinders;
12914 + int partition_number;
12915 + unsigned char partition_entry_end_head, partition_entry_end_sector;
12917 + for( partition_number = 0; partition_number < 4; partition_number++ )
12919 + partition_entry_end_head = partition_entry->end_head;
12920 + partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12922 + if( partition_entry_end_head == ( 64 - 1 ) )
12924 + disk_parameters->heads = 64;
12925 + disk_parameters->sectors = 32;
12928 + else if( partition_entry_end_head == ( 128 - 1 ) )
12930 + disk_parameters->heads = 128;
12931 + disk_parameters->sectors = 32;
12934 + else if( partition_entry_end_head == ( 255 - 1 ) )
12936 + disk_parameters->heads = 255;
12937 + disk_parameters->sectors = 63;
12940 + partition_entry++;
12943 + if( partition_number == 4 )
12945 + partition_entry_end_head = first_partition_entry->end_head;
12946 + partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12949 + disk_parameters->cylinders = scsi_disk_ptr->capacity
12950 + /( disk_parameters->heads * disk_parameters->sectors );
12952 + if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
12954 + if( disk_parameters->cylinders != saved_cylinders )
12955 + cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12956 + disk_parameters->heads, disk_parameters->sectors, partition_number );
12958 + else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
12960 + cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
12961 + partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
12962 + cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
12963 + disk_parameters->heads, disk_parameters->sectors );
12967 + brelse( buffer_head_ptr );
12973 +/*------------------------------------------------------------------------------
12974 + AAC_SelectQueueDepths()
12976 + Selects queue depths for each target device based on the host adapter's
12977 + total capacity and the queue depth supported by the target device.
12978 + A queue depth of one automatically disables tagged queueing.
12979 + *----------------------------------------------------------------------------*/
12980 +void AAC_SelectQueueDepths(
12981 + struct Scsi_Host * host_ptr,
12982 + Scsi_Device * scsi_device_ptr )
12983 +/*----------------------------------------------------------------------------*/
12985 + Scsi_Device * device_ptr;
12987 + cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
12988 + cmn_err( CE_DEBUG, "Device # Q Depth Online" );
12989 + cmn_err( CE_DEBUG, "---------------------------" );
12990 + for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
12991 + if( device_ptr->host == host_ptr )
12993 + device_ptr->queue_depth = 10;
12994 + cmn_err( CE_DEBUG, " %2d %d %d",
12995 + device_ptr->id, device_ptr->queue_depth, device_ptr->online );
13000 +/*------------------------------------------------------------------------------
13001 + AAC_SearchBiosSignature()
13003 + Locate adapter signature in BIOS
13004 + *----------------------------------------------------------------------------*/
13005 +int AAC_SearchBiosSignature( void )
13006 +/*----------------------------------------------------------------------------*/
13012 + char name_buf[32];
13013 + int result = FALSE;
13015 + for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13017 + val = readb( base );
13018 + if( val != 0x55 )
13022 + namep = base + 0x1e;
13023 + memcpy_fromio( name_buf, namep, 32 );
13024 + name_buf[31] = '\0';
13026 + return( result );
13030 +/*------------------------------------------------------------------------------
13033 + Handle SCSI ioctls
13034 + *----------------------------------------------------------------------------*/
13036 + Scsi_Device * scsi_dev_ptr,
13039 +/*----------------------------------------------------------------------------*/
13041 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13043 + cmn_err( CE_DEBUG, "AAC_Ioctl" );
13044 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13045 + return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13050 +/*------------------------------------------------------------------------------
13051 + AAC_ChardevOpen()
13053 + Handle character device open
13057 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13058 + *----------------------------------------------------------------------------*/
13059 +int AAC_ChardevOpen(
13060 + struct inode * inode_ptr,
13061 + struct file * file_ptr )
13062 +/*----------------------------------------------------------------------------*/
13064 + unsigned minor_number;
13066 + cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13068 + // check device permissions in file_ptr->f_mode ??
13070 + // extract & check the minor number
13071 + minor_number = MINOR( inode_ptr->i_rdev );
13072 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13074 + cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13075 + return( -ENODEV );
13079 + MOD_INC_USE_COUNT;
13086 +/*------------------------------------------------------------------------------
13087 + AAC_ChardevRelease()
13089 + Handle character device release.
13093 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13094 + *----------------------------------------------------------------------------*/
13095 +int AAC_ChardevRelease(
13096 + struct inode * inode_ptr,
13097 + struct file * file_ptr )
13098 +/*----------------------------------------------------------------------------*/
13100 + cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13103 + MOD_DEC_USE_COUNT;
13110 +/*------------------------------------------------------------------------------
13111 + AAC_ChardevIoctl()
13113 + Handle character device interface ioctls
13117 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13118 + *----------------------------------------------------------------------------*/
13119 +int AAC_ChardevIoctl(
13120 + struct inode * inode_ptr,
13121 + struct file * file_ptr,
13122 + unsigned int cmd,
13123 + unsigned long arg )
13125 + unsigned minor_number;
13126 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13128 + cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13130 + // check device permissions in file_ptr->f_mode ??
13132 + // extract & check the minor number
13133 + minor_number = MINOR( inode_ptr->i_rdev );
13134 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13136 + cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13137 + return( -ENODEV );
13140 + // get device pointer
13141 + CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13143 + // dispatch ioctl - AacHba_Ioctl() returns zero on success
13144 + if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13145 + return( -EINVAL );
13151 +/*------------------------------------------------------------------------------
13154 + Look for the keyword in str_ptr
13159 + - return true and update the pointer str_ptr.
13162 + *----------------------------------------------------------------------------*/
13163 +static int parse_keyword(
13166 +/*----------------------------------------------------------------------------*/
13168 + char * ptr = *str_ptr;
13170 + while( *keyword != '\0' )
13172 + char string_char = *ptr++;
13173 + char keyword_char = *keyword++;
13175 + if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13176 + string_char += 'a' - 'Z';
13177 + if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13178 + keyword_char += 'a' - 'Z';
13179 + if( string_char != keyword_char )
13187 +/*------------------------------------------------------------------------------
13188 + AAC_ParseDriverOptions()
13190 + For modules the usage is:
13191 + insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13192 + *----------------------------------------------------------------------------*/
13193 +static void AAC_ParseDriverOptions(
13194 + char * cmnd_line_options_str )
13195 +/*----------------------------------------------------------------------------*/
13197 + int message_level;
13198 + int reverse_scan;
13202 + cp = cmnd_line_options_str;
13204 + cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13207 + if( parse_keyword( &cp, "message_level:" ) ) {
13208 + message_level = simple_strtoul( cp, 0, 0 );
13209 + if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13210 + g_options.message_level = message_level;
13211 + cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13214 + cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13216 + } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13217 + reverse_scan = simple_strtoul( cp, 0, 0 );
13218 + if (reverse_scan) {
13219 + g_options.reverse_scan = 1;
13220 + cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13224 + cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13228 + * skip to next option, accept " ", ";", and "," as delimiters
13230 + while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13233 + if (*cp) /* skip over the delimiter */
13240 +/*------------------------------------------------------------------------------
13241 + Include Module support if requested.
13243 + To use the low level SCSI driver support using the linux kernel loadable
13244 + module interface we should initialize the global variable driver_interface
13245 + (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13246 + This should also be wrapped in a #ifdef MODULE/#endif
13247 + *----------------------------------------------------------------------------*/
13251 + The Loadable Kernel Module Installation Facility may pass us
13252 + a pointer to a driver specific options string to be parsed,
13253 + we assign this to options string.
13255 +MODULE_PARM( module_options, "s" );
13257 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13259 +#include "scsi_module.c"
13262 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13264 +#include "scsi_module.c"
13267 +/*********************************************************************
13268 + AAC_ProcDirectoryInfo()
13270 + Implement /proc/scsi/<drivername>/<n>.
13271 + Used to export driver statistics and other infos to the world outside
13272 + the kernel using the proc file system. Also provides an interface to
13273 + feed the driver with information.
13277 + - if offset > 0 return 0
13278 + - if offset == 0 write data to proc_buffer and set the start_ptr to
13279 + beginning of proc_buffer, return the number of characters written.
13281 + - writes currently not supported, return 0
13282 +************************************************************/
13283 +int AAC_ProcDirectoryInfo(
13284 + char *proc_buffer, // read/write buffer
13285 + char **start_ptr, // start of valid data in the buffer
13286 + off_t offset, // offset from the beginning of the imaginary file
13287 + int bytes_available, // bytes available
13288 + int host_no, // SCSI host number
13289 + int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13292 + cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13294 + if( ( write ) || ( offset > 0 ) )
13297 + *start_ptr = proc_buffer;
13299 + return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13302 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13304 + void *BaseAddress;
13305 + ULONG PhysAddress;
13310 + AFA_COMM_ADAPTER *Adapter;
13311 + Adapter = CommonExtension->Adapter;
13314 + // Allocate 1 fib for synch fibs
13315 + // Allocate 1 page.
13316 + BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13317 + bzero(BaseAddress, PAGE_SIZE);
13318 + PhysAddress = virt_to_phys (BaseAddress);
13319 + Adapter->SyncFib = BaseAddress;
13320 + Adapter->SyncFibPhysicalAddress = PhysAddress;
13321 + cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13324 diff -burN linux-2.4.4/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13325 --- linux-2.4.4/drivers/scsi/aacraid/osddi.c Wed Dec 31 18:00:00 1969
13326 +++ linux/drivers/scsi/aacraid/osddi.c Mon Apr 30 09:43:34 2001
13329 + * Adaptec aacraid device driver for Linux.
13331 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13333 + * This program is free software; you can redistribute it and/or modify
13334 + * it under the terms of the GNU General Public License as published by
13335 + * the Free Software Foundation; either version 2, or (at your option)
13336 + * any later version.
13338 + * This program is distributed in the hope that it will be useful,
13339 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13340 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13341 + * GNU General Public License for more details.
13343 + * You should have received a copy of the GNU General Public License
13344 + * along with this program; see the file COPYING. If not, write to
13345 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13350 + * Abstract: This file contains all the proceedures which use LINUX specific Device
13351 + * Driver Interfaces.
13355 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13357 +#include "osheaders.h"
13359 +#include <linux/smp_lock.h>
13364 +#include "AacGenericTypes.h"
13365 +#include "aac_unix_defs.h"
13366 +#include "comstruc.h"
13367 +#include "monkerapi.h"
13368 +#include "protocol.h"
13369 +#include "fsafs.h"
13371 +#include "sap1common.h"
13372 +#include "fsaport.h"
13373 +#include "pcisup.h"
13375 +#include "nodetype.h"
13376 +#include "comsup.h"
13377 +#include "afacomm.h"
13378 +#include "adapter.h"
13384 + struct pt_regs *regs);
13389 + struct pt_regs *regs);
13391 +unsigned SaPciIsr (
13392 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13394 +unsigned RxPciIsr (
13395 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13398 +/*----------------------------------------------------------------------------*/
13399 +VOID AfaCommInterruptHost(
13400 + PVOID AdapterArg,
13401 + ADAPTER_EVENT AdapterEvent )
13402 +/*----------------------------------------------------------------------------*/
13404 + PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13405 + PCOMM_REGION CommRegion = Adapter->CommRegion;
13407 + switch (AdapterEvent) {
13409 + case HostNormRespQue:
13410 + OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13412 + // #REVIEW# - what do we do with this
13413 + // if (FsaCommData.HardInterruptModeration)
13414 + // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13418 + case AdapNormCmdNotFull:
13419 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13422 + case HostNormCmdQue:
13423 + OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13426 + case AdapNormRespNotFull:
13427 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13430 + // #REVIEW# - what do we do with these
13431 + case HostHighCmdQue:
13432 + case HostHighRespQue:
13433 + case AdapHighCmdNotFull:
13434 + case AdapHighRespNotFull:
13435 + case SynchCommandComplete:
13436 + case AdapInternalError:
13442 +// get the device name associated with this instance of the device
13443 +/*----------------------------------------------------------------------------*/
13444 +char *OsGetDeviceName(
13445 + void *AdapterExtension )
13446 +/*----------------------------------------------------------------------------*/
13448 + return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13449 + OsDep.scsi_host_ptr->hostt->name );
13453 +/*----------------------------------------------------------------------------*/
13454 +int OsGetDeviceInstance(
13455 + void *AdapterExtension )
13456 +/*----------------------------------------------------------------------------*/
13458 + return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13459 + OsDep.scsi_host_ptr->unique_id );
13463 +/*------------------------------------------------------------------------------
13464 + OsMapDeviceRegisters()
13467 + Return zero on success non-zero otherwise.
13468 + *----------------------------------------------------------------------------*/
13469 +int OsMapDeviceRegisters(
13470 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13471 +/*----------------------------------------------------------------------------*/
13473 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13475 + CommonExtension = AdapterExtension->Common;
13477 + if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13478 + ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13480 + cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13485 + cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13491 +/*------------------------------------------------------------------------------
13492 + OsUnMapDeviceRegisters()
13495 + *----------------------------------------------------------------------------*/
13496 +void OsUnMapDeviceRegisters(
13497 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13498 +/*----------------------------------------------------------------------------*/
13500 + iounmap( ( void * )AdapterExtension->Device );
13504 +/*----------------------------------------------------------------------------*/
13505 +int OsAttachInterrupt(
13506 + Sa_ADAPTER_EXTENSION *AdapterExtension ,
13508 +/*----------------------------------------------------------------------------*/
13510 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13514 + CommonExtension = AdapterExtension->Common;
13515 + irq_data = ( void * )AdapterExtension;
13517 + switch (WhichIsr) {
13519 + Isr = AacSaPciIsr;
13522 + Isr = AacRxPciIsr;
13525 + cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13526 + return( FAILURE );
13531 + if ( OsRegisterInterrupt (
13532 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13533 + Isr, // handler function
13537 + cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13538 + CommonExtension->OsDep.scsi_host_ptr->irq );
13539 + return( FAILURE );
13546 +/*----------------------------------------------------------------------------*/
13550 + struct pt_regs *regs)
13551 +/*----------------------------------------------------------------------------*/
13553 + // call the actual interrupt handler
13554 + SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13557 +/*----------------------------------------------------------------------------*/
13561 + struct pt_regs *regs)
13562 +/*----------------------------------------------------------------------------*/
13564 + // call the actual interrupt handler
13565 + RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13569 +/*----------------------------------------------------------------------------*/
13570 +void OsDetachInterrupt(
13571 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13572 +/*----------------------------------------------------------------------------*/
13574 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13577 + CommonExtension = AdapterExtension->Common;
13578 + irq_data = ( void * )AdapterExtension;
13580 + OsUnregisterInterrupt (
13581 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13586 +/*----------------------------------------------------------------------------*/
13588 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13589 +/*----------------------------------------------------------------------------*/
13594 +/*----------------------------------------------------------------------------*/
13596 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13597 +/*----------------------------------------------------------------------------*/
13602 +/*----------------------------------------------------------------------------*/
13603 +void OsDetachDevice(
13604 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13605 +/*----------------------------------------------------------------------------*/
13607 + OsUnMapDeviceRegisters( AdapterExtension );
13611 +/*----------------------------------------------------------------------------*/
13612 +ULONG *OsAllocCommPhysMem(
13613 + Sa_ADAPTER_EXTENSION *AdapterExtension,
13615 + ULONG **virt_addr_pptr,
13616 + ULONG *phys_addr_ptr )
13617 +/*----------------------------------------------------------------------------*/
13619 + if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13621 + *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13622 + if( !*phys_addr_ptr )
13624 + cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13627 + return( *virt_addr_pptr );
13633 +OsAifKernelThread(
13634 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13637 + struct fs_struct *fs;
13639 + struct task_struct *tsk;
13645 + * set up the name that will appear in 'ps'
13646 + * stored in task_struct.comm[16].
13649 + sprintf(tsk->comm, "AIFd");
13652 + // use_init_fs_context(); only exists in 2.2.13 onward.
13659 + * we were started as a result of loading the module.
13660 + * free all of user space pages
13669 + fs = init_task.fs;
13672 + tsk->session = 1;
13676 + atomic_inc(&fs->count);
13685 + NormCommandThread(AdapterExtension);
13686 + /* NOT REACHED */
13689 +/*----------------------------------------------------------------------------*/
13690 +void OsStartKernelThreads(
13691 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13692 +/*----------------------------------------------------------------------------*/
13694 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13695 + AFA_COMM_ADAPTER *Adapter;
13696 + extern void NormCommandThread(void *Adapter);
13698 + CommonExtension = AdapterExtension->Common;
13699 + Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13702 + // Start thread which will handle interrupts for this adapter
13704 + //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13707 + // Start thread which will handle AdapterInititatedFibs from this adapter
13709 + CommonExtension->OsDep.thread_pid =
13710 + kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13711 +// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13714 +/*----------------------------------------------------------------------------*/
13715 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13717 + IN PMAPFIB_CONTEXT MapFibContext )
13718 +/*----------------------------------------------------------------------------*/
13720 + PVOID BaseAddress;
13721 + ULONG PhysAddress;
13723 + if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13725 + cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13729 + PhysAddress = OsVirtToPhys( BaseAddress );
13731 + MapFibContext->FibVirtualAddress = BaseAddress;
13732 + MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13737 +/*----------------------------------------------------------------------------*/
13738 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13740 + IN PMAPFIB_CONTEXT MapFibContext )
13741 +/*----------------------------------------------------------------------------*/
13743 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13745 + OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13750 +/*----------------------------------------------------------------------------*/
13751 +BOOLEAN AfaPortFreeAdapterCommArea(
13753 +/*----------------------------------------------------------------------------*/
13755 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13757 + OsFreeMemory( CommonExtension->CommAddress, 0 );
13763 +/* ================================================================================ */
13765 + * Not sure if the functions below here ever get called in the current code
13766 + * These probably should be a different file.
13769 +ddi_dma_attr_t AfaPortDmaAttributes = {
13770 + //rpbfix : we may want something different for I/O
13787 +AfaPortBuildSgMap(
13789 + IN PSGMAP_CONTEXT SgMapContext
13794 +Routine Description:
13796 + This routine build a scatter gather map using the information
13797 + in the SgMapContext.
13801 + AdapterExtension - Pointer to adapter extension structure.
13802 + SgMapContext - Pointer to the SgMapContext for the request.
13810 + printk( "<1>AfaPortBuildSgMap: unimplemented function called" );
13811 + return (STATUS_UNSUCCESSFUL);
13815 +AfaPortFreeDmaResources(
13817 + IN PSGMAP_CONTEXT SgMapContext
13822 +Routine Description:
13824 + Given a pointer to the IRP context will free all reserved DMA resources allocated for
13825 + the completed IO operation.
13829 + Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13830 + Context - Pointer to the Irp Context we use to store the dma mapping information
13831 + we need to do and complete the IO.
13840 diff -burN linux-2.4.4/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13841 --- linux-2.4.4/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 18:00:00 1969
13842 +++ linux/drivers/scsi/aacraid/osfuncs.c Mon Apr 30 09:43:34 2001
13845 + * Adaptec aacraid device driver for Linux.
13847 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13849 + * This program is free software; you can redistribute it and/or modify
13850 + * it under the terms of the GNU General Public License as published by
13851 + * the Free Software Foundation; either version 2, or (at your option)
13852 + * any later version.
13854 + * This program is distributed in the hope that it will be useful,
13855 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13856 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13857 + * GNU General Public License for more details.
13859 + * You should have received a copy of the GNU General Public License
13860 + * along with this program; see the file COPYING. If not, write to
13861 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13866 + * Abstract: Holds all of the O/S specific interface functions.
13870 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13872 +#include "osheaders.h"
13874 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13876 +extern aac_options_t g_options;
13878 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13879 +wait_queue_t * g_wait_queue_ptr = NULL;
13880 +wait_queue_t g_wait;
13882 +void OsTimeoutHandler(
13883 + struct semaphore * sem );
13885 +int * OsIdleTask( void * data );
13887 +//-----------------------------------------------------------------------------
13888 +// Memory Allocation functions
13890 +/*----------------------------------------------------------------------------*/
13891 +void * OsAllocMemory(
13893 + unsigned int Flags )
13894 +/*----------------------------------------------------------------------------*/
13898 + if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13899 + cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13900 + return( mem_ptr );
13904 +/*----------------------------------------------------------------------------*/
13905 +void OsFreeMemory(
13908 +/*----------------------------------------------------------------------------*/
13914 +/*----------------------------------------------------------------------------*/
13915 +int OsRegisterInterrupt(
13916 + unsigned int irq, // interrupt number
13917 + void ( *handler )( int, void*, struct pt_regs * ), // handler function
13918 + void *irq_data ) // argument to handler function
13919 +/*----------------------------------------------------------------------------*/
13921 + return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13925 +/*----------------------------------------------------------------------------*/
13926 +void OsUnregisterInterrupt(
13927 + unsigned int irq, // interrupt number
13929 +/*----------------------------------------------------------------------------*/
13932 + irq, // interrupt number
13937 +/*----------------------------------------------------------------------------*/
13938 +unsigned long OsVirtToPhys(
13939 + void * virtual_address )
13940 +/*----------------------------------------------------------------------------*/
13942 + return( virt_to_phys( virtual_address ) );
13946 +//-----------------------------------------------------------------------------
13947 +// MUTEX functions
13949 +/*----------------------------------------------------------------------------*/
13950 +OS_STATUS OsMutexInit(
13952 + OS_SPINLOCK_COOKIE Cookie )
13953 +/*----------------------------------------------------------------------------*/
13955 + Mutex->lock_var = 0;
13956 + // bzero (&Mutex->wq, sizeof (Mutex->wq));
13957 + init_waitqueue_head (&Mutex->wq);
13962 +/*----------------------------------------------------------------------------*/
13963 +void OsMutexDestroy(
13964 + OS_MUTEX *Mutex )
13965 +/*----------------------------------------------------------------------------*/
13970 +/*----------------------------------------------------------------------------*/
13971 +void OsMutexAcquire(
13972 + OS_MUTEX *Mutex )
13973 +/*----------------------------------------------------------------------------*/
13975 + // wait_queue_t wait = { current, NULL };
13976 + unsigned long time_stamp;
13978 + DECLARE_WAITQUEUE (wait, current);
13980 + time_stamp = jiffies;
13982 + if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13984 + if( in_interrupt() )
13985 + panic( "OsMutexAcquire going to sleep at interrupt time\n" );
13986 + current->state = TASK_INTERRUPTIBLE;
13987 + add_wait_queue( &( Mutex->wq ), &wait );
13988 + while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
13990 + remove_wait_queue( &( Mutex->wq ), &wait );
13993 + if( ( jiffies - 1 ) > time_stamp )
13994 + cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
13995 + Mutex, jiffies - time_stamp );
13999 +/*----------------------------------------------------------------------------*/
14000 +void OsMutexRelease(
14001 + OS_MUTEX *Mutex )
14002 +/*----------------------------------------------------------------------------*/
14004 + if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14005 + cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14006 + wake_up_interruptible( &( Mutex->wq ) );
14009 +// see man hierarchy(D5)
14010 +#define FSA_LOCK 1
14012 +//-----------------------------------------------------------------------------
14013 +// Spinlock functions
14015 +/*----------------------------------------------------------------------------*/
14016 +OS_SPINLOCK * OsSpinLockAlloc( void )
14017 +/*----------------------------------------------------------------------------*/
14019 + OS_SPINLOCK *SpinLock;
14023 + SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14025 + if (SpinLock == NULL)
14026 + cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14028 + SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14029 + for( i = 0; i < NR_CPUS; i++ )
14030 + SpinLock->cpu_lock_count[ i ] = 0;
14031 + return( SpinLock );
14035 +/*----------------------------------------------------------------------------*/
14036 +OS_STATUS OsSpinLockInit(
14037 + OS_SPINLOCK *SpinLock,
14038 + OS_SPINLOCK_COOKIE Cookie )
14039 +/*----------------------------------------------------------------------------*/
14045 +/*----------------------------------------------------------------------------*/
14046 +void OsSpinLockDestroy(
14047 + OS_SPINLOCK *SpinLock )
14048 +/*----------------------------------------------------------------------------*/
14050 + kfree( SpinLock );
14055 +/*----------------------------------------------------------------------------*/
14056 +void OsSpinLockAcquire(
14057 + OS_SPINLOCK *SpinLock )
14058 +/*----------------------------------------------------------------------------*/
14060 + unsigned cpu_id, i;
14065 + cpu_id = smp_processor_id();
14066 + if( SpinLock->cpu_lock_count[ cpu_id ] ){
14067 + cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14068 + cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14071 + spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14072 + SpinLock->cpu_lock_count[ cpu_id ]++;
14075 + cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14080 +/*----------------------------------------------------------------------------*/
14081 +void OsSpinLockRelease(
14082 + OS_SPINLOCK *SpinLock )
14083 +/*----------------------------------------------------------------------------*/
14087 + SpinLock->cpu_lock_count[ smp_processor_id() ]--;
14088 + spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flag );
14091 + cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14095 +/*----------------------------------------------------------------------------*/
14096 +int OsSpinLockOwned(
14097 + OS_SPINLOCK *SpinLock )
14098 +/*----------------------------------------------------------------------------*/
14101 + if( SpinLock->spin_lock.lock != 0 )
14109 +//-----------------------------------------------------------------------------
14110 +// CvLock functions
14112 +/*----------------------------------------------------------------------------*/
14113 +OS_CVLOCK *OsCvLockAlloc( void )
14115 + OS_CVLOCK *cv_lock;
14118 +#ifdef CVLOCK_USE_SPINLOCK
14119 + cv_lock = OsSpinLockAlloc();
14121 + cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14122 + cv_lock->wq = NULL;
14123 + cv_lock->lock_var = 0;
14126 + return( cv_lock );
14130 +/*----------------------------------------------------------------------------*/
14131 +OS_STATUS OsCvLockInit(
14132 + OS_CVLOCK *cv_lock,
14133 + OS_SPINLOCK_COOKIE Cookie )
14134 +/*----------------------------------------------------------------------------*/
14140 +/*----------------------------------------------------------------------------*/
14141 +void OsCvLockDestroy(
14142 + OS_CVLOCK *cv_lock )
14143 +/*----------------------------------------------------------------------------*/
14146 + kfree( cv_lock );
14151 +/*----------------------------------------------------------------------------*/
14152 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14154 +#ifdef CVLOCK_USE_SPINLOCK
14155 + OsSpinLockAcquire( cv_lock );
14157 + OsMutexAcquire( cv_lock );
14162 +/*----------------------------------------------------------------------------*/
14163 +void OsCvLockRelease(
14164 + OS_CVLOCK *cv_lock )
14165 +/*----------------------------------------------------------------------------*/
14167 +#ifdef CVLOCK_USE_SPINLOCK
14168 + OsSpinLockRelease( cv_lock );
14170 + OsMutexRelease( cv_lock );
14175 +/*----------------------------------------------------------------------------*/
14176 +int OsCvLockOwned(
14177 + OS_CVLOCK *cv_lock )
14178 +/*----------------------------------------------------------------------------*/
14184 +//-----------------------------------------------------------------------------
14185 +// Conditional variable functions
14187 +/*----------------------------------------------------------------------------*/
14189 + OS_CV_T *cv_ptr )
14190 +/*----------------------------------------------------------------------------*/
14192 + cv_ptr->lock_var = 1;
14193 + init_waitqueue_head (&cv_ptr->wq);
14197 +/*----------------------------------------------------------------------------*/
14198 +void OsCv_destroy(
14199 + OS_CV_T *cv_ptr )
14200 +/*----------------------------------------------------------------------------*/
14205 +/*______________________________________________________________________________
14208 + -----------------------------------------------------------------------------*/
14209 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14211 + unsigned long flags;
14213 + DECLARE_WAITQUEUE (wait, current);
14215 + if( in_interrupt() )
14216 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14218 + cv_ptr->type = TASK_UNINTERRUPTIBLE;
14219 + current->state = TASK_UNINTERRUPTIBLE;
14221 + add_wait_queue( &cv_ptr->wq, &wait );
14223 + OsCvLockRelease( cv_lock_ptr );
14226 + while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14228 + if( in_interrupt() )
14229 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14233 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14235 + OsCvLockAcquire( cv_lock_ptr );
14239 +/*----------------------------------------------------------------------------*/
14240 +int OsCv_wait_sig(
14242 + OS_CVLOCK *cv_lock_ptr )
14243 +/*----------------------------------------------------------------------------*/
14245 + unsigned long flags;
14246 + int signal_state = 1;
14248 + DECLARE_WAITQUEUE (wait, current);
14250 + if( in_interrupt() )
14251 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14253 + cv_ptr->type = TASK_INTERRUPTIBLE;
14254 + current->state = TASK_INTERRUPTIBLE;
14256 + add_wait_queue( &( cv_ptr->wq ), &wait );
14258 + OsCvLockRelease( cv_lock_ptr );
14261 + while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14262 + ( !signal_pending( current ) ) )
14264 + if( in_interrupt() )
14265 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14269 + if( signal_pending( current ) )
14270 + signal_state = 0;
14272 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14274 + OsCvLockAcquire( cv_lock_ptr );
14275 + return( signal_state );
14279 +/*----------------------------------------------------------------------------*/
14281 + OS_CV_T *cv_ptr )
14282 +/*----------------------------------------------------------------------------*/
14285 + clear_bit( 0, &( cv_ptr->lock_var ) );
14286 + if( cv_ptr->type == TASK_INTERRUPTIBLE )
14287 + wake_up_interruptible( &( cv_ptr->wq ) );
14289 + wake_up( &( cv_ptr->wq ) );
14294 +// return time in seconds
14295 +/*----------------------------------------------------------------------------*/
14296 +unsigned long OsGetSeconds( void )
14297 +/*----------------------------------------------------------------------------*/
14299 + return( jiffies/HZ );
14303 +//-----------------------------------------------------------------------------
14304 +// Deferred procedure call functions
14306 +// create a soft interrupt object
14307 +/*----------------------------------------------------------------------------*/
14308 +int OsSoftInterruptAdd(
14309 + OS_SOFTINTR **ptr,
14312 +/*----------------------------------------------------------------------------*/
14314 + OS_SOFTINTR *tmp_ptr;
14316 + if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14318 + tmp_ptr->routine = handler;
14319 + tmp_ptr->data = data;
14320 + tmp_ptr->sync = 0;
14328 + Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14330 +/*----------------------------------------------------------------------------*/
14331 +int * OsIdleTask( void * data )
14332 +/*----------------------------------------------------------------------------*/
14334 + DECLARE_WAITQUEUE (wait, current);
14338 + current->state = TASK_INTERRUPTIBLE;
14339 + add_wait_queue( &g_wait_queue_ptr, &wait );
14341 + remove_wait_queue( &g_wait_queue_ptr, &wait );
14342 + wait.task = current;
14343 + wait.task_list.next = NULL;
14349 +// dispatch a soft interrupt
14350 +/*----------------------------------------------------------------------------*/
14351 +void OsSoftInterruptTrigger(
14352 + OS_SOFTINTR *soft_intr_ptr )
14353 +/*----------------------------------------------------------------------------*/
14355 + // call the completion routine directly
14356 + soft_intr_ptr->routine( soft_intr_ptr->data );
14360 +// delete a soft interrupt object
14361 +/*----------------------------------------------------------------------------*/
14362 +void OsSoftInterruptRemove(
14363 + OS_SOFTINTR *arg )
14364 +/*----------------------------------------------------------------------------*/
14372 +/*----------------------------------------------------------------------------*/
14374 + unsigned time ) // in seconds
14375 +/*----------------------------------------------------------------------------*/
14377 + struct semaphore sem;
14378 + struct timer_list timer_var;
14380 + init_MUTEX_LOCKED (&sem);
14382 + // if( in_interrupt() )
14383 + // panic( "OsSleep going to sleep at interrupt time\n" );
14385 + init_timer( &timer_var );
14386 + timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14387 + timer_var.data = ( unsigned long )&sem;
14388 + timer_var.expires = jiffies + time * HZ;
14390 + add_timer( &timer_var );
14393 + del_timer( &timer_var );
14397 +/*----------------------------------------------------------------------------*/
14398 +void OsTimeoutHandler(
14399 + struct semaphore * sem )
14400 +/*----------------------------------------------------------------------------*/
14402 + if( sem != NULL )
14407 +/*----------------------------------------------------------------------------*/
14412 +/*----------------------------------------------------------------------------*/
14417 + va_start(ap, fmt);
14418 + (void) vsprintf(buf, fmt, ap);
14421 + if( flag <= g_options.message_level )
14422 + printk("<1>%s\n", buf);
14425 +/* void aac_show_tasks (struct list_head *our_tasks){ */
14427 +/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14429 +/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14430 +/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14432 +/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14434 +/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14435 +/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14437 +/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14440 diff -burN linux-2.4.4/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14441 --- linux-2.4.4/drivers/scsi/aacraid/ossup.c Wed Dec 31 18:00:00 1969
14442 +++ linux/drivers/scsi/aacraid/ossup.c Mon Apr 30 09:43:34 2001
14445 + * Adaptec aacraid device driver for Linux.
14447 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14449 + * This program is free software; you can redistribute it and/or modify
14450 + * it under the terms of the GNU General Public License as published by
14451 + * the Free Software Foundation; either version 2, or (at your option)
14452 + * any later version.
14454 + * This program is distributed in the hope that it will be useful,
14455 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14456 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14457 + * GNU General Public License for more details.
14459 + * You should have received a copy of the GNU General Public License
14460 + * along with this program; see the file COPYING. If not, write to
14461 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14470 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14472 +#include "osheaders.h"
14474 +#include "aac_unix_defs.h"
14479 + IN PZONE_HEADER Zone,
14480 + IN ULONG BlockSize,
14481 + IN PVOID InitialSegment,
14482 + IN ULONG InitialSegmentSize
14487 +Routine Description:
14489 + This function initializes a zone header. Once successfully
14490 + initialized, blocks can be allocated and freed from the zone, and
14491 + the zone can be extended.
14495 + Zone - Supplies the address of a zone header to be initialized.
14497 + BlockSize - Supplies the block size of the allocatable unit within
14498 + the zone. The size must be larger that the size of the
14499 + initial segment, and must be 64-bit aligned.
14501 + InitialSegment - Supplies the address of a segment of storage. The
14502 + first ZONE_SEGMENT_HEADER-sized portion of the segment
14503 + is used by the zone allocator. The remainder of
14504 + the segment is carved up into fixed size
14505 + (BlockSize) blocks and is made available for
14506 + allocation and deallocation from the zone. The
14507 + address of the segment must be aligned on a 64-bit
14510 + InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14514 + STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14515 + 64-bit boundaries, or BlockSize was larger than
14516 + the initial segment size.
14518 + STATUS_SUCCESS - The zone was successfully initialized.
14527 + Zone->BlockSize = BlockSize;
14529 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14530 + ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14531 + ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14533 + Zone->FreeList.Next = NULL;
14535 + p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14537 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14538 + i <= InitialSegmentSize - BlockSize;
14541 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14542 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14545 + Zone->TotalSegmentSize = i;
14548 + DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14549 + Zone, InitialSegment, InitialSegmentSize,
14554 + return STATUS_SUCCESS;
14559 + IN PZONE_HEADER Zone,
14560 + IN PVOID Segment,
14561 + IN ULONG SegmentSize
14566 +Routine Description:
14568 + This function extends a zone by adding another segment's worth of
14569 + blocks to the zone.
14573 + Zone - Supplies the address of a zone header to be extended.
14575 + Segment - Supplies the address of a segment of storage. The first
14576 + ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14577 + zone allocator. The remainder of the segment is carved up
14578 + into fixed-size (BlockSize) blocks and is added to the
14579 + zone. The address of the segment must be aligned on a 64-
14582 + SegmentSize - Supplies the size in bytes of Segment.
14586 + STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14587 + 64-bit boundaries, or BlockSize was larger than
14588 + the segment size.
14590 + STATUS_SUCCESS - The zone was successfully extended.
14599 + ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14600 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14602 + p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14604 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14605 + i <= SegmentSize - Zone->BlockSize;
14606 + i += Zone->BlockSize
14609 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14610 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14611 + p += Zone->BlockSize;
14613 + Zone->TotalSegmentSize += i;
14616 + DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14617 + Zone, Segment, SegmentSize, Zone->BlockSize, p
14621 + return STATUS_SUCCESS;
14628 +/* Function: InqStrCopy()
14630 + * Arguments: [2] pointer to char
14632 + * Purpose: Copy a String from one location to another
14633 + * without copying \0
14636 +InqStrCopy(char *a, char *b)
14639 + while(*a != (char)0)
14643 diff -burN linux-2.4.4/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14644 --- linux-2.4.4/drivers/scsi/aacraid/port.c Wed Dec 31 18:00:00 1969
14645 +++ linux/drivers/scsi/aacraid/port.c Mon Apr 30 09:43:34 2001
14648 + * Adaptec aacraid device driver for Linux.
14650 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14652 + * This program is free software; you can redistribute it and/or modify
14653 + * it under the terms of the GNU General Public License as published by
14654 + * the Free Software Foundation; either version 2, or (at your option)
14655 + * any later version.
14657 + * This program is distributed in the hope that it will be useful,
14658 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14659 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14660 + * GNU General Public License for more details.
14662 + * You should have received a copy of the GNU General Public License
14663 + * along with this program; see the file COPYING. If not, write to
14664 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14669 + * Abstract: All support routines for FSA communication which are miniport specific.
14673 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14675 +#include "osheaders.h"
14678 +#include "AacGenericTypes.h"
14680 +#include "aac_unix_defs.h"
14682 +#include "fsatypes.h"
14683 +#include "comstruc.h"
14684 +#include "protocol.h"
14686 +#include "fsaport.h"
14687 +#include "fsaioctl.h"
14689 +#include "pcisup.h"
14692 +int AfaPortPrinting = 1;
14694 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14695 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14696 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14697 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14703 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14704 + IN AAC_STATUS ErrorCode,
14705 + IN PUCHAR StringBuffer,
14706 + IN ULONG StringLength
14710 +Routine Description:
14712 + Does all of the work to log an error log entry
14715 + CommonExtension - Pointer to the adapter that caused the error.
14717 + ErrorCode - Which error is being logged.
14719 + StringBuffer - Pointer to optional String for error log entry.
14721 + StringLength - Length of StringBuffer.
14734 +AfaPortGetNextAdapterNumber(
14735 + IN PDRIVER_OBJECT DriverObject,
14736 + OUT PDEVICE_OBJECT *FsaDeviceObject,
14737 + OUT PFILE_OBJECT *FileObject,
14738 + OUT PULONG AdapterNumber
14743 +AfaPortAllocateAdapterCommArea(
14745 + IN OUT PVOID *CommHeaderAddress,
14746 + IN ULONG CommAreaSize,
14747 + IN ULONG CommAreaAlignment
14750 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14751 + PVOID BaseAddress;
14752 + PHYSICAL_ADDRESS PhysicalBaseAddress;
14753 + ULONG TotalSize, BytesToAlign;
14754 + size_t RealLength;
14756 +// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14757 +// ULONG AdapterFibsSize = PAGE_SIZE;
14758 + ULONG AdapterFibsSize = 4096;
14759 + ULONG PrintfBufferSize = 256;
14760 + PADAPTER_INIT_STRUCT InitStruct;
14761 + extern int MiniPortRevision;
14762 + ULONG PhysAddress;
14764 +// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14765 +// SizeOfFastIoComm + PrintfBufferSize;
14766 + TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14767 + PrintfBufferSize;
14770 + OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14772 + CommonExtension->CommAddress = BaseAddress;
14773 + CommonExtension->CommPhysAddr = PhysAddress;
14774 + CommonExtension->CommSize = TotalSize;
14776 + PhysicalBaseAddress.HighPart = 0;
14777 + PhysicalBaseAddress.LowPart = PhysAddress;
14779 + CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14780 + CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14782 + InitStruct = CommonExtension->InitStruct;
14784 + InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14785 + InitStruct->MiniPortRevision = MiniPortRevision;
14786 + InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14789 + // Adapter Fibs are the first thing allocated so that they start page aligned
14791 + InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14792 + InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14793 + InitStruct->AdapterFibsSize = AdapterFibsSize;
14794 + InitStruct->AdapterFibAlign = sizeof(FIB);
14797 + // Increment the base address by the amount already used
14799 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14800 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14803 + // Align the beginning of Headers to CommAreaAlignment
14805 + BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14806 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14807 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14810 + // Fill in addresses of the Comm Area Headers and Queues
14812 + *CommHeaderAddress = BaseAddress;
14813 + InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14816 + // Increment the base address by the size of the CommArea
14818 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14819 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14823 + // Place the Printf buffer area after the Fast I/O comm area.
14825 + CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14826 + InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14827 + InitStruct->PrintfBufferSize = PrintfBufferSize;
14828 + bzero (BaseAddress, PrintfBufferSize);
14830 + AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14831 + TotalSize, InitStruct->AdapterFibsVirtualAddress,
14832 + (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14834 + AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14841 + IN PDEVICE_OBJECT DeviceObject,
14846 +Routine Description:
14848 + The routine will get called each time a user issues a CreateFile on the DeviceObject
14851 + The main purpose of this routine is to set up any data structures that may be needed
14852 + to handle any requests made on this DeviceObject.
14856 + DeviceObject - Pointer to device object representing adapter
14858 + Irp - Pointer to Irp that caused this open
14863 + Status value returned from File system driver AdapterOpen
14872 + IN PDEVICE_OBJECT DeviceObject,
14877 +Routine Description:
14879 + This routine will get called each time a user issues a CloseHandle on the DeviceObject
14882 + The main purpose of this routine is to cleanup any data structures that have been set up
14883 + while this FileObject has been opened.
14887 + DeviceObject - Pointer to device object representing adapter
14889 + Irp - Pointer to Irp that caused this close
14893 + Status value returned from File system driver AdapterClose
14902 +AfaPortDeviceControl (
14903 + IN PDEVICE_OBJECT DeviceObject,
14911 +AfaPortGetMaxPhysicalPage(
14912 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14916 +Routine Description:
14918 + This routine determines the max physical page in host memory.
14926 + Max physical page in host memory.
14934 diff -burN linux-2.4.4/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14935 --- linux-2.4.4/drivers/scsi/aacraid/rx.c Wed Dec 31 18:00:00 1969
14936 +++ linux/drivers/scsi/aacraid/rx.c Mon Apr 30 09:43:34 2001
14939 + * Adaptec aacraid device driver for Linux.
14941 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14943 + * This program is free software; you can redistribute it and/or modify
14944 + * it under the terms of the GNU General Public License as published by
14945 + * the Free Software Foundation; either version 2, or (at your option)
14946 + * any later version.
14948 + * This program is distributed in the hope that it will be useful,
14949 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14950 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14951 + * GNU General Public License for more details.
14953 + * You should have received a copy of the GNU General Public License
14954 + * along with this program; see the file COPYING. If not, write to
14955 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14960 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
14964 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
14966 +#include "osheaders.h"
14969 +#include "AacGenericTypes.h"
14971 +#include "aac_unix_defs.h"
14973 +#include "fsatypes.h"
14974 +#include "comstruc.h"
14975 +#include "fsact.h"
14976 +#include "protocol.h"
14978 +#define DEFINE_PCI_IDS
14979 +#include "rxcommon.h"
14980 +#include "monkerapi.h"
14982 +#include "fsaport.h"
14983 +#include "fsaioctl.h"
14985 +#include "pcisup.h"
14990 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
14992 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
14994 +#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
14996 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15000 +// The list of all the Rx adapter structures
15003 +PRx_ADAPTER_EXTENSION RxAdapterList;
15007 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15008 + IN ULONG AdapterNumber,
15016 + ULONG FibPhysicalAddress
15019 +FSA_USER_VAR RxUserVars[] = {
15020 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15025 +// Declare private use routines for this modual
15030 + IN PRx_ADAPTER_EXTENSION AdapterExtension
15035 +Routine Description:
15037 + The Isr routine for fsa Rx based adapter boards.
15044 + TRUE - if the interrupt was handled by this isr
15045 + FALSE - if the interrupt was not handled by this isr
15050 + ULONG DoorbellBits;
15051 + UCHAR InterruptStatus, Mask;
15052 + u_int OurInterrupt = INTR_UNCLAIMED;
15054 + //cmn_err(CE_WARN, "RxPciIsr entered\n");
15056 + InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15059 + // Read mask and invert because drawbridge is reversed.
15061 + // This allows us to only service interrupts that have been enabled.
15064 + Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15066 + // Check to see if this is our interrupt. If it isn't just return FALSE.
15069 + if (InterruptStatus & Mask) {
15071 + DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15073 + OurInterrupt = INTR_CLAIMED;
15075 + if (DoorbellBits & DoorBellPrintfReady) {
15077 + ULONG Length, Level;
15078 + unsigned char *cp;
15080 + cp = AdapterExtension->Common->PrintfBufferAddress;
15083 + // The size of the Printfbuffer is set in port.c
15084 + // There is no variable or define for it
15086 + if (Length > 255)
15089 + if (cp[Length] != 0) {
15090 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15094 + if (Level == LOG_HIGH_ERROR)
15095 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15097 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15099 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15101 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15103 + Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15106 + } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15108 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15109 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15111 + } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15113 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15114 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15116 + } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15118 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15119 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15121 + } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15123 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15124 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15129 + return(OurInterrupt);
15133 +RxEnableInterrupt(
15135 + ADAPTER_EVENT AdapterEvent,
15136 + BOOLEAN AtDeviceIrq
15140 +Routine Description:
15142 + This routine will enable the corresponding adapter event to cause an interrupt on
15147 + AdapterExtension - Which adapter to enable.
15149 + AdapterEvent - Which adapter event.
15151 + AtDeviceIrq - Whether the system is in DEVICE irql
15159 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15160 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15162 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15163 + switch (AdapterEvent) {
15165 + case HostNormCmdQue:
15167 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15171 + case HostNormRespQue:
15173 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15177 + case AdapNormCmdNotFull:
15179 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15183 + case AdapNormRespNotFull:
15185 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15194 +RxDisableInterrupt(
15196 + ADAPTER_EVENT AdapterEvent,
15197 + BOOLEAN AtDeviceIrq
15201 +Routine Description:
15203 + This routine will disable the corresponding adapter event to cause an interrupt on
15208 + AdapterExtension - Which adapter to enable.
15210 + AdapterEvent - Which adapter event.
15212 + AtDeviceIrq - Whether the system is in DEVICE irql
15220 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15221 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15223 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15225 + switch (AdapterEvent) {
15228 + case HostNormCmdQue:
15230 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15234 + case HostNormRespQue:
15236 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15240 + case AdapNormCmdNotFull:
15242 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15247 + case AdapNormRespNotFull:
15249 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15260 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15263 + PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15266 + // Free the register mapping.
15269 + OsDetachDevice( AdapterExtension);
15271 + OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15277 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15278 + IN ULONG AdapterNumber,
15285 +Routine Description:
15287 + Scans the PCI bus looking for the Rx card. When found all resources for the
15288 + device will be allocated and the interrupt vectors and csrs will be allocated and
15291 + The device_interface in the commregion will be allocated and linked to the comm region.
15298 + TRUE - if the device was setup with not problems
15299 + FALSE - if the device could not be mapped and init successfully
15304 + AAC_STATUS Status;
15305 + PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15306 + FSA_NEW_ADAPTER NewAdapter;
15307 + ULONG StartTime, EndTime, WaitTime;
15308 + ULONG InitStatus;
15313 + AfaPortPrint("In init device.\n");
15315 + //cmn_err(CE_WARN, "In RxInitDevice");
15317 +// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15318 + CommonExtension->AdapterNumber = AdapterNumber;
15321 + CommonExtension->PciBusNumber = PciBus;
15322 + CommonExtension->PciSlotNumber = PciSlot;
15325 + AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15326 + AdapterExtension->Common = CommonExtension;
15327 + CommonExtension->MiniPort = AdapterExtension;
15329 + instance = OsGetDeviceInstance(AdapterExtension);
15330 + name = OsGetDeviceName(AdapterExtension);
15332 + // Map in the registers from the adapter, register space 0 is config space,
15333 + // register space 1 is the memery space.
15336 + if (OsMapDeviceRegisters(AdapterExtension)) {
15338 + cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15339 + OsGetDeviceName(AdapterExtension), instance);
15344 + // Check to see if the board failed any self tests.
15347 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15349 + cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15350 + OsGetDeviceName(AdapterExtension), instance);
15354 + //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15355 + // OsGetDeviceName(AdapterExtension), instance);
15358 + // Check to see if the board panic'd while booting.
15361 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15363 + cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15364 + OsGetDeviceName(AdapterExtension), instance);
15369 + StartTime = OsGetSeconds();
15374 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
15377 + while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15379 + EndTime = OsGetSeconds();
15381 + WaitTime = EndTime - StartTime;
15383 + if ( WaitTime > (3 * 10) ) {
15385 + InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15387 + cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15388 + OsGetDeviceName(AdapterExtension), instance, InitStatus);
15394 + if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15395 + cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15400 + if (OsAttachDMA(AdapterExtension)) {
15401 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15406 + // Fill in the function dispatch table.
15409 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15410 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15411 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15412 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15413 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15414 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15415 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15416 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15417 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15418 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15419 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15420 + AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15421 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15423 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15425 + NewAdapter.AdapterExtension = CommonExtension;
15426 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15427 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15428 + NewAdapter.AdapterUserVars = RxUserVars;
15429 + NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15431 + NewAdapter.Dip = CommonExtension->OsDep.dip;
15434 + if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15436 + cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15437 + return (FAILURE);
15441 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15443 + if (AdapterExtension->Common->Adapter == NULL) {
15445 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15446 + cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15449 + return (FAILURE);
15454 + // Start any kernel threads needed
15456 + OsStartKernelThreads(AdapterExtension);
15459 + // Tell the adapter that all is configure, and it can start accepting requests
15462 + RxStartAdapter(AdapterExtension);
15470 + // Put this adapter into the list of Rx adapters
15473 + AdapterExtension->Next = RxAdapterList;
15474 + RxAdapterList = AdapterExtension;
15476 + AdapterExtension->Common->AdapterConfigured = TRUE;
15481 + // Call the disk layer to initialize itself.
15484 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15490 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15494 + OsAttachHBA(AdapterExtension);
15501 + PRx_ADAPTER_EXTENSION AdapterExtension
15504 + ULONG ReturnStatus;
15505 + LARGE_INTEGER HostTime;
15506 + ULONG ElapsedSeconds;
15507 + PADAPTER_INIT_STRUCT InitStruct;
15509 + //cmn_err(CE_WARN, "RxStartAdapter");
15511 + // Fill in the remaining pieces of the InitStruct.
15514 + InitStruct = AdapterExtension->Common->InitStruct;
15516 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15518 + ElapsedSeconds = OsGetSeconds();
15520 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
15523 + // Tell the adapter we are back and up and running so it will scan its command
15524 + // queues and enable our interrupts
15527 + AdapterExtension->LocalMaskInterruptControl =
15528 + (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15531 + // First clear out all interrupts. Then enable the one's that we can handle.
15534 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15535 + Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15536 +// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15537 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15539 + RxSendSynchCommand(AdapterExtension,
15540 + INIT_STRUCT_BASE_ADDRESS,
15541 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15559 +RxInterruptAdapter(
15564 +Routine Description:
15566 + The will cause the adapter to take a break point.
15578 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15579 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15581 + ULONG ReturnStatus;
15583 + RxSendSynchCommand(AdapterExtension,
15584 + BREAKPOINT_REQUEST,
15596 + IN HOST_2_ADAP_EVENT AdapterEvent
15600 +Routine Description:
15602 + Will read the adapter CSRs to find the reason the adapter has
15607 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15615 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15616 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15617 + ULONG ReturnStatus;
15619 + //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15621 + switch (AdapterEvent) {
15622 + case AdapNormCmdQue:
15624 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15627 + case HostNormRespNotFull:
15629 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15632 + case AdapNormRespQue:
15634 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15637 + case HostNormCmdNotFull:
15639 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15642 + case HostShutdown:
15644 +// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15649 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15652 + case AdapPrintfDone:
15653 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15658 + RxBugCheck(0,0,0);
15659 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15665 +RxSendSynchCommand(
15668 + ULONG Parameter1,
15669 + ULONG Parameter2,
15670 + ULONG Parameter3,
15671 + ULONG Parameter4,
15672 + PULONG ReturnStatus
15676 +Routine Description:
15678 + This routine will send a synchronous comamnd to the adapter and wait for its
15683 + AdapterExtension - Pointer to adapter extension structure.
15684 + Command - Which command to send
15685 + Parameter1 - 4 - Parameters for command
15686 + ReturnStatus - return status from adapter after completion of command
15695 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15696 + ULONG StartTime,EndTime,WaitTime;
15697 + BOOLEAN CommandSucceeded;
15699 + //cmn_err(CE_WARN, "RxSendSyncCommand");
15701 + // Write the Command into Mailbox 0
15704 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15707 + // Write the parameters into Mailboxes 1 - 4
15710 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15711 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15712 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15713 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15716 + // Clear the synch command doorbell to start on a clean slate.
15719 + Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15722 + // disable doorbell interrupts
15725 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15726 + Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15729 + // force the completion of the mask register write before issuing the interrupt.
15732 + Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15735 + // Signal that there is a new synch command
15738 + Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15740 + CommandSucceeded = FALSE;
15742 + StartTime = OsGetSeconds();
15745 + while (WaitTime < 30) { // wait up to 30 seconds
15747 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15750 + // Mon110 will set doorbell0 bit when it has completed the command.
15753 + if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15756 + // clear the doorbell.
15759 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15761 + CommandSucceeded = TRUE;
15765 + EndTime = OsGetSeconds();
15766 + WaitTime = EndTime - StartTime;
15770 + if (CommandSucceeded != TRUE) {
15773 + // restore interrupt mask even though we timed out
15776 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15777 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15779 + return (STATUS_IO_TIMEOUT);
15784 + // Pull the synch status from Mailbox 0.
15787 + *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15790 + // Clear the synch command doorbell.
15793 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15796 + // restore interrupt mask
15799 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15800 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15803 + // Return SUCCESS
15806 + return (STATUS_SUCCESS);
15813 + ULONG FibPhysicalAddress
15817 +Routine Description:
15819 + This routine will send a synchronous fib to the adapter and wait for its
15824 + AdapterExtension - Pointer to adapter extension structure.
15825 + FibPhysicalAddress - Physical address of fib to send.
15834 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15835 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15836 + ULONG returnStatus;
15838 + if (RxSendSynchCommand( AdapterExtension,
15839 + SEND_SYNCHRONOUS_FIB,
15840 + FibPhysicalAddress,
15844 + &returnStatus ) != STATUS_SUCCESS ) {
15855 diff -burN linux-2.4.4/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15856 --- linux-2.4.4/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 18:00:00 1969
15857 +++ linux/drivers/scsi/aacraid/sap1sup.c Mon Apr 30 09:43:34 2001
15860 + * Adaptec aacraid device driver for Linux.
15862 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15864 + * This program is free software; you can redistribute it and/or modify
15865 + * it under the terms of the GNU General Public License as published by
15866 + * the Free Software Foundation; either version 2, or (at your option)
15867 + * any later version.
15869 + * This program is distributed in the hope that it will be useful,
15870 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15871 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15872 + * GNU General Public License for more details.
15874 + * You should have received a copy of the GNU General Public License
15875 + * along with this program; see the file COPYING. If not, write to
15876 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15881 + * Abstract: Drawbridge specific support functions
15885 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15887 +#include "osheaders.h"
15890 +#include "AacGenericTypes.h"
15892 +#include "aac_unix_defs.h"
15894 +#include "fsatypes.h"
15895 +#include "comstruc.h"
15896 +#include "fsact.h"
15897 +#include "protocol.h"
15899 +#define DEFINE_PCI_IDS
15900 +#include "sap1common.h"
15901 +#include "monkerapi.h"
15903 +#include "fsaport.h"
15904 +#include "fsaioctl.h"
15907 +#include "pcisup.h"
15912 +#include "nodetype.h"
15913 +#include "comsup.h"
15914 +#include "afacomm.h"
15915 +#include "adapter.h"
15917 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15919 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15921 +#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15923 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15925 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15929 +// The list of all the Sa adapter structures
15932 +PSa_ADAPTER_EXTENSION SaAdapterList;
15936 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15937 + IN ULONG AdapterNumber,
15945 + ULONG FibPhysicalAddress
15948 +FSA_USER_VAR SaUserVars[] = {
15949 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15954 +// Declare private use routines for this modual
15960 +Routine Description:
15962 + The Isr routine for fsa Sa based adapter boards.
15969 + TRUE - if the interrupt was handled by this isr
15970 + FALSE - if the interrupt was not handled by this isr
15974 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
15976 + USHORT InterruptStatus, Mask;
15977 + u_int OurInterrupt = INTR_UNCLAIMED;
15979 + InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
15982 + // Read mask and invert because drawbridge is reversed.
15984 + // This allows us to only service interrupts that have been enabled.
15987 + Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
15989 + // Check to see if this is our interrupt. If it isn't just return FALSE.
15992 + if (InterruptStatus & Mask) {
15994 + OurInterrupt = INTR_CLAIMED;
15996 + if (InterruptStatus & PrintfReady) {
15998 + ULONG Length, Level;
15999 + unsigned char *cp;
16001 + cp = AdapterExtension->Common->PrintfBufferAddress;
16004 + // The size of the Printbuffer is set in port.c
16005 + // There is no variable or define for it
16007 + if (Length > 255)
16010 + if (cp[Length] != 0) {
16011 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16015 + if (Level == LOG_HIGH_ERROR)
16016 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16018 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16020 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16022 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16024 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16026 + } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
16028 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16029 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16031 + } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
16033 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16034 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16036 + } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
16038 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16039 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16041 + } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
16043 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16044 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16049 + return(OurInterrupt);
16055 +Routine Description:
16057 + This routine will enable the corresponding adapter event to cause an interrupt on
16062 + AdapterExtension - Which adapter to enable.
16064 + AdapterEvent - Which adapter event.
16066 + AtDeviceIrq - Whether the system is in DEVICE irql
16074 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16076 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16077 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16079 + switch (AdapterEvent) {
16081 + case HostNormCmdQue:
16083 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16087 + case HostNormRespQue:
16089 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16093 + case AdapNormCmdNotFull:
16095 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16099 + case AdapNormRespNotFull:
16101 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16113 +Routine Description:
16115 + This routine will disable the corresponding adapter event to cause an interrupt on
16120 + AdapterExtension - Which adapter to enable.
16122 + AdapterEvent - Which adapter event.
16124 + AtDeviceIrq - Whether the system is in DEVICE irql
16132 +SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16134 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16135 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16137 + switch (AdapterEvent) {
16140 + case HostNormCmdQue:
16142 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16146 + case HostNormRespQue:
16148 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16152 + case AdapNormCmdNotFull:
16154 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16159 + case AdapNormRespNotFull:
16161 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16170 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16172 + PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16175 + // Free the register mapping.
16178 + OsDetachDevice(AdapterExtension);
16180 + OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16187 +Routine Description:
16189 + Scans the PCI bus looking for the Sa card. When found all resources for the
16190 + device will be allocated and the interrupt vectors and csrs will be allocated and
16193 + The device_interface in the commregion will be allocated and linked to the comm region.
16200 + TRUE - if the device was setup with not problems
16201 + FALSE - if the device could not be mapped and init successfully
16205 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16206 + IN ULONG AdapterNumber, IN ULONG PciBus,
16207 + IN ULONG PciSlot)
16209 + AAC_STATUS Status;
16210 + PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16211 + FSA_NEW_ADAPTER NewAdapter;
16212 + ULONG StartTime, EndTime, WaitTime;
16213 + ULONG InitStatus;
16217 + AfaPortPrint("In init device.\n");
16219 + CommonExtension->AdapterNumber = AdapterNumber;
16221 + CommonExtension->PciBusNumber = PciBus;
16222 + CommonExtension->PciSlotNumber = PciSlot;
16224 + AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16225 + AdapterExtension->Common = CommonExtension;
16226 + CommonExtension->MiniPort = AdapterExtension;
16228 + instance = OsGetDeviceInstance(AdapterExtension);
16229 + name = OsGetDeviceName(AdapterExtension);
16232 + // Map in the registers from the adapter, register space 0 is config space,
16233 + // register space 1 is the memery space.
16236 + if (OsMapDeviceRegisters(AdapterExtension)){
16237 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16243 + // Check to see if the board failed any self tests.
16246 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16248 + cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16254 + // Check to see if the board panic'd while booting.
16257 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16259 + cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16265 + StartTime = OsGetSeconds();
16270 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
16273 + while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16275 + EndTime = OsGetSeconds();
16277 + WaitTime = EndTime - StartTime;
16279 + if ( WaitTime > (3 * 60) ) {
16281 + InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16283 + cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16284 + name, instance, InitStatus);
16290 + if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16291 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16295 + if (OsAttachDMA(AdapterExtension)) {
16296 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16302 + // Fill in the function dispatch table.
16305 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16306 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16307 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16308 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16309 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16310 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16311 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16312 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16313 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16314 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16315 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16316 + AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16317 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16319 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16321 + NewAdapter.AdapterExtension = CommonExtension;
16322 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16323 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16324 + NewAdapter.AdapterUserVars = SaUserVars;
16325 + NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16327 + NewAdapter.Dip = CommonExtension->OsDep.dip;
16330 + if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16331 + cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16332 + return (FAILURE);
16336 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16338 + if (AdapterExtension->Common->Adapter == NULL) {
16340 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16341 + cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16343 + return (FAILURE);
16348 + // Start any kernel threads needed
16349 + OsStartKernelThreads(AdapterExtension);
16352 + // Tell the adapter that all is configure, and it can start accepting requests
16355 + SaStartAdapter(AdapterExtension);
16360 + // Put this adapter into the list of Sa adapters
16363 + AdapterExtension->Next = SaAdapterList;
16364 + SaAdapterList = AdapterExtension;
16366 + AdapterExtension->Common->AdapterConfigured = TRUE;
16371 + // Call the disk layer to initialize itself.
16374 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16380 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16382 + OsAttachHBA(AdapterExtension);
16388 + return (FAILURE);
16394 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16396 + ULONG ReturnStatus;
16397 + LARGE_INTEGER HostTime;
16398 + ULONG ElapsedSeconds;
16399 + PADAPTER_INIT_STRUCT InitStruct;
16402 + // Fill in the remaining pieces of the InitStruct.
16405 + InitStruct = AdapterExtension->Common->InitStruct;
16407 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16409 + ElapsedSeconds = OsGetSeconds();
16411 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
16414 + // Tell the adapter we are back and up and running so it will scan its command
16415 + // queues and enable our interrupts
16418 + AdapterExtension->LocalMaskInterruptControl =
16419 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16423 + // First clear out all interrupts. Then enable the one's that we can handle.
16426 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16427 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16428 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16430 + SaSendSynchCommand(AdapterExtension,
16431 + INIT_STRUCT_BASE_ADDRESS,
16432 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16442 +SaResetDevice (PVOID Arg1){
16449 +Routine Description:
16451 + The will cause the adapter to take a break point.
16463 +SaInterruptAdapter (PVOID Arg1)
16465 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16466 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16468 + ULONG ReturnStatus;
16470 + SaSendSynchCommand(AdapterExtension,
16471 + BREAKPOINT_REQUEST,
16483 +Routine Description:
16485 + Will read the adapter CSRs to find the reason the adapter has
16490 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16498 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16500 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16501 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16502 + ULONG ReturnStatus;
16504 + switch (AdapterEvent) {
16505 + case AdapNormCmdQue:
16507 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16510 + case HostNormRespNotFull:
16512 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16515 + case AdapNormRespQue:
16517 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16520 + case HostNormCmdNotFull:
16522 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16525 + case HostShutdown:
16527 +// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16532 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16535 + case AdapPrintfDone:
16536 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16541 + SaBugCheck(0,0,0);
16542 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16550 +Routine Description:
16552 + This routine will send a synchronous comamnd to the adapter and wait for its
16557 + AdapterExtension - Pointer to adapter extension structure.
16558 + Command - Which command to send
16559 + Parameter1 - 4 - Parameters for command
16560 + ReturnStatus - return status from adapter after completion of command
16569 +SaSendSynchCommand(
16572 + ULONG Parameter1,
16573 + ULONG Parameter2,
16574 + ULONG Parameter3,
16575 + ULONG Parameter4,
16576 + PULONG ReturnStatus
16579 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16580 + ULONG StartTime,EndTime,WaitTime;
16581 + BOOLEAN CommandSucceeded;
16584 + // Write the Command into Mailbox 0
16587 + Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16590 + // Write the parameters into Mailboxes 1 - 4
16593 + Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16594 + Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16595 + Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16596 + Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16599 + // Clear the synch command doorbell to start on a clean slate.
16602 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16605 + // Signal that there is a new synch command
16608 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16610 + CommandSucceeded = FALSE;
16612 + StartTime = OsGetSeconds();
16615 + while (WaitTime < 30) { // wait up to 30 seconds
16617 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16620 + // Mon110 will set doorbell0 bit when it has completed the command.
16623 + if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16625 + CommandSucceeded = TRUE;
16629 + EndTime = OsGetSeconds();
16630 + WaitTime = EndTime - StartTime;
16634 + if (CommandSucceeded != TRUE) {
16636 + return (STATUS_IO_TIMEOUT);
16641 + // Clear the synch command doorbell.
16644 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16647 + // Pull the synch status from Mailbox 0.
16650 + *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16653 + // Return SUCCESS
16656 + return (STATUS_SUCCESS);
16663 +Routine Description:
16665 + This routine will send a synchronous fib to the adapter and wait for its
16670 + AdapterExtension - Pointer to adapter extension structure.
16671 + FibPhysicalAddress - Physical address of fib to send.
16680 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16682 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16683 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16684 + ULONG returnStatus;
16686 + if (SaSendSynchCommand( AdapterExtension,
16687 + SEND_SYNCHRONOUS_FIB,
16688 + FibPhysicalAddress,
16692 + &returnStatus ) != STATUS_SUCCESS ) {
16704 + PVOID AdapterExtension,
16705 + ULONG *MappedBuffer)
16712 + PVOID AdapterExtension,
16713 + ULONG *MappedBuffer)