1 diff -burN linux-2.4.7/MAINTAINERS linux/MAINTAINERS
2 --- linux-2.4.7/MAINTAINERS Sun Jul 15 18:15:44 2001
3 +++ linux/MAINTAINERS Sat Jul 21 17:55:13 2001
5 W: http://www.uni-karlsruhe.de/~Robert.Siemer/Private/
8 +AACRAID SCSI RAID DRIVER
9 +P: Adaptec OEM Raid Solutions
10 +M: linux-aacraid-devel@dell.com
11 +L: linux-aacraid-devel@dell.com
12 +L: linux-aacraid-announce@dell.com
13 +W: http://domsch.com/linux
18 M: andrew.grover@intel.com
19 diff -burN linux-2.4.7/arch/i386/defconfig linux/arch/i386/defconfig
20 --- linux-2.4.7/arch/i386/defconfig Mon Jul 16 12:45:15 2001
21 +++ linux/arch/i386/defconfig Sat Jul 21 17:55:13 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.7/drivers/scsi/Config.in linux/drivers/scsi/Config.in
31 --- linux-2.4.7/drivers/scsi/Config.in Thu Jul 5 13:28:16 2001
32 +++ linux/drivers/scsi/Config.in Sat Jul 21 17:55:13 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.7/drivers/scsi/Makefile linux/drivers/scsi/Makefile
42 --- linux-2.4.7/drivers/scsi/Makefile Fri May 4 17:16:28 2001
43 +++ linux/drivers/scsi/Makefile Sat Jul 21 17:55:13 2001
45 obj-$(CONFIG_SCSI_AHA152X) += aha152x.o
46 obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
47 obj-$(CONFIG_SCSI_AHA1740) += aha1740.o
48 +obj-$(CONFIG_SCSI_AACRAID) += aacraid.o
49 ifeq ($(CONFIG_SCSI_AIC7XXX),y)
50 obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx/aic7xxx_drv.o
53 sim710_u.h: sim710_d.h
60 diff -burN linux-2.4.7/drivers/scsi/aacraid/ChangeLog linux/drivers/scsi/aacraid/ChangeLog
61 --- linux-2.4.7/drivers/scsi/aacraid/ChangeLog Wed Dec 31 18:00:00 1969
62 +++ linux/drivers/scsi/aacraid/ChangeLog Sat Jul 21 17:55:51 2001
64 +2001-07-21 Matt Domsch <Matt_Domsch@dell.com>
65 +* changed __SMP__ to CONFIG_SMP everywhere (really this time)
66 +* Applied read capacity patch
67 +* released patch against 2.4.6
68 +* released patch against 2.4.7
70 +2001-07-04 Matt Domsch <Matt_Domsch@dell.com>
71 +* Started with linux-2.4.5-aacraid-043001.patch
72 +* Applied Chris Pascoe's SMP fix patch
73 +* Released patch against 2.4.6
76 +2001-04-30 Matt Domsch <Matt_Domsch@dell.com>
77 +* Started with linux-2.4.3-aacraid-030101.patch
78 +* Applied against 2.4.4.
79 +* Added scsi_set_pci_device() call in linit.c
81 diff -burN linux-2.4.7/drivers/scsi/aacraid/Makefile linux/drivers/scsi/aacraid/Makefile
82 --- linux-2.4.7/drivers/scsi/aacraid/Makefile Wed Dec 31 18:00:00 1969
83 +++ linux/drivers/scsi/aacraid/Makefile Sat Jul 21 17:55:13 2001
86 +# Makefile aacraid Raid Controller
89 +###############################################################################
90 +### SOURCE FILES DEFINES
91 +###############################################################################
109 + ./include/AacGenericTypes.h \
110 + ./include/aac_unix_defs.h \
111 + ./include/adapter.h \
112 + ./include/afacomm.h \
113 + ./include/aifstruc.h \
114 + ./include/build_number.h \
115 + ./include/commdata.h \
116 + ./include/commerr.h \
117 + ./include/commfibcontext.h \
118 + ./include/comprocs.h \
119 + ./include/comproto.h \
120 + ./include/comstruc.h \
121 + ./include/comsup.h \
122 + ./include/fsact.h \
123 + ./include/fsafs.h \
124 + ./include/fsaioctl.h \
125 + ./include/fsaport.h \
126 + ./include/fsatypes.h \
127 + ./include/linit.h \
128 + ./include/monkerapi.h \
129 + ./include/nodetype.h \
130 + ./include/nvramioctl.h \
131 + ./include/osheaders.h \
132 + ./include/ostypes.h \
133 + ./include/pcisup.h \
134 + ./include/perfpack.h \
136 + ./include/protocol.h \
137 + ./include/revision.h \
138 + ./include/rxcommon.h \
140 + ./include/sap1common.h \
142 + ./include/version.h
148 +###############################################################################
149 +### OBJECT FILES DEFINES
150 +###############################################################################
167 +TARGET_OFILES= ${OFILES_DRIVER} aacid.o
169 +###############################################################################
171 +###############################################################################
173 +# Remember that we're doing a chdir one level lower, so we need an extra ../
176 + -I../../../include -I..
178 +WARNINGS= -w -Wall -Wno-unused -Wno-switch -Wno-missing-prototypes -Wno-implicit
182 + -D__KERNEL__=1 -DUNIX -DCVLOCK_USE_SPINLOCK -DLINUX \
186 +AACFLAGS=${CFLAGS} ${COMMON_FLAGS} ${EXTRA_FLAGS}
188 +###############################################################################
189 +### DO GENERAL STUFF
190 +###############################################################################
193 +.SUFFIXES: .c .o .h .a
195 +all: source ${TARGET_OFILES} aacraid.o
197 +source: ${ALL_SOURCE}
202 +###############################################################################
204 +###############################################################################
206 +aacraid.o: source ${TARGET_OFILES}
207 + ld -r -o $@ $(TARGET_OFILES)
208 + cp -r aacraid.o ../
210 +###############################################################################
212 +###############################################################################
215 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o linit.o ./linit.c
217 +aachba.o: ./aachba.c
218 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aachba.o ./aachba.c
221 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osddi.o ./osddi.c
223 +osfuncs.o: ./osfuncs.c
224 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o osfuncs.o ./osfuncs.c
226 +commctrl.o: ./commctrl.c
227 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commctrl.o ./commctrl.c
229 +comminit.o: ./comminit.c
230 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o comminit.o ./comminit.c
232 +commsup.o: ./commsup.c
233 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o commsup.o ./commsup.c
235 +dpcsup.o: ./dpcsup.c
236 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o dpcsup.o ./dpcsup.c
239 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o aacid.o ./aacid.c
242 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o port.o ./port.c
245 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o ossup.o ./ossup.c
248 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o rx.o ./rx.c
250 +sap1sup.o: ./sap1sup.c
251 + $(CC) $(COMMON_FLAGS) $(AACFLAGS) -c -o sap1sup.o ./sap1sup.c
254 diff -burN linux-2.4.7/drivers/scsi/aacraid/README linux/drivers/scsi/aacraid/README
255 --- linux-2.4.7/drivers/scsi/aacraid/README Wed Dec 31 18:00:00 1969
256 +++ linux/drivers/scsi/aacraid/README Sat Jul 21 17:55:13 2001
258 + AACRAID Driver for Linux
261 +-------------------------
262 +The aacraid driver adds support for Adaptec (http://www.adaptec.com)
263 +OEM based RAID controllers.
265 +It is important to note the amount of test time the 2.4.x driver
266 +received. Though not a great deal has changed between 2.2 and 2.4
267 +for this version, it has not recevied a great deal of test time.
269 +A new driver version is in the works and that version will be
270 +submitted to the standard distribution kernel. The previous
271 +2.2 version was submitted but rejected due to the large
272 +amount of code reduncdancy and NTisms. This driver was
273 +initially ported from NT to Solaris and then to Linux.
275 +The new version is being written on Unix for Unix and
276 +should be much easier to read and a great deal cleaner.
278 +Supported Cards/Chipsets
279 +-------------------------
280 + Dell Computer Corporation PERC 2 Quad Channel
281 + Dell Computer Corporation PERC 2/Si
282 + Dell Computer Corporation PERC 3/Si
283 + Dell Computer Corporation PERC 3/Di
286 +Not Supported Devices
287 +-------------------------
288 + Any and All Adaptec branded raid controllers.
291 +-------------------------
292 + Adaptec Unix OEM Product Group
295 +-------------------------
296 +please see http://domsch.com/linux for information
297 +on mailing lists. There is both a development and
298 +an announcment list. Due to the overwhelming amount
299 +of mail I receive about this driver, I can not
300 +answer questions individually and requests should
301 +be directed to the list server. Thanks.
303 +Modified by Brian Boerner February 2001
304 diff -burN linux-2.4.7/drivers/scsi/aacraid/aachba.c linux/drivers/scsi/aacraid/aachba.c
305 --- linux-2.4.7/drivers/scsi/aacraid/aachba.c Wed Dec 31 18:00:00 1969
306 +++ linux/drivers/scsi/aacraid/aachba.c Sat Jul 21 17:55:13 2001
309 + * Adaptec aacraid device driver for Linux.
311 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
313 + * This program is free software; you can redistribute it and/or modify
314 + * it under the terms of the GNU General Public License as published by
315 + * the Free Software Foundation; either version 2, or (at your option)
316 + * any later version.
318 + * This program is distributed in the hope that it will be useful,
319 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
320 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
321 + * GNU General Public License for more details.
323 + * You should have received a copy of the GNU General Public License
324 + * along with this program; see the file COPYING. If not, write to
325 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
330 + * Abstract: driver...
334 +static char *ident_aachba = "aacraid_ident aachba.c 1.0.6 2000/10/09 Adaptec, Inc.";
336 +/*------------------------------------------------------------------------------
338 + *----------------------------------------------------------------------------*/
339 +#include "osheaders.h"
340 +#include "AacGenericTypes.h"
341 +#include "aac_unix_defs.h"
342 +#include "comstruc.h"
343 +#include "monkerapi.h"
344 +#include "protocol.h"
347 +#include "fsaioctl.h"
349 +#include "sap1common.h"
350 +#include "fsaport.h"
353 +#include "nodetype.h"
355 +#include "afacomm.h"
356 +#include "adapter.h"
358 +/*------------------------------------------------------------------------------
360 + *----------------------------------------------------------------------------*/
362 +#define SS_TEST 0x00 /* Test unit ready */
363 +#define SS_REZERO 0x01 /* Rezero unit */
364 +#define SS_REQSEN 0x03 /* Request Sense */
365 +#define SS_REASGN 0x07 /* Reassign blocks */
366 +#define SS_READ 0x08 /* Read 6 */
367 +#define SS_WRITE 0x0A /* Write 6 */
368 +#define SS_INQUIR 0x12 /* inquiry */
369 +#define SS_ST_SP 0x1B /* Start/Stop unit */
370 +#define SS_LOCK 0x1E /* prevent/allow medium removal */
371 +#define SS_RESERV 0x16 /* Reserve */
372 +#define SS_RELES 0x17 /* Release */
373 +#define SS_MODESEN 0x1A /* Mode Sense 6 */
374 +#define SS_RDCAP 0x25 /* Read Capacity */
375 +#define SM_READ 0x28 /* Read 10 */
376 +#define SM_WRITE 0x2A /* Write 10 */
377 +#define SS_SEEK 0x2B /* Seek */
379 +/* values for inqd_pdt: Peripheral device type in plain English */
380 +#define INQD_PDT_DA 0x00 /* Direct-access (DISK) device */
381 +#define INQD_PDT_PROC 0x03 /* Processor device */
382 +#define INQD_PDT_CHNGR 0x08 /* Changer (jukebox, scsi2) */
383 +#define INQD_PDT_COMM 0x09 /* Communication device (scsi2) */
384 +#define INQD_PDT_NOLUN2 0x1f /* Unknown Device (scsi2) */
385 +#define INQD_PDT_NOLUN 0x7f /* Logical Unit Not Present */
387 +#define INQD_PDT_DMASK 0x1F /* Peripheral Device Type Mask */
388 +#define INQD_PDT_QMASK 0xE0 /* Peripheral Device Qualifer Mask */
390 +#define TARGET_LUN_TO_CONTAINER(Target, Lun) (((Lun) << 4) | Target)
391 +#define CONTAINER_TO_TARGET(Container) ((Container) & 0xf)
392 +#define CONTAINER_TO_LUN(Container) ((Container) >> 4)
394 +#define MAX_FIB_DATA (sizeof(FIB) - sizeof(FIB_HEADER))
396 +#define MAX_DRIVER_SG_SEGMENT_COUNT 17
398 +// ------------------------------------------------------
401 +#define SENKEY_NO_SENSE 0x00 //
402 +#define SENKEY_UNDEFINED 0x01 //
403 +#define SENKEY_NOT_READY 0x02 //
404 +#define SENKEY_MEDIUM_ERR 0x03 //
405 +#define SENKEY_HW_ERR 0x04 //
406 +#define SENKEY_ILLEGAL 0x05 //
407 +#define SENKEY_ATTENTION 0x06 //
408 +#define SENKEY_PROTECTED 0x07 //
409 +#define SENKEY_BLANK 0x08 //
410 +#define SENKEY_V_UNIQUE 0x09 //
411 +#define SENKEY_CPY_ABORT 0x0A //
412 +#define SENKEY_ABORT 0x0B //
413 +#define SENKEY_EQUAL 0x0C //
414 +#define SENKEY_VOL_OVERFLOW 0x0D //
415 +#define SENKEY_MISCOMP 0x0E //
416 +#define SENKEY_RESERVED 0x0F //
418 +// ------------------------------------------------------
421 +#define SENCODE_NO_SENSE 0x00
422 +#define SENCODE_END_OF_DATA 0x00
423 +#define SENCODE_BECOMING_READY 0x04
424 +#define SENCODE_INIT_CMD_REQUIRED 0x04
425 +#define SENCODE_PARAM_LIST_LENGTH_ERROR 0x1A
426 +#define SENCODE_INVALID_COMMAND 0x20
427 +#define SENCODE_LBA_OUT_OF_RANGE 0x21
428 +#define SENCODE_INVALID_CDB_FIELD 0x24
429 +#define SENCODE_LUN_NOT_SUPPORTED 0x25
430 +#define SENCODE_INVALID_PARAM_FIELD 0x26
431 +#define SENCODE_PARAM_NOT_SUPPORTED 0x26
432 +#define SENCODE_PARAM_VALUE_INVALID 0x26
433 +#define SENCODE_RESET_OCCURRED 0x29
434 +#define SENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x3E
435 +#define SENCODE_INQUIRY_DATA_CHANGED 0x3F
436 +#define SENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x39
437 +#define SENCODE_DIAGNOSTIC_FAILURE 0x40
438 +#define SENCODE_INTERNAL_TARGET_FAILURE 0x44
439 +#define SENCODE_INVALID_MESSAGE_ERROR 0x49
440 +#define SENCODE_LUN_FAILED_SELF_CONFIG 0x4c
441 +#define SENCODE_OVERLAPPED_COMMAND 0x4E
443 +// ------------------------------------------------------
444 +// Additional sense codes
446 +#define ASENCODE_NO_SENSE 0x00
447 +#define ASENCODE_END_OF_DATA 0x05
448 +#define ASENCODE_BECOMING_READY 0x01
449 +#define ASENCODE_INIT_CMD_REQUIRED 0x02
450 +#define ASENCODE_PARAM_LIST_LENGTH_ERROR 0x00
451 +#define ASENCODE_INVALID_COMMAND 0x00
452 +#define ASENCODE_LBA_OUT_OF_RANGE 0x00
453 +#define ASENCODE_INVALID_CDB_FIELD 0x00
454 +#define ASENCODE_LUN_NOT_SUPPORTED 0x00
455 +#define ASENCODE_INVALID_PARAM_FIELD 0x00
456 +#define ASENCODE_PARAM_NOT_SUPPORTED 0x01
457 +#define ASENCODE_PARAM_VALUE_INVALID 0x02
458 +#define ASENCODE_RESET_OCCURRED 0x00
459 +#define ASENCODE_LUN_NOT_SELF_CONFIGURED_YET 0x00
460 +#define ASENCODE_INQUIRY_DATA_CHANGED 0x03
461 +#define ASENCODE_SAVING_PARAMS_NOT_SUPPORTED 0x00
462 +#define ASENCODE_DIAGNOSTIC_FAILURE 0x80
463 +#define ASENCODE_INTERNAL_TARGET_FAILURE 0x00
464 +#define ASENCODE_INVALID_MESSAGE_ERROR 0x00
465 +#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
466 +#define ASENCODE_OVERLAPPED_COMMAND 0x00
468 +#define BYTE0( x ) ( unsigned char )( x )
469 +#define BYTE1( x ) ( unsigned char )( x >> 8 )
470 +#define BYTE2( x ) ( unsigned char )( x >> 16 )
471 +#define BYTE3( x ) ( unsigned char )( x >> 24 )
473 +/*------------------------------------------------------------------------------
474 + * S T R U C T S / T Y P E D E F S
475 + *----------------------------------------------------------------------------*/
476 +/* SCSI inquiry data */
477 +struct inquiry_data {
478 + unchar inqd_pdt; /* Peripheral qualifier | Peripheral Device Type */
479 + unchar inqd_dtq; /* RMB | Device Type Qualifier */
480 + unchar inqd_ver; /* ISO version | ECMA version | ANSI-approved version */
481 + unchar inqd_rdf; /* AENC | TrmIOP | Response data format */
482 + unchar inqd_len; /* Additional length (n-4) */
483 + unchar inqd_pad1[2]; /* Reserved - must be zero */
484 + unchar inqd_pad2; /* RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe */
485 + unchar inqd_vid[8]; /* Vendor ID */
486 + unchar inqd_pid[16]; /* Product ID */
487 + unchar inqd_prl[4]; /* Product Revision Level */
491 + unchar error_code; // 70h (current errors), 71h(deferred errors)
492 + unchar valid:1; // A valid bit of one indicates that the information
493 + // field contains valid information as defined in the
494 + // SCSI-2 Standard.
496 + unchar segment_number; // Only used for COPY, COMPARE, or COPY AND VERIFY
499 + unchar sense_key:4; // Sense Key
501 + unchar ILI:1; // Incorrect Length Indicator
502 + unchar EOM:1; // End Of Medium - reserved for random access devices
503 + unchar filemark:1; // Filemark - reserved for random access devices
505 + unchar information[4]; // for direct-access devices, contains the unsigned
506 + // logical block address or residue associated with
508 + unchar add_sense_len; // number of additional sense bytes to follow this field
509 + unchar cmnd_info[4]; // not used
510 + unchar ASC; // Additional Sense Code
511 + unchar ASCQ; // Additional Sense Code Qualifier
512 + unchar FRUC; // Field Replaceable Unit Code - not used
514 + unchar bit_ptr:3; // indicates which byte of the CDB or parameter data
516 + unchar BPV:1; // bit pointer valid (BPV): 1- indicates that
517 + // the bit_ptr field has valid value
518 + unchar reserved2:2;
519 + unchar CD:1; // command data bit: 1- illegal parameter in CDB.
520 + // 0- illegal parameter in data.
523 + unchar field_ptr[2]; // byte of the CDB or parameter data in error
526 +/*------------------------------------------------------------------------------
528 + *----------------------------------------------------------------------------*/
529 +/*------------------------------------------------------------------------------
530 + * M O D U L E G L O B A L S
531 + *----------------------------------------------------------------------------*/
532 +static fsadev_t *g_fsa_dev_array[8]; // SCSI Device Instance Pointers
533 +static struct sense_data g_sense_data[MAXIMUM_NUM_CONTAINERS];
535 +/*------------------------------------------------------------------------------
536 + * F U N C T I O N P R O T O T Y P E S
537 + *----------------------------------------------------------------------------*/
538 +AAC_STATUS AacHba_OpenAdapter( PVOID AdapterArg);
539 +AAC_STATUS AacHba_CloseAdapter( PVOID AdapterArg);
540 +BOOLEAN AacHba_HandleAif( PVOID AdapterArg, PFIB_CONTEXT FibContext);
541 +BOOLEAN AacHba_AdapterDeviceControl ( PVOID AdapterArg,
542 + PAFA_IOCTL_CMD IoctlCmdPtr, int * ReturnStatus);
544 +void AacHba_CompleteScsi(
545 + Scsi_Cmnd *scsi_cmnd_ptr );
547 +void AacHba_CompleteScsiNoLock(
548 + Scsi_Cmnd *scsi_cmnd_ptr );
550 +static void AacHba_ReadCallback(
552 + PFIB_CONTEXT FibContext,
555 +static void AacHba_WriteCallback(
557 + PFIB_CONTEXT FibContext,
560 +int AacHba_DoScsiRead(
561 + Scsi_Cmnd *scsi_cmnd_ptr,
565 +int AacHba_DoScsiWrite(
566 + Scsi_Cmnd *scsi_cmnd_ptr,
570 +int AacHba_QueryDisk(
571 + PVOID AdapterArg, // CommonExtensionPtr
572 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
574 +int AacHba_ForceDeleteDisk(
575 + PVOID AdapterArg, // CommonExtensionPtr
576 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
578 +int AacHba_DeleteDisk(
580 + IN PAFA_IOCTL_CMD IoctlCmdPtr );
582 +void AacHba_DetachAdapter(
583 + IN PVOID AdapterArg );
585 +BOOLEAN AacCommDetachAdapter(
586 + IN PAFA_COMM_ADAPTER Adapter );
588 +void AacHba_SetSenseData(
592 + unchar a_sense_code,
593 + unchar incorrect_length,
594 + unchar bit_pointer,
595 + unsigned field_pointer,
596 + unsigned long residue );
598 +static void get_sd_devname(
602 +// Keep these here for the time being - #REVIEW#
604 +AfaCommAdapterDeviceControl (
605 + IN PVOID AdapterArg,
606 + IN PAFA_IOCTL_CMD IoctlCmdPtr
610 +AfaCommRegisterNewClassDriver(
611 + IN PAFA_COMM_ADAPTER Adapter,
612 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
613 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
617 +SetInqDataStr (int, void *, int);
618 +/*------------------------------------------------------------------------------
619 + * F U N C T I O N S
620 + *----------------------------------------------------------------------------*/
622 +/*------------------------------------------------------------------------------
623 + AacHba_ClassDriverInit()
625 + Setup 'core' class driver to answer ioctl's
626 + *----------------------------------------------------------------------------*/
627 +int AacHba_ClassDriverInit(
628 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr)
629 +/*----------------------------------------------------------------------------*/
631 + AFA_NEW_CLASS_DRIVER NewClassDriver;
632 + AFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse;
633 + PAFA_COMM_ADAPTER Adapter;
635 + Adapter = (AFA_COMM_ADAPTER *)CommonExtensionPtr->Adapter;
637 + RtlZeroMemory( &NewClassDriver, sizeof( AFA_NEW_CLASS_DRIVER ) );
639 + // ClassDriverExtension is the first argument passed to class driver functions below
640 + NewClassDriver.ClassDriverExtension = CommonExtensionPtr;
642 + NewClassDriver.OpenAdapter = AacHba_OpenAdapter;
643 + NewClassDriver.CloseAdapter = AacHba_CloseAdapter;
644 + NewClassDriver.DeviceControl = AacHba_AdapterDeviceControl;
645 + NewClassDriver.HandleAif = AacHba_HandleAif;
646 + AfaCommRegisterNewClassDriver( Adapter, &NewClassDriver, &NewClassDriverResponse );
652 +/*------------------------------------------------------------------------------
653 + AacHba_ProbeContainers()
655 + Make a list of all containers in the system.
656 +------------------------------------------------------------------------------*/
657 +int AacHba_ProbeContainers (PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr)
659 + fsadev_t *fsa_dev_ptr;
662 + PMNTINFORESPONSE DiskInfoResponse;
663 + PFIB_CONTEXT FibContext;
664 + AFA_COMM_ADAPTER *Adapter;
670 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
671 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
672 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
674 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
676 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
677 + return( STATUS_UNSUCCESSFUL );
680 + for ( Index = 0; Index < MAXIMUM_NUM_CONTAINERS; Index++ )
682 + Adapter->CommFuncs.InitializeFib( FibContext );
684 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
686 + DiskInfo->Command = VM_NameServe;
687 + DiskInfo->MntCount = Index;
688 + DiskInfo->MntType = FT_FILESYS;
690 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
701 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
705 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
708 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
709 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
713 + fsa_dev_ptr->ContainerValid[Index] = TRUE;
714 + fsa_dev_ptr->ContainerType[Index] = DiskInfoResponse->MntTable[0].VolType;
715 + fsa_dev_ptr->ContainerSize[Index] = DiskInfoResponse->MntTable[0].Capacity;
717 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
718 + fsa_dev_ptr->ContainerReadOnly[Index] = TRUE;
721 + Adapter->CommFuncs.CompleteFib( FibContext );
723 + // If there are no more containers, then stop asking.
724 + if ((Index + 1) >= DiskInfoResponse->MntRespCount)
728 + Adapter->CommFuncs.FreeFib( FibContext );
730 + g_fsa_dev_array[instance] = fsa_dev_ptr;
735 +/*------------------------------------------------------------------------------
736 + AacHba_ProbeContainer()
738 + Probe a single container.
739 + *----------------------------------------------------------------------------*/
740 +int AacHba_ProbeContainer(
741 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr,
743 +/*----------------------------------------------------------------------------*/
745 + fsadev_t *fsa_dev_ptr;
748 + PMNTINFORESPONSE DiskInfoResponse;
749 + PFIB_CONTEXT FibContext;
750 + AFA_COMM_ADAPTER *Adapter;
753 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtensionPtr->Adapter;
754 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
755 + instance = CommonExtensionPtr->OsDep.scsi_host_ptr->unique_id;
757 + if( !( FibContext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
759 + cmn_err( CE_WARN, "AacHba_ProbeContainers: AllocateFib failed" );
760 + return( STATUS_UNSUCCESSFUL );
763 + Adapter->CommFuncs.InitializeFib( FibContext );
765 + DiskInfo = ( PMNTINFO )Adapter->CommFuncs.GetFibData( FibContext );
767 + DiskInfo->Command = VM_NameServe;
768 + DiskInfo->MntCount = ContainerId;
769 + DiskInfo->MntType = FT_FILESYS;
771 + Status = Adapter->CommFuncs.SendFib (ContainerCommand,
782 + cmn_err( CE_WARN, "ProbeContainers: SendFIb Failed" );
783 + Adapter->CommFuncs.CompleteFib( FibContext );
784 + Adapter->CommFuncs.FreeFib( FibContext );
788 + DiskInfoResponse = ( PMNTINFORESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
791 + if ( ( DiskInfoResponse->Status == ST_OK ) &&
792 + ( DiskInfoResponse->MntTable[0].VolType != CT_NONE ) )
795 + fsa_dev_ptr->ContainerValid[ContainerId] = TRUE;
796 + fsa_dev_ptr->ContainerType[ContainerId] = DiskInfoResponse->MntTable[0].VolType;
797 + fsa_dev_ptr->ContainerSize[ContainerId] = DiskInfoResponse->MntTable[0].Capacity;
798 + if (DiskInfoResponse->MntTable[0].ContentState & FSCS_READONLY)
799 + fsa_dev_ptr->ContainerReadOnly[ContainerId] = TRUE;
802 + Adapter->CommFuncs.CompleteFib( FibContext );
803 + Adapter->CommFuncs.FreeFib( FibContext );
809 +/*------------------------------------------------------------------------------
810 + AacHba_CompleteScsi()
812 + Call SCSI completion routine after acquiring io_request_lock
816 + *----------------------------------------------------------------------------*/
817 +void AacHba_CompleteScsi(
818 + Scsi_Cmnd *scsi_cmnd_ptr )
820 + unsigned long cpu_flags;
822 + spin_lock_irqsave( &io_request_lock, cpu_flags );
823 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
824 + spin_unlock_irqrestore( &io_request_lock, cpu_flags );
828 +/*------------------------------------------------------------------------------
829 + AacHba_CompleteScsiNoLock()
831 + Call SCSI completion routine
835 + *----------------------------------------------------------------------------*/
836 +void AacHba_CompleteScsiNoLock(
837 + Scsi_Cmnd *scsi_cmnd_ptr )
839 + scsi_cmnd_ptr->scsi_done( scsi_cmnd_ptr );
842 +/*------------------------------------------------------------------------------
845 + Process SCSI command
849 + Returns 0 on success, -1 on failure
850 + *----------------------------------------------------------------------------*/
851 +int AacHba_DoScsiCmd(
852 + Scsi_Cmnd *scsi_cmnd_ptr,
855 + int ContainerId = 0;
856 + fsadev_t *fsa_dev_ptr;
857 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
860 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
861 + MiniPortIndex = CommonExtensionPtr->OsDep.MiniPortIndex;
863 + fsa_dev_ptr = g_fsa_dev_array[ scsi_cmnd_ptr->host->unique_id ];
865 + // If the bus, target or lun is out of range, return fail
866 + // Test does not apply to ID 16, the pseudo id for the controller itself.
867 + if ( scsi_cmnd_ptr->target != scsi_cmnd_ptr->host->this_id )
869 + if( ( scsi_cmnd_ptr->channel > 0 ) ||
870 + ( scsi_cmnd_ptr->target > 15 ) ||
871 + ( scsi_cmnd_ptr->lun > 7 ) )
873 + cmn_err( CE_DEBUG, "The bus, target or lun is out of range = %d, %d, %d",
874 + scsi_cmnd_ptr->channel,
875 + scsi_cmnd_ptr->target,
876 + scsi_cmnd_ptr->lun );
877 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
879 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
884 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
887 + // If the target container doesn't exist, it may have been newly created
888 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
890 + switch( scsi_cmnd_ptr->cmnd[0] )
895 + spin_unlock_irq( &io_request_lock );
896 + AacHba_ProbeContainer( CommonExtensionPtr, ContainerId );
897 + spin_lock_irq( &io_request_lock );
903 + // If the target container still doesn't exist, return failure
904 + if( fsa_dev_ptr->ContainerValid[ContainerId] == 0 )
907 + scsi_cmnd_ptr->result = DID_BAD_TARGET << 16;
908 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
913 + else // the command is for the controller itself
914 + if( ( scsi_cmnd_ptr->cmnd[0] != SS_INQUIR ) && // only INQUIRY & TUR cmnd supported for controller
915 + ( scsi_cmnd_ptr->cmnd[0] != SS_TEST ) )
917 + cmn_err( CE_WARN, "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x",
918 + scsi_cmnd_ptr->cmnd[0] );
920 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
922 + AacHba_SetSenseData( (char *)&g_sense_data[ ContainerId ],
923 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
926 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
931 + // Handle commands here that don't really require going out to the adapter
932 + switch ( scsi_cmnd_ptr->cmnd[0] )
936 + struct inquiry_data *inq_data_ptr;
938 + cmn_err( CE_DEBUG, "INQUIRY command, ID: %d", scsi_cmnd_ptr->target );
939 + inq_data_ptr = ( struct inquiry_data * )scsi_cmnd_ptr->request_buffer;
940 + bzero( inq_data_ptr, sizeof( struct inquiry_data ) );
942 + inq_data_ptr->inqd_ver = 2; // claim compliance to SCSI-2
944 + inq_data_ptr->inqd_dtq = 0x80; // set RMB bit to one indicating
945 + // that the medium is removable
946 + inq_data_ptr->inqd_rdf = 2; // A response data format value of
947 + // two indicates that the data shall
948 + // be in the format specified in SCSI-2
949 + inq_data_ptr->inqd_len = 31;
951 + // Set the Vendor, Product, and Revision Level see: <vendor>.c i.e. aac.c
952 + SetInqDataStr( MiniPortIndex,
953 + (void *)(inq_data_ptr->inqd_vid),
954 + fsa_dev_ptr->ContainerType[ContainerId]);
956 + if ( scsi_cmnd_ptr->target == scsi_cmnd_ptr->host->this_id )
957 + inq_data_ptr->inqd_pdt = INQD_PDT_PROC; // Processor device
959 + inq_data_ptr->inqd_pdt = INQD_PDT_DA; // Direct/random access device
961 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
962 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
972 + cmn_err( CE_DEBUG, "READ CAPACITY command" );
973 + capacity = fsa_dev_ptr->ContainerSize[ContainerId] - 1;
974 + cp = scsi_cmnd_ptr->request_buffer;
975 + cp[0] = ( capacity >> 24 ) & 0xff;
976 + cp[1] = ( capacity >> 16 ) & 0xff;
977 + cp[2] = ( capacity >> 8 ) & 0xff;
978 + cp[3] = ( capacity >> 0 ) & 0xff;
984 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
985 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
994 + cmn_err( CE_DEBUG, "MODE SENSE command" );
995 + mode_buf = scsi_cmnd_ptr->request_buffer;
996 + mode_buf[0] = 0; // Mode data length (MSB)
997 + mode_buf[1] = 6; // Mode data length (LSB)
998 + mode_buf[2] = 0; // Medium type - default
999 + mode_buf[3] = 0; // Device-specific param, bit 8: 0/1 = write enabled/protected
1000 + mode_buf[4] = 0; // reserved
1001 + mode_buf[5] = 0; // reserved
1002 + mode_buf[6] = 0; // Block descriptor length (MSB)
1003 + mode_buf[7] = 0; // Block descriptor length (LSB)
1005 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1006 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1012 + // These commands are all No-Ops
1014 + cmn_err( CE_DEBUG, "TEST UNIT READY command" );
1015 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1016 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1020 + cmn_err( CE_DEBUG, "REQUEST SENSE command" );
1022 + memcpy( scsi_cmnd_ptr->sense_buffer, &g_sense_data[ContainerId],
1023 + sizeof( struct sense_data ) );
1024 + bzero( &g_sense_data[ContainerId], sizeof( struct sense_data ) );
1026 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1027 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1031 + cmn_err(CE_DEBUG, "LOCK command");
1033 + if( scsi_cmnd_ptr->cmnd[4] )
1034 + fsa_dev_ptr->ContainerLocked[ContainerId] = 1;
1036 + fsa_dev_ptr->ContainerLocked[ContainerId] = 0;
1038 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1039 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1043 + cmn_err( CE_DEBUG, "RESERVE command" );
1044 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1045 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1049 + cmn_err( CE_DEBUG, "RELEASE command" );
1050 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1051 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1055 + cmn_err( CE_DEBUG, "REZERO command" );
1056 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1057 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1061 + cmn_err( CE_DEBUG, "REASSIGN command" );
1062 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1063 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1067 + cmn_err( CE_DEBUG, "SEEK command" );
1068 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1069 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1073 + cmn_err( CE_DEBUG, "START/STOP command" );
1074 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1075 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1079 + switch ( scsi_cmnd_ptr->cmnd[0] )
1083 + // Hack to keep track of ordinal number of the device that corresponds
1084 + // to a container. Needed to convert containers to /dev/sd device names
1085 + fsa_dev_ptr->ContainerDevNo[ContainerId] =
1086 + DEVICE_NR( scsi_cmnd_ptr->request.rq_dev );
1088 + return( AacHba_DoScsiRead( scsi_cmnd_ptr, ContainerId, wait ) );
1094 + return( AacHba_DoScsiWrite( scsi_cmnd_ptr, ContainerId, wait ) );
1098 + // Unhandled commands
1100 + cmn_err( CE_WARN, "Unhandled SCSI Command: 0x%x", scsi_cmnd_ptr->cmnd[0] );
1101 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1103 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1104 + SENKEY_ILLEGAL, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND,
1107 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1112 +/*------------------------------------------------------------------------------
1113 + AacHba_DoScsiRead()
1115 + Handles SCSI READ requests
1119 + Returns 0 on success, -1 on failure
1120 + *----------------------------------------------------------------------------*/
1121 +int AacHba_DoScsiRead(
1122 + Scsi_Cmnd *scsi_cmnd_ptr,
1125 +/*----------------------------------------------------------------------------*/
1129 + u_long byte_count;
1132 + PBLOCKREAD BlockReadDisk;
1133 + PBLOCKREADRESPONSE BlockReadResponse;
1135 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1136 + AFA_COMM_ADAPTER *Adapter;
1137 + PFIB_CONTEXT cmd_fibcontext;
1139 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1140 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1142 + // Get block address and transfer length
1143 + if ( scsi_cmnd_ptr->cmnd[0] == SS_READ ) // 6 byte command
1145 + cmn_err( CE_DEBUG, "aachba: received a read(6) command on target %d", ContainerId );
1147 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1148 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1149 + scsi_cmnd_ptr->cmnd[3];
1150 + count = scsi_cmnd_ptr->cmnd[4];
1157 + cmn_err( CE_DEBUG, "aachba: received a read(10) command on target %d", ContainerId );
1159 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1160 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1162 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1164 + cmn_err( CE_DEBUG, "AacHba_DoScsiRead[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1166 + //-------------------------------------------------------------------------
1167 + // Alocate and initialize a Fib
1168 + // Setup BlockRead command
1169 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1171 + cmn_err( CE_WARN, "AacHba_DoScsiRead: AllocateFib failed\n" );
1172 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1173 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1177 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1179 + BlockReadDisk = ( PBLOCKREAD )Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1180 + BlockReadDisk->Command = VM_CtBlockRead;
1181 + BlockReadDisk->ContainerId = ContainerId;
1182 + BlockReadDisk->BlockNumber = lba;
1183 + BlockReadDisk->ByteCount = count * 512;
1184 + BlockReadDisk->SgMap.SgCount = 1;
1186 + if( BlockReadDisk->ByteCount > ( 64 * 1024 ) )
1188 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request is larger than 64K" );
1189 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1191 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1192 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1198 + //-------------------------------------------------------------------------
1199 + // Build Scatter/Gather list
1201 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1203 + struct scatterlist *scatterlist_ptr;
1206 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1209 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1211 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress =
1212 + ( void * )OsVirtToPhys( scatterlist_ptr[segment].address );
1213 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount =
1214 + scatterlist_ptr[segment].length;
1216 +#ifdef DEBUG_SGBUFFER
1217 + memset( scatterlist_ptr[segment].address, 0xa5,
1218 + scatterlist_ptr[segment].length );
1221 + byte_count += scatterlist_ptr[segment].length;
1223 + if( BlockReadDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1225 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Segment byte count is larger than 64K" );
1226 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1228 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1229 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1235 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1237 + BlockReadDisk->SgMap.SgEntry[segment].SgAddress,
1238 + BlockReadDisk->SgMap.SgEntry[segment].SgByteCount);
1241 + BlockReadDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1243 + if( BlockReadDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1245 + cmn_err( CE_WARN, "AacHba_DoScsiRead: READ request with SgCount > %d",
1246 + MAX_DRIVER_SG_SEGMENT_COUNT );
1247 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1251 + else // one piece of contiguous phys mem
1253 + BlockReadDisk->SgMap.SgEntry[0].SgAddress =
1254 + ( void * )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1255 + BlockReadDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1257 + byte_count = scsi_cmnd_ptr->request_bufflen;
1259 + if( BlockReadDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1261 + cmn_err( CE_WARN, "AacHba_DoScsiRead: Single segment byte count is larger than 64K" );
1262 + cmn_err( CE_WARN, "AacHba_DoScsiRead: ByteCount: %d", BlockReadDisk->ByteCount);
1263 + cmn_err( CE_WARN, "AacHba_DoScsiRead: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg);
1264 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1266 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1267 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1274 + if( byte_count != BlockReadDisk->ByteCount )
1275 + cmn_err( CE_WARN, "AacHba_DoScsiRead: byte_count != BlockReadDisk->ByteCount" );
1277 + //-------------------------------------------------------------------------
1278 + // Now send the Fib to the adapter
1280 + FibSize = sizeof( BLOCKREAD ) + ( ( BlockReadDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1284 + // This path shouldn't ever get executed with the current driver
1285 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1295 + BlockReadResponse = ( PBLOCKREADRESPONSE )
1296 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1298 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1299 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1301 + if( BlockReadResponse->Status != ST_OK )
1303 + cmn_err( CE_WARN, "AacHba_DoScsiRead: BlockReadCommand failed with status: %d",
1304 + BlockReadResponse->Status );
1305 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1307 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1308 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1311 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1315 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1317 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1322 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1329 + ( PFIB_CALLBACK )AacHba_ReadCallback,
1330 + ( void *)scsi_cmnd_ptr );
1332 + // Check that the command queued to the controller
1333 + if (Status != STATUS_PENDING) {
1334 + cmn_err( CE_WARN, "AacHba_DoScsiRead: SendFib failed with status: %d\n",
1337 + // For some reason, the Fib didn't queue, return QUEUE_FULL
1338 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1342 + // don't call done func here
1347 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1349 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1350 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1356 +/*------------------------------------------------------------------------------
1357 + AacHba_DoScsiWrite()
1359 + Handles SCSI WRITE requests
1363 + Returns 0 on success, -1 on failure
1364 + *----------------------------------------------------------------------------*/
1365 +int AacHba_DoScsiWrite(
1366 + Scsi_Cmnd *scsi_cmnd_ptr,
1369 +/*----------------------------------------------------------------------------*/
1373 + u_long byte_count;
1376 + PBLOCKWRITE BlockWriteDisk;
1377 + PBLOCKWRITERESPONSE BlockWriteResponse;
1379 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1380 + AFA_COMM_ADAPTER *Adapter;
1381 + PFIB_CONTEXT cmd_fibcontext;
1383 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1384 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1386 + // Get block address and transfer length
1387 + if ( scsi_cmnd_ptr->cmnd[0] == SS_WRITE ) // 6 byte command
1389 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1390 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1391 + scsi_cmnd_ptr->cmnd[3];
1392 + count = scsi_cmnd_ptr->cmnd[4];
1399 + cmn_err( CE_DEBUG, "aachba: received a write(10) command on target %d", ContainerId );
1401 + lba = ( scsi_cmnd_ptr->cmnd[2] << 24 ) | ( scsi_cmnd_ptr->cmnd[3] << 16 ) |
1402 + ( scsi_cmnd_ptr->cmnd[4] << 8 ) | scsi_cmnd_ptr->cmnd[5];
1404 + count = ( scsi_cmnd_ptr->cmnd[7] << 8 ) | scsi_cmnd_ptr->cmnd[8];
1407 + cmn_err( CE_DEBUG, "AacHba_DoScsiWrite[cpu %d]: lba = %lu, t = %ld", smp_processor_id(), lba, jiffies );
1409 + //-------------------------------------------------------------------------
1410 + // Alocate and initialize a Fib
1411 + // Setup BlockWrite command
1412 + if( !( cmd_fibcontext = Adapter->CommFuncs.AllocateFib( Adapter ) ) )
1414 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: AllocateFib failed\n" );
1415 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1416 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1420 + Adapter->CommFuncs.InitializeFib( cmd_fibcontext );
1422 + BlockWriteDisk = (PBLOCKWRITE) Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1423 + BlockWriteDisk->Command = VM_CtBlockWrite;
1424 + BlockWriteDisk->ContainerId = ContainerId;
1425 + BlockWriteDisk->BlockNumber = lba;
1426 + BlockWriteDisk->ByteCount = count * 512;
1427 + BlockWriteDisk->SgMap.SgCount = 1;
1430 + if ( BlockWriteDisk->ByteCount > ( 64 * 1024 ) )
1432 + struct scatterlist *scatterlist_ptr;
1434 + scatterlist_ptr = (struct scatterlist *)scsi_cmnd_ptr->request_buffer;
1436 + cmn_err( CE_WARN, "\n");
1437 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request is larger than 64K");
1438 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: ByteCount: %d", BlockWriteDisk->ByteCount);
1439 +/* cmn_err( CE_WARN, "AacHba_DoScsiWrite: SG ELEMENTS: %d", scsi_cmnd_ptr->use_sg); */
1440 +/* cmn_err( CE_WARN, "Dump SG Element Size..."); */
1441 +/* for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ ) */
1443 +/* cmn_err (CE_WARN, "SG Segment %d: %d", segment, scatterlist_ptr[segment].length); */
1445 +/* cmn_err (CE_WARN, "\n"); */
1447 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1449 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1450 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1456 + //-------------------------------------------------------------------------
1457 + // Build Scatter/Gather list
1459 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1461 + struct scatterlist *scatterlist_ptr;
1464 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1467 + for( segment = 0; segment< scsi_cmnd_ptr->use_sg; segment++ )
1469 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress =
1470 + ( HOSTADDRESS )OsVirtToPhys( scatterlist_ptr[segment].address );
1471 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount =
1472 + scatterlist_ptr[segment].length;
1474 + byte_count += scatterlist_ptr[segment].length;
1476 + if ( BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount > ( 64 * 1024 ) )
1478 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Segment byte count is larger than 64K" );
1479 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1481 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1482 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1489 + cmn_err(CE_DEBUG, "SgEntry[%d].SgAddress = 0x%x, Byte count = 0x%x",
1491 + BlockWriteDisk->SgMap.SgEntry[segment].SgAddress,
1492 + BlockWriteDisk->SgMap.SgEntry[segment].SgByteCount);
1495 + BlockWriteDisk->SgMap.SgCount = scsi_cmnd_ptr->use_sg;
1497 + if( BlockWriteDisk->SgMap.SgCount > MAX_DRIVER_SG_SEGMENT_COUNT )
1499 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: WRITE request with SgCount > %d",
1500 + MAX_DRIVER_SG_SEGMENT_COUNT );
1501 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1505 + else // one piece of contiguous phys mem
1507 + BlockWriteDisk->SgMap.SgEntry[0].SgAddress =
1508 + ( HOSTADDRESS )OsVirtToPhys( scsi_cmnd_ptr->request_buffer );
1509 + BlockWriteDisk->SgMap.SgEntry[0].SgByteCount = scsi_cmnd_ptr->request_bufflen;
1511 + byte_count = scsi_cmnd_ptr->request_bufflen;
1513 + if ( BlockWriteDisk->SgMap.SgEntry[0].SgByteCount > ( 64 * 1024 ) )
1515 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: Single segment byte count is larger than 64K" );
1517 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1518 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1519 + SENKEY_ILLEGAL, SENCODE_INVALID_CDB_FIELD, ASENCODE_INVALID_CDB_FIELD,
1526 + if( byte_count != BlockWriteDisk->ByteCount )
1527 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: byte_count != BlockReadDisk->ByteCount" );
1529 + //-------------------------------------------------------------------------
1530 + // Now send the Fib to the adapter
1532 + FibSize = sizeof( BLOCKWRITE ) + ( ( BlockWriteDisk->SgMap.SgCount - 1 ) * sizeof( SGENTRY ) );
1536 + // This path shouldn't ever get executed with the current driver
1537 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1547 + BlockWriteResponse = ( PBLOCKWRITERESPONSE )
1548 + Adapter->CommFuncs.GetFibData( cmd_fibcontext );
1550 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1551 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1553 + if( BlockWriteResponse->Status != ST_OK )
1555 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: BlockWriteCommand failed with status: %d\n",
1556 + BlockWriteResponse->Status );
1557 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;;
1558 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1559 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1561 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1565 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1567 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1572 + Status = Adapter->CommFuncs.SendFib( ContainerCommand,
1579 + ( PFIB_CALLBACK )AacHba_WriteCallback,
1580 + ( void * )scsi_cmnd_ptr );
1582 + // Check that the command queued to the controller
1583 + if (Status != STATUS_PENDING) {
1584 + cmn_err( CE_WARN, "AacHba_DoScsiWrite: SendFib failed with status: %d\n",
1587 + // For some reason, the Fib didn't queue, return QUEUE_FULL
1588 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | QUEUE_FULL ;
1592 + // don't call done func here - it should be called by the WriteCallback
1597 + AacHba_CompleteScsiNoLock( scsi_cmnd_ptr );
1599 + Adapter->CommFuncs.CompleteFib( cmd_fibcontext );
1600 + Adapter->CommFuncs.FreeFib( cmd_fibcontext );
1606 +/*------------------------------------------------------------------------------
1607 + AacHba_ReadCallback()
1608 + *----------------------------------------------------------------------------*/
1609 +void AacHba_ReadCallback(
1611 + PFIB_CONTEXT FibContext,
1613 +/*----------------------------------------------------------------------------*/
1615 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1616 + AFA_COMM_ADAPTER *Adapter;
1617 + BLOCKREADRESPONSE *BlockReadResponse;
1618 + Scsi_Cmnd * scsi_cmnd_ptr;
1622 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1624 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1625 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1627 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1629 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1630 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1631 + scsi_cmnd_ptr->cmnd[3];
1632 + cmn_err( CE_DEBUG, "AacHba_ReadCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1634 + if( FibContext == 0 )
1636 + cmn_err( CE_WARN, "AacHba_ReadCallback: no fib context" );
1637 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1638 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1642 + BlockReadResponse = ( PBLOCKREADRESPONSE )Adapter->CommFuncs.GetFibData( FibContext );
1644 + if ( BlockReadResponse->Status == ST_OK )
1645 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1648 + cmn_err( CE_WARN, "AacHba_ReadCallback: read failed, status = %d\n",
1649 + BlockReadResponse->Status );
1650 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1651 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1652 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1656 +#ifdef DEBUG_SGBUFFER
1657 + if ( scsi_cmnd_ptr->use_sg ) // use scatter/gather list
1659 + struct scatterlist *scatterlist_ptr;
1660 + int i, segment, count;
1663 + scatterlist_ptr = ( struct scatterlist * )scsi_cmnd_ptr->request_buffer;
1665 + for( segment = 0; segment < scsi_cmnd_ptr->use_sg; segment++ )
1668 + ptr = scatterlist_ptr[segment].address;
1669 + for( i = 0; i < scatterlist_ptr[segment].length; i++ )
1671 + if( *( ptr++ ) == 0xa5 )
1674 + if( count == scatterlist_ptr[segment].length )
1675 + cmn_err( CE_WARN, "AacHba_ReadCallback: segment %d not filled", segment );
1681 + Adapter->CommFuncs.CompleteFib( FibContext );
1682 + Adapter->CommFuncs.FreeFib( FibContext );
1684 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1687 +/*------------------------------------------------------------------------------
1688 + AacHba_WriteCallback()
1689 + *----------------------------------------------------------------------------*/
1690 +void AacHba_WriteCallback(
1692 + PFIB_CONTEXT FibContext,
1694 +/*----------------------------------------------------------------------------*/
1696 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
1697 + AFA_COMM_ADAPTER *Adapter;
1698 + BLOCKWRITERESPONSE *BlockWriteResponse;
1699 + Scsi_Cmnd *scsi_cmnd_ptr;
1703 + scsi_cmnd_ptr = ( Scsi_Cmnd * )Context;
1705 + CommonExtension = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
1706 + Adapter = ( AFA_COMM_ADAPTER * )CommonExtension->Adapter;
1708 + ContainerId = TARGET_LUN_TO_CONTAINER( scsi_cmnd_ptr->target, scsi_cmnd_ptr->lun );
1710 + lba = ( ( scsi_cmnd_ptr->cmnd[1] & 0x1F ) << 16 ) |
1711 + ( scsi_cmnd_ptr->cmnd[2] << 8 ) |
1712 + scsi_cmnd_ptr->cmnd[3];
1713 + cmn_err( CE_DEBUG, "AacHba_WriteCallback[cpu %d]: lba = %ld, t = %ld", smp_processor_id(), lba, jiffies );
1714 + if( FibContext == 0 )
1716 + cmn_err( CE_WARN, "AacHba_WriteCallback: no fib context" );
1717 + scsi_cmnd_ptr->result = DID_ERROR << 16;
1718 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1722 + BlockWriteResponse = (PBLOCKWRITERESPONSE) Adapter->CommFuncs.GetFibData( FibContext );
1723 + if (BlockWriteResponse->Status == ST_OK)
1724 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | GOOD;
1727 + cmn_err( CE_WARN, "AacHba_WriteCallback: write failed, status = %d\n",
1728 + BlockWriteResponse->Status );
1729 + scsi_cmnd_ptr->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION;
1730 + AacHba_SetSenseData( ( char * )&g_sense_data[ ContainerId ],
1731 + SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE,
1735 + Adapter->CommFuncs.CompleteFib( FibContext );
1736 + Adapter->CommFuncs.FreeFib( FibContext );
1738 + AacHba_CompleteScsi( scsi_cmnd_ptr );
1742 +/*------------------------------------------------------------------------------
1745 + Handle IOCTL requests
1749 + *----------------------------------------------------------------------------*/
1751 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
1754 +/*----------------------------------------------------------------------------*/
1756 + Sa_ADAPTER_EXTENSION *AdapterExtension;
1757 + AFA_IOCTL_CMD IoctlCmd;
1760 + AdapterExtension = ( Sa_ADAPTER_EXTENSION * )CommonExtension->MiniPort;
1762 + cmn_err( CE_DEBUG, "AacHba_Ioctl, type = %d", cmd );
1765 + case FSACTL_SENDFIB:
1766 + cmn_err( CE_DEBUG, "FSACTL_SENDFIB" );
1769 + case FSACTL_AIF_THREAD:
1770 + cmn_err( CE_DEBUG, "FSACTL_AIF_THREAD" );
1773 + case FSACTL_NULL_IO_TEST:
1774 + cmn_err( CE_DEBUG, "FSACTL_NULL_IO_TEST" );
1777 + case FSACTL_SIM_IO_TEST:
1778 + cmn_err( CE_DEBUG, "FSACTL_SIM_IO_TEST" );
1781 + case FSACTL_GET_FIBTIMES:
1782 + cmn_err( CE_DEBUG, "FSACTL_GET_FIBTIMES" );
1785 + case FSACTL_ZERO_FIBTIMES:
1786 + cmn_err( CE_DEBUG, "FSACTL_ZERO_FIBTIMES");
1789 + case FSACTL_GET_VAR:
1790 + cmn_err( CE_DEBUG, "FSACTL_GET_VAR" );
1793 + case FSACTL_SET_VAR:
1794 + cmn_err( CE_DEBUG, "FSACTL_SET_VAR" );
1797 + case FSACTL_OPEN_ADAPTER_CONFIG:
1798 + cmn_err( CE_DEBUG, "FSACTL_OPEN_ADAPTER_CONFIG" );
1801 + case FSACTL_CLOSE_ADAPTER_CONFIG:
1802 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_ADAPTER_CONFIG" );
1805 + case FSACTL_QUERY_ADAPTER_CONFIG:
1806 + cmn_err( CE_DEBUG, "FSACTL_QUERY_ADAPTER_CONFIG" );
1809 + case FSACTL_OPEN_GET_ADAPTER_FIB:
1810 + cmn_err( CE_DEBUG, "FSACTL_OPEN_GET_ADAPTER_FIB" );
1813 + case FSACTL_GET_NEXT_ADAPTER_FIB:
1814 + cmn_err( CE_DEBUG, "FSACTL_GET_NEXT_ADAPTER_FIB" );
1817 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
1818 + cmn_err( CE_DEBUG, "FSACTL_CLOSE_GET_ADAPTER_FIB" );
1821 + case FSACTL_MINIPORT_REV_CHECK:
1822 + cmn_err( CE_DEBUG, "FSACTL_MINIPORT_REV_CHECK" );
1825 + case FSACTL_OPENCLS_COMM_PERF_DATA:
1826 + cmn_err( CE_DEBUG, "FSACTL_OPENCLS_COMM_PERF_DATA" );
1829 + case FSACTL_GET_COMM_PERF_DATA:
1830 + cmn_err( CE_DEBUG, "FSACTL_GET_COMM_PERF_DATA" );
1833 + case FSACTL_QUERY_DISK:
1834 + cmn_err( CE_DEBUG, "FSACTL_QUERY_DISK" );
1837 + case FSACTL_DELETE_DISK:
1838 + cmn_err( CE_DEBUG, "FSACTL_DELETE_DISK" );
1842 + cmn_err( CE_DEBUG, "Unknown ioctl: 0x%x", cmd );
1845 + IoctlCmd.cmd = cmd;
1846 + IoctlCmd.arg = ( intptr_t )arg;
1847 + IoctlCmd.flag = 0;
1848 + IoctlCmd.cred_p = 0;
1849 + IoctlCmd.rval_p = 0;
1851 + status = AfaCommAdapterDeviceControl( CommonExtension->Adapter, &IoctlCmd );
1852 + cmn_err( CE_DEBUG, "AAC_Ioctl, completion status = %d", status );
1857 +/*------------------------------------------------------------------------------
1858 + AacHba_AdapterDeviceControl()
1862 + Returns TRUE if ioctl handled, FALSE otherwise
1863 + *ReturnStatus set to completion status
1864 + *----------------------------------------------------------------------------*/
1865 +BOOLEAN AacHba_AdapterDeviceControl (
1866 + PVOID AdapterArg, // CommonExtensionPtr
1867 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
1868 + OUT int * ReturnStatus )
1869 +/*----------------------------------------------------------------------------*/
1871 + BOOLEAN Handled = TRUE; // start out handling it.
1872 + int Status = EFAULT;
1874 + switch( IoctlCmdPtr->cmd )
1876 + case FSACTL_QUERY_DISK:
1877 + Status = AacHba_QueryDisk( AdapterArg, IoctlCmdPtr );
1880 + case FSACTL_DELETE_DISK:
1881 + Status = AacHba_DeleteDisk( AdapterArg, IoctlCmdPtr );
1884 + case FSACTL_FORCE_DELETE_DISK:
1885 + Status = AacHba_ForceDeleteDisk( AdapterArg, IoctlCmdPtr );
1889 + if( AacHba_ProbeContainers( ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg ) )
1898 + *ReturnStatus = Status;
1900 + return( Handled );
1904 +/*------------------------------------------------------------------------------
1905 + AacHba_QueryDisk()
1910 + -EFAULT = Bad address
1911 + -EINVAL = Bad container number
1912 + *----------------------------------------------------------------------------*/
1913 +int AacHba_QueryDisk(
1914 + PVOID AdapterArg, // CommonExtensionPtr
1915 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
1916 +/*----------------------------------------------------------------------------*/
1918 + UNIX_QUERY_DISK QueryDisk;
1919 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
1920 + fsadev_t *fsa_dev_ptr;
1922 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
1923 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
1925 + if( copyin( IoctlCmdPtr->arg, &QueryDisk, sizeof( UNIX_QUERY_DISK ) ) )
1926 + return( -EFAULT );
1928 + if (QueryDisk.ContainerNumber == -1)
1929 + QueryDisk.ContainerNumber = TARGET_LUN_TO_CONTAINER( QueryDisk.Target, QueryDisk.Lun );
1931 + if( ( QueryDisk.Bus == -1 ) && ( QueryDisk.Target == -1 ) && ( QueryDisk.Lun == -1 ) )
1933 + if( QueryDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
1934 + return( -EINVAL );
1936 + QueryDisk.Instance = CommonExtensionPtr->OsDep.scsi_host_ptr->host_no;
1937 + QueryDisk.Bus = 0;
1938 + QueryDisk.Target = CONTAINER_TO_TARGET( QueryDisk.ContainerNumber );
1939 + QueryDisk.Lun = CONTAINER_TO_LUN( QueryDisk.ContainerNumber );
1942 + return( -EINVAL );
1944 + QueryDisk.Valid = fsa_dev_ptr->ContainerValid[QueryDisk.ContainerNumber];
1945 + QueryDisk.Locked = fsa_dev_ptr->ContainerLocked[QueryDisk.ContainerNumber];
1946 + QueryDisk.Deleted = fsa_dev_ptr->ContainerDeleted[QueryDisk.ContainerNumber];
1948 + if( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber] == -1 )
1949 + QueryDisk.UnMapped = TRUE;
1951 + QueryDisk.UnMapped = FALSE;
1953 + get_sd_devname( fsa_dev_ptr->ContainerDevNo[QueryDisk.ContainerNumber],
1954 + QueryDisk.diskDeviceName );
1956 + if( copyout( &QueryDisk, IoctlCmdPtr->arg, sizeof( UNIX_QUERY_DISK ) ) )
1957 + return( -EFAULT );
1963 +/*------------------------------------------------------------------------------
1965 + *----------------------------------------------------------------------------*/
1966 +static void get_sd_devname(
1969 +/*----------------------------------------------------------------------------*/
1973 + sprintf(buffer, "%s", "");
1977 + if( disknum < 26 )
1978 + sprintf(buffer, "sd%c", 'a' + disknum);
1980 + unsigned int min1;
1981 + unsigned int min2;
1983 + * For larger numbers of disks, we need to go to a new
1986 + min1 = disknum / 26;
1987 + min2 = disknum % 26;
1988 + sprintf(buffer, "sd%c%c", 'a' + min1 - 1, 'a' + min2);
1993 +/*------------------------------------------------------------------------------
1994 + AacHba_ForceDeleteDisk()
1999 + -EFAULT = Bad address
2000 + -EINVAL = Bad container number
2001 + *----------------------------------------------------------------------------*/
2002 +int AacHba_ForceDeleteDisk(
2003 + PVOID AdapterArg, // CommonExtensionPtr
2004 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
2005 +/*----------------------------------------------------------------------------*/
2007 + DELETE_DISK DeleteDisk;
2008 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2009 + fsadev_t *fsa_dev_ptr;
2011 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2012 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2014 + if ( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2015 + return( -EFAULT );
2017 + if ( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2018 + return( -EINVAL );
2020 + // Mark this container as being deleted.
2021 + fsa_dev_ptr->ContainerDeleted[DeleteDisk.ContainerNumber] = TRUE;
2023 + // Mark the container as no longer valid
2024 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2030 +/*------------------------------------------------------------------------------
2031 + AacHba_DeleteDisk()
2036 + -EFAULT = Bad address
2037 + -EINVAL = Bad container number
2038 + -EBUSY = Device locked
2039 + *----------------------------------------------------------------------------*/
2040 +int AacHba_DeleteDisk(
2042 + IN PAFA_IOCTL_CMD IoctlCmdPtr )
2043 +/*----------------------------------------------------------------------------*/
2045 + DELETE_DISK DeleteDisk;
2046 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2047 + fsadev_t *fsa_dev_ptr;
2049 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )AdapterArg;
2050 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
2052 + if( copyin( IoctlCmdPtr->arg, &DeleteDisk, sizeof( DELETE_DISK ) ) )
2053 + return( -EFAULT );
2055 + if( DeleteDisk.ContainerNumber > MAXIMUM_NUM_CONTAINERS )
2056 + return( -EINVAL );
2058 + // If the container is locked, it can not be deleted by the API.
2059 + if( fsa_dev_ptr->ContainerLocked[DeleteDisk.ContainerNumber] )
2063 + // Mark the container as no longer being valid.
2064 + fsa_dev_ptr->ContainerValid[DeleteDisk.ContainerNumber] = 0;
2065 + fsa_dev_ptr->ContainerDevNo[DeleteDisk.ContainerNumber] = -1;
2071 +/*------------------------------------------------------------------------------
2072 + AacHba_OpenAdapter()
2073 + *----------------------------------------------------------------------------*/
2074 +AAC_STATUS AacHba_OpenAdapter(
2075 + IN PVOID AdapterArg )
2076 +/*----------------------------------------------------------------------------*/
2078 + return( STATUS_SUCCESS );
2082 +/*------------------------------------------------------------------------------
2083 + AacHba_CloseAdapter()
2084 + *----------------------------------------------------------------------------*/
2085 +AAC_STATUS AacHba_CloseAdapter(
2086 + IN PVOID AdapterArg )
2087 +/*----------------------------------------------------------------------------*/
2089 + return( STATUS_SUCCESS );
2093 +/*------------------------------------------------------------------------------
2094 + AacHba_DetachAdapter()
2095 + *----------------------------------------------------------------------------*/
2096 +void AacHba_DetachAdapter(
2097 + IN PVOID AdapterArg )
2098 +/*----------------------------------------------------------------------------*/
2100 + AacCommDetachAdapter( AdapterArg );
2104 +/*------------------------------------------------------------------------------
2105 + AacHba_AbortScsiCommand()
2106 + *----------------------------------------------------------------------------*/
2107 +void AacHba_AbortScsiCommand(
2108 + Scsi_Cmnd *scsi_cmnd_ptr )
2109 +/*----------------------------------------------------------------------------*/
2111 + u_short interrupt_status;
2112 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
2114 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
2115 + interrupt_status = Sa_READ_USHORT( ( PSa_ADAPTER_EXTENSION )( CommonExtensionPtr->MiniPort ),
2117 + cmn_err( CE_WARN, "interrupt_status = %d", interrupt_status );
2119 + if( interrupt_status & DOORBELL_1) { // Adapter -> Host Normal Command Ready
2120 + cmn_err( CE_WARN, "DOORBELL_1: Adapter -> Host Normal Command Ready" );
2123 + if( interrupt_status & DOORBELL_2) { // Adapter -> Host Normal Response Ready
2124 + cmn_err( CE_WARN, "DOORBELL_2: Adapter -> Host Normal Response Ready" );
2127 + if ( interrupt_status & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
2128 + cmn_err( CE_WARN, "DOORBELL_3: Adapter -> Host Normal Command Not Full" );
2131 + if ( interrupt_status & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
2132 + cmn_err( CE_WARN, "DOORBELL_4: Adapter -> Host Normal Response Not Full" );
2138 +/*------------------------------------------------------------------------------
2139 + AacHba_HandleAif()
2140 + *----------------------------------------------------------------------------*/
2141 +BOOLEAN AacHba_HandleAif(
2142 + IN PVOID AdapterArg,
2143 + IN PFIB_CONTEXT FibContext )
2144 +/*----------------------------------------------------------------------------*/
2150 +/*------------------------------------------------------------------------------
2151 + AacHba_SetSenseData()
2152 + Fill in the sense data.
2155 + *----------------------------------------------------------------------------*/
2156 +void AacHba_SetSenseData(
2159 + unchar sense_code,
2160 + unchar a_sense_code,
2161 + unchar incorrect_length,
2162 + unchar bit_pointer,
2163 + unsigned field_pointer,
2164 + unsigned long residue )
2165 +/*----------------------------------------------------------------------------*/
2167 + sense_buf[0] = 0xF0; // Sense data valid, err code 70h (current error)
2168 + sense_buf[1] = 0; // Segment number, always zero
2170 + if( incorrect_length )
2172 + sense_buf[2] = sense_key | 0x20; // Set the ILI bit | sense key
2173 + sense_buf[3] = BYTE3(residue);
2174 + sense_buf[4] = BYTE2(residue);
2175 + sense_buf[5] = BYTE1(residue);
2176 + sense_buf[6] = BYTE0(residue);
2179 + sense_buf[2] = sense_key; // Sense key
2181 + if( sense_key == SENKEY_ILLEGAL )
2182 + sense_buf[7] = 10; // Additional sense length
2184 + sense_buf[7] = 6; // Additional sense length
2186 + sense_buf[12] = sense_code; // Additional sense code
2187 + sense_buf[13] = a_sense_code; // Additional sense code qualifier
2188 + if( sense_key == SENKEY_ILLEGAL )
2190 + sense_buf[15] = 0;
2192 + if( sense_code == SENCODE_INVALID_PARAM_FIELD )
2193 + sense_buf[15] = 0x80; // Std sense key specific field
2194 + // Illegal parameter is in the parameter block
2196 + if( sense_code == SENCODE_INVALID_CDB_FIELD )
2197 + sense_buf[15] = 0xc0; // Std sense key specific field
2198 + // Illegal parameter is in the CDB block
2199 + sense_buf[15] |= bit_pointer;
2200 + sense_buf[16] = field_pointer >> 8; // MSB
2201 + sense_buf[17] = field_pointer; // LSB
2205 diff -burN linux-2.4.7/drivers/scsi/aacraid/aacid.c linux/drivers/scsi/aacraid/aacid.c
2206 --- linux-2.4.7/drivers/scsi/aacraid/aacid.c Wed Dec 31 18:00:00 1969
2207 +++ linux/drivers/scsi/aacraid/aacid.c Sat Jul 21 17:55:13 2001
2210 + * Adaptec aacraid device driver for Linux.
2212 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2214 + * This program is free software; you can redistribute it and/or modify
2215 + * it under the terms of the GNU General Public License as published by
2216 + * the Free Software Foundation; either version 2, or (at your option)
2217 + * any later version.
2219 + * This program is distributed in the hope that it will be useful,
2220 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2221 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2222 + * GNU General Public License for more details.
2224 + * You should have received a copy of the GNU General Public License
2225 + * along with this program; see the file COPYING. If not, write to
2226 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2231 + * Abstract: Data structures for controller specific info.
2235 +static char *ident_aacid = "aacraid_ident aacid.c 1.0.6 2000/10/09 Adaptec, Inc.";
2237 +#include "osheaders.h"
2239 +#include "AacGenericTypes.h"
2241 +#include "aac_unix_defs.h"
2243 +#include "fsatypes.h"
2244 +#include "comstruc.h"
2245 +#include "fsaport.h"
2246 +#include "pcisup.h"
2248 +#include "version.h"
2251 +/* Function Prototypes */
2252 +void InqStrCopy(char *a, char *b); /* ossup.c */
2254 +/* Device name used to register and unregister
2255 + the device in linit.c */
2256 +char devicestr[]="aac";
2258 +char *container_types[] = {
2277 +/* Local Structure to set SCSI inquiry data strings */
2278 +typedef struct _INQSTR {
2279 + char vid[8]; /* Vendor ID */
2280 + char pid[16]; /* Product ID */
2281 + char prl[4]; /* Product Revision Level */
2282 +} INQSTR, *INQSTRP;
2284 +FSA_MINIPORT MiniPorts[];
2286 +/* Function: SetInqDataStr
2288 + * Arguments: [1] pointer to void [1] int
2290 + * Purpose: Sets SCSI inquiry data strings for vendor, product
2291 + * and revision level. Allows strings to be set in platform dependant
2292 + * files instead of in OS dependant driver source.
2296 + int MiniPortIndex,
2300 + INQSTRP InqStrPtr;
2304 + mp = &MiniPorts[MiniPortIndex];
2306 + InqStrPtr = (INQSTRP)(dataPtr); /* cast dataPtr to type INQSTRP */
2308 + InqStrCopy (mp->Vendor, InqStrPtr->vid);
2309 + InqStrCopy (mp->Model, InqStrPtr->pid); /* last six chars reserved for vol type */
2311 + findit = InqStrPtr->pid;
2313 + for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */
2316 + if (tindex < (sizeof(container_types)/sizeof(char *))){
2317 + InqStrCopy (container_types[tindex], findit);
2319 + InqStrCopy ("0001", InqStrPtr->prl);
2324 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2325 + IN ULONG AdapterNumber,
2332 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
2333 + IN ULONG AdapterNumber,
2340 + * Because of the way Linux names scsi devices, the order in this table has
2341 + * become important. Check for on-board Raid first, add-in cards second.
2344 +FSA_MINIPORT MiniPorts[] = {
2345 + { 0x1028, 0x0001, 0x1028, 0x0001, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2346 + { 0x1028, 0x0002, 0x1028, 0x0002, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2347 + { 0x1028, 0x0003, 0x1028, 0x0003, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2348 + { 0x1028, 0x0004, 0x1028, 0x00d0, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Si */
2349 + { 0x1028, 0x0002, 0x1028, 0x00d1, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2350 + { 0x1028, 0x0002, 0x1028, 0x00d9, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2351 + { 0x1028, 0x000a, 0x1028, 0x0106, "afa", RxInitDevice, "percraid", "DELL ", "PERCRAID " }, /* PERC 3/Di */
2352 + { 0x1011, 0x0046, 0x9005, 0x1364, "afa", SaInitDevice, "percraid", "DELL ", "PERCRAID " }, /* Dell PERC2 "Quad Channel */
2353 + { 0x1011, 0x0046, 0x103c, 0x10c2, "hpn", SaInitDevice, "hpnraid", "HP ", "NetRAID-4M " } /* HP NetRAID-4M */
2357 +#define NUM_MINIPORTS (sizeof(MiniPorts) / sizeof(FSA_MINIPORT))
2359 +int NumMiniPorts = NUM_MINIPORTS;
2361 +char DescriptionString[] = "AACxxx Raid Controller" FSA_VERSION_STRING ;
2362 diff -burN linux-2.4.7/drivers/scsi/aacraid/commctrl.c linux/drivers/scsi/aacraid/commctrl.c
2363 --- linux-2.4.7/drivers/scsi/aacraid/commctrl.c Wed Dec 31 18:00:00 1969
2364 +++ linux/drivers/scsi/aacraid/commctrl.c Sat Jul 21 17:55:13 2001
2367 + * Adaptec aacraid device driver for Linux.
2369 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
2371 + * This program is free software; you can redistribute it and/or modify
2372 + * it under the terms of the GNU General Public License as published by
2373 + * the Free Software Foundation; either version 2, or (at your option)
2374 + * any later version.
2376 + * This program is distributed in the hope that it will be useful,
2377 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2378 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2379 + * GNU General Public License for more details.
2381 + * You should have received a copy of the GNU General Public License
2382 + * along with this program; see the file COPYING. If not, write to
2383 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
2388 + * Abstract: Contains all routines for control of the AFA comm layer
2392 +static char *ident_commctrl = "aacraid_ident commctrl.c 1.0.7 2000/10/11 Adaptec, Inc.";
2394 +#include "comprocs.h"
2395 +#include "osheaders.h"
2396 +#include "ostypes.h"
2402 +typedef BOOLEAN BOOL;
2403 +#define inline /* _inline */
2405 +#include <revision.h>
2407 +FsaCtlCheckRevision(
2408 + IN PAFA_COMM_ADAPTER Adapter,
2409 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2413 +Routine Description:
2415 + This routine validates the revision of the caller with the current revision
2416 + of the filesystem.
2420 + Adapter - Supplies which adapter is being processed.
2422 + Irp - Supplies the Irp being processed.
2424 + IrpContext - Supplies the IrpContext.
2433 + RevCheck APIRevCheck;
2434 + RevCheckResp APIRevCheckResp;
2435 + RevComponent APICallingComponent;
2436 + ULONG APIBuildNumber;
2438 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &APIRevCheck, sizeof(RevCheck), IoctlCmdPtr->flag )) {
2442 + APICallingComponent = APIRevCheck.callingComponent;
2443 + APIBuildNumber = APIRevCheck.callingRevision.buildNumber;
2445 + APIRevCheckResp.possiblyCompatible = RevCheckCompatibility( RevMiniportDriver , APICallingComponent, APIBuildNumber );
2447 + APIRevCheckResp.adapterSWRevision.external.ul = RevGetExternalRev();
2448 + APIRevCheckResp.adapterSWRevision.buildNumber = RevGetBuildNumber();
2450 + if (COPYOUT( (caddr_t) &APIRevCheckResp, (caddr_t) IoctlCmdPtr->arg, sizeof(RevCheckResp), IoctlCmdPtr->flag )) {
2459 +AfaCommAdapterDeviceControl(
2460 + IN PVOID AdapterArg,
2461 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2464 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
2465 + int Status = ENOTTY;
2466 +// PIO_STACK_LOCATION IrpSp;
2467 + PAFA_CLASS_DRIVER ClassDriver;
2470 + // First loop through all of the class drivers to give them a chance to handle
2471 + // the Device control first.
2474 + ClassDriver = Adapter->ClassDriverList;
2476 + while (ClassDriver) {
2478 + if (ClassDriver->DeviceControl) {
2480 + if (ClassDriver->DeviceControl( ClassDriver->ClassDriverExtension, IoctlCmdPtr, &Status ) ) {
2487 + ClassDriver = ClassDriver->Next;
2490 + switch (IoctlCmdPtr->cmd) {
2493 + case FSACTL_SENDFIB:
2495 + Status = AfaCommCtlSendFib( Adapter, IoctlCmdPtr );
2498 + case FSACTL_AIF_THREAD:
2500 + Status = AfaCommCtlAifThread( Adapter, IoctlCmdPtr );
2504 + case FSACTL_OPEN_GET_ADAPTER_FIB:
2506 + Status = FsaCtlOpenGetAdapterFib( Adapter, IoctlCmdPtr );
2509 + case FSACTL_GET_NEXT_ADAPTER_FIB:
2511 + Status = FsaCtlGetNextAdapterFib( Adapter, IoctlCmdPtr );
2514 + case FSACTL_CLOSE_GET_ADAPTER_FIB:
2516 + Status = FsaCtlCloseGetAdapterFib( Adapter, IoctlCmdPtr );
2519 + case FSACTL_MINIPORT_REV_CHECK:
2521 + Status = FsaCtlCheckRevision( Adapter , IoctlCmdPtr );
2537 +AfaCommRegisterNewClassDriver(
2538 + IN PAFA_COMM_ADAPTER Adapter,
2539 + IN PAFA_NEW_CLASS_DRIVER NewClassDriver,
2540 + OUT PAFA_NEW_CLASS_DRIVER_RESPONSE NewClassDriverResponse
2544 +Routine Description:
2546 + This routine registers a new class driver for the comm layer.
2548 + It will return a pointer to the communication functions for the class driver
2553 + Adapter - Supplies which adapter is being processed.
2555 + Irp - Supplies the Irp being processed.
2559 + STATUS_SUCCESS - Everything OK.
2563 + AAC_STATUS Status;
2564 + PAFA_CLASS_DRIVER ClassDriver;
2567 + ClassDriver = (PAFA_CLASS_DRIVER) OsAllocMemory( sizeof(AFA_CLASS_DRIVER), OS_ALLOC_MEM_SLEEP );
2569 + if (ClassDriver == NULL) {
2571 + Status = STATUS_INSUFFICIENT_RESOURCES;
2577 + // If the class driver has sent in user Vars, then copy them into the global
2581 + if (NewClassDriver->NumUserVars) {
2583 + PFSA_USER_VAR NewUserVars;
2585 + NewUserVars = OsAllocMemory( (FsaCommData.NumUserVars +
2586 + NewClassDriver->NumUserVars) * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
2589 + // First copy the existing into the new area.
2592 + RtlCopyMemory( NewUserVars, FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2595 + // Next copy the new vars passed in from class driver.
2598 + RtlCopyMemory( (NewUserVars + FsaCommData.NumUserVars),
2599 + NewClassDriver->UserVars,
2600 + NewClassDriver->NumUserVars * sizeof(FSA_USER_VAR) );
2603 + // Free up the old user vars.
2606 + OsFreeMemory( FsaCommData.UserVars, FsaCommData.NumUserVars * sizeof(FSA_USER_VAR) );
2609 + // Point the global to the new area.
2612 + FsaCommData.UserVars = NewUserVars;
2615 + // Update the total count.
2618 + FsaCommData.NumUserVars += NewClassDriver->NumUserVars;
2622 + ClassDriver->OpenAdapter = NewClassDriver->OpenAdapter;
2623 + ClassDriver->CloseAdapter = NewClassDriver->CloseAdapter;
2624 + ClassDriver->DeviceControl = NewClassDriver->DeviceControl;
2625 + ClassDriver->HandleAif = NewClassDriver->HandleAif;
2626 + ClassDriver->ClassDriverExtension = NewClassDriver->ClassDriverExtension;
2628 + ClassDriver->Next = Adapter->ClassDriverList;
2629 + Adapter->ClassDriverList = ClassDriver;
2632 + // Now return the information needed by the class driver to communicate to us.
2635 + NewClassDriverResponse->CommFuncs = &Adapter->CommFuncs;
2636 + NewClassDriverResponse->CommPortExtension = Adapter;
2637 + NewClassDriverResponse->MiniPortExtension = Adapter->AdapterExtension;
2638 + NewClassDriverResponse->SpinLockCookie = Adapter->SpinLockCookie;
2639 + NewClassDriverResponse->Dip = Adapter->Dip;
2641 + return (STATUS_SUCCESS);
2648 + IN PAFA_COMM_ADAPTER Adapter,
2649 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2653 +Routine Description:
2655 + This routine sends a fib to the adapter on behalf of a user level
2660 + Adapter - Supplies which adapter is being processed.
2662 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2666 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2668 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2670 + STATUS_SUCCESS - Everything OK.
2675 +// PMDL DmaMdl = NULL;
2676 + PCOMM_FIB_CONTEXT FibContext;
2677 + PSGMAP_CONTEXT SgMapContext;
2678 + SGMAP_CONTEXT _SgMapContext;
2679 + QUEUE_TYPES WhichQueue;
2680 + PVOID UsersAddress;
2681 + AAC_STATUS Status;
2683 + FibContext = AllocateFib( Adapter );
2685 + KFib = FibContext->Fib;
2688 + // First copy in the header so that we can check the size field.
2691 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2692 + FreeFib( FibContext );
2698 + // Since we copy based on the fib header size, make sure that we
2699 + // will not overrun the buffer when we copy the memory. Return
2700 + // an error if we would.
2703 + if (KFib->Header.Size > sizeof(FIB) - sizeof(FIB_HEADER)) {
2704 + FreeFib( FibContext );
2710 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) KFib, KFib->Header.Size + sizeof(FIB_HEADER), IoctlCmdPtr->flag )) {
2711 + FreeFib( FibContext );
2716 + WhichQueue = AdapNormCmdQueue;
2719 + if (KFib->Header.Command == TakeABreakPt) {
2721 + InterruptAdapter(Adapter);
2724 + // Since we didn't really send a fib, zero out the state to allow
2725 + // cleanup code not to assert.
2728 + KFib->Header.XferState = 0;
2733 + if (SendFib(KFib->Header.Command, FibContext, KFib->Header.Size , FsaNormal,
2734 + TRUE, NULL, TRUE, NULL, NULL) != FSA_SUCCESS) {
2735 + FsaCommPrint("User SendFib failed!.\n");
2738 + FreeFib( FibContext );
2742 + if (CompleteFib(FibContext) != FSA_SUCCESS) {
2743 + FsaCommPrint("User Complete FIB failed.\n");
2745 + FreeFib( FibContext );
2754 + // Make sure that the size returned by the adapter (which includes
2755 + // the header) is less than or equal to the size of a fib, so we
2756 + // don't corrupt application data. Then copy that size to the user
2757 + // buffer. (Don't try to add the header information again, since it
2758 + // was already included by the adapter.)
2760 + ASSERT(KFib->Header.Size <= sizeof(FIB));
2762 + if (COPYOUT( (caddr_t) KFib, (caddr_t) IoctlCmdPtr->arg, KFib->Header.Size, IoctlCmdPtr->flag )) {
2763 + FreeFib( FibContext );
2768 + FreeFib( FibContext );
2775 +AfaCommCtlAifThread(
2776 + IN PAFA_COMM_ADAPTER Adapter,
2777 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2781 +Routine Description:
2783 + This routine will act as the AIF thread for this adapter.
2787 + Adapter - Supplies which adapter is being processed.
2789 + IoctlCmdPtr - Pointer to the arguments to the IOCTL call
2793 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2795 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2797 + STATUS_SUCCESS - Everything OK.
2801 + return (NormCommandThread(Adapter));
2806 +#ifdef GATHER_FIB_TIMES
2808 +AfaCommGetFibTimes(
2809 + IN PAFA_COMM_ADAPTER Adapter,
2814 +Routine Description:
2816 + This routine returns the gathered fibtimes to the user.
2820 + Adapter - Supplies which adapter is being processed.
2822 + Irp - Supplies the Irp being processed.
2826 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2828 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2830 + STATUS_SUCCESS - Everything OK.
2834 + PALL_FIB_TIMES AllFibTimes;
2835 + PLARGE_INTEGER FreqPtr;
2836 + PIO_STACK_LOCATION IrpSp;
2839 + // Get a pointer to the current Irp stack location
2842 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2844 + FreqPtr = (PLARGE_INTEGER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2846 + *FreqPtr = Adapter->FibTimesFrequency;
2848 + AllFibTimes = (PALL_FIB_TIMES)((PUCHAR)FreqPtr + sizeof(LARGE_INTEGER));
2850 + RtlCopyMemory(AllFibTimes, Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2852 + Irp->IoStatus.Information = 0;
2854 + return (STATUS_SUCCESS);
2859 +AfaCommZeroFibTimes(
2860 + IN PAFA_COMM_ADAPTER Adapter,
2865 +Routine Description:
2867 + This routine zero's the FibTimes structure within the adapter structure.
2871 + Adapter - Supplies which adapter is being processed.
2873 + Irp - Supplies the Irp being processed.
2877 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2879 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2881 + STATUS_SUCCESS - Everything OK.
2885 + PFIB_TIMES FibTimesPtr;
2887 + PIO_STACK_LOCATION IrpSp;
2890 + // Get a pointer to the current Irp stack location
2893 + IrpSp = IoGetCurrentIrpStackLocation( Irp );
2896 + // Initialize the Fib timing data structures
2898 + RtlZeroMemory(Adapter->FibTimes, sizeof(ALL_FIB_TIMES));
2900 + for (i = 0; i < MAX_FSACOMMAND_NUM; i++) {
2902 + FibTimesPtr = &Adapter->FibTimes->FileSys[i];
2904 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2905 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2906 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2907 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2909 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2911 + FibTimesPtr = &Adapter->FibTimes->Read[i];
2913 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2914 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2915 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2916 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2918 + for (i = 0; i < MAX_RW_FIB_TIMES; i++) {
2920 + FibTimesPtr = &Adapter->FibTimes->Write[i];
2922 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2923 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2924 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2925 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2928 + FibTimesPtr = &Adapter->FibTimes->Other;
2930 + FibTimesPtr->Minimum.LowPart = 0xffffffff;
2931 + FibTimesPtr->Minimum.HighPart = 0x7fffffff;
2932 + FibTimesPtr->AdapterMinimum.LowPart = 0xffffffff;
2933 + FibTimesPtr->AdapterMinimum.HighPart = 0x7fffffff;
2935 + Irp->IoStatus.Information = 0;
2937 + return (STATUS_SUCCESS);
2940 +#endif // GATHER_FIB_TIMES
2944 +FsaCtlOpenGetAdapterFib(
2945 + IN PAFA_COMM_ADAPTER Adapter,
2946 + IN PAFA_IOCTL_CMD IoctlCmdPtr
2950 +Routine Description:
2952 + This routine will get the next Fib, if available, from the AdapterFibContext
2953 + passed in from the user.
2957 + Adapter - Supplies which adapter is being processed.
2959 + Irp - Supplies the Irp being processed.
2963 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
2965 + STATUS_INSUFFICIENT_RESOURCES - If a memory allocation failed.
2967 + STATUS_SUCCESS - Everything OK.
2971 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
2973 +// PKEVENT eventObject = (PKEVENT) NULL;
2977 + // The context must be allocated from NonPagedPool because we need to use MmIsAddressValid.
2980 + AdapterFibContext = OsAllocMemory(sizeof(GET_ADAPTER_FIB_CONTEXT), OS_ALLOC_MEM_SLEEP);
2982 + if (AdapterFibContext == NULL) {
2988 + AdapterFibContext->NodeTypeCode = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
2989 + AdapterFibContext->NodeByteSize = sizeof(GET_ADAPTER_FIB_CONTEXT);
2993 + // Initialize the conditional variable use to wait for the next AIF.
2996 + OsCv_init( &AdapterFibContext->UserEvent);
2999 + // Set WaitingForFib to FALSE to indicate we are not in a WaitForSingleObject
3002 + AdapterFibContext->WaitingForFib = FALSE;
3005 + // Initialize the FibList and set the count of fibs on the list to 0.
3008 + AdapterFibContext->FibCount = 0;
3009 + InitializeListHead(&AdapterFibContext->FibList);
3012 + // Overload FileObject with a time stamp.
3014 + AdapterFibContext->FileObject = (void *)OsGetSeconds();
3017 + // Now add this context onto the adapter's AdapterFibContext list.
3020 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3022 + InsertTailList(&Adapter->AdapterFibContextList, &AdapterFibContext->NextContext);
3024 + OsCvLockRelease(Adapter->AdapterFibMutex);
3026 + if (COPYOUT( &AdapterFibContext, (caddr_t) IoctlCmdPtr->arg, sizeof(PGET_ADAPTER_FIB_CONTEXT),
3027 + IoctlCmdPtr->flag )) {
3043 +FsaCtlGetNextAdapterFib(
3044 + IN PAFA_COMM_ADAPTER Adapter,
3045 + IN PAFA_IOCTL_CMD IoctlCmdPtr
3049 +Routine Description:
3051 + This routine will get the next Fib, if available, from the AdapterFibContext
3052 + passed in from the user.
3056 + Adapter - Supplies which adapter is being processed.
3058 + Irp - Supplies the Irp being processed.
3062 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3064 + STATUS_NO_MORE_ENTRIES - There are no more Fibs for this AdapterFibContext.
3066 + STATUS_SUCCESS - Everything OK.
3070 + GET_ADAPTER_FIB_IOCTL AdapterFibIoctl;
3071 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3074 + PLIST_ENTRY Entry;
3077 + if (COPYIN( (caddr_t) IoctlCmdPtr->arg, (caddr_t) &AdapterFibIoctl,
3078 + sizeof(GET_ADAPTER_FIB_IOCTL), IoctlCmdPtr->flag )) {
3083 + // Extract the AdapterFibContext from the Input parameters.
3086 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) AdapterFibIoctl.AdapterFibContext;
3089 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3091 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3092 + // this is a valid address
3095 + Entry = Adapter->AdapterFibContextList.Flink;
3097 + while ( Entry != &Adapter->AdapterFibContextList ) {
3098 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3099 + if ( AdapterFibContext == aifcp ) { // We found a winner
3103 + Entry = Entry->Flink;
3106 + if ( found == 0 ) {
3107 + return ( EINVAL );;
3110 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3111 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3113 + return ( EINVAL );
3117 + Status = STATUS_SUCCESS;
3119 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3122 + // If there are no fibs to send back, then either wait or return EAGAIN
3126 + if (!IsListEmpty(&AdapterFibContext->FibList)) {
3128 + PLIST_ENTRY Entry;
3131 + // Pull the next fib from the FibList
3133 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3135 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3137 + AdapterFibContext->FibCount--;
3139 + if (COPYOUT( Fib, AdapterFibIoctl.AifFib, sizeof(FIB), IoctlCmdPtr->flag )) {
3141 + OsCvLockRelease( Adapter->AdapterFibMutex );
3142 + OsFreeMemory( Fib, sizeof(Fib) );
3148 + // Free the space occupied by this copy of the fib.
3151 + OsFreeMemory(Fib, sizeof(FIB));
3156 + // Overload FileObject with a time stamp
3158 + AdapterFibContext->FileObject = ( void * )OsGetSeconds();
3162 + if (AdapterFibIoctl.Wait) {
3164 + if (OsCv_wait_sig( &AdapterFibContext->UserEvent, Adapter->AdapterFibMutex ) == 0) {
3180 + OsCvLockRelease( Adapter->AdapterFibMutex );
3186 +FsaCtlCloseGetAdapterFib(
3187 + IN PAFA_COMM_ADAPTER Adapter,
3188 + IN PAFA_IOCTL_CMD IoctlCmdPtr
3192 +Routine Description:
3194 + This routine will close down the AdapterFibContext passed in from the user.
3198 + Adapter - Supplies which adapter is being processed.
3200 + Irp - Supplies the Irp being processed.
3204 + STATUS_INVALID_PARAMETER - If the AdapterFibContext was not a valid pointer.
3206 + STATUS_SUCCESS - Everything OK.
3210 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext, aifcp;
3211 + AAC_STATUS Status;
3213 + PLIST_ENTRY Entry;
3217 + // Extract the AdapterFibContext from the Input parameters
3220 + AdapterFibContext = (PGET_ADAPTER_FIB_CONTEXT) IoctlCmdPtr->arg;
3222 + if (AdapterFibContext == 0) {
3223 + cmn_err(CE_WARN, "FsaCtlCloseGetAdapterFib: AdapterFibContext is NULL");
3228 + // Verify that the HANDLE passed in was a valid AdapterFibContext
3230 + // Search the list of AdapterFibContext addresses on the adapter to be sure
3231 + // this is a valid address
3234 + Entry = Adapter->AdapterFibContextList.Flink;
3236 + while ( Entry != &Adapter->AdapterFibContextList ) {
3237 + aifcp = CONTAINING_RECORD ( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3238 + if ( AdapterFibContext == aifcp ) { // We found a winner
3242 + Entry = Entry->Flink;
3245 + if ( found == 0 ) {
3246 + return ( 0 ); // Already Gone
3249 + if ( (AdapterFibContext->NodeTypeCode != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
3250 + (AdapterFibContext->NodeByteSize != sizeof(GET_ADAPTER_FIB_CONTEXT)) ) {
3256 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3258 + Status = FsaCloseAdapterFibContext(Adapter, AdapterFibContext);
3260 + OsCvLockRelease(Adapter->AdapterFibMutex);
3266 +FsaCloseAdapterFibContext(
3267 + IN PAFA_COMM_ADAPTER Adapter,
3268 + IN PGET_ADAPTER_FIB_CONTEXT AdapterFibContext
3275 + // First free any FIBs that have not been consumed yet.
3278 + while (!IsListEmpty(&AdapterFibContext->FibList)) {
3280 + PLIST_ENTRY Entry;
3283 + // Pull the next fib from the FibList
3286 + Entry = RemoveHeadList(&AdapterFibContext->FibList);
3288 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
3290 + AdapterFibContext->FibCount--;
3293 + // Free the space occupied by this copy of the fib.
3296 + OsFreeMemory(Fib, sizeof(FIB));
3300 + // Remove the Context from the AdapterFibContext List
3303 + RemoveEntryList(&AdapterFibContext->NextContext);
3305 + OsCv_destroy( &AdapterFibContext->UserEvent );
3308 + // Invalidate context
3311 + AdapterFibContext->NodeTypeCode = 0;
3314 + // Free the space occupied by the Context
3317 + OsFreeMemory(AdapterFibContext, sizeof(GET_ADAPTER_FIB_CONTEXT));
3319 + Status = STATUS_SUCCESS;
3326 +AfaCommOpenAdapter(
3331 +Routine Description:
3333 + The routine will get called by the miniport each time a user issues a CreateFile on the DeviceObject
3336 + The main purpose of this routine is to set up any data structures that may be needed
3337 + to handle any requests made on this DeviceObject.
3341 + Adapter - Pointer to which adapter miniport was opened.
3351 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3352 + AAC_STATUS Status = STATUS_SUCCESS;
3353 + PAFA_CLASS_DRIVER ClassDriver;
3355 + ClassDriver = Adapter->ClassDriverList;
3357 + while (ClassDriver) {
3359 + if (ClassDriver->OpenAdapter) {
3361 + Status = ClassDriver->OpenAdapter( ClassDriver->ClassDriverExtension );
3363 + if (Status != STATUS_SUCCESS)
3367 + ClassDriver = ClassDriver->Next;
3370 + return ( Status );
3374 +AfaCommCloseAdapter(
3379 +Routine Description:
3381 + This routine will get called by the miniport each time a user issues a CloseHandle on the DeviceObject
3384 + The main purpose of this routine is to cleanup any data structures that have been set up
3385 + while this FileObject has been opened.
3387 + This routine loops through all of the AdapterFibContext structures to determine if any need
3388 + to be deleted for this FileObject.
3392 + Adapter - Pointer to adapter miniport
3394 + Irp - Pointer to Irp that caused this close
3398 + Status value returned from File system driver AdapterClose
3402 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) Arg;
3403 + PLIST_ENTRY Entry, NextEntry;
3404 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
3405 + AAC_STATUS Status = STATUS_SUCCESS;
3406 + PAFA_CLASS_DRIVER ClassDriver;
3408 + OsCvLockAcquire(Adapter->AdapterFibMutex);
3410 + Entry = Adapter->AdapterFibContextList.Flink;
3413 + // Loop through all of the AdapterFibContext, looking for any that
3414 + // were created with the FileObject that is being closed.
3416 + while (Entry != &Adapter->AdapterFibContextList) {
3419 + // Extract the AdapterFibContext
3421 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
3424 + // Save the next entry because CloseAdapterFibContext will delete the AdapterFibContext
3426 + NextEntry = Entry->Flink;
3428 + Entry = NextEntry;
3432 +#ifdef unix_config_file
3434 + // If this FileObject had the adapter open for configuration, then release it.
3436 + if ( Adapter->AdapterConfigFileObject == IrpSp->FileObject ) {
3438 + Adapter->AdapterConfigFileObject = NULL;
3443 + OsCvLockRelease(Adapter->AdapterFibMutex);
3445 + ClassDriver = Adapter->ClassDriverList;
3447 + while (ClassDriver) {
3449 + if (ClassDriver->CloseAdapter) {
3451 + Status = ClassDriver->CloseAdapter( ClassDriver->ClassDriverExtension );
3453 + if (Status != STATUS_SUCCESS)
3457 + ClassDriver = ClassDriver->Next;
3460 + return ( Status );
3464 diff -burN linux-2.4.7/drivers/scsi/aacraid/comminit.c linux/drivers/scsi/aacraid/comminit.c
3465 --- linux-2.4.7/drivers/scsi/aacraid/comminit.c Wed Dec 31 18:00:00 1969
3466 +++ linux/drivers/scsi/aacraid/comminit.c Sat Jul 21 17:55:13 2001
3469 + * Adaptec aacraid device driver for Linux.
3471 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
3473 + * This program is free software; you can redistribute it and/or modify
3474 + * it under the terms of the GNU General Public License as published by
3475 + * the Free Software Foundation; either version 2, or (at your option)
3476 + * any later version.
3478 + * This program is distributed in the hope that it will be useful,
3479 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3480 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3481 + * GNU General Public License for more details.
3483 + * You should have received a copy of the GNU General Public License
3484 + * along with this program; see the file COPYING. If not, write to
3485 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
3490 + * Abstract: This supports the initialization of the host adapter commuication interface.
3491 + * This is a platform dependent module for the pci cyclone board.
3495 +static char *ident_comminit = "aacraid_ident comminit.c 1.0.6 2000/10/09 Adaptec, Inc.";
3497 +#include "comprocs.h"
3499 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMINIT)
3502 +AfaCommBugcheckHandler(
3508 +ThrottlePeriodEndDpcRtn(
3510 + IN PVOID DeferredContext,
3511 + IN PVOID SystemArgument1,
3512 + IN PVOID SystemArgument2);
3514 +FSA_COMM_DATA FsaCommData;
3517 +HardInterruptModeration1Changed(
3518 + IN PVOID AdapterContext,
3522 + PAFA_COMM_ADAPTER Adapter = AdapterContext;
3525 + // If we are using interrupt moderation, then disable the interrupt
3526 + // until we need to use it.
3528 + if (FsaCommData.HardInterruptModeration1)
3529 + DisableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3531 + EnableInterrupt( Adapter, AdapNormCmdNotFull, FALSE );
3533 + return (STATUS_SUCCESS);
3537 +FsaFibTimeoutChanged(
3538 + IN PVOID AdapterContext,
3543 + // scale the new timeout from seconds to 100 nsec units
3545 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*NewValue);
3547 + return (STATUS_SUCCESS);
3550 +#ifdef GATHER_FIB_TIMES
3551 +extern int GatherFibTimes;
3554 +FSA_USER_VAR FsaCommUserVars[] = {
3555 +#ifdef FIB_CHECKSUMS
3556 + { "do_fib_checksums", (PULONG)&FsaCommData.do_fib_checksums, NULL },
3558 +#ifdef GATHER_FIB_TIMES
3559 + { "GatherFibTimes", (PULONG)&GatherFibTimes, NULL },
3561 + { "EnableAdapterTimeouts", (PULONG)&FsaCommData.EnableAdapterTimeouts, NULL},
3562 + { "EnableInterruptModeration", (PULONG)&FsaCommData.EnableInterruptModeration, NULL },
3563 + { "FsaDataFibsSent", (PULONG) &FsaCommData.FibsSent, NULL },
3564 + { "FsaDataFibRecved", (PULONG) &FsaCommData.FibRecved, NULL },
3565 + { "HardInterruptModeration", (PULONG)&FsaCommData.HardInterruptModeration, NULL},
3566 + { "HardInterruptModeration1", (PULONG)&FsaCommData.HardInterruptModeration1, HardInterruptModeration1Changed},
3567 + { "EnableFibTimeoutBreak", (PULONG)&FsaCommData.EnableFibTimeoutBreak, NULL},
3568 + { "PeakFibsConsumed", (PULONG)&FsaCommData.PeakFibsConsumed, NULL },
3569 + { "ZeroFibsConsumed", (PULONG)&FsaCommData.ZeroFibsConsumed, NULL },
3570 + { "FibTimeoutSeconds", (PULONG) &FsaCommData.FibTimeoutSeconds, FsaFibTimeoutChanged },
3573 +#define NUM_COMM_USER_VARS (sizeof(FsaCommUserVars) / sizeof(FSA_USER_VAR) )
3577 +AacCommDriverEntry(
3582 +Routine Description:
3584 + This is the initialization routine for the FileArray Comm layer device driver.
3588 + DriverObject - Pointer to driver object created by the system.
3592 + AAC_STATUS - The function value is the final status from the initialization
3598 + AAC_STATUS Status;
3599 + PVOID BugCheckBuffer;
3601 + RtlZeroMemory( &FsaCommData, sizeof(FSA_COMM_DATA) );
3605 + // Load the global timeout value for the adapter timeout
3606 + // Also init the global that enables or disables adapter timeouts
3609 +// FsaCommData.AdapterTimeout = RtlConvertLongToLargeInteger(-10*1000*1000*180);
3611 + FsaCommData.FibTimeoutSeconds = 180;
3613 + FsaCommData.EnableAdapterTimeouts = TRUE;
3615 +// FsaCommData.QueueFreeTimeout = RtlConvertLongToLargeInteger(QUEUE_ENTRY_FREE_TIMEOUT);
3617 +#ifdef unix_fib_timeout
3618 + FsaCommData.FibTimeoutIncrement = (180 * 1000 * 1000 * 10) / KeQueryTimeIncrement();
3621 + FsaCommData.EnableInterruptModeration = FALSE;
3624 + // Preload UserVars with all variables from the comm layer. The class layers will
3625 + // include theirs when they register.
3628 + FsaCommData.UserVars = OsAllocMemory(NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR), OS_ALLOC_MEM_SLEEP );
3629 + FsaCommData.NumUserVars = NUM_COMM_USER_VARS;
3631 + RtlCopyMemory( FsaCommData.UserVars, &FsaCommUserVars, NUM_COMM_USER_VARS * sizeof(FSA_USER_VAR) );
3636 + // Call the disk driver to initialize itself.
3639 + AacDiskDriverEntry();
3645 + return (STATUS_SUCCESS);
3651 + IN PAFA_COMM_ADAPTER Adapter,
3652 + IN OUT PCOMM_QUE Queue,
3653 + IN QUEUE_TYPES WhichQueue
3657 +Routine Description:
3659 + This routine will release all of the resources used by a given queue.
3663 + Adapter - Which adapter the queue belongs to
3664 + Queue - Pointer to the queue itself
3665 + WhichQueue - Identifies which of the host queues this is.
3673 + switch (WhichQueue) {
3675 + case HostNormCmdQueue:
3677 + Os_remove_softintr( Queue->ConsumerRoutine );
3678 + OsSpinLockDestroy( Queue->QueueLock );
3679 + OsCv_destroy( &Queue->CommandReady );
3683 + case HostHighCmdQueue:
3685 + Os_remove_softintr( Queue->ConsumerRoutine );
3686 + OsSpinLockDestroy( Queue->QueueLock );
3687 + OsCv_destroy( &Queue->CommandReady );
3691 + case HostNormRespQueue:
3693 + Os_remove_softintr( Queue->ConsumerRoutine );
3694 + OsSpinLockDestroy( Queue->QueueLock );
3697 + case HostHighRespQueue:
3699 + Os_remove_softintr( Queue->ConsumerRoutine );
3700 + OsSpinLockDestroy( Queue->QueueLock );
3703 + case AdapNormCmdQueue:
3704 + case AdapHighCmdQueue:
3705 + case AdapNormRespQueue:
3706 + case AdapHighRespQueue:
3707 + OsCv_destroy( &Queue->QueueFull );
3714 + IN PAFA_COMM_ADAPTER Adapter,
3715 + IN OUT PCOMM_QUE Queue,
3716 + IN QUEUE_TYPES WhichQueue
3720 +Routine Description:
3722 + Will initialize all entries in the queue that is NT specific.
3728 + Nothing there is nothing to allocate so nothing should fail
3733 + Queue->NumOutstandingIos = 0;
3736 + // Store a pointer to the adapter structure.
3739 + Queue->Adapter = Adapter;
3741 + InitializeListHead( &Queue->OutstandingIoQueue );
3743 + switch (WhichQueue) {
3745 + case HostNormCmdQueue:
3747 + OsCv_init( &Queue->CommandReady);
3748 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3749 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3750 + NULL, (PUNIX_INTR_HANDLER)HostCommandNormDpc,
3751 + (caddr_t)Queue ) != DDI_SUCCESS) {
3753 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3756 + InitializeListHead(&Queue->CommandQueue);
3760 + case HostHighCmdQueue:
3762 + OsCv_init( &Queue->CommandReady);
3763 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3764 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3765 + NULL, (PUNIX_INTR_HANDLER)HostCommandHighDpc,
3766 + (caddr_t) Queue ) != DDI_SUCCESS) {
3768 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3771 + InitializeListHead(&Queue->CommandQueue);
3774 + case HostNormRespQueue:
3776 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3777 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3778 + NULL, (PUNIX_INTR_HANDLER)HostResponseNormalDpc,
3779 + (caddr_t) Queue ) != DDI_SUCCESS) {
3781 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3785 + case HostHighRespQueue:
3788 + OsSpinLockInit( Queue->QueueLock, Adapter->SpinLockCookie);
3789 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &Queue->ConsumerRoutine, NULL,
3790 + NULL, (PUNIX_INTR_HANDLER)HostResponseHighDpc,
3791 + (caddr_t) Queue ) != DDI_SUCCESS) {
3793 + cmn_err(CE_CONT, "OS_addr_intr failed\n");
3797 + case AdapNormCmdQueue:
3798 + case AdapHighCmdQueue:
3799 + case AdapNormRespQueue:
3800 + case AdapHighRespQueue:
3802 + OsCv_init( &Queue->QueueFull);
3808 +StartFsaCommandThreads(PAFA_COMM_ADAPTER Adapter)
3811 +Routine Description:
3813 + Create and start the command receiver threads.
3832 +Routine Description:
3834 + This routine gets called to detach all resources that have been allocated for
3839 + Adapter - Pointer to the adapter structure to detach.
3843 + TRUE - All resources have been properly released.
3844 + FALSE - An error occured while trying to release resources.
3847 +AacCommDetachAdapter (IN PAFA_COMM_ADAPTER Adapter)
3849 + PAFA_CLASS_DRIVER ClassDriver;
3851 + // First remove this adapter from the list of adapters.
3854 + if (FsaCommData.AdapterList == Adapter) {
3856 + FsaCommData.AdapterList = Adapter->NextAdapter;
3860 + PAFA_COMM_ADAPTER CurrentAdapter, NextAdapter;
3862 + CurrentAdapter = FsaCommData.AdapterList;
3863 + NextAdapter = CurrentAdapter->NextAdapter;
3865 + while (NextAdapter) {
3867 + if (NextAdapter == Adapter) {
3869 + CurrentAdapter->NextAdapter = NextAdapter->NextAdapter;
3874 + CurrentAdapter = NextAdapter;
3875 + NextAdapter = CurrentAdapter->NextAdapter;
3880 + // First send a shutdown to the adapter.
3883 + AfaCommShutdown( Adapter );
3886 + // Destroy the FibContextZone for this adapter. This will free up all
3887 + // of the fib space used by this adapter.
3890 + FsaFreeFibContextZone( Adapter );
3893 + // Destroy the mutex used for synch'ing adapter fibs.
3896 + OsCvLockDestroy( Adapter->AdapterFibMutex );
3899 + // Detach all of the host queues.
3902 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighRespQue, AdapHighRespQueue );
3903 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormRespQue, AdapNormRespQueue );
3904 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighRespQue, HostHighRespQueue );
3905 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormRespQue, HostNormRespQueue );
3906 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapHighCmdQue, AdapHighCmdQueue );
3907 + DetachNTQueue( Adapter, &Adapter->CommRegion->AdapNormCmdQue, AdapNormCmdQueue );
3908 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostHighCmdQue, HostHighCmdQueue );
3909 + DetachNTQueue( Adapter, &Adapter->CommRegion->HostNormCmdQue, HostNormCmdQueue );
3912 + // Destroy the mutex used to protect the FibContextZone
3915 + OsSpinLockDestroy( Adapter->FibContextZoneSpinLock );
3918 + // Call the miniport to free the space allocated for the shared comm queues
3919 + // between the host and the adapter.
3922 + FsaFreeAdapterCommArea( Adapter );
3925 + // Free the memory used by the comm region for this adapter
3928 + OsFreeMemory( Adapter->CommRegion, sizeof(COMM_REGION) );
3931 + // Free the memory used by the adapter structure.
3933 + ClassDriver = Adapter->ClassDriverList;
3934 + Adapter->ClassDriverList = Adapter->ClassDriverList->Next;
3935 + OsFreeMemory( ClassDriver, sizeof(AFA_CLASS_DRIVER) );
3937 + OsFreeMemory( Adapter, sizeof(AFA_COMM_ADAPTER) );
3943 +AfaCommInitNewAdapter (IN PFSA_NEW_ADAPTER NewAdapter)
3945 + PVOID BugCheckBuffer;
3946 + PAFA_COMM_ADAPTER Adapter;
3947 + MAPFIB_CONTEXT MapFibContext;
3948 + LARGE_INTEGER Time;
3949 + char ErrorBuffer[60];
3951 + Adapter = (PAFA_COMM_ADAPTER) OsAllocMemory( sizeof(AFA_COMM_ADAPTER) , OS_ALLOC_MEM_SLEEP );
3953 + if (Adapter == NULL)
3956 + RtlZeroMemory(Adapter, sizeof(AFA_COMM_ADAPTER));
3960 + // Save the current adapter number and increment the total number.
3963 + Adapter->AdapterNumber = FsaCommData.TotalAdapters++;
3967 + // Fill in the pointer back to the device specific structures.
3968 + // The device specific driver has also passed a pointer for us to
3969 + // fill in with the Adapter object that we have created.
3972 + Adapter->AdapterExtension = NewAdapter->AdapterExtension;
3973 + Adapter->AdapterFuncs = NewAdapter->AdapterFuncs;
3974 + Adapter->InterruptsBelowDpc = NewAdapter->AdapterInterruptsBelowDpc;
3975 + Adapter->AdapterUserVars = NewAdapter->AdapterUserVars;
3976 + Adapter->AdapterUserVarsSize = NewAdapter->AdapterUserVarsSize;
3978 + Adapter->Dip = NewAdapter->Dip;
3981 + // Fill in Our address into the function dispatch table
3984 + NewAdapter->AdapterFuncs->InterruptHost = AfaCommInterruptHost;
3985 + NewAdapter->AdapterFuncs->OpenAdapter = AfaCommOpenAdapter;
3986 + NewAdapter->AdapterFuncs->CloseAdapter = AfaCommCloseAdapter;
3987 + NewAdapter->AdapterFuncs->DeviceControl = AfaCommAdapterDeviceControl;
3990 + // Ok now init the communication subsystem
3993 + Adapter->CommRegion = (PCOMM_REGION) OsAllocMemory(sizeof(COMM_REGION), OS_ALLOC_MEM_SLEEP);
3994 + if (Adapter->CommRegion == NULL) {
3995 + cmn_err(CE_WARN, "Error could not allocate comm region.\n");
3998 + RtlZeroMemory(Adapter->CommRegion, sizeof(COMM_REGION));
4001 + // Get a pointer to the iblock_cookie
4004 + ddi_get_soft_iblock_cookie( Adapter->Dip, DDI_SOFTINT_HIGH, &Adapter->SpinLockCookie );
4006 + if (!CommInit(Adapter)) {
4007 + FsaCommPrint("Failed to init the commuication subsystem.\n");
4013 + // Initialize the list of AdapterFibContext's.
4016 + InitializeListHead(&Adapter->AdapterFibContextList);
4019 + // Initialize the fast mutex used for synchronization of the adapter fibs
4022 + Adapter->AdapterFibMutex = OsCvLockAlloc();
4023 + OsCvLockInit(Adapter->AdapterFibMutex, NULL);
4026 + // Allocate and start the FSA command threads. These threads will handle
4027 + // command requests from the adapter. They will wait on an event then pull
4028 + // all CDBs off the thread's queue. Each CDB will be given to a worker thread
4029 + // upto a defined limit. When that limit is reached wait a event will be waited
4030 + // on till a worker thread is finished.
4033 + if (!StartFsaCommandThreads(Adapter)) {
4034 + FsaCommPrint("Fsainit could not initilize the command receiver threads.\n");
4038 +#ifdef unix_crash_dump
4040 + // Allocate and map a fib for use by the synch path, which is used for crash
4043 + // Allocate an entire page so that alignment is correct.
4046 + Adapter->SyncFib = OsAllocMemory( PAGE_SIZE, OS_ALLOC_MEM_SLEEP );
4047 + MapFibContext.Fib = Adapter->SyncFib;
4048 + MapFibContext.Size = sizeof(FIB);
4049 + MapFib( Adapter, &MapFibContext );
4050 + Adapter->SyncFibPhysicalAddress = MapFibContext.LogicalFibAddress.LowPart;
4053 + Adapter->CommFuncs.SizeOfAfaCommFuncs = sizeof(AFACOMM_FUNCS);
4055 + Adapter->CommFuncs.AllocateFib = AllocateFib;
4057 + Adapter->CommFuncs.FreeFib = FreeFib;
4058 + Adapter->CommFuncs.FreeFibFromDpc = FreeFibFromDpc;
4059 + Adapter->CommFuncs.DeallocateFib = DeallocateFib;
4061 + Adapter->CommFuncs.InitializeFib = InitializeFib;
4062 + Adapter->CommFuncs.GetFibData = FsaGetFibData;
4063 + Adapter->CommFuncs.SendFib = SendFib;
4064 + Adapter->CommFuncs.CompleteFib = CompleteFib;
4065 + Adapter->CommFuncs.CompleteAdapterFib = CompleteAdapterFib;
4067 + Adapter->CommFuncs.SendSynchFib = SendSynchFib;
4069 + Adapter->CommFuncs.FreeDmaResources = Adapter->AdapterFuncs->FreeDmaResources;
4070 + Adapter->CommFuncs.BuildSgMap = Adapter->AdapterFuncs->BuildSgMap;
4073 + // Add this adapter in to our Adapter List.
4076 + Adapter->NextAdapter = FsaCommData.AdapterList;
4077 + FsaCommData.AdapterList = Adapter;
4079 + NewAdapter->Adapter = Adapter;
4081 +// AfaDiskInitNewAdapter( Adapter->AdapterNumber, Adapter );
4088 + PAFA_COMM_ADAPTER Adapter
4092 + // Now allocate and initialize the zone structures used as our pool
4093 + // of FIB context records. The size of the zone is based on the
4094 + // system memory size. We also initialize the mutex used to protect
4097 + Adapter->FibContextZoneSpinLock = OsSpinLockAlloc();
4098 + OsSpinLockInit( Adapter->FibContextZoneSpinLock, Adapter->SpinLockCookie );
4100 + Adapter->FibContextZoneExtendSize = 64;
4102 + return (STATUS_SUCCESS);
4109 +Routine Description:
4111 + Initializes the data structures that are required for the FSA commuication
4112 + interface to operate.
4116 + None - all global or allocated data.
4120 + TRUE - if we were able to init the commuication interface.
4121 + FALSE - If there were errors initing. This is a fatal error.
4124 +CommInit(PAFA_COMM_ADAPTER Adapter)
4127 + ULONG SizeOfHeaders = (sizeof(QUEUE_INDEX) * NUMBER_OF_COMM_QUEUES) * 2;
4128 + ULONG SizeOfQueues = sizeof(QUEUE_ENTRY) * TOTAL_QUEUE_ENTRIES;
4129 + PQUEUE_INDEX Headers;
4130 + PQUEUE_ENTRY Queues;
4132 + PCOMM_REGION CommRegion = Adapter->CommRegion;
4134 + CommInitialize( Adapter );
4136 + 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",
4137 + sizeof(QUEUE_ENTRY), sizeof(QUEUE_INDEX), TOTAL_QUEUE_ENTRIES, NUMBER_OF_COMM_QUEUES);
4140 + // Allocate the physically contigous space for the commuication queue
4144 + TotalSize = SizeOfHeaders + SizeOfQueues;
4146 + if (!FsaAllocateAdapterCommArea(Adapter, (PVOID *)&Headers, TotalSize, QUEUE_ALIGNMENT))
4149 + Queues = (PQUEUE_ENTRY)((PUCHAR)Headers + SizeOfHeaders);
4151 + if (ddi_add_softintr( Adapter->Dip, DDI_SOFTINT_HIGH, &CommRegion->QueueNotFullDpc, NULL,
4152 + NULL, (PUNIX_INTR_HANDLER)CommonNotFullDpc,
4153 + (caddr_t)CommRegion ) != DDI_SUCCESS) {
4155 + cmn_err(CE_CONT, "Os_addr_intr failed\n");
4159 + // Adapter to Host normal priority Command queue
4162 + CommRegion->HostNormCmdQue.Headers.ProducerIndex = Headers++;
4163 + CommRegion->HostNormCmdQue.Headers.ConsumerIndex = Headers++;
4164 + *CommRegion->HostNormCmdQue.Headers.ProducerIndex = HOST_NORM_CMD_ENTRIES;
4165 + *CommRegion->HostNormCmdQue.Headers.ConsumerIndex = HOST_NORM_CMD_ENTRIES;
4167 + CommRegion->HostNormCmdQue.SavedIrql = 0;
4168 + CommRegion->HostNormCmdQue.BaseAddress = Queues;
4169 + CommRegion->HostNormCmdQue.QueueEntries = HOST_NORM_CMD_ENTRIES;
4171 + CommRegion->HostNormCmdQue.QueueLock = OsSpinLockAlloc();
4172 + if (CommRegion->HostNormCmdQue.QueueLock == NULL) {
4175 + InitializeNTQueue(Adapter, &CommRegion->HostNormCmdQue, HostNormCmdQueue);
4178 + Queues += HOST_NORM_CMD_ENTRIES;
4180 + // Adapter to Host high priority command queue
4182 + CommRegion->HostHighCmdQue.Headers.ProducerIndex = Headers++;
4183 + CommRegion->HostHighCmdQue.Headers.ConsumerIndex = Headers++;
4184 + *CommRegion->HostHighCmdQue.Headers.ProducerIndex = HOST_HIGH_CMD_ENTRIES;
4185 + *CommRegion->HostHighCmdQue.Headers.ConsumerIndex = HOST_HIGH_CMD_ENTRIES;
4187 + CommRegion->HostHighCmdQue.SavedIrql = 0;
4188 + CommRegion->HostHighCmdQue.BaseAddress = Queues;
4189 + CommRegion->HostHighCmdQue.QueueEntries = HOST_HIGH_CMD_ENTRIES;
4190 +// CommRegion->HostHighCmdQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4191 + CommRegion->HostHighCmdQue.QueueLock = OsSpinLockAlloc();
4192 + if (CommRegion->HostHighCmdQue.QueueLock == NULL) {
4195 + InitializeNTQueue(Adapter, &CommRegion->HostHighCmdQue, HostHighCmdQueue);
4197 + Queues += HOST_HIGH_CMD_ENTRIES;
4199 + // Host to adapter normal priority command queue
4201 + CommRegion->AdapNormCmdQue.Headers.ProducerIndex = Headers++;
4202 + CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = Headers++;
4203 + *CommRegion->AdapNormCmdQue.Headers.ProducerIndex = ADAP_NORM_CMD_ENTRIES;
4204 + *CommRegion->AdapNormCmdQue.Headers.ConsumerIndex = ADAP_NORM_CMD_ENTRIES;
4206 + CommRegion->AdapNormCmdQue.SavedIrql = 0;
4207 + CommRegion->AdapNormCmdQue.BaseAddress = Queues;
4208 + CommRegion->AdapNormCmdQue.QueueEntries = ADAP_NORM_CMD_ENTRIES;
4209 + InitializeNTQueue(Adapter, &CommRegion->AdapNormCmdQue, AdapNormCmdQueue);
4211 + Queues += ADAP_NORM_CMD_ENTRIES;
4213 + // host to adapter high priority command queue
4215 + CommRegion->AdapHighCmdQue.Headers.ProducerIndex = Headers++;
4216 + CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = Headers++;
4217 + *CommRegion->AdapHighCmdQue.Headers.ProducerIndex = ADAP_HIGH_CMD_ENTRIES;
4218 + *CommRegion->AdapHighCmdQue.Headers.ConsumerIndex = ADAP_HIGH_CMD_ENTRIES;
4220 + CommRegion->AdapHighCmdQue.SavedIrql = 0;
4221 + CommRegion->AdapHighCmdQue.BaseAddress = Queues;
4222 + CommRegion->AdapHighCmdQue.QueueEntries = ADAP_HIGH_CMD_ENTRIES;
4223 + InitializeNTQueue(Adapter, &CommRegion->AdapHighCmdQue, AdapHighCmdQueue);
4225 + Queues += ADAP_HIGH_CMD_ENTRIES;
4227 + // adapter to host normal priority response queue
4229 + CommRegion->HostNormRespQue.Headers.ProducerIndex = Headers++;
4230 + CommRegion->HostNormRespQue.Headers.ConsumerIndex = Headers++;
4231 + *CommRegion->HostNormRespQue.Headers.ProducerIndex = HOST_NORM_RESP_ENTRIES;
4232 + *CommRegion->HostNormRespQue.Headers.ConsumerIndex = HOST_NORM_RESP_ENTRIES;
4234 + CommRegion->HostNormRespQue.SavedIrql = 0;
4235 + CommRegion->HostNormRespQue.BaseAddress = Queues;
4236 + CommRegion->HostNormRespQue.QueueEntries = HOST_NORM_RESP_ENTRIES;
4237 +// CommRegion->HostNormRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4238 + CommRegion->HostNormRespQue.QueueLock = OsSpinLockAlloc();
4239 + if (CommRegion->HostNormRespQue.QueueLock == NULL) {
4242 + InitializeNTQueue(Adapter, &CommRegion->HostNormRespQue, HostNormRespQueue);
4244 + Queues += HOST_NORM_RESP_ENTRIES;
4246 + // adapter to host high priority response queue
4248 + CommRegion->HostHighRespQue.Headers.ProducerIndex = Headers++;
4249 + CommRegion->HostHighRespQue.Headers.ConsumerIndex = Headers++;
4250 + *CommRegion->HostHighRespQue.Headers.ProducerIndex = HOST_HIGH_RESP_ENTRIES;
4251 + *CommRegion->HostHighRespQue.Headers.ConsumerIndex = HOST_HIGH_RESP_ENTRIES;
4253 + CommRegion->HostHighRespQue.SavedIrql = 0;
4254 + CommRegion->HostHighRespQue.BaseAddress = Queues;
4255 + CommRegion->HostHighRespQue.QueueEntries = HOST_HIGH_RESP_ENTRIES;
4256 +// CommRegion->HostHighRespQue.QueueLock = (PKSPIN_LOCK) ExAllocatePool(NonPagedPool, sizeof(KSPIN_LOCK));
4257 + CommRegion->HostHighRespQue.QueueLock = OsSpinLockAlloc();
4258 + if (CommRegion->HostHighRespQue.QueueLock == NULL) {
4261 + InitializeNTQueue(Adapter, &CommRegion->HostHighRespQue, HostHighRespQueue);
4263 + Queues += HOST_HIGH_RESP_ENTRIES;
4265 + // host to adapter normal priority response queue
4267 + CommRegion->AdapNormRespQue.Headers.ProducerIndex = Headers++;
4268 + CommRegion->AdapNormRespQue.Headers.ConsumerIndex = Headers++;
4269 + *CommRegion->AdapNormRespQue.Headers.ProducerIndex = ADAP_NORM_RESP_ENTRIES;
4270 + *CommRegion->AdapNormRespQue.Headers.ConsumerIndex = ADAP_NORM_RESP_ENTRIES;
4272 + CommRegion->AdapNormRespQue.SavedIrql = 0;
4273 + CommRegion->AdapNormRespQue.BaseAddress = Queues;
4274 + CommRegion->AdapNormRespQue.QueueEntries = ADAP_NORM_RESP_ENTRIES;
4275 + InitializeNTQueue(Adapter, &CommRegion->AdapNormRespQue, AdapNormRespQueue);
4277 + Queues += ADAP_NORM_RESP_ENTRIES;
4279 + // host to adapter high priority response queue
4281 + CommRegion->AdapHighRespQue.Headers.ProducerIndex = Headers++;
4282 + CommRegion->AdapHighRespQue.Headers.ConsumerIndex = Headers++;
4283 + *CommRegion->AdapHighRespQue.Headers.ProducerIndex = ADAP_HIGH_RESP_ENTRIES;
4284 + *CommRegion->AdapHighRespQue.Headers.ConsumerIndex = ADAP_HIGH_RESP_ENTRIES;
4286 + CommRegion->AdapHighRespQue.SavedIrql = 0;
4287 + CommRegion->AdapHighRespQue.BaseAddress = Queues;
4288 + CommRegion->AdapHighRespQue.QueueEntries = ADAP_HIGH_RESP_ENTRIES;
4289 + InitializeNTQueue(Adapter, &CommRegion->AdapHighRespQue, AdapHighRespQueue);
4291 + CommRegion->AdapNormCmdQue.QueueLock = CommRegion->HostNormRespQue.QueueLock;
4292 + CommRegion->AdapHighCmdQue.QueueLock = CommRegion->HostHighRespQue.QueueLock;
4293 + CommRegion->AdapNormRespQue.QueueLock = CommRegion->HostNormCmdQue.QueueLock;
4294 + CommRegion->AdapHighRespQue.QueueLock = CommRegion->HostHighCmdQue.QueueLock;
4301 + PAFA_COMM_ADAPTER Adapter
4305 +Routine Description:
4307 + This routine will send a shutdown request to each adapter.
4311 + Adapter - which adapter to send the shutdown to.
4315 + NT Status success.
4320 + PFIB_CONTEXT FibContext;
4321 + PCLOSECOMMAND CloseCommand;
4322 + AAC_STATUS Status;
4324 + FibContext = AllocateFib( Adapter );
4326 + InitializeFib( FibContext );
4328 + CloseCommand = (PCLOSECOMMAND) FsaGetFibData( FibContext );
4330 + CloseCommand->Command = VM_CloseAll;
4331 + CloseCommand->ContainerId = 0xffffffff;
4333 + Status = SendFib( ContainerCommand, FibContext, sizeof(CLOSECOMMAND), FsaNormal, TRUE, NULL, TRUE, NULL, NULL );
4335 + if (Status != STATUS_SUCCESS) {
4337 + FreeFib( FibContext );
4343 + CompleteFib( FibContext );
4345 + FreeFib( FibContext );
4348 + Status = STATUS_SUCCESS;
4357 +AfaCommBugcheckHandler(
4363 +Routine Description:
4365 + This routine will shutdown the adapter if there is a bugcheck and
4366 + copy the shutdown data from the adapter response into the buffer
4367 + so it will show up in the host dump file.
4371 + Buffer - This buffer will be written to the host dump by nt for us.
4373 + Length - The size of the buffer.
4381 + PAFA_COMM_ADAPTER Adapter = FsaCommData.AdapterList;
4385 + NotifyAdapter(Adapter, HostShutdown);
4387 + Adapter = Adapter->NextAdapter;
4395 + PFIB_CONTEXT FibContext,
4396 + PDEVICE_OBJECT DeviceObject,
4397 + AAC_STATUS FsaStatus,
4398 + AAC_STATUS AacStatus,
4399 + ULONG LocationCode,
4408 + PAFA_COMM_ADAPTER Adapter
4411 + PMNTINFO DiskInfo;
4412 + PMNTINFORESPONSE DiskInfoResponse;
4413 + AAC_STATUS Status;
4414 + PCOMM_FIB_CONTEXT FibContext;
4416 + FibContext = AllocateFib( Adapter );
4418 + InitializeFib( FibContext );
4420 + DiskInfo = (PMNTINFO) FibContext->Fib->data;
4421 + DiskInfo->Command = VM_NameServe;
4422 + DiskInfo->MntCount = 0;
4423 + DiskInfo->MntType = FT_FILESYS;
4425 + Status = SendFib(ContainerCommand,
4435 + DiskInfoResponse = (PMNTINFORESPONSE) FibContext->Fib->data;
4437 + if (DiskInfoResponse->MntRespCount) {
4439 + cmn_err(CE_CONT, "container found on adapter, size = 0x%x blocks\n",
4440 + DiskInfoResponse->MntTable[0].Capacity);
4444 + cmn_err(CE_CONT, "no containers found on adapter\n");
4448 + CompleteFib( FibContext );
4450 + FreeFib( FibContext );
4454 diff -burN linux-2.4.7/drivers/scsi/aacraid/commsup.c linux/drivers/scsi/aacraid/commsup.c
4455 --- linux-2.4.7/drivers/scsi/aacraid/commsup.c Wed Dec 31 18:00:00 1969
4456 +++ linux/drivers/scsi/aacraid/commsup.c Sat Jul 21 17:55:13 2001
4459 + * Adaptec aacraid device driver for Linux.
4461 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
4463 + * This program is free software; you can redistribute it and/or modify
4464 + * it under the terms of the GNU General Public License as published by
4465 + * the Free Software Foundation; either version 2, or (at your option)
4466 + * any later version.
4468 + * This program is distributed in the hope that it will be useful,
4469 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4470 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4471 + * GNU General Public License for more details.
4473 + * You should have received a copy of the GNU General Public License
4474 + * along with this program; see the file COPYING. If not, write to
4475 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
4480 + * Abstract: Contain all routines that are required for FSA host/adapter
4486 +static char *ident_commsup = "aacraid_ident commsup.c 1.0.7 2000/10/11 Adaptec, Inc.";
4488 +#include "comprocs.h"
4490 +#define BugCheckFileId (FSAFS_BUG_CHECK_COMMSUP)
4495 +ThrottleExceptionHandler(
4496 + IN PCOMM_REGION CommRegion,
4500 +void ThrottlePeriodEndDpcRtn(
4502 + IN PVOID DeferredContext,
4503 + IN PVOID SystemArgument1,
4504 + IN PVOID SystemArgument2
4510 +Routine Description:
4512 + This routine will free all resources used by a given FibContextSegment.
4516 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4517 + ZoneSegment - The segment to release resources from.
4521 + TRUE - All resources were properly freed.
4522 + FALSE - An Error occured while freeing resources.
4526 +FsaFreeFibContextSegment (PAFA_COMM_ADAPTER Adapter,
4527 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment)
4529 + PCOMM_FIB_CONTEXT FibContext;
4532 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4534 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)ZoneSegment->FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4535 + i < ZoneSegment->ExtendSize; i++, FibContext++) {
4537 + OsCvLockDestroy( FibContext->FsaEventMutex );
4538 + OsCv_destroy( &FibContext->FsaEvent );
4542 + UnmapAndFreeFibSpace( Adapter, &ZoneSegment->MapFibContext );
4544 + OsFreeMemory( ZoneSegment->FibContextSegment, ZoneSegment->FibContextSegmentSize );
4546 + OsFreeMemory( ZoneSegment, sizeof( FIB_CONTEXT_ZONE_SEGMENT ) );
4552 +FsaFreeFibContextZone(
4553 + PAFA_COMM_ADAPTER Adapter
4557 +Routine Description:
4559 + This routine will walk through the FibContextSegmentList and free up all
4560 + resources used by the FibContextZone.
4564 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4568 + TRUE - All resources were properly freed.
4569 + FALSE - An Error occured while freeing resources.
4574 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment, NextZoneSegment;
4576 + ZoneSegment = Adapter->FibContextSegmentList;
4578 + while (ZoneSegment) {
4580 + NextZoneSegment = ZoneSegment->Next;
4582 + FsaFreeFibContextSegment( Adapter, ZoneSegment );
4584 + ZoneSegment = NextZoneSegment;
4593 +FsaExtendFibContextZone (IN PAFA_COMM_ADAPTER Adapter)
4597 + ULONG ZoneSegmentAllocSize, FibAllocSize;
4598 + PVOID FibContextSegment;
4599 + PCOMM_FIB_CONTEXT FibContext;
4601 + PVOID FibPhysicalAddress;
4603 + PFIB_CONTEXT_ZONE_SEGMENT ZoneSegment;
4606 + // Allocate space to describe this zone segment.
4609 + cmn_err (CE_DEBUG, "Entered FsaExtendFibContextZone");
4610 + ZoneSegment = OsAllocMemory( sizeof( FIB_CONTEXT_ZONE_SEGMENT ), OS_ALLOC_MEM_SLEEP );
4611 + if (ZoneSegment == NULL) {
4615 + ExtendSize = Adapter->FibContextZoneExtendSize;
4616 + ZoneSegmentAllocSize = (ExtendSize * sizeof(COMM_FIB_CONTEXT)) + sizeof(ZONE_SEGMENT_HEADER);
4618 + FibContextSegment = OsAllocMemory( ZoneSegmentAllocSize, OS_ALLOC_MEM_SLEEP );
4620 + if (FibContextSegment == NULL) {
4621 + OsFreeMemory(ZoneSegment);
4625 + RtlZeroMemory( FibContextSegment, ZoneSegmentAllocSize );
4627 + ZoneSegment->FibContextSegment = FibContextSegment;
4628 + ZoneSegment->FibContextSegmentSize = ZoneSegmentAllocSize;
4629 + ZoneSegment->ExtendSize = ExtendSize;
4631 + FibAllocSize = ExtendSize * sizeof(FIB);
4634 + ZoneSegment->MapFibContext.Size = FibAllocSize;
4636 + AllocateAndMapFibSpace( Adapter, &ZoneSegment->MapFibContext );
4638 + Fib = ZoneSegment->MapFibContext.FibVirtualAddress;
4639 + FibPhysicalAddress = ZoneSegment->MapFibContext.FibPhysicalAddress;
4641 + RtlZeroMemory( Fib, FibAllocSize );
4643 + // Account for the ZONE_SEGMENT_HEADER before the first actual FibContext.
4645 + for (i = 0, FibContext = (PCOMM_FIB_CONTEXT)((PUCHAR)FibContextSegment + sizeof(ZONE_SEGMENT_HEADER));
4646 + i < ExtendSize; i++, FibContext++) {
4648 + FibContext->Adapter = Adapter;
4650 + FibContext->Fib = Fib;
4651 + FibContext->FibData = (PVOID) FibContext->Fib->data;
4653 + OsCv_init( &FibContext->FsaEvent);
4654 + FibContext->FsaEventMutex = OsCvLockAlloc();
4655 + OsCvLockInit( FibContext->FsaEventMutex, Adapter->SpinLockCookie );
4657 + Fib->Header.XferState = 0xffffffff;
4658 + Fib->Header.SenderSize = sizeof(FIB);
4660 + FibContext->LogicalFibAddress.LowPart = (ULONG) FibPhysicalAddress;
4662 + Fib = (PFIB)((PUCHAR)Fib + sizeof(FIB));
4663 + FibPhysicalAddress = (PVOID)((PUCHAR)FibPhysicalAddress + sizeof(FIB));
4667 + // If FibContextZone.TotalSegmentSize is non-zero, then a zone has already been
4668 + // initialized, we just need to extend it.
4671 + if (Adapter->FibContextZone.TotalSegmentSize) {
4673 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4675 + ExExtendZone( &Adapter->FibContextZone,
4676 + FibContextSegment,
4677 + ZoneSegmentAllocSize );
4679 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4683 + if (ExInitializeZone( &Adapter->FibContextZone,
4684 + sizeof(COMM_FIB_CONTEXT),
4685 + FibContextSegment,
4686 + ZoneSegmentAllocSize ) != STATUS_SUCCESS)
4687 + FsaBugCheck(0,0,0);
4692 + // Add this segment to the adapter's list of segments
4695 + ZoneSegment->Next = Adapter->FibContextSegmentList;
4696 + Adapter->FibContextSegmentList = ZoneSegment;
4705 +Routine Description:
4707 + This routine creates a new COMM_FIB_CONTEXT record
4711 + Adapter - The adapter that this COMM_FIB_CONTEXT will communicate with.
4715 + PCOMM_FIB_CONTEXT - returns a pointer to the newly allocate COMM_FIB_CONTEXT Record
4719 +AllocateFib (IN PVOID AdapterArg)
4721 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) AdapterArg;
4723 + PCOMM_FIB_CONTEXT FibContext;
4724 + int FullZoneLoopCounter = 0;
4728 + // Acquire the zone spin lock, and check to see if the zone is full.
4729 + // If it is, then release the spin lock and allocate more fibs for the
4730 + // zone. The ExtendFibZone routine will re-acquire the spin lock to add
4731 + // the new fibs onto the zone.
4734 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4736 + while (ExIsFullZone( &Adapter->FibContextZone )) {
4738 + if (++FullZoneLoopCounter > 10)
4739 + FsaBugCheck(0,0,0);
4741 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4744 + cmn_err (CE_DEBUG, "Extending FibContextZone");
4745 + if (FsaExtendFibContextZone(Adapter) == FALSE) {
4749 + OsSpinLockAcquire( Adapter->FibContextZoneSpinLock );
4754 + // At this point we now know that the zone has at least one more
4755 + // IRP context record available. So allocate from the zone and
4756 + // then release the mutex.
4759 + FibContext = (PCOMM_FIB_CONTEXT) ExAllocateFromZone( &Adapter->FibContextZone );
4761 + OsSpinLockRelease( Adapter->FibContextZoneSpinLock );
4764 + // Set the proper node type code and node byte size
4767 + FibContext->NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
4768 + FibContext->NodeByteSize = sizeof( COMM_FIB_CONTEXT );
4771 + // Null out fields that depend on being zero at the start of each I/O
4774 + FibContext->Fib->Header.XferState = 0;
4775 + FibContext->FibCallback = NULL;
4776 + FibContext->FibCallbackContext = NULL;
4780 + // return and tell the caller
4783 + return ((PFIB_CONTEXT) FibContext);
4789 +Routine Description:
4791 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4792 + from the Fsafs in memory data structures. It should only be called
4793 + by FsaCompleteRequest.
4797 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4805 +FreeFib (IN PFIB_CONTEXT Context)
4808 + PCOMM_FIB_CONTEXT FibContext = Context;
4810 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4812 + OsSpinLockAcquire( FibContext->Adapter->FibContextZoneSpinLock );
4814 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4816 + FsaCommData.TimedOutFibs++;
4818 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4819 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4823 + ASSERT(FibContext->Fib->Header.XferState == 0);
4825 + if (FibContext->Fib->Header.XferState != 0) {
4826 + cmn_err(CE_WARN, "FreeFib, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4827 + FibContext, FibContext->Fib->Header.XferState);
4830 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4834 + OsSpinLockRelease( FibContext->Adapter->FibContextZoneSpinLock );
4837 + // return and tell the caller
4846 +Routine Description:
4848 + This routine deallocates and removes the specified COMM_FIB_CONTEXT record
4849 + from the Fsafs in memory data structures. It should only be called
4850 + from the dpc routines to from dpc to free an FibContext from an async or
4855 + FibContext - Supplies the COMM_FIB_CONTEXT to remove
4863 +FreeFibFromDpc (IN PFIB_CONTEXT Context)
4865 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4867 + ASSERT(FibContext->NodeTypeCode == FSAFS_NTC_FIB_CONTEXT);
4869 + OsSpinLockAcquire(FibContext->Adapter->FibContextZoneSpinLock);
4871 + if (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) {
4873 + FsaCommData.TimedOutFibs++;
4875 + FibContext->Next = FibContext->Adapter->FibContextTimedOutList;
4876 + FibContext->Adapter->FibContextTimedOutList = FibContext;
4880 + ASSERT(FibContext->Fib->Header.XferState == 0);
4882 + if (FibContext->Fib->Header.XferState != 0) {
4883 + cmn_err(CE_WARN, "FreeFibFromDpc, XferState != 0, FibContext = 0x%x, XferState = 0x%x\n",
4884 + FibContext, FibContext->Fib->Header.XferState);
4888 + ExFreeToZone( &FibContext->Adapter->FibContextZone, FibContext );
4892 + OsSpinLockRelease(FibContext->Adapter->FibContextZoneSpinLock);
4895 + // return and tell the caller
4904 +Routine Description:
4906 + Will initialize a FIB of the requested size.
4910 + Fib is a pointer to a location which will receive the address of the allocated
4913 + Size is the size of the Fib to allocate.
4917 + NT_SUCCESS if a Fib was returned to the caller.
4918 + NT_ERROR if event was an invalid event.
4922 +InitializeFib (IN PFIB_CONTEXT Context)
4924 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4925 + PFIB Fib = FibContext->Fib;
4927 + Fib->Header.StructType = TFib;
4928 + Fib->Header.Size = sizeof(FIB);
4929 +// if (Fib->Header.XferState & AllocatedFromPool)
4930 +// Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | AllocatedFromPool;
4932 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty | FastResponseCapable;
4933 + Fib->Header.SenderFibAddress = 0;
4934 + Fib->Header.ReceiverFibAddress = 0;
4935 + Fib->Header.SenderSize = sizeof(FIB);
4937 + return(STATUS_SUCCESS);
4943 +Routine Description:
4945 + Will allocate and initialize a FIB of the requested size and return a
4946 + pointer to the structure. The size allocated may be larger than the size
4947 + requested due to allocation performace optimizations.
4951 + Fib is a pointer to a location which will receive the address of the allocated
4954 + Size is the size of the Fib to allocate.
4956 + JustInitialize is a boolean which indicates a Fib has been allocated most likly in an
4957 + imbedded structure the FS always allocates. So just initiaize it and return.
4961 + NT_SUCCESS if a Fib was returned to the caller.
4962 + NT_ERROR if event was an invalid event.
4966 +AllocatePoolFib (OUT PFIB *Fib, IN USHORT Size)
4972 +Routine Description:
4974 + Will deallocate and return to the free pool the FIB pointed to by the
4975 + caller. Upon return accessing locations pointed to by the FIB parameter
4976 + could cause system access faults.
4980 + Fib is a pointer to the FIB that caller wishes to deallocate.
4984 + NT_SUCCESS if a Fib was returned to the caller.
4985 + NT_ERROR if event was an invalid event.
4989 +DeallocateFib (PFIB_CONTEXT Context)
4991 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
4992 + PFIB Fib = FibContext->Fib;
4994 + if ( Fib->Header.StructType != TFib ) {
4995 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
4996 + return(STATUS_UNSUCCESSFUL);
5000 + Fib->Header.XferState = 0;
5002 + return(STATUS_SUCCESS);
5009 + IN PCOMM_QUE ResponseQueue,
5014 +Routine Description:
5016 + Gets a QE off the requested response queue and gets the response FIB into
5017 + host memory. The FIB may already be in host memory depending on the bus
5018 + interface, or may require the host to DMA it over from the adapter. The routine
5019 + will return the FIB to the caller.
5023 + ResponseQueue - Is the queue the caller wishes to have the response gotten from.
5024 + Fib - Is the Fib which was the response from the adapter
5028 + NT_SUCCESS if a Fib was returned to the caller.
5029 + NT_ERROR if there was no Fib to return to the caller.
5030 + bkpfix - add in all the other possible errors ect
5034 +return(STATUS_UNSUCCESSFUL);
5038 +// Commuication primitives define and support the queuing method we use to
5039 +// support host to adapter commuication. All queue accesses happen through
5040 +// these routines and are the only routines which have a knowledge of the
5041 +// how these queues are implemented.
5047 +Routine Description:
5049 + With a priority the routine returns a queue entry if the queue has free entries. If the queue
5050 + is full(no free entries) than no entry is returned and the function returns FALSE otherwise TRUE is
5055 + Priority is an enumerated type which determines which priority level
5056 + command queue the QE is going to be queued on.
5058 + Entry is a pointer to the address of where to return the address of
5059 + the queue entry from the requested command queue.
5061 + Index is a pointer to the address of where to store the index of the new
5062 + queue entry returned.
5064 + DontInterrupt - We set this true if the queue state is such that we don't
5065 + need to interrupt the adapter for this queue entry.
5069 + TRUE - If a queue entry is returned
5070 + FALSE - If there are no free queue entries on the requested command queue.
5074 +GetEntry (IN PAFA_COMM_ADAPTER Adapter, IN QUEUE_TYPES WhichQueue,
5075 + OUT PQUEUE_ENTRY *Entry, OUT PQUEUE_INDEX Index,
5076 + OUT ULONG *DontInterrupt)
5078 + ULONG QueueOffset;
5080 + PCOMM_REGION CommRegion;
5082 + CommRegion = Adapter->CommRegion;
5085 + // All of the queues wrap when they reach the end, so we check to see if they
5086 + // have reached the end and if they have we just set the index back to zero.
5087 + // This is a wrap. You could or off the high bits in all updates but this is
5088 + // a bit faster I think.
5091 + if (WhichQueue == AdapHighCmdQueue) {
5092 + *Index = *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex);
5094 + if (*Index - 2 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex))
5095 + *DontInterrupt = TRUE;
5097 + if (*Index >= ADAP_HIGH_CMD_ENTRIES)
5100 + if (*Index + 1 == *(CommRegion->AdapHighCmdQue.Headers.ConsumerIndex)) { // Queue is full
5102 + cmn_err(CE_WARN, "Adapter High Command Queue full, %d outstanding",
5103 + CommRegion->AdapHighCmdQue.NumOutstandingIos);
5105 + QueueOffset = sizeof(QUEUE_ENTRY) * (*Index);
5106 + *Entry = QueueOffset + CommRegion->AdapHighCmdQue.BaseAddress;
5110 + } else if (WhichQueue == AdapNormCmdQueue) {
5112 + *Index = *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex);
5114 + if (*Index - 2 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex))
5115 + *DontInterrupt = TRUE;
5118 + // If we are at the end of the QUEUE then wrap back to
5122 + if (*Index >= ADAP_NORM_CMD_ENTRIES)
5123 + *Index = 0; // Wrap to front of the Producer Queue.
5126 + // The IEEE spec says that it the producer is one behind the consumer then
5127 + // the queue is full.
5130 + ASSERT(*(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex) != 0);
5132 + if (*Index + 1 == *(CommRegion->AdapNormCmdQue.Headers.ConsumerIndex)) { // Queue is full
5133 + cmn_err(CE_WARN, "Adapter Norm Command Queue full, %d outstanding",
5134 + CommRegion->AdapNormCmdQue.NumOutstandingIos);
5138 + // The success case just falls through and returns the a valid queue entry.
5142 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormCmdQue.BaseAddress + *Index);
5143 + FsaCommPrint("GetEntry: Index = %d, QueueOffset = %x, Entry = %x, *Entry = %x.\n",
5144 + *Index, QueueOffset, Entry, *Entry);
5146 + *Entry = CommRegion->AdapNormCmdQue.BaseAddress + *Index;
5150 + } else if (WhichQueue == AdapHighRespQueue) {
5152 + *Index = *(CommRegion->AdapHighRespQue.Headers.ProducerIndex);
5154 + if (*Index - 2 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex))
5155 + *DontInterrupt = TRUE;
5157 + if (*Index >= ADAP_HIGH_RESP_ENTRIES)
5160 + if (*Index + 1 == *(CommRegion->AdapHighRespQue.Headers.ConsumerIndex)) { // Queue is full
5162 + cmn_err(CE_WARN, "Adapter High Resp Queue full, %d outstanding",
5163 + CommRegion->AdapHighRespQue.NumOutstandingIos);
5165 + *Entry = CommRegion->AdapHighRespQue.BaseAddress + *Index;
5168 + } else if (WhichQueue == AdapNormRespQueue) {
5170 + *Index = *(CommRegion->AdapNormRespQue.Headers.ProducerIndex);
5172 + if (*Index - 2 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex))
5173 + *DontInterrupt = TRUE;
5176 + // If we are at the end of the QUEUE then wrap back to
5180 + if (*Index >= ADAP_NORM_RESP_ENTRIES)
5181 + *Index = 0; // Wrap to front of the Producer Queue.
5184 + // The IEEE spec says that it the producer is one behind the consumer then
5185 + // the queue is full.
5188 + if (*Index + 1 == *(CommRegion->AdapNormRespQue.Headers.ConsumerIndex)) { // Queue is full
5190 + cmn_err(CE_WARN, "Adapter Norm Resp Queue full, %d outstanding",
5191 + CommRegion->AdapNormRespQue.NumOutstandingIos);
5194 + // The success case just falls through and returns the a valid queue entry.
5197 + *Entry = CommRegion->AdapNormRespQue.BaseAddress + *Index;
5200 + FsaCommPrint("queue entry = %x.\n",CommRegion->AdapNormRespQue.BaseAddress + *Index);
5201 + FsaCommPrint("GetEntry: Index = %d, Entry = %x, *Entry = %x.\n",*Index, Entry, *Entry);
5206 + cmn_err(CE_PANIC, "GetEntry: invalid queue %d", WhichQueue);
5215 +#ifdef API_THROTTLE
5217 +void ThrottleCheck(
5218 + IN PAFA_COMM_ADAPTER Adapter,
5223 +Routine Description:
5225 + This routine implements data I/O throttling. Throttling occurs when
5226 + a CLI FIB is detected. To ensure the CLI responds quickly (the user
5227 + is waiting for the response), this mechanism restricts the queue
5228 + depth of data IOs at the adapter for a period of time (called the
5229 + Throttle Period, default 5 seconds).
5231 + The mechanism uses a counted semaphore to place threads into a wait
5232 + state should there be too many data I/Os outstanding.
5234 + At the start of a throttle period (indicated by the first CLI FIB)
5235 + a timer is started. When the timer expires, new requests can go to
5236 + the adapter freely. Throttled requests gradually drain to the
5237 + adapter as each outstanding throttle I/O completes.
5239 + To avoid hurting regular I/O performance, we use a flag in the FIB
5240 + header to mark FIBs involved in throttling. This means we only need
5241 + take the extra spinlock in the response DPC routine for FIBs who
5242 + were subject to throttling. If no throttling is occurring, the cost
5243 + to the regular code paths is a handful of instructions.
5247 + Adapter - Pointer to per-adapter context. This is used to locate the
5248 + throttle information for this adapter.
5250 + Fib - Pointer to the header for the fib being sent.
5258 + PCOMM_REGION CommRegion = Adapter->CommRegion;
5259 + AAC_STATUS Status;
5262 + // This routine is called under protection of the queue spinlock.
5263 + // As such we are allowed to check and change the counts for the
5265 + // Check the FIB. If its not a data operation, send it on without
5266 + // throttle check. If it is a data operation, check for throttle.
5269 + CommRegion->TotalFibs++; // Keep statistics
5271 + if ((Fib->Header.XferState & ApiFib) != 0) {
5273 + CommRegion->ApiFibs++; // Keep statistics
5276 + // Its an API fib. If the throttle is not already active,
5277 + // make it so. This will prevent new data Fibs being sent
5278 + // if they exceed the throttle check.
5281 + if (!CommRegion->ThrottleActive) {
5284 + CommRegion->ThrottleActive = TRUE; // This causes new data I/Os to be throttled
5287 + // Schedule a timer for the throttle active period. When
5288 + // it expires, we'll be called back at routine ThrottleDpcRoutine
5289 + // above. This will signify the throttle active period ended
5290 + // and any waiting threads will be signalled to restart.
5293 + FsaCommPrint("Throttle Period Start - CommRegion: %x\n", CommRegion);
5294 + CommRegion->ThrottleTimerSets++;
5295 + InQue = KeSetTimer( &CommRegion->ThrottleTimer,
5296 + CommRegion->ThrottleTimeout,
5297 + &CommRegion->ThrottleDpc);
5298 + ASSERT(InQue == FALSE);
5305 + // Its a non-API fib, so subject to throttle checks.
5306 + // The following are exempt from throttling:
5307 + // o FIBs marked as "throttle exempt" by upper layers.
5308 + // o I/Os issued from a raised IRQL. We can't suspend
5309 + // a thread when at raised IRQL so throttling is exempt.
5312 + if (CommRegion->AdapNormCmdQue.SavedIrql != PASSIVE_LEVEL) {
5314 + CommRegion->NonPassiveFibs++;
5315 + FsaCommPrint("ThrottleCheck: Non-Passive level FIB bypasses throttle: %x\n", Fib);
5320 + if (CommRegion->ThrottleActive) {
5323 + // Throttle is active.
5324 + // Check if the FIB is a read or write. If so, and its to the
5325 + // file system information area, let it through without throttling.
5328 + if (Fib->Header.Command == ContainerCommand) {
5329 + PBLOCKREAD BlockDisk = (PBLOCKREAD) &Fib->data;
5332 + // *** Note *** We are using read and write command formats
5333 + // interchangably here. This is ok for this purpose as the
5334 + // command is in the same place for both. Read and write command
5335 + // formats are different at higher offsets though.
5338 + if ( ((BlockDisk->Command == VM_CtBlockRead) ||
5339 + (BlockDisk->Command == VM_CtBlockWrite)) &&
5340 + (BlockDisk->BlockNumber <= FILESYSTEM_INFO_MAX_BLKNO)) {
5342 + CommRegion->FSInfoFibs++; // Keep statistics
5350 + // Throttle the FIB.
5351 + // Mark it as throttle active so that it can signal a waiter
5352 + // when it completes.
5354 + CommRegion->ThrottledFibs++;
5355 + Fib->Header.Flags |= ThrottledFib;
5358 + // Release the spinlock so we can wait the thread if necessary.
5359 + // Since we specify a timeout, check the caller is at passive level.
5362 + OsSpinLockRelease((CommRegion->AdapNormCmdQue.QueueLock), CommRegion->AdapNormCmdQue.SavedIrql);
5364 + FsaCommPrint("ThrottleCheck - Thread Suspension - FIB: %x\n", Fib);
5366 + Status = KeWaitForSingleObject(&CommRegion->ThrottleReleaseSema,
5367 + Executive, // Don't allow user APCs to wake us
5368 + KernelMode, // Wait in kernel mode
5369 + FALSE, // Not alertable
5370 + &CommRegion->ThrottleWaitTimeout); // Timeout after this time
5373 + // Check the signal status. If we've timed out, clear the throttle
5374 + // flag on the FIB to avoid us signalling the semaphore on completion.
5375 + // We never acquired the semaphore.
5377 + if (Status == STATUS_TIMEOUT) {
5379 + CommRegion->ThrottleTimedoutFibs++;
5380 + FsaCommPrint("ThrottledFib Timed Out - FIB: %x\n", Fib);
5381 + Fib->Header.Flags &= ~ThrottledFib; // Clear the throttledfib flag
5385 + ASSERT(Status == STATUS_SUCCESS); // No other return is possible
5390 + // We've been woken up and can now send the FIB to the adapter.
5391 + // Acquire the spinlock again so we can get a queue entry. This
5392 + // returns to GetQueueEntry.
5395 + FsaCommPrint("ThrottleCheck - Thread Resume - FIB: %x\n", Fib);
5396 + KeAcquireSpinLock((CommRegion->AdapNormCmdQue.QueueLock), &(CommRegion->AdapNormCmdQue.SavedIrql));
5397 + CommRegion->ThrottleOutstandingFibs++; // There's another throttle controlled FIB going.
5403 +#endif //#ifdef API_THROTTLE
5405 +int GetQueueEntryTimeouts = 0;
5410 +Routine Description:
5412 + Gets the next free QE off the requested priorty adapter command queue and
5413 + associates the Fib with the QE. The QE represented by index is ready to
5414 + insert on the queue when this routine returns success.
5418 + Index is the returned value which represents the QE which is ready to
5419 + insert on the adapter's command queue.
5421 + Priority is an enumerated type which determines which priority level
5422 + command queue the QE is going to be queued on.
5424 + Fib is a pointer to the FIB the caller wishes to have associated with the
5427 + Wait is a boolean which determines if the routine will wait if there are
5428 + no free QEs on the requested priority command queue.
5430 + FibContext is where the driver stores all system resources required to execute the
5431 + command requested from the calling thread. This includes mapping resources for
5432 + the FIB and the 'users' buffer.
5434 + DontInterrupt - We set this true if the queue state is such that we don't
5435 + need to interrupt the adapter for this queue entry.
5439 + NT_SUCCESS if a Fib was returned to the caller.
5440 + NT_ERROR if event was an invalid event.
5444 +GetQueueEntry (IN PAFA_COMM_ADAPTER Adapter, OUT PQUEUE_INDEX Index,
5445 + IN QUEUE_TYPES WhichQueue, IN PFIB Fib, IN BOOLEAN Wait,
5446 + IN PCOMM_FIB_CONTEXT FibContext, OUT ULONG *DontInterrupt)
5448 + PQUEUE_ENTRY QueueEntry = NULL;
5449 + BOOLEAN MapAddress = FALSE;
5451 + AAC_STATUS Status;
5452 + PCOMM_REGION CommRegion;
5454 + CommRegion = Adapter->CommRegion;
5457 + // Get the spinlock for the queue we are putting a command on
5460 + if (WhichQueue == AdapHighCmdQueue)
5461 + OsSpinLockAcquire(CommRegion->AdapHighCmdQue.QueueLock);
5462 + else if (WhichQueue == AdapNormCmdQueue)
5463 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
5464 + else if (WhichQueue == AdapHighRespQueue)
5465 + OsSpinLockAcquire(CommRegion->AdapHighRespQue.QueueLock);
5466 + else if (WhichQueue == AdapNormRespQueue)
5467 + OsSpinLockAcquire(CommRegion->AdapNormRespQue.QueueLock);
5469 + FsaCommPrint("Invalid queue priority passed to GetQueueEntry.\n");
5470 + return(FSA_INVALID_QUEUE);
5474 + // Get the pointers to a queue entry on the queue the caller wishes to queue
5475 + // a command request on. If there are no entries then wait if that is what the
5476 + // caller requested.
5479 + if (WhichQueue == AdapHighCmdQueue) {
5480 + // if no entries wait for some if caller wants to
5481 + while ( !GetEntry(Adapter, AdapHighCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5482 + cmn_err(CE_PANIC, "GetEntries failed (1)\n");
5486 + // Setup queue entry with a command, status and Fib mapped
5489 + QueueEntry->Size = Fib->Header.Size;
5490 + MapAddress = TRUE;
5492 + } else if (WhichQueue == AdapNormCmdQueue) {
5493 + // if no entries wait for some if caller wants to
5494 + while ( !GetEntry(Adapter, AdapNormCmdQueue, &QueueEntry, Index, DontInterrupt) ) {
5495 + cmn_err(CE_PANIC, "GetEntries failed (2)\n");
5499 + // Setup queue entry with command, status and Fib mapped
5502 + QueueEntry->Size = Fib->Header.Size;
5503 + MapAddress = TRUE;
5505 + } else if (WhichQueue == AdapHighRespQueue) {
5507 + while ( !GetEntry(Adapter, AdapHighRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5511 + // Setup queue entry with command, status and Fib mapped
5514 + QueueEntry->Size = Fib->Header.Size;
5515 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5516 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5517 + MapAddress = FALSE;
5519 + } else if (WhichQueue == AdapNormRespQueue) {
5520 + while ( !GetEntry(Adapter, AdapNormRespQueue, &QueueEntry, Index, DontInterrupt) ) { // if no entries wait for some if caller wants to
5524 + // Setup queue entry with command, status, adapter's pointer to the Fib it sent
5527 + QueueEntry->Size = Fib->Header.Size;
5528 + QueueEntry->FibAddress = Fib->Header.SenderFibAddress; // Restore adapters pointer to the FIB
5529 + Fib->Header.ReceiverFibAddress = Fib->Header.SenderFibAddress; // Let the adapter now where to find its data
5530 + MapAddress = FALSE;
5534 + // If MapFib is true than we need to map the Fib and put pointers in the queue entry.
5538 + QueueEntry->FibAddress = (ULONG)(FibContext->LogicalFibAddress.LowPart);
5545 + FsaCommPrint("Queue Entry contents:.\n");
5546 + FsaCommPrint(" Command = %d.\n", QueueEntry->Command);
5547 + FsaCommPrint(" Status = %x.\n", QueueEntry->Status);
5548 + FsaCommPrint(" Rec Fib address low = %x.\n", QueueEntry->FibAddressLow);
5549 + FsaCommPrint(" Fib size in bytes = %d.\n", QueueEntry->Size);
5552 + return(FSA_SUCCESS);
5558 +Routine Description:
5560 + Gets the next free QE off the requested priorty adapter command queue and
5561 + associates the Fib with the QE. The QE represented by index is ready to
5562 + insert on the queue when this routine returns success.
5566 + Index is the returned value which represents the QE which is ready to
5567 + insert on the adapter's command queue.
5569 + WhichQueue tells us which queue the caller wishes to have the entry put.
5573 + NT_SUCCESS if a Fib was returned to the caller.
5574 + NT_ERROR if event was an invalid event.
5579 + IN PAFA_COMM_ADAPTER Adapter,
5580 + IN QUEUE_INDEX Index,
5581 + IN QUEUE_TYPES WhichQueue,
5582 + IN ULONG DontInterrupt
5585 + PCOMM_REGION CommRegion;
5587 + CommRegion = Adapter->CommRegion;
5590 + // We have already verified the queue in getentry, but we still have to make
5591 + // sure we don't wrap here too.
5594 + if (WhichQueue == AdapHighCmdQueue) {
5596 + *(CommRegion->AdapHighCmdQue.Headers.ProducerIndex) = Index + 1;
5598 + OsSpinLockRelease(CommRegion->AdapHighCmdQue.QueueLock);
5600 + if (!DontInterrupt)
5601 + NotifyAdapter(Adapter, AdapHighCmdQue);
5603 + } else if (WhichQueue == AdapNormCmdQueue) {
5606 + FsaCommPrint("InsertQueueEntry: Inerting with an index of %d.\n",Index);
5608 + *(CommRegion->AdapNormCmdQue.Headers.ProducerIndex) = Index + 1;
5610 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
5612 + if (!DontInterrupt)
5613 + NotifyAdapter(Adapter, AdapNormCmdQue);
5615 + } else if (WhichQueue == AdapHighRespQueue) {
5617 + *(CommRegion->AdapHighRespQue.Headers.ProducerIndex) = Index + 1;
5619 + OsSpinLockRelease(CommRegion->AdapHighRespQue.QueueLock);
5621 + if (!DontInterrupt)
5622 + NotifyAdapter(Adapter, AdapHighRespQue);
5624 + } else if (WhichQueue == AdapNormRespQueue) {
5626 + *(CommRegion->AdapNormRespQue.Headers.ProducerIndex) = Index + 1;
5628 + OsSpinLockRelease(CommRegion->AdapNormRespQue.QueueLock);
5630 + if (!DontInterrupt)
5631 + NotifyAdapter(Adapter, AdapNormRespQue);
5634 + FsaCommPrint("Invalid queue priority passed to InsertQueueEntry.\n");
5635 + return(FSA_INVALID_QUEUE_PRIORITY);
5638 + return(FSA_SUCCESS);
5641 +extern int GatherFibTimes;
5646 + FIB_COMMAND Command,
5650 + USHORT *ResponseSize
5654 +Routine Description:
5656 + This routine will send a synchronous FIB to the adapter and wait for its
5661 + DeviceExtension - Pointer to adapter extension structure.
5670 + PAFA_COMM_ADAPTER Adapter = Arg;
5672 + ULONG returnStatus;
5674 + Fib = Adapter->SyncFib;
5676 + Fib->Header.StructType = TFib;
5677 + Fib->Header.Size = sizeof(FIB);
5678 + Fib->Header.XferState = HostOwned | FibInitialized | FibEmpty;
5679 + Fib->Header.ReceiverFibAddress = 0;
5680 + Fib->Header.SenderSize = sizeof(FIB);
5681 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5682 + Fib->Header.Command = Command;
5685 + // Copy the Data portion into the Fib.
5688 + RtlCopyMemory( Fib->data, Data, Size );
5691 + Fib->Header.XferState |= (SentFromHost | NormalPriority);
5694 + // Set the size of the Fib we want to send to the adapter
5697 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5699 + if (!Adapter->AdapterFuncs->SendSynchFib( Adapter->AdapterExtension,
5700 + Adapter->SyncFibPhysicalAddress )) {
5707 + // Copy the response back to the caller's buffer.
5710 + RtlCopyMemory( Response, Fib->data, Fib->Header.Size - sizeof(FIB_HEADER) );
5712 + *ResponseSize = Fib->Header.Size - sizeof(FIB_HEADER);
5715 + // Indicate success
5722 +// Define the highest level of host to adapter communication routines. These
5723 +// routines will support host to adapter FS commuication. These routines have
5724 +// no knowledge of the commuication method used. This level sends and receives
5725 +// FIBs. This level has no knowledge of how these FIBs get passed back and forth.
5732 +Routine Description:
5734 + Sends the requested FIB to the adapter and optionally will wait for a
5735 + response FIB. If the caller does not wish to wait for a response than
5736 + an event to wait on must be supplied. This event will be set when a
5737 + response FIB is received from the adapter.
5741 + Fib is a pointer to the FIB the caller wishes to send to the adapter.
5743 + Size - Size of the data portion of the Fib.
5745 + Priority is an enumerated type which determines which priority level
5746 + the caller wishes to send this command at.
5748 + Wait is a boolean which determines if the routine will wait for the
5749 + completion Fib to be returned(TRUE), or return when the Fib has been
5750 + successfully received by the adapter(FALSE).
5752 + WaitOn is only vaild when Wait is FALSE. The Event will be set when the response
5753 + FIB has been returned by the adapter.
5755 + ReturnFib is an optional pointer to a FIB that if present the response FIB will
5760 + NT_SUCCESS if a Fib was returned to the caller.
5761 + NT_ERROR if event was an invalid event.
5765 +SendFib (IN FIB_COMMAND Command,
5766 + IN PFIB_CONTEXT Context,
5768 + IN COMM_PRIORITIES Priority,
5771 + IN BOOLEAN ResponseExpected,
5772 + IN PFIB_CALLBACK FibCallback,
5773 + IN PVOID FibCallbackContext)
5775 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
5776 + QUEUE_INDEX Index;
5777 + QUEUE_TYPES WhichQueue;
5778 + LARGE_INTEGER Timeout;
5779 + AAC_STATUS Status;
5780 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
5781 + ULONG DontInterrupt = FALSE;
5782 + PFIB Fib = FibContext->Fib;
5783 + IN PCOMM_QUE OurQueue;
5785 + Timeout = FsaCommData.AdapterTimeout;
5787 + if (!(Fib->Header.XferState & HostOwned)) {
5788 + FsaCommPrint("SendFib was called with a xfer state not set to HostOwned!\n");
5789 + FsaCommLogEvent(FibContext,
5790 + FsaCommData.DeviceObject,
5791 + FSAFS_FIB_INVALID,
5792 + STATUS_UNSUCCESSFUL,
5793 + BugCheckFileId | __LINE__,
5794 + FACILITY_FSAFS_ERROR_CODE,
5798 + return(STATUS_UNSUCCESSFUL);
5803 + // There are 5 cases with the wait and reponse requested flags. The only invalid cases
5804 + // are if the caller requests to wait and does not request a response and if the
5805 + // caller does not want a response and the Fib is not allocated from pool. If a response
5806 + // is not requesed the Fib will just be deallocaed by the DPC routine when the response
5807 + // comes back from the adapter. No further processing will be done besides deleting the
5808 + // Fib. We will have a debug mode where the adapter can notify the host it had a problem
5809 + // and the host can log that fact.
5811 + if (Wait && !ResponseExpected) {
5813 + FsaCommLogEvent(FibContext,
5814 + FsaCommData.DeviceObject,
5815 + FSAFS_FIB_INVALID,
5816 + STATUS_UNSUCCESSFUL,
5817 + BugCheckFileId | __LINE__,
5818 + FACILITY_FSAFS_ERROR_CODE,
5822 + return(STATUS_UNSUCCESSFUL);
5824 + } else if (!Wait && ResponseExpected) {
5825 + Fib->Header.XferState |= (Async | ResponseExpected);
5826 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncSent);
5827 + } else if (!Wait && !ResponseExpected) {
5828 + Fib->Header.XferState |= NoResponseExpected;
5829 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseSent);
5830 + } else if (Wait && ResponseExpected) {
5831 + Fib->Header.XferState |= ResponseExpected;
5832 + FIB_COUNTER_INCREMENT(FsaCommData.NormalSent);
5835 + Fib->Header.SenderData = (ULONG)FibContext; // so we can complete the io in the dpc routine
5838 + // Set FIB state to indicate where it came from and if we want a response from the
5839 + // adapter. Also load the command from the caller.
5842 + Fib->Header.SenderFibAddress = (ULONG)Fib;
5843 + Fib->Header.Command = Command;
5844 + Fib->Header.XferState |= SentFromHost;
5845 + FibContext->Fib->Header.Flags = 0; // Zero the flags field - its internal only...
5848 + // Set the size of the Fib we want to send to the adapter
5851 + Fib->Header.Size = sizeof(FIB_HEADER) + Size;
5852 + if (Fib->Header.Size > Fib->Header.SenderSize) {
5853 + return(STATUS_BUFFER_OVERFLOW);
5857 + // Get a queue entry connect the FIB to it and send an notify the adapter a command is ready.
5860 + if (Priority == FsaHigh) {
5861 + Fib->Header.XferState |= HighPriority;
5862 + WhichQueue = AdapHighCmdQueue;
5863 + OurQueue = &Adapter->CommRegion->AdapHighCmdQue;
5865 + Fib->Header.XferState |= NormalPriority;
5866 + WhichQueue = AdapNormCmdQueue;
5867 + OurQueue = &Adapter->CommRegion->AdapNormCmdQue;
5871 + OsCvLockAcquire( FibContext->FsaEventMutex );
5874 + if ( GetQueueEntry( Adapter, &Index, WhichQueue, Fib, TRUE, FibContext, &DontInterrupt) != FSA_SUCCESS )
5875 + return(STATUS_UNSUCCESSFUL);
5879 + cmn_err (CE_DEBUG,"SendFib: inserting a queue entry at index %d.\n",Index);
5880 + cmn_err (CE_DEBUG,"Fib contents:.\n");
5881 + cmn_err (CE_DEBUG," Command = %d.\n", Fib->Header.Command);
5882 + cmn_err (CE_DEBUG," XferState = %x.\n", Fib->Header.XferState );
5885 + // Fill in the Callback and CallbackContext if we are not going to wait.
5890 + FibContext->FibCallback = FibCallback;
5891 + FibContext->FibCallbackContext = FibCallbackContext;
5895 + FIB_COUNTER_INCREMENT(FsaCommData.FibsSent);
5897 + InsertTailList( &OurQueue->OutstandingIoQueue, &FibContext->QueueEntry );
5898 + OurQueue->NumOutstandingIos++;
5900 + FibContext->FibComplete = 0;
5904 + if ( InsertQueueEntry( Adapter, Index, WhichQueue, (DontInterrupt & FsaCommData.EnableInterruptModeration)) != FSA_SUCCESS )
5905 + return(STATUS_UNSUCCESSFUL);
5908 + // If the caller wanted us to wait for response wait now.
5909 + // If Timeouts are enabled than set the timeout otherwise wait forever.
5913 + while (FibContext->FibComplete == 0) {
5914 + OsCv_wait( &FibContext->FsaEvent, FibContext->FsaEventMutex );
5917 + OsCvLockRelease( FibContext->FsaEventMutex );
5919 + if ( (FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT) ) {
5920 + return(STATUS_IO_TIMEOUT);
5922 + return(STATUS_SUCCESS);
5927 + // If the user does not want a response than return success otherwise return pending
5930 + ASSERT( FibCallback );
5932 + if (ResponseExpected)
5933 + return(STATUS_PENDING);
5935 + return(STATUS_SUCCESS);
5940 + IN PAFA_COMM_ADAPTER Adapter,
5941 + PCOMM_QUE OurQueue,
5942 + OUT PQUEUE_ENTRY *Entry
5946 +Routine Description:
5948 + Will return a pointer to the entry on the top of the queue requested that we are a consumer
5949 + of, and return the address of the queue entry. It does not change the state of the queue.
5953 + OurQueue - is the queue the queue entry should be removed from.
5955 + Entry - is a pointer where the address of the queue entry should be returned.
5959 + TRUE if there was a queue entry on the response queue for the host to consume.
5960 + FALSE if there were no queue entries to consume.
5965 + QUEUE_INDEX Index;
5968 + if (*OurQueue->Headers.ProducerIndex == *OurQueue->Headers.ConsumerIndex) {
5973 + // The consumer index must be wrapped if we have reached the end of
5975 + // Else we just use the entry pointed to by the header index
5978 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
5981 + Index = *OurQueue->Headers.ConsumerIndex;
5983 + *Entry = OurQueue->BaseAddress + Index;
5986 + FsaCommPrint("Got a QE at Index %d, QE Addrss of %x.\n",Index,*Entry);
5995 +ConsumerEntryAvailable(
5996 + IN PAFA_COMM_ADAPTER Adapter,
5997 + PCOMM_QUE OurQueue
6000 + return (*OurQueue->Headers.ProducerIndex != *OurQueue->Headers.ConsumerIndex);
6005 + IN PAFA_COMM_ADAPTER Adapter,
6006 + PCOMM_QUE OurQueue,
6007 + QUEUE_TYPES WhichQueue
6011 +Routine Description:
6013 + Frees up the current top of the queue we are a consumer of. If the queue was full
6014 + notify the producer that the queue is no longer full.
6018 + OurQueue - is the queue we will free the current consumer entry on.
6022 + TRUE if there was a queue entry on the response queue for the host to consume.
6023 + FALSE if there were no queue entries to consume.
6028 + BOOLEAN WasFull = FALSE;
6029 + HOST_2_ADAP_EVENT Notify;
6031 + if (*OurQueue->Headers.ProducerIndex+1 == *OurQueue->Headers.ConsumerIndex)
6034 + if (*OurQueue->Headers.ConsumerIndex >= OurQueue->QueueEntries)
6035 + *OurQueue->Headers.ConsumerIndex = 1;
6037 + *OurQueue->Headers.ConsumerIndex += 1;
6040 + switch (WhichQueue) {
6042 + case HostNormCmdQueue:
6043 + Notify = HostNormCmdNotFull;
6045 + case HostHighCmdQueue:
6046 + Notify = HostHighCmdNotFull;
6049 + case HostNormRespQueue:
6050 + Notify = HostNormRespNotFull;
6053 + case HostHighRespQueue:
6054 + Notify = HostHighRespNotFull;
6058 + NotifyAdapter(Adapter, Notify);
6064 +CompleteAdapterFib(
6065 + IN PFIB_CONTEXT Context,
6070 +Routine Description:
6072 + Will do all necessary work to complete a FIB that was sent from the adapter.
6076 + Fib is a pointer to the FIB that caller wishes to complete processing on.
6078 + Size - Size of the completion Packet(Opitional). If not present than the current
6079 + largest size in the Fib will be used
6081 + Adapter - Pointer to which adapter sent this FIB
6085 + NT_SUCCESS if a Fib was returned to the caller.
6086 + NT_ERROR if event was an invalid event.
6090 + PCOMM_FIB_CONTEXT FibContext = Context;
6091 + PFIB Fib = FibContext->Fib;
6092 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6093 + ULONG DontInterrupt = FALSE;
6095 + if (Fib->Header.XferState == 0)
6096 + return(STATUS_SUCCESS);
6099 + // If we plan to do anything check the structure type first.
6102 + if ( Fib->Header.StructType != TFib ) {
6103 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6104 + return(STATUS_UNSUCCESSFUL);
6108 + // This block handles the case where the adapter had sent us a command and we
6109 + // have finished processing the command. We call completeFib when we are done
6110 + // processing the command and want to send a response back to the adapter. This
6111 + // will send the completed cdb to the adapter.
6114 + if (Fib->Header.XferState & SentFromAdapter) {
6115 + Fib->Header.XferState |= HostProcessed;
6116 + if (Fib->Header.XferState & HighPriority) {
6117 + QUEUE_INDEX Index;
6120 + Size += sizeof(FIB_HEADER);
6121 + if (Size > Fib->Header.SenderSize)
6122 + return(STATUS_BUFFER_OVERFLOW);
6123 + Fib->Header.Size = Size;
6126 + if (GetQueueEntry(Adapter, &Index, AdapHighRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6127 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6128 + return(FSA_FATAL);
6130 + if (InsertQueueEntry(Adapter,
6132 + AdapHighRespQueue,
6133 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6134 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6136 + } else if (Fib->Header.XferState & NormalPriority) {
6137 + QUEUE_INDEX Index;
6140 + Size += sizeof(FIB_HEADER);
6141 + if (Size > Fib->Header.SenderSize)
6142 + return(STATUS_BUFFER_OVERFLOW);
6143 + Fib->Header.Size = Size;
6146 + if (GetQueueEntry(Adapter, &Index, AdapNormRespQueue, Fib, TRUE, NULL, &DontInterrupt) != STATUS_SUCCESS) {
6147 + FsaCommPrint("CompleteFib got an error geting a queue entry for a response.\n");
6148 + return(FSA_FATAL);
6150 + if (InsertQueueEntry(Adapter,
6152 + AdapNormRespQueue,
6153 + (DontInterrupt & (BOOLEAN)FsaCommData.EnableInterruptModeration)) != STATUS_SUCCESS) {
6154 + FsaCommPrint("CompleteFib failed while inserting entry on the queue.\n");
6158 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6159 + FsaBugCheck(0,0,0);
6161 + return(STATUS_SUCCESS);
6166 + IN PFIB_CONTEXT Context
6170 +Routine Description:
6172 + Will do all necessary work to complete a FIB. If the caller wishes to
6173 + reuse the FIB after post processing has been completed Reinitialize
6174 + should be called set to TRUE, otherwise the FIB will be returned to the
6175 + free FIB pool. If Reinitialize is set to TRUE then the FIB header is
6176 + reinitialzied and is ready for reuse on return from this routine.
6180 + Fib is a pointer to the FIB that caller wishes to complete processing on.
6182 + Size - Size of the completion Packet(Opitional). If not present than the current
6183 + largest size in the Fib will be used
6185 + Reinitialize is a boolean which determines if the routine will ready the
6186 + completed FIB for reuse(TRUE) or not(FALSE).
6190 + NT_SUCCESS if a Fib was returned to the caller.
6191 + NT_ERROR if event was an invalid event.
6195 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6196 + PAFA_COMM_ADAPTER Adapter = FibContext->Adapter;
6197 + PFIB Fib = FibContext->Fib;
6200 + // Check for a fib which has already been completed
6203 +// ASSERT(Fib->Header.XferState & AdapterProcessed);
6204 + if (Fib->Header.XferState == 0)
6205 + return(STATUS_SUCCESS);
6208 + // If we plan to do anything check the structure type first.
6211 + if ( Fib->Header.StructType != TFib ) {
6212 + FsaCommPrint("Error CompleteFib called with a non Fib structure.\n");
6213 + return(STATUS_UNSUCCESSFUL);
6217 +//#if FSA_ADAPTER_METER
6219 + // Meter the completion
6221 + fsaMeterEnd( // meter the end of an operation
6222 + &(Adapter->FibMeter), // .. the meter
6223 + IrpContext->FibMeterType, // .. type of operation
6224 + &(IrpContext->FibStartTime), // .. ptr to operation start timestamp
6225 + FibGetMeterSize(Fib, // .. number of bytes in operation
6226 + IrpContext->FibMeterType,
6227 + IrpContext->FibSubCommand));
6228 +#endif // FSA_ADAPTER_METER
6231 + // This block completes a cdb which orginated on the host and we just need
6232 + // to deallocate the cdb or reinit it. At this point the command is complete
6233 + // that we had sent to the adapter and this cdb could be reused.
6236 + if ( (Fib->Header.XferState & SentFromHost) &&
6237 + (Fib->Header.XferState & AdapterProcessed)) {
6239 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6241 + return( DeallocateFib(FibContext) );
6244 + // This handles the case when the host has aborted the I/O to the
6245 + // adapter because the adapter is not responding
6248 + } else if (Fib->Header.XferState & SentFromHost) {
6250 + ASSERT(FibContext->LogicalFibAddress.LowPart != 0);
6253 + return( DeallocateFib(FibContext) );
6255 + } else if (Fib->Header.XferState & HostOwned) {
6257 + return(DeallocateFib(FibContext));
6260 + cmn_err(CE_WARN, "CompleteFib: Unknown xferstate detected.\n");
6261 + FsaBugCheck(0,0,0);
6263 + return(STATUS_SUCCESS);
6268 + IN PAFA_COMM_ADAPTER Adapter,
6269 + IN PCOMM_FIB_CONTEXT FibContext
6273 +Routine Description:
6275 + This routine handles a driver notify fib from the adapter and dispatches it to
6276 + the appropriate routine for handling.
6280 + Adapter - Which adapter this fib is from
6281 + FibContext - Pointer to FibContext from adapter.
6289 + PFIB Fib = FibContext->Fib;
6290 + PAFA_CLASS_DRIVER ClassDriver;
6291 + BOOLEAN Handled = FALSE;
6295 + // First loop through all of the class drivers to give them a chance to handle
6299 + ClassDriver = Adapter->ClassDriverList;
6301 + while (ClassDriver) {
6303 + if (ClassDriver->HandleAif) {
6305 + if (ClassDriver->HandleAif( ClassDriver->ClassDriverExtension, FibContext ) ) {
6313 + ClassDriver = ClassDriver->Next;
6319 + // Set the status of this FIB to be Invalid parameter.
6322 +// *(FSASTATUS *)Fib->data = ST_INVAL;
6323 + *(FSASTATUS *)Fib->data = ST_OK;
6326 + CompleteAdapterFib(FibContext, sizeof(FSASTATUS));
6333 + IN PAFA_COMM_ADAPTER Adapter
6337 +Routine Description:
6339 + Waits on the commandready event in it's queue. When the event gets set it will
6340 + pull FIBs off it's queue. It will continue to pull FIBs off till the queue is empty.
6341 + When the queue is empty it will wait for more FIBs.
6345 + Context is used. All data os global
6353 + COMM_FIB_CONTEXT FibContext; // for error logging
6355 + PCOMM_REGION CommRegion = Adapter->CommRegion;
6356 + PLIST_ENTRY Entry;
6357 + PGET_ADAPTER_FIB_CONTEXT AdapterFibContext;
6360 + // We can only have one thread per adapter for AIF's.
6363 + if (Adapter->AifThreadStarted) {
6367 +// cmn_err(CE_DEBUG, "AIF thread started");
6370 + // Let the DPC know it has a place to send the AIF's to.
6373 + Adapter->AifThreadStarted = TRUE;
6375 + RtlZeroMemory(&FibContext, sizeof(COMM_FIB_CONTEXT));
6377 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6382 + // NOTE : the QueueLock is held at the top of each loop.
6385 + ASSERT(OsSpinLockOwned(CommRegion->HostNormCmdQue.QueueLock));
6387 + while (!IsListEmpty(&(CommRegion->HostNormCmdQue.CommandQueue))) {
6388 + PLIST_ENTRY Entry;
6389 + PAIFCOMMANDTOHOST AifCommandToHost;
6391 + Entry = RemoveHeadList(&(CommRegion->HostNormCmdQue.CommandQueue));
6393 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6395 + Fib = CONTAINING_RECORD( Entry, FIB, Header.FibLinks );
6398 + // We will process the FIB here or pass it to a worker thread that is TBD. We Really
6399 + // can't do anything at this point since we don't have anything defined for this thread to
6403 + // cmn_err(CE_DEBUG, "Got Fib from the adapter with a NORMAL priority, command 0x%x.\n", Fib->Header.Command);
6405 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
6408 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
6409 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
6410 + FibContext.Fib = Fib;
6411 + FibContext.FibData = Fib->data;
6412 + FibContext.Adapter = Adapter;
6416 + // We only handle AifRequest fibs from the adapter.
6419 + ASSERT(Fib->Header.Command == AifRequest);
6422 + AifCommandToHost = (PAIFCOMMANDTOHOST) Fib->data;
6424 + if (AifCommandToHost->command == AifCmdDriverNotify) {
6428 + HandleDriverAif( Adapter, &FibContext );
6431 + AAC_UINT32 time_now, time_last;
6432 + time_now = (AAC_UINT32)OsGetSeconds();
6435 + OsCvLockAcquire(Adapter->AdapterFibMutex);
6437 + Entry = Adapter->AdapterFibContextList.Flink;
6440 + // For each Context that is on the AdapterFibContextList, make a copy of the
6441 + // fib, and then set the event to wake up the thread that is waiting for it.
6444 + while (Entry != &Adapter->AdapterFibContextList) {
6447 + // Extract the AdapterFibContext
6450 + AdapterFibContext = CONTAINING_RECORD( Entry, GET_ADAPTER_FIB_CONTEXT, NextContext );
6453 + // Check if the queue is getting backlogged
6455 + if ( AdapterFibContext->FibCount > 20 ) {
6456 + time_last = (AAC_UINT32)(AdapterFibContext->FileObject);
6459 + // has it been > 2 minutes since the last read off the queue?
6461 + if ((time_now - time_last) > 120) {
6462 + Entry = Entry->Flink;
6463 + // cmn_err (CE_WARN, "aifd: Flushing orphaned AdapterFibContext: idle %d seconds, %d fibs",
6464 + // time_now - time_last,
6465 + // AdapterFibContext->FibCount);
6466 + FsaCloseAdapterFibContext ( Adapter, AdapterFibContext );
6471 +// Warning: sleep possible while holding spinlock
6472 + NewFib = OsAllocMemory(sizeof(FIB), OS_ALLOC_MEM_SLEEP);
6477 + // Make the copy of the FIB
6480 + RtlCopyMemory(NewFib, Fib, sizeof(FIB));
6483 + // Put the FIB onto the AdapterFibContext's FibList
6486 + InsertTailList(&AdapterFibContext->FibList, &NewFib->Header.FibLinks);
6487 + AdapterFibContext->FibCount++;
6490 + // Set the event to wake up the thread that will waiting.
6493 + OsCv_signal(&AdapterFibContext->UserEvent);
6497 + cmn_err (CE_WARN, "aifd: didn't allocate NewFib");
6501 + Entry = Entry->Flink;
6505 + // Set the status of this FIB
6508 + *(FSASTATUS *)Fib->data = ST_OK;
6510 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
6512 + OsCvLockRelease(Adapter->AdapterFibMutex);
6516 + OsSpinLockAcquire(CommRegion->HostNormCmdQue.QueueLock);
6521 + // There are no more AIF's, call cv_wait_sig to wait for more
6525 + // cmn_err(CE_DEBUG, "no more AIF's going to sleep\n");
6527 + if (OsCv_wait_sig( &(CommRegion->HostNormCmdQue.CommandReady),
6528 + CommRegion->HostNormCmdQue.QueueLock ) == 0) {
6530 + OsSpinLockRelease(CommRegion->HostNormCmdQue.QueueLock);
6532 + Adapter->AifThreadStarted = FALSE;
6534 + // cmn_err(CE_DEBUG, "AifThread awoken by a signal\n");
6540 + // cmn_err(CE_DEBUG, "Aif thread awake, going to look for more AIF's\n");
6548 + IN PFIB_CONTEXT Context
6551 + PCOMM_FIB_CONTEXT FibContext = (PCOMM_FIB_CONTEXT) Context;
6553 + return ((PVOID)FibContext->Fib->data);
6557 +#ifdef API_THROTTLE
6559 +void ThrottlePeriodEndDpcRtn(
6561 + IN PVOID DeferredContext,
6562 + IN PVOID SystemArgument1,
6563 + IN PVOID SystemArgument2
6567 +Routine Description:
6569 + This routine is called as a DPC when a throttle period expires. It
6570 + restarts all threads suspended due to the throttling flow control.
6572 + The throttling counted semaphore is signalled for all waiting threads
6573 + and the indicator of throttling active is cleared.
6577 + Dpc - Pointer to Dpc structure. Not used.
6578 + DefferedContext - Pointer to per-adapter context. This is used to locate the
6579 + throttle information for this adapter.
6580 + SystemArgument1 - Not used
6581 + SystemArgument2 - Not used
6589 + PCOMM_REGION CommRegion;
6590 + PAFA_COMM_ADAPTER Adapter = (PAFA_COMM_ADAPTER) DeferredContext;
6592 + CommRegion = Adapter->CommRegion;
6595 + // Acquire the spinlock protecting the throttle status.
6597 + OsSpinLockAcquire(CommRegion->AdapNormCmdQue.QueueLock);
6599 + FsaCommPrint("ThrottlePeriodEndDpc\n");
6602 + // Check that the timer has fired as many times as it was set !
6605 + CommRegion->ThrottleTimerFires++;
6606 + ASSERT(CommRegion->ThrottleTimerFires == CommRegion->ThrottleTimerSets);
6609 + // The throttle period is now over. Restart all threads waiting
6610 + // on the throttle being released.
6611 + // Clear the throttle active indicator. This will allow new FIBs
6612 + // to be sent to the adapter once we release the spinlock on exiting
6613 + // the DPC. This means all restarted threads will be runnable
6614 + // threads by then.
6617 + ASSERT(CommRegion->ThrottleActive == TRUE); // The throttle had better be on !
6618 + CommRegion->ThrottleActive = FALSE; // This allows new data FIBs to go to the adapter on dpc exit
6620 + OsSpinLockRelease(CommRegion->AdapNormCmdQue.QueueLock);
6623 +#endif // #ifdef API_THROTTLE
6626 + * Overrides for Emacs so that we almost follow Linus's tabbing style.
6627 + * Emacs will notice this stuff at the end of the file and automatically
6628 + * adjust the settings for this buffer only. This must remain at the end
6630 + * ---------------------------------------------------------------------------
6631 + * Local variables:
6632 + * c-indent-level: 4
6633 + * c-brace-imaginary-offset: 0
6634 + * c-brace-offset: -4
6635 + * c-argdecl-indent: 4
6636 + * c-label-offset: -4
6637 + * c-continued-statement-offset: 4
6638 + * c-continued-brace-offset: 0
6639 + * indent-tabs-mode: nil
6643 diff -burN linux-2.4.7/drivers/scsi/aacraid/dpcsup.c linux/drivers/scsi/aacraid/dpcsup.c
6644 --- linux-2.4.7/drivers/scsi/aacraid/dpcsup.c Wed Dec 31 18:00:00 1969
6645 +++ linux/drivers/scsi/aacraid/dpcsup.c Sat Jul 21 17:55:13 2001
6648 + * Adaptec aacraid device driver for Linux.
6650 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
6652 + * This program is free software; you can redistribute it and/or modify
6653 + * it under the terms of the GNU General Public License as published by
6654 + * the Free Software Foundation; either version 2, or (at your option)
6655 + * any later version.
6657 + * This program is distributed in the hope that it will be useful,
6658 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6659 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6660 + * GNU General Public License for more details.
6662 + * You should have received a copy of the GNU General Public License
6663 + * along with this program; see the file COPYING. If not, write to
6664 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
6669 + * Abstract: All DPC processing routines for the cyclone board occur here.
6674 +static char *ident_dpcsup = "aacraid_ident dpcsup.c 1.0.6 2000/10/09 Adaptec, Inc.";
6676 +#include "comprocs.h"
6680 +// The Bug check file id for this module
6683 +#define BugCheckFileId (FSAFS_BUG_CHECK_DPCSUP)
6685 +#define Dbg (DEBUG_TRACE_DPCSUP)
6689 + IN PCOMM_REGION CommRegion
6693 +Routine Description:
6695 + This DPC routine will be queued when the adapter interrupts us to let us know the queue is
6696 + no longer full. The Isr will pass the queue that we will set the not full event.
6700 + Dpc - Pointer to this routine.
6702 + Dummy - is a pointer to the comm region which is global so we don't need it anyway
6704 + Queue is a pointer to the queue structure we will operate on.
6706 + MoreData2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6715 +#ifdef unix_queue_full
6716 + KeSetEvent(&Queue->QueueFull, 0, FALSE);
6721 +int GatherFibTimes = 0;
6723 +// XXX - hack this in until I figure out which header file should contain it. <smb>
6734 +Routine Description:
6736 + This DPC routine will be queued when the adapter interrupts us to let us know there
6737 + is a response on our normal priority queue. We will pull off all QE there are and wake
6738 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6743 + Dpc - Pointer to this routine.
6745 + OurQueue is a pointer to the queue structure we will operate on.
6747 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6755 +HostResponseNormalDpc (IN PCOMM_QUE OurQueue)
6757 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
6758 + PQUEUE_ENTRY QueueEntry;
6760 + PCOMM_FIB_CONTEXT FibContext;
6764 + LARGE_INTEGER ResponseAllocSize;
6767 + FsaCommPrint("entering the host normal reponse dpc routine.\n");
6770 + OsSpinLockAcquire( OurQueue->QueueLock );
6773 + // Keep pulling response QEs off the response queue and waking
6774 + // up the waiters until there are no more QEs. We then return
6775 + // back to the system. If no response was requesed we just
6776 + // deallocate the Fib here and continue.
6780 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
6782 + int IsFastResponse;
6784 + IsFastResponse = (int) (QueueEntry->FibAddress & 0x01);
6785 + Fib = (PFIB) (QueueEntry->FibAddress & ~0x01);
6787 + FreeConsumerEntry(Adapter, OurQueue, HostNormRespQueue);
6789 + FibContext = (PCOMM_FIB_CONTEXT)Fib->Header.SenderData;
6791 + ASSERT(FibContext->Fib == Fib);
6794 + // Remove this FibContext from the Outstanding I/O queue.
6795 + // But only if it has not already been timed out.
6797 + // If the fib has been timed out already, then just continue.
6798 + // The caller has already been notified that the fib timed out.
6801 + if (!(FibContext->Flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
6803 + RemoveEntryList( &FibContext->QueueEntry );
6804 + Adapter->CommRegion->AdapNormCmdQue.NumOutstandingIos--;
6808 + FsaCommLogEvent(FibContext,
6809 + FsaCommData.DeviceObject,
6810 + FSAFS_TIMED_OUT_FIB_COMPLETED,
6811 + STATUS_UNSUCCESSFUL,
6812 + BugCheckFileId | __LINE__,
6813 + FACILITY_FSAFS_ERROR_CODE,
6821 + OsSpinLockRelease( OurQueue->QueueLock );
6823 + if (IsFastResponse) {
6829 + *(FSASTATUS *)Fib->data = ST_OK;
6831 + Fib->Header.XferState |= AdapterProcessed;
6835 + ASSERT((Fib->Header.XferState & (AdapterProcessed | HostOwned | SentFromHost)) == (AdapterProcessed | HostOwned | SentFromHost));
6837 + FIB_COUNTER_INCREMENT(FsaCommData.FibRecved);
6839 + ASSERT(FsaCommData.FibsSent >= FsaCommData.FibRecved);
6842 + if (Fib->Header.Command == NuFileSystem) {
6844 + FSASTATUS *pStatus = (FSASTATUS *)Fib->data;
6846 + if (*pStatus & 0xffff0000) {
6848 + ULONG Hint = *pStatus;
6853 + DbgPrint("Replacing hint in fid (drive = %d, f1 = 0x%x, f2 = 0x%x, hint = 0x%x, new_hint = 0x%x)\n",
6854 + IrpContext->NonPaged->FileId.fid_driveno,
6855 + IrpContext->NonPaged->FileId.fid_f1,
6856 + IrpContext->NonPaged->FileId.fid_f2,
6857 + IrpContext->NonPaged->FileId.fid_hint,
6865 + if (Fib->Header.XferState & (NoResponseExpected | Async) ) {
6867 + ASSERT(FibContext->FibCallback);
6869 + if (Fib->Header.XferState & NoResponseExpected)
6870 + FIB_COUNTER_INCREMENT(FsaCommData.NoResponseRecved);
6872 + FIB_COUNTER_INCREMENT(FsaCommData.AsyncRecved);
6875 + // NOTE: we can not touch the FibContext after this call, because it may have been
6879 + FibContext->FibCallback(FibContext->FibCallbackContext, FibContext, STATUS_SUCCESS);
6883 + OsCvLockAcquire( FibContext->FsaEventMutex);
6885 + FibContext->FibComplete = 1;
6887 + OsCv_signal( &FibContext->FsaEvent );
6889 + OsCvLockRelease( FibContext->FsaEventMutex );
6891 + FIB_COUNTER_INCREMENT(FsaCommData.NormalRecved);
6898 + OsSpinLockAcquire( OurQueue->QueueLock );
6902 + if (Consumed > FsaCommData.PeakFibsConsumed)
6903 + FsaCommData.PeakFibsConsumed = Consumed;
6905 + if (Consumed == 0)
6906 + FsaCommData.ZeroFibsConsumed++;
6908 + if (FsaCommData.HardInterruptModeration) {
6911 + // Re-Enable the interrupt from the adapter, then recheck to see if anything has
6912 + // been put on the queue. This removes the race condition that exists between the
6913 + // last time we checked the queue, and when we re-enabled the interrupt.
6915 + // If there is something on the queue, then go handle it.
6918 + EnableInterrupt( Adapter, HostNormRespQue, FALSE );
6920 + if (ConsumerEntryAvailable( Adapter, OurQueue ) ) {
6922 + DisableInterrupt( Adapter, HostNormRespQue, FALSE );
6930 + FsaCommPrint("Exiting host normal reponse dpc routine after consuming %d QE(s).\n",Consumed);
6933 + OsSpinLockRelease( OurQueue->QueueLock );
6939 +Routine Description:
6941 + This DPC routine wiol be queued when the adapter interrupts us to let us know there
6942 + is a response on our high priority queue. We will pull off all QE there are and wake
6943 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6948 + Dpc - Pointer to this routine.
6950 + OurQueue is a pointer to the queue structure we will operate on.
6952 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6960 +HostResponseHighDpc (IN PCOMM_QUE OurQueue)
6966 +Routine Description:
6968 + This DPC routine will be queued when the adapter interrupts us to let us know there
6969 + is a command on our high priority queue. We will pull off all QE there are and wake
6970 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
6975 + Dpc - Pointer to this routine.
6977 + OurQueue is a pointer to the queue structure we will operate on.
6979 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
6987 +HostCommandHighDpc (IN PCOMM_QUE OurQueue)
6993 +Routine Description:
6995 + This DPC routine will be queued when the adapter interrupts us to let us know there
6996 + is a command on our normal priority queue. We will pull off all QE there are and wake
6997 + up all the waiters before exiting. We will take a spinlock out on the queue before operating
7002 + Dpc - Pointer to this routine.
7004 + OurQueue is a pointer to the queue structure we will operate on.
7006 + MoreData1&2 are DPC parameters we don't need for this function. Maybe we can add some accounting
7014 +HostCommandNormDpc (IN PCOMM_QUE OurQueue)
7016 + PAFA_COMM_ADAPTER Adapter = OurQueue->Adapter;
7017 + PQUEUE_ENTRY QueueEntry;
7019 + OsSpinLockAcquire( OurQueue->QueueLock );
7022 + // Keep pulling response QEs off the response queue and waking
7023 + // up the waiters until there are no more QEs. We then return
7024 + // back to the system.
7027 + while ( GetConsumerEntry( Adapter, OurQueue, &QueueEntry) ) {
7031 + Fib = (PFIB)QueueEntry->FibAddress;
7034 + if (Adapter->AifThreadStarted) {
7037 +// cmn_err(CE_CONT, "^Received AIF, putting onto command queue\n");
7040 + InsertTailList(&OurQueue->CommandQueue, &Fib->Header.FibLinks);
7041 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7042 + OsCv_signal(&OurQueue->CommandReady);
7050 + COMM_FIB_CONTEXT FibContext;
7054 + FreeConsumerEntry(Adapter, OurQueue, HostNormCmdQueue);
7058 + OsSpinLockRelease( OurQueue->QueueLock );
7062 +// cmn_err(CE_CONT, "^Received AIF, thread not started\n");
7065 + RtlZeroMemory( &FibContext, sizeof(COMM_FIB_CONTEXT) );
7067 + FibContext.NodeTypeCode = FSAFS_NTC_FIB_CONTEXT;
7068 + FibContext.NodeByteSize = sizeof( COMM_FIB_CONTEXT );
7069 + FibContext.Fib = Fib;
7070 + FibContext.FibData = Fib->data;
7071 + FibContext.Adapter = Adapter;
7074 + // Set the status of this FIB
7077 + *(FSASTATUS *)Fib->data = ST_OK;
7079 + CompleteAdapterFib( &FibContext, sizeof(FSASTATUS) );
7083 + OsSpinLockAcquire( OurQueue->QueueLock );
7087 + OsSpinLockRelease( OurQueue->QueueLock );
7090 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/AacGenericTypes.h linux/drivers/scsi/aacraid/include/AacGenericTypes.h
7091 --- linux-2.4.7/drivers/scsi/aacraid/include/AacGenericTypes.h Wed Dec 31 18:00:00 1969
7092 +++ linux/drivers/scsi/aacraid/include/AacGenericTypes.h Sat Jul 21 17:55:13 2001
7095 + * Adaptec aacraid device driver for Linux.
7097 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7099 + * This program is free software; you can redistribute it and/or modify
7100 + * it under the terms of the GNU General Public License as published by
7101 + * the Free Software Foundation; either version 2, or (at your option)
7102 + * any later version.
7104 + * This program is distributed in the hope that it will be useful,
7105 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7106 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7107 + * GNU General Public License for more details.
7109 + * You should have received a copy of the GNU General Public License
7110 + * along with this program; see the file COPYING. If not, write to
7111 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7115 + * AacGenericTypes.h
7119 + * The module defines the generic data types that all of the other header files
7123 +#ifndef _AAC_GENERIC_TYPES
7124 +#define _AAC_GENERIC_TYPES
7126 +static char *ident_AacGeneric = "aacraid_ident AacGenericTypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
7128 +typedef char AAC_INT8, *PAAC_INT8;
7129 +typedef short AAC_INT16, *PAAC_INT16;
7130 +typedef int AAC_INT32, *PAAC_INT32;
7131 +typedef long long AAC_INT64, *PAAC_INT64;
7133 +typedef unsigned char AAC_UINT8, *PAAC_UINT8;
7134 +typedef unsigned short AAC_UINT16, *PAAC_UINT16;
7135 +typedef unsigned int AAC_UINT32, *PAAC_UINT32;
7136 +typedef unsigned long long AAC_UINT64, *PAAC_UINT64;
7138 +typedef void AAC_VOID, *PAAC_VOID;
7141 +// this compiler uses 32 bit enum data types
7144 +#define AAC_32BIT_ENUMS 1
7146 +#define INTR_UNCLAIMED 1
7147 +#define INTR_CLAIMED 0
7149 +#endif // _AAC_GENERIC_TYPES
7151 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/aac_unix_defs.h linux/drivers/scsi/aacraid/include/aac_unix_defs.h
7152 --- linux-2.4.7/drivers/scsi/aacraid/include/aac_unix_defs.h Wed Dec 31 18:00:00 1969
7153 +++ linux/drivers/scsi/aacraid/include/aac_unix_defs.h Sat Jul 21 17:55:13 2001
7156 + * Adaptec aacraid device driver for Linux.
7158 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7160 + * This program is free software; you can redistribute it and/or modify
7161 + * it under the terms of the GNU General Public License as published by
7162 + * the Free Software Foundation; either version 2, or (at your option)
7163 + * any later version.
7165 + * This program is distributed in the hope that it will be useful,
7166 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7167 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7168 + * GNU General Public License for more details.
7170 + * You should have received a copy of the GNU General Public License
7171 + * along with this program; see the file COPYING. If not, write to
7172 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7180 + * Macro definition and typedefs
7184 +#ifndef _AAC_UNIX_DEFS
7185 +#define _AAC_UNIX_DEFS
7187 +static char *ident_aac_unix = "aacraid_ident aac_unix_defs.h 1.0.6 2000/10/09 Adaptec, Inc.";
7189 +#define AAC_MAX_ADAPTERS 64
7196 +#define PAGE_SIZE 4096
7199 +typedef VOID *PVOID;
7201 +typedef char CHAR, *PCHAR;
7202 +typedef unsigned char UCHAR, *PUCHAR;
7203 +typedef short SHORT, *PSHORT;
7204 +typedef short CSHORT, *PCSHORT;
7205 +typedef unsigned short USHORT, *PUSHORT;
7206 +typedef unsigned long ULONG, *PULONG;
7207 +typedef long LONG, *PLONG;
7209 +typedef unsigned long BOOLEAN;
7211 +typedef unsigned long AAC_STATUS, *PNT_STATUS;
7214 + unsigned long LowPart;
7215 + unsigned long HighPart;
7218 +typedef LARGE_INTEGER PHYSICAL_ADDRESS;
7221 +typedef struct _AFA_IOCTL_CMD {
7227 +} AFA_IOCTL_CMD, *PAFA_IOCTL_CMD;
7231 +// Singly linked list structure. Can be used as either a list head, or
7235 +typedef struct _SINGLE_LIST_ENTRY {
7236 + struct _SINGLE_LIST_ENTRY *Next;
7237 +} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
7241 +// Calculate the address of the base of the structure given its type, and an
7242 +// address of a field within the structure.
7245 +#define CONTAINING_RECORD(address, type, field) ((type *)( \
7246 + (PCHAR)(address) - \
7247 + (PCHAR)(&((type *)0)->field)))
7249 +typedef PVOID PMDL;
7250 +typedef PVOID PDEVICE_OBJECT;
7251 +typedef PVOID PADAPTER_OBJECT;
7252 +typedef ULONG KIRQL;
7253 +typedef PVOID HANDLE;
7254 +typedef PVOID KDPC, *PKDPC;
7255 +typedef PVOID PFILE_OBJECT;
7256 +typedef PVOID PIRP;
7257 +typedef PVOID PDRIVER_OBJECT;
7258 +typedef ULONG KTIMER;
7261 +#define STATUS_SUCCESS 0x00000000
7262 +#define STATUS_PENDING 0x40000001
7263 +#define STATUS_IO_TIMEOUT 0xc0000001
7264 +#define STATUS_UNSUCCESSFUL 0xc0000002
7265 +#define STATUS_INSUFFICIENT_RESOURCES 0xc0000005
7266 +#define STATUS_BUFFER_OVERFLOW 0xc0000003
7274 +(*PUNIX_INTR_HANDLER)(caddr_t Arg);
7280 +typedef struct _ZONE_SEGMENT_HEADER {
7281 + SINGLE_LIST_ENTRY SegmentList;
7283 +} ZONE_SEGMENT_HEADER, *PZONE_SEGMENT_HEADER;
7285 +typedef struct _ZONE_HEADER {
7286 + SINGLE_LIST_ENTRY FreeList;
7287 + SINGLE_LIST_ENTRY SegmentList;
7289 + ULONG TotalSegmentSize;
7290 +} ZONE_HEADER, *PZONE_HEADER;
7296 +// ExAllocateFromZone(
7297 +// IN PZONE_HEADER Zone
7300 +// Routine Description:
7302 +// This routine removes an entry from the zone and returns a pointer to it.
7306 +// Zone - Pointer to the zone header controlling the storage from which the
7307 +// entry is to be allocated.
7311 +// The function value is a pointer to the storage allocated from the zone.
7315 +#define ExAllocateFromZone(Zone) \
7316 + (PVOID)((Zone)->FreeList.Next); \
7317 + if ( (Zone)->FreeList.Next ) (Zone)->FreeList.Next = (Zone)->FreeList.Next->Next
7323 +// IN PZONE_HEADER Zone,
7327 +// Routine Description:
7329 +// This routine places the specified block of storage back onto the free
7330 +// list in the specified zone.
7334 +// Zone - Pointer to the zone header controlling the storage to which the
7335 +// entry is to be inserted.
7337 +// Block - Pointer to the block of storage to be freed back to the zone.
7341 +// Pointer to previous block of storage that was at the head of the free
7342 +// list. NULL implies the zone went from no available free blocks to
7343 +// at least one free block.
7347 +#define ExFreeToZone(Zone,Block) \
7348 + ( ((PSINGLE_LIST_ENTRY)(Block))->Next = (Zone)->FreeList.Next, \
7349 + (Zone)->FreeList.Next = ((PSINGLE_LIST_ENTRY)(Block)), \
7350 + ((PSINGLE_LIST_ENTRY)(Block))->Next \
7357 +// IN PZONE_HEADER Zone
7360 +// Routine Description:
7362 +// This routine determines if the specified zone is full or not. A zone
7363 +// is considered full if the free list is empty.
7367 +// Zone - Pointer to the zone header to be tested.
7371 +// TRUE if the zone is full and FALSE otherwise.
7375 +#define ExIsFullZone(Zone) \
7376 + ( (Zone)->FreeList.Next == (PSINGLE_LIST_ENTRY)NULL )
7379 +#define RtlCopyMemory( Destination, Source, Size ) bcopy( (Source), (Destination), (Size) )
7380 +#define RtlZeroMemory( Destination, Size ) bzero( (Destination), (Size) )
7383 +// Doubly-linked list manipulation routines. Implemented as macros
7384 +// but logically these are procedures.
7389 +// InitializeListHead(
7390 +// PLIST_ENTRY ListHead
7394 +#define InitializeListHead(ListHead) (\
7395 + (ListHead)->Flink = (ListHead)->Blink = (ListHead))
7400 +// PLIST_ENTRY ListHead
7404 +#define IsListEmpty(ListHead) \
7405 + ((ListHead)->Flink == (ListHead))
7410 +// PLIST_ENTRY ListHead
7414 +#define RemoveHeadList(ListHead) \
7415 + (ListHead)->Flink;\
7416 + {RemoveEntryList((ListHead)->Flink)}
7421 +// RemoveEntryList(
7422 +// PLIST_ENTRY Entry
7426 +#define RemoveEntryList(Entry) {\
7427 + PLIST_ENTRY _EX_Blink;\
7428 + PLIST_ENTRY _EX_Flink;\
7429 + _EX_Flink = (Entry)->Flink;\
7430 + _EX_Blink = (Entry)->Blink;\
7431 + _EX_Blink->Flink = _EX_Flink;\
7432 + _EX_Flink->Blink = _EX_Blink;\
7438 +// PLIST_ENTRY ListHead,
7439 +// PLIST_ENTRY Entry
7443 +#define InsertTailList(ListHead,Entry) {\
7444 + PLIST_ENTRY _EX_Blink;\
7445 + PLIST_ENTRY _EX_ListHead;\
7446 + _EX_ListHead = (ListHead);\
7447 + _EX_Blink = _EX_ListHead->Blink;\
7448 + (Entry)->Flink = _EX_ListHead;\
7449 + (Entry)->Blink = _EX_Blink;\
7450 + _EX_Blink->Flink = (Entry);\
7451 + _EX_ListHead->Blink = (Entry);\
7454 +#endif /* AAC_UNIX_DEFS */
7455 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/adapter.h linux/drivers/scsi/aacraid/include/adapter.h
7456 --- linux-2.4.7/drivers/scsi/aacraid/include/adapter.h Wed Dec 31 18:00:00 1969
7457 +++ linux/drivers/scsi/aacraid/include/adapter.h Sat Jul 21 17:55:13 2001
7460 + * Adaptec aacraid device driver for Linux.
7462 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7464 + * This program is free software; you can redistribute it and/or modify
7465 + * it under the terms of the GNU General Public License as published by
7466 + * the Free Software Foundation; either version 2, or (at your option)
7467 + * any later version.
7469 + * This program is distributed in the hope that it will be useful,
7470 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7471 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7472 + * GNU General Public License for more details.
7474 + * You should have received a copy of the GNU General Public License
7475 + * along with this program; see the file COPYING. If not, write to
7476 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7483 + * The module contains the definitions for a comm layer view of the adapter.
7492 +static char *ident_adapter = "aacraid_ident adapter.h 1.0.6 2000/10/09 Adaptec, Inc.";
7494 +typedef struct _GET_ADAPTER_FIB_CONTEXT {
7496 + NODE_TYPE_CODE NodeTypeCode; // used for verification of structure
7497 + NODE_BYTE_SIZE NodeByteSize;
7498 + PFILE_OBJECT FileObject; // used for cleanup
7499 + LIST_ENTRY NextContext; // used to link context's into a linked list
7500 + OS_CV_T UserEvent; // this is used to wait for the next fib to arrive.
7501 + BOOLEAN WaitingForFib; // Set to true when thread is in WaitForSingleObject
7502 + ULONG FibCount; // total number of FIBs on FibList
7503 + LIST_ENTRY FibList;
7504 +} GET_ADAPTER_FIB_CONTEXT;
7505 +typedef GET_ADAPTER_FIB_CONTEXT *PGET_ADAPTER_FIB_CONTEXT;
7508 +typedef struct _FIB_CONTEXT_ZONE_SEGMENT {
7510 + struct _FIB_CONTEXT_ZONE_SEGMENT *Next;
7511 + ULONG FibContextSegmentSize;
7512 + PVOID FibContextSegment;
7514 + MAPFIB_CONTEXT MapFibContext;
7516 +} FIB_CONTEXT_ZONE_SEGMENT;
7517 +typedef FIB_CONTEXT_ZONE_SEGMENT *PFIB_CONTEXT_ZONE_SEGMENT;
7519 +typedef struct _AFA_COMM_ADAPTER {
7521 + struct _AFA_COMM_ADAPTER *NextAdapter;
7524 + // The following fields are used to allocate FIB context structures
7525 + // using the zone allocator, and other fixed sized structures from a
7526 + // small cache. The mutex protects access to the zone/lists
7529 + ZONE_HEADER FibContextZone;
7530 + OS_SPINLOCK *FibContextZoneSpinLock;
7531 + int FibContextZoneExtendSize;
7533 + PFIB_CONTEXT_ZONE_SEGMENT FibContextSegmentList;
7535 + PVOID FibContextTimedOutList;
7538 + ULONG SyncFibPhysicalAddress;
7540 + PCOMM_REGION CommRegion;
7542 + OS_SPINLOCK_COOKIE SpinLockCookie;
7545 + // The user API will use an IOCTL to register itself to receive FIBs
7546 + // from the adapter. The following list is used to keep track of all
7547 + // the threads that have requested these FIBs. The mutex is used to
7548 + // synchronize access to all data associated with the adapter fibs.
7550 + LIST_ENTRY AdapterFibContextList;
7551 + OS_CVLOCK *AdapterFibMutex;
7554 + // The following holds which FileObject is allow to send configuration
7555 + // commands to the adapter that would modify the configuration.
7557 + // This is controlled by the FSACTL_OPEN_ADAPTER_CONFIG and FSACTL_CLOSE_ADAPTER_CONFIG
7560 + PFILE_OBJECT AdapterConfigFileObject;
7563 + // The following is really here because of the simulator
7565 + BOOLEAN InterruptsBelowDpc;
7568 + // The following is the device specific extension.
7570 + PVOID AdapterExtension;
7571 + PFSAPORT_FUNCS AdapterFuncs;
7575 + // The following are user variables that are specific to the mini port.
7577 + PFSA_USER_VAR AdapterUserVars;
7578 + ULONG AdapterUserVarsSize;
7581 + // The following is the number of the individual adapter..i.e. \Device\Afa0
7583 + LONG AdapterNumber;
7585 + AFACOMM_FUNCS CommFuncs;
7587 + PAFA_CLASS_DRIVER ClassDriverList;
7589 + BOOLEAN AifThreadStarted;
7591 +} AFA_COMM_ADAPTER;
7593 +typedef AFA_COMM_ADAPTER *PAFA_COMM_ADAPTER;
7596 +#define FsaAllocateAdapterCommArea(Adapter, BaseAddress, Size, Alignment) \
7597 + Adapter->AdapterFuncs->AllocateAdapterCommArea(Adapter->AdapterExtension, BaseAddress, Size, Alignment)
7599 +#define FsaFreeAdapterCommArea(Adapter) \
7600 + Adapter->AdapterFuncs->FreeAdapterCommArea(Adapter->AdapterExtension)
7603 +#define AllocateAndMapFibSpace(Adapter, MapFibContext) \
7604 + Adapter->AdapterFuncs->AllocateAndMapFibSpace(Adapter->AdapterExtension, MapFibContext)
7606 +#define UnmapAndFreeFibSpace(Adapter, MapFibContext) \
7607 + Adapter->AdapterFuncs->UnmapAndFreeFibSpace(Adapter->AdapterExtension, MapFibContext)
7609 +#define InterruptAdapter(Adapter) \
7610 + Adapter->AdapterFuncs->InterruptAdapter(Adapter->AdapterExtension)
7612 +#define NotifyAdapter(Adapter, AdapterEvent) \
7613 + Adapter->AdapterFuncs->NotifyAdapter(Adapter->AdapterExtension, AdapterEvent)
7615 +#define EnableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7616 + Adapter->AdapterFuncs->EnableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7618 +#define DisableInterrupt(Adapter, AdapterEvent, AtDeviceIrq) \
7619 + Adapter->AdapterFuncs->DisableInterrupt(Adapter->AdapterExtension, AdapterEvent, AtDeviceIrq)
7622 +#endif // _ADAPTER_
7623 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/afacomm.h linux/drivers/scsi/aacraid/include/afacomm.h
7624 --- linux-2.4.7/drivers/scsi/aacraid/include/afacomm.h Wed Dec 31 18:00:00 1969
7625 +++ linux/drivers/scsi/aacraid/include/afacomm.h Sat Jul 21 17:55:13 2001
7628 + * Adaptec aacraid device driver for Linux.
7630 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7632 + * This program is free software; you can redistribute it and/or modify
7633 + * it under the terms of the GNU General Public License as published by
7634 + * the Free Software Foundation; either version 2, or (at your option)
7635 + * any later version.
7637 + * This program is distributed in the hope that it will be useful,
7638 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7639 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7640 + * GNU General Public License for more details.
7642 + * You should have received a copy of the GNU General Public License
7643 + * along with this program; see the file COPYING. If not, write to
7644 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7650 + * This module defines all of the external interfaces to the AFA comm layer.
7658 +static char *ident_afacomm = "aacraid_ident afacomm.h 1.0.6 2000/10/09 Adaptec, Inc.";
7660 +#include "fsaport.h"
7662 +typedef void *PFIB_CONTEXT;
7666 + PVOID FibCallbackContext,
7667 + PFIB_CONTEXT FibContext,
7672 +typedef PFIB_CONTEXT
7673 +(*PAFA_COMM_ALLOCATE_FIB) (
7674 + IN PVOID AdapterExtension
7678 +(*PAFA_COMM_FREE_FIB) (
7679 + IN PFIB_CONTEXT FibContext
7684 +(*PAFA_COMM_DEALLOCATE_FIB) (
7685 + IN PFIB_CONTEXT FibContext
7690 +(*PAFA_COMM_FREE_FIB_FROM_DPC) (
7691 + IN PFIB_CONTEXT FibContext
7695 +(*PAFA_COMM_INITIALIZE_FIB) (
7696 + IN PFIB_CONTEXT FibContext
7700 +(*PAFA_COMM_GET_FIB_DATA) (
7701 + IN PFIB_CONTEXT FibContext
7705 +(*PAFA_COMM_SEND_FIB) (
7706 + IN FIB_COMMAND Command,
7707 + IN PFIB_CONTEXT FibContext,
7709 + IN COMM_PRIORITIES Priority,
7712 + IN BOOLEAN ResponseExpected,
7713 + IN PFIB_CALLBACK FibCallback,
7714 + IN PVOID FibCallbackContext
7718 +(*PAFA_COMM_COMPLETE_FIB) (
7719 + IN PFIB_CONTEXT FibContext
7723 +(*PAFA_COMM_COMPLETE_ADAPTER_FIB) (
7724 + IN PFIB_CONTEXT FibContext,
7729 +(*PAFA_COMM_SEND_SYNCH_FIB) (
7730 + PVOID AdapterExtension,
7731 + FIB_COMMAND Command,
7735 + USHORT *ResponseSize
7739 +typedef struct _AFACOMM_FUNCS {
7740 + ULONG SizeOfAfaCommFuncs;
7741 + PAFA_COMM_ALLOCATE_FIB AllocateFib;
7742 + PAFA_COMM_FREE_FIB FreeFib;
7743 + PAFA_COMM_FREE_FIB_FROM_DPC FreeFibFromDpc;
7744 + PAFA_COMM_DEALLOCATE_FIB DeallocateFib;
7745 + PAFA_COMM_INITIALIZE_FIB InitializeFib;
7746 + PAFA_COMM_GET_FIB_DATA GetFibData;
7747 + PAFA_COMM_SEND_FIB SendFib;
7748 + PAFA_COMM_COMPLETE_FIB CompleteFib;
7749 + PAFA_COMM_COMPLETE_ADAPTER_FIB CompleteAdapterFib;
7750 + PAFA_COMM_SEND_SYNCH_FIB SendSynchFib;
7751 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
7752 + PFSA_BUILD_SGMAP BuildSgMap;
7753 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
7755 +typedef AFACOMM_FUNCS *PAFACOMM_FUNCS;
7759 +(*PAFA_CLASS_OPEN_ADAPTER) (
7765 +(*PAFA_CLASS_CLOSE_ADAPTER) (
7771 +(*PAFA_CLASS_DEV_CONTROL) (
7773 + IN PAFA_IOCTL_CMD IoctlCmdPtr,
7778 +(*PAFA_CLASS_HANDLE_AIF) (
7780 + IN PFIB_CONTEXT FibContext
7784 +typedef struct _AFA_NEW_CLASS_DRIVER {
7785 + PVOID ClassDriverExtension;
7786 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7787 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7788 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7789 + PAFA_CLASS_HANDLE_AIF HandleAif;
7790 + PFSA_USER_VAR UserVars;
7791 + ULONG NumUserVars;
7792 +} AFA_NEW_CLASS_DRIVER;
7793 +typedef AFA_NEW_CLASS_DRIVER *PAFA_NEW_CLASS_DRIVER;
7796 +typedef struct _AFA_NEW_CLASS_DRIVER_RESPONSE {
7797 + PAFACOMM_FUNCS CommFuncs;
7798 + PVOID CommPortExtension;
7799 + PVOID MiniPortExtension;
7800 + OS_SPINLOCK_COOKIE SpinLockCookie;
7802 +} AFA_NEW_CLASS_DRIVER_RESPONSE;
7803 +typedef AFA_NEW_CLASS_DRIVER_RESPONSE *PAFA_NEW_CLASS_DRIVER_RESPONSE;
7806 +typedef struct _AFA_CLASS_DRIVER {
7807 + struct _AFA_CLASS_DRIVER *Next;
7808 + PVOID ClassDriverExtension;
7809 + PAFA_CLASS_OPEN_ADAPTER OpenAdapter;
7810 + PAFA_CLASS_CLOSE_ADAPTER CloseAdapter;
7811 + PAFA_CLASS_DEV_CONTROL DeviceControl;
7812 + PAFA_CLASS_HANDLE_AIF HandleAif;
7813 +} AFA_CLASS_DRIVER;
7814 +typedef AFA_CLASS_DRIVER *PAFA_CLASS_DRIVER;
7817 +#endif // _AFACOMM_
7818 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/aifstruc.h linux/drivers/scsi/aacraid/include/aifstruc.h
7819 --- linux-2.4.7/drivers/scsi/aacraid/include/aifstruc.h Wed Dec 31 18:00:00 1969
7820 +++ linux/drivers/scsi/aacraid/include/aifstruc.h Sat Jul 21 17:55:13 2001
7823 + * Adaptec aacraid device driver for Linux.
7825 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
7827 + * This program is free software; you can redistribute it and/or modify
7828 + * it under the terms of the GNU General Public License as published by
7829 + * the Free Software Foundation; either version 2, or (at your option)
7830 + * any later version.
7832 + * This program is distributed in the hope that it will be useful,
7833 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7834 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7835 + * GNU General Public License for more details.
7837 + * You should have received a copy of the GNU General Public License
7838 + * along with this program; see the file COPYING. If not, write to
7839 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
7845 + * Define all shared data types relating to
7846 + * the set of features utilizing Adapter
7852 +#ifndef _AIFSTRUC_H
7853 +#define _AIFSTRUC_H
7855 +static char *ident_aifstruc = "aacraid_ident aifstruc.h 1.0.6 2000/10/09 Adaptec, Inc.";
7857 +#include <protocol.h>
7860 +// Progress report structure definitions
7863 + AifJobStsSuccess = 1,
7864 + AifJobStsFinished,
7867 + AifJobStsLastReportMarker = 100, // All before mean last report
7868 + AifJobStsSuspended,
7872 +#ifdef AAC_32BIT_ENUMS
7873 +typedef _E_AifJobStatus AifJobStatus;
7875 +typedef AAC_UINT32 AifJobStatus;
7880 + AifJobScsiMin = 1, // Minimum value for Scsi operation
7881 + AifJobScsiZero, // SCSI device clear operation
7882 + AifJobScsiVerify, // SCSI device Verify operation NO REPAIR
7883 + AifJobScsiExercise, // SCSI device Exercise operation
7884 + AifJobScsiVerifyRepair, // SCSI device Verify operation WITH repair
7885 + // Add new SCSI task types above this line
7886 + AifJobScsiMax = 99, // Max Scsi value
7887 + AifJobCtrMin, // Min Ctr op value
7888 + AifJobCtrZero, // Container clear operation
7889 + AifJobCtrCopy, // Container copy operation
7890 + AifJobCtrCreateMirror, // Container Create Mirror operation
7891 + AifJobCtrMergeMirror, // Container Merge Mirror operation
7892 + AifJobCtrScrubMirror, // Container Scrub Mirror operation
7893 + AifJobCtrRebuildRaid5, // Container Rebuild Raid5 operation
7894 + AifJobCtrScrubRaid5, // Container Scrub Raid5 operation
7895 + AifJobCtrMorph, // Container morph operation
7896 + AifJobCtrPartCopy, // Container Partition copy operation
7897 + AifJobCtrRebuildMirror, // Container Rebuild Mirror operation
7898 + AifJobCtrCrazyCache, // crazy cache
7899 + // Add new container task types above this line
7900 + AifJobCtrMax = 199, // Max Ctr type operation
7901 + AifJobFsMin, // Min Fs type operation
7902 + AifJobFsCreate, // File System Create operation
7903 + AifJobFsVerify, // File System Verify operation
7904 + AifJobFsExtend, // File System Extend operation
7905 + // Add new file system task types above this line
7906 + AifJobFsMax = 299, // Max Fs type operation
7907 + // Add new API task types here
7908 + AifJobApiFormatNTFS, // Format a drive to NTFS
7909 + AifJobApiFormatFAT, // Format a drive to FAT
7910 + AifJobApiUpdateSnapshot, // update the read/write half of a snapshot
7911 + AifJobApiFormatFAT32, // Format a drive to FAT32
7912 + AifJobApiMax = 399, // Max API type operation
7913 + AifJobCtlContinuousCtrVerify, // Controller operation
7914 + AifJobCtlMax = 499 // Max Controller type operation
7918 +#ifdef AAC_32BIT_ENUMS
7919 +typedef _E_AifJobType AifJobType;
7921 +typedef AAC_UINT32 AifJobType;
7924 +union SrcContainer {
7926 + AAC_UINT32 master;
7927 + AAC_UINT32 container;
7930 +union DstContainer {
7933 + AAC_UINT32 container;
7937 +struct AifContainers {
7938 + union SrcContainer src;
7939 + union DstContainer dst;
7942 +union AifJobClient {
7944 + struct AifContainers container; // For Container nd file system progress ops;
7945 + AAC_INT32 scsi_dh; // For SCSI progress ops
7948 +struct AifJobDesc {
7949 + AAC_UINT32 jobID; // DO NOT FILL IN! Will be filled in by AIF
7950 + AifJobType type; // Operation that is being performed
7951 + union AifJobClient client; // Details
7954 +struct AifJobProgressReport {
7955 + struct AifJobDesc jd;
7956 + AifJobStatus status;
7957 + AAC_UINT32 finalTick;
7958 + AAC_UINT32 currentTick;
7959 + AAC_UINT32 jobSpecificData1;
7960 + AAC_UINT32 jobSpecificData2;
7964 +// Notification of events structure definition starts here
7967 + // General application notifies start here
7968 + AifEnGeneric = 1, // Generic notification
7969 + AifEnTaskComplete, // Task has completed
7970 + AifEnConfigChange, // Adapter configuration change occurred
7971 + AifEnContainerChange, // Adapter specific container configuration change
7972 + AifEnDeviceFailure, // SCSI device failed
7973 + AifEnMirrorFailover, // Mirror failover started
7974 + AifEnContainerEvent, // Significant container event
7975 + AifEnFileSystemChange, // File system changed
7976 + AifEnConfigPause, // Container pause event
7977 + AifEnConfigResume, // Container resume event
7978 + AifEnFailoverChange, // Failover space assignment changed
7979 + AifEnRAID5RebuildDone, // RAID5 rebuild finished
7980 + AifEnEnclosureManagement, // Enclosure management event
7981 + AifEnBatteryEvent, // Significant NV battery event
7982 + AifEnAddContainer, // A new container was created.
7983 + AifEnDeleteContainer, // A container was deleted.
7984 + AifEnSMARTEvent, // SMART Event
7985 + AifEnBatteryNeedsRecond, // The battery needs reconditioning
7986 + AifEnClusterEvent, // Some cluster event
7987 + AifEnDiskSetEvent, // A disk set event occured.
7988 + // Add general application notifies above this comment
7989 + AifDriverNotifyStart=199, // Notifies for host driver go here
7990 + // Host driver notifications start here
7991 + AifDenMorphComplete, // A morph operation completed
7992 + AifDenVolumeExtendComplete // A volume expand operation completed
7993 + // Add host driver notifications above this comment
7994 +} _E_AifEventNotifyType;
7996 +#ifdef AAC_32BIT_ENUMS
7997 +typedef _E_AifEventNotifyType AifEventNotifyType;
7999 +typedef AAC_UINT32 AifEventNotifyType;
8002 +struct AifEnsGeneric {
8003 + AAC_INT8 text[132]; // Generic text
8006 +struct AifEnsDeviceFailure {
8007 + AAC_INT32 deviceHandle; // SCSI device handle
8010 +struct AifEnsMirrorFailover {
8011 + AAC_UINT32 container; // Container with failed element
8012 + AAC_UINT32 failedSlice; // Old slice which failed
8013 + AAC_UINT32 creatingSlice; // New slice used for auto-create
8016 +struct AifEnsContainerChange {
8017 + AAC_UINT32 container[2]; // container that changed, -1 if no container
8020 +struct AifEnsContainerEvent {
8021 + AAC_UINT32 container; // container number
8022 + AAC_UINT32 eventType; // event type
8025 +struct AifEnsEnclosureEvent {
8026 + AAC_UINT32 empID; // enclosure management processor number
8027 + AAC_UINT32 unitID; // unitId, fan id, power supply id, slot id, tempsensor id.
8028 + AAC_UINT32 eventType; // event type
8032 +struct AifEnsBatteryEvent {
8033 + NVBATT_TRANSITION transition_type; // e.g. from low to ok
8034 + NVBATTSTATUS current_state; // current battery state
8035 + NVBATTSTATUS prior_state; // previous battery state
8038 +struct AifEnsDiskSetEvent {
8039 + AAC_UINT32 eventType;
8040 + AAC_UINT32 DsNum[2];
8041 + AAC_UINT32 CreatorId[2];
8046 +typedef enum _CLUSTER_AIF_EVENT {
8047 + CLUSTER_NULL_EVENT = 0,
8048 + CLUSTER_PARTNER_NAME_EVENT, // change in partner hostname or adaptername from NULL to non-NULL
8049 + // (partner's agent may be up)
8050 + CLUSTER_PARTNER_NULL_NAME_EVENT // change in partner hostname or adaptername from non-null to NULL
8051 + // (partner has rebooted)
8052 +} _E_CLUSTER_AIF_EVENT;
8054 +#ifdef AAC_32BIT_ENUMS
8055 +typedef _E_CLUSTER_AIF_EVENT CLUSTER_AIF_EVENT;
8057 +typedef AAC_UINT32 CLUSTER_AIF_EVENT;
8060 +struct AifEnsClusterEvent {
8061 + CLUSTER_AIF_EVENT eventType;
8064 +struct AifEventNotify {
8065 + AifEventNotifyType type;
8067 + struct AifEnsGeneric EG;
8068 + struct AifEnsDeviceFailure EDF;
8069 + struct AifEnsMirrorFailover EMF;
8070 + struct AifEnsContainerChange ECC;
8071 + struct AifEnsContainerEvent ECE;
8072 + struct AifEnsEnclosureEvent EEE;
8073 + struct AifEnsBatteryEvent EBE;
8074 + struct AifEnsDiskSetEvent EDS;
8076 + struct AifEnsSMARTEvent ES;
8078 + struct AifEnsClusterEvent ECLE;
8083 +// Generic API structure
8085 +#define AIF_API_REPORT_MAX_SIZE 64
8086 +typedef AAC_INT8 AifApiReport[AIF_API_REPORT_MAX_SIZE];
8091 +// For FIB communication, we need all of the following things
8092 +// to send back to the user.
8095 + AifCmdEventNotify = 1, // Notify of event
8096 + AifCmdJobProgress, // Progress report
8097 + AifCmdAPIReport, // Report from other user of API
8098 + AifCmdDriverNotify, // Notify host driver of event
8099 + AifReqJobList = 100, // Gets back complete job list
8100 + AifReqJobsForCtr, // Gets back jobs for specific container
8101 + AifReqJobsForScsi, // Gets back jobs for specific SCSI device
8102 + AifReqJobReport, // Gets back a specific job report or list of them
8103 + AifReqTerminateJob, // Terminates job
8104 + AifReqSuspendJob, // Suspends a job
8105 + AifReqResumeJob, // Resumes a job
8106 + AifReqSendAPIReport, // API generic report requests
8107 + AifReqAPIJobStart, // Start a job from the API
8108 + AifReqAPIJobUpdate, // Update a job report from the API
8109 + AifReqAPIJobFinish // Finish a job from the API
8112 +#ifdef AAC_32BIT_ENUMS
8113 +typedef _E_AIFCOMMAND AIFCOMMAND;
8115 +typedef AAC_UINT32 AIFCOMMAND;
8121 +// Adapter Initiated FIB command structures. Start with the adapter
8122 +// initiated FIBs that really come from the adapter, and get responded
8125 +typedef struct _AIFCOMMANDTOHOST {
8126 + AIFCOMMAND command; // Tell host what type of notify this is
8127 + AAC_UINT32 seqNumber; // To allow ordering of reports (if necessary)
8129 + // First define data going to the adapter
8130 + struct AifEventNotify EN; // Event notify structure
8131 + struct AifJobProgressReport PR[1]; // Progress report
8134 +} AIFCOMMANDTOHOST, *PAIFCOMMANDTOHOST;
8137 +#endif // _AIFSTRUC_H
8141 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/build_number.h linux/drivers/scsi/aacraid/include/build_number.h
8142 --- linux-2.4.7/drivers/scsi/aacraid/include/build_number.h Wed Dec 31 18:00:00 1969
8143 +++ linux/drivers/scsi/aacraid/include/build_number.h Sat Jul 21 17:55:13 2001
8146 + * Adaptec aacraid device driver for Linux.
8148 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8150 + * This program is free software; you can redistribute it and/or modify
8151 + * it under the terms of the GNU General Public License as published by
8152 + * the Free Software Foundation; either version 2, or (at your option)
8153 + * any later version.
8155 + * This program is distributed in the hope that it will be useful,
8156 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8157 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8158 + * GNU General Public License for more details.
8160 + * You should have received a copy of the GNU General Public License
8161 + * along with this program; see the file COPYING. If not, write to
8162 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8168 + * DThis module contains the single location where the build number
8174 +#ifndef _BUILD_NUMBER_H
8175 +#define _BUILD_NUMBER_H
8177 +static char *ident_build_num = "aacraid_ident build_number.h 1.0.6 2000/10/09 Adaptec, Inc.";
8179 +#define REV_BUILD_NUMBER 3911
8182 +#endif // _BUILD_NUMBER_H
8184 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commdata.h linux/drivers/scsi/aacraid/include/commdata.h
8185 --- linux-2.4.7/drivers/scsi/aacraid/include/commdata.h Wed Dec 31 18:00:00 1969
8186 +++ linux/drivers/scsi/aacraid/include/commdata.h Sat Jul 21 17:55:13 2001
8189 + * Adaptec aacraid device driver for Linux.
8191 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8193 + * This program is free software; you can redistribute it and/or modify
8194 + * it under the terms of the GNU General Public License as published by
8195 + * the Free Software Foundation; either version 2, or (at your option)
8196 + * any later version.
8198 + * This program is distributed in the hope that it will be useful,
8199 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8200 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8201 + * GNU General Public License for more details.
8203 + * You should have received a copy of the GNU General Public License
8204 + * along with this program; see the file COPYING. If not, write to
8205 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8210 + * Abstract: Define the communication layer of the adapter
8218 +static char *ident_commdata = "aacraid_ident commdata.h 1.0.6 2000/10/09 Adaptec, Inc.";
8220 +typedef struct _FSA_COMM_DATA {
8223 + // A pointer to the Driver and Device object we were initialized with
8226 + PDRIVER_OBJECT DriverObject;
8227 + PDEVICE_OBJECT DeviceObject;
8230 + // A list of all adapters we have configured.
8233 + PAFA_COMM_ADAPTER AdapterList;
8234 + ULONG TotalAdapters;
8237 + // Adapter timeout support. This is the default timeout to wait for the
8238 + // adapter to respond(setup in initfs.c), and a boolean to indicate if
8239 + // we should timeout requests to the adapter or not.
8242 + LARGE_INTEGER QueueFreeTimeout;
8243 + LARGE_INTEGER AdapterTimeout;
8244 + BOOLEAN EnableAdapterTimeouts;
8246 + ULONG FibTimeoutIncrement;
8250 + ULONG NoResponseSent;
8251 + ULONG NoResponseRecved;
8253 + ULONG AsyncRecved;
8255 + ULONG NormalRecved;
8257 + ULONG TimedOutFibs;
8260 + KTIMER TimeoutTimer;
8263 + // If this value is set to 1 then interrupt moderation will occur
8264 + // in the base commuication support.
8267 + ULONG EnableInterruptModeration;
8269 + int HardInterruptModeration;
8270 + int HardInterruptModeration1;
8271 + int PeakFibsConsumed;
8272 + int ZeroFibsConsumed;
8273 + int EnableFibTimeoutBreak;
8274 + ULONG FibTimeoutSeconds;
8277 + // The following holds all of the available user settable variables.
8278 + // This includes all for the comm layer as well as any from the class
8279 + // drivers as well.
8282 + FSA_USER_VAR *UserVars;
8283 + ULONG NumUserVars;
8288 +#ifdef FIB_CHECKSUMS
8289 + int do_fib_checksums;
8293 +typedef FSA_COMM_DATA *PFSA_COMM_DATA;
8295 +extern FSA_COMM_DATA FsaCommData;
8298 +#endif // _COMMDATA_
8300 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commerr.h linux/drivers/scsi/aacraid/include/commerr.h
8301 --- linux-2.4.7/drivers/scsi/aacraid/include/commerr.h Wed Dec 31 18:00:00 1969
8302 +++ linux/drivers/scsi/aacraid/include/commerr.h Sat Jul 21 17:55:13 2001
8305 + * Adaptec aacraid device driver for Linux.
8307 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8309 + * This program is free software; you can redistribute it and/or modify
8310 + * it under the terms of the GNU General Public License as published by
8311 + * the Free Software Foundation; either version 2, or (at your option)
8312 + * any later version.
8314 + * This program is distributed in the hope that it will be useful,
8315 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8316 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8317 + * GNU General Public License for more details.
8319 + * You should have received a copy of the GNU General Public License
8320 + * along with this program; see the file COPYING. If not, write to
8321 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8326 + * Abstract: This file defines all errors that are unique to the Adaptec Fsa Filesystem
8335 +static char *ident_commerr = "aacraid_ident commerr.h 1.0.6 2000/10/09 Adaptec, Inc.";
8338 +// Note: comments in the .mc file must use both ";" and "//".
8340 +// Status values are 32 bit values layed out as follows:
8342 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8343 +// 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
8344 +// +---+-+-------------------------+-------------------------------+
8345 +// |Sev|C| Facility | Code |
8346 +// +---+-+-------------------------+-------------------------------+
8350 +// Sev - is the severity code
8353 +// 01 - Informational
8357 +// C - is the Customer code flag
8359 +// Facility - is the facility code
8361 +// Code - is the facility's status code
8366 +// %1 is reserved by the IO Manager. If IoAllocateErrorLogEntry is
8367 +// called with a device, the name of the device will be inserted into
8368 +// the message at %1. Otherwise, the place of %1 will be left empty.
8369 +// In either case, the insertion strings from the driver's error log
8370 +// entry starts at %2. In other words, the first insertion string goes
8371 +// to %2, the second to %3 and so on.
8375 +// Values are 32 bit values layed out as follows:
8377 +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
8378 +// 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
8379 +// +---+-+-+-----------------------+-------------------------------+
8380 +// |Sev|C|R| Facility | Code |
8381 +// +---+-+-+-----------------------+-------------------------------+
8385 +// Sev - is the severity code
8388 +// 01 - Informational
8392 +// C - is the Customer code flag
8394 +// R - is a reserved bit
8396 +// Facility - is the facility code
8398 +// Code - is the facility's status code
8401 +// Define the facility codes
8405 +#define FACILITY_FSAFS_ERROR_CODE 0x7
8410 +// MessageId: FSAFS_FIB_INVALID
8414 +// A communication packet was detected to be formatted poorly. Please Contact Adaptec support.
8416 +#define FSAFS_FIB_INVALID ((AAC_STATUS)0xE0070009L)
8420 +// MessageId: FSAFS_TIMED_OUT_FIB_COMPLETED
8424 +// A Fib previously timed out by host has been completed by the adapter. (\\.\Afa%2)
8426 +#define FSAFS_TIMED_OUT_FIB_COMPLETED ((AAC_STATUS)0xA007000EL)
8429 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/commfibcontext.h linux/drivers/scsi/aacraid/include/commfibcontext.h
8430 --- linux-2.4.7/drivers/scsi/aacraid/include/commfibcontext.h Wed Dec 31 18:00:00 1969
8431 +++ linux/drivers/scsi/aacraid/include/commfibcontext.h Sat Jul 21 17:55:13 2001
8434 + * Adaptec aacraid device driver for Linux.
8436 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8438 + * This program is free software; you can redistribute it and/or modify
8439 + * it under the terms of the GNU General Public License as published by
8440 + * the Free Software Foundation; either version 2, or (at your option)
8441 + * any later version.
8443 + * This program is distributed in the hope that it will be useful,
8444 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8445 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8446 + * GNU General Public License for more details.
8448 + * You should have received a copy of the GNU General Public License
8449 + * along with this program; see the file COPYING. If not, write to
8450 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8453 + * commfibcontext.h
8455 + * Abstract: defines the _COMM_FIB_CONTEXT strcuture
8460 +#ifndef _COMM_FIB_CONTEXT_
8461 +#define _COMM_FIB_CONTEXT_
8463 +static char *ident_commfib = "aacraid_ident commfibcontext.h 1.0.6 2000/10/09 Adaptec, Inc.";
8465 +typedef struct _COMM_FIB_CONTEXT {
8467 + PVOID Next; // this is used by the zone allocation
8470 + // Type and size of this record (must be FSA_NTC_FIB_CONTEXT)
8472 + // NOTE: THIS STRUCTURE MUST REMAIN 64-bit ALIGNED IN SIZE, SINCE
8473 + // IT IS ZONE ALLOCATED, AND REPINNED_BCBS_ARRAY_SIZE AFFECTS
8477 + NODE_TYPE_CODE NodeTypeCode;
8478 + NODE_BYTE_SIZE NodeByteSize;
8481 + // The Adapter that this I/O is destined for.
8484 + PAFA_COMM_ADAPTER Adapter;
8486 + PHYSICAL_ADDRESS LogicalFibAddress;
8489 + // This is the event the sendfib routine will wait on if the
8490 + // caller did not pass one and this is synch io.
8494 + OS_CVLOCK *FsaEventMutex;
8496 + ULONG FibComplete; // gets set to 1 when fib is complete
8498 + PFIB_CALLBACK FibCallback;
8499 + PVOID FibCallbackContext;
8504 +#ifdef GATHER_FIB_TIMES
8505 + LARGE_INTEGER FibTimeStamp;
8506 + PFIB_TIMES FibTimesPtr;
8510 + // The following is used to put this fib context onto the Outstanding I/O queue.
8513 + LIST_ENTRY QueueEntry;
8516 + // The following is used to timeout a fib to the adapter.
8519 + LARGE_INTEGER TimeoutValue;
8525 +} COMM_FIB_CONTEXT;
8526 +typedef COMM_FIB_CONTEXT *PCOMM_FIB_CONTEXT;
8528 +#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
8530 +#endif /* _COMM_FIB_CONTEXT_ */
8531 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comprocs.h linux/drivers/scsi/aacraid/include/comprocs.h
8532 --- linux-2.4.7/drivers/scsi/aacraid/include/comprocs.h Wed Dec 31 18:00:00 1969
8533 +++ linux/drivers/scsi/aacraid/include/comprocs.h Sat Jul 21 17:55:13 2001
8536 + * Adaptec aacraid device driver for Linux.
8538 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8540 + * This program is free software; you can redistribute it and/or modify
8541 + * it under the terms of the GNU General Public License as published by
8542 + * the Free Software Foundation; either version 2, or (at your option)
8543 + * any later version.
8545 + * This program is distributed in the hope that it will be useful,
8546 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8547 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8548 + * GNU General Public License for more details.
8550 + * You should have received a copy of the GNU General Public License
8551 + * along with this program; see the file COPYING. If not, write to
8552 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8557 + * Abstract: This module defines all of the globally used procedures in the Afa comm layer
8565 +static char *ident_comproc = "aacraid_ident comprocs.h 1.0.6 2000/10/09 Adaptec, Inc.";
8567 +#include "osheaders.h"
8569 +#include "AacGenericTypes.h"
8571 +#include "aac_unix_defs.h"
8573 +#include "nodetype.h"
8575 +// #define GATHER_FIB_TIMES
8577 +#include "fsatypes.h"
8579 +#include "perfpack.h"
8581 +#include "comstruc.h"
8583 +//#include "unix_protocol.h"
8587 +#include "protocol.h"
8589 +#include "fsaioctl.h"
8591 +#undef GATHER_FIB_TIMES
8593 +#include "aifstruc.h"
8595 +#include "fsaport.h"
8596 +#include "comsup.h"
8597 +#include "afacomm.h"
8598 +#include "adapter.h"
8600 +#include "commfibcontext.h"
8601 +#include "comproto.h"
8602 +#include "commdata.h"
8603 +#include "commerr.h"
8609 +// The following macro is used when sending and receiving FIBs. It is only used for
8613 +#define FIB_COUNTER_INCREMENT(Counter) InterlockedIncrement(&(Counter))
8615 +#define FIB_COUNTER_INCREMENT(Counter)
8621 +AfaCommAdapterDeviceControl (
8622 + IN PVOID AdapterArg,
8623 + IN PAFA_IOCTL_CMD IoctlCmdPtr
8627 +#endif // _COMPROCS_
8628 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comproto.h linux/drivers/scsi/aacraid/include/comproto.h
8629 --- linux-2.4.7/drivers/scsi/aacraid/include/comproto.h Wed Dec 31 18:00:00 1969
8630 +++ linux/drivers/scsi/aacraid/include/comproto.h Sat Jul 21 17:55:13 2001
8633 + * Adaptec aacraid device driver for Linux.
8635 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8637 + * This program is free software; you can redistribute it and/or modify
8638 + * it under the terms of the GNU General Public License as published by
8639 + * the Free Software Foundation; either version 2, or (at your option)
8640 + * any later version.
8642 + * This program is distributed in the hope that it will be useful,
8643 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8644 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8645 + * GNU General Public License for more details.
8647 + * You should have received a copy of the GNU General Public License
8648 + * along with this program; see the file COPYING. If not, write to
8649 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8654 + * Abstract: Global routines for the commuication interface that are device
8660 +#ifndef _COMM_PROTO
8661 +#define _COMM_PROTO
8663 +static char *ident_comproto = "aacraid_ident comproto.h 1.0.6 2000/10/09 Adaptec, Inc.";
8666 +// define the routines we need so we can commuicate with the
8671 +// The following 4 dpc routines will support commuication from the adapter to the
8672 +// host. There is one DPC routine to deal with each type of queue that supports
8673 +// commuication from the adapter. (adapter to host resposes, adapter to host commands)
8674 +// These routines will simply pull off the QE and set an event. In the case of a
8675 +// adapter to host command they will also put the FIB on a queue to be processed by
8676 +// a FS thread running at passive level.
8679 +// Handle queue not full notification to the file system thread waiting for a queue entry
8683 + IN PCOMM_REGION CommRegion
8686 +// Adapter to host normal priority responses
8689 +HostResponseNormalDpc(
8690 + IN PCOMM_QUE OurQueue
8693 +// Adapter to host high priority responses
8695 +HostResponseHighDpc(
8696 + IN PCOMM_QUE OurQueue
8699 +// Adapter to host high priority commands
8701 +HostCommandHighDpc(
8702 + IN PCOMM_QUE OurQueue
8706 +// Adapter to host normal priority commands
8708 +HostCommandNormDpc(
8709 + IN PCOMM_QUE OurQueue
8717 + FIB_COMMAND Command,
8721 + USHORT *ResponseSize
8731 + IN PFIB_CONTEXT FibContext
8736 + IN PFIB_CONTEXT FibContext
8741 + IN PFIB_CONTEXT FibContext
8748 + IN FIB_COMMAND Command,
8749 + IN PFIB_CONTEXT FibContext,
8751 + IN COMM_PRIORITIES Priority,
8754 + IN BOOLEAN ResponseExpected,
8755 + IN PFIB_CALLBACK FibCallback,
8756 + IN PVOID FibCallbackContext
8761 + IN PFIB_CONTEXT FibContext
8765 +CompleteAdapterFib(
8766 + IN PFIB_CONTEXT FibContext,
8772 + IN PFIB_CONTEXT FibContext
8778 + IN PFIB_CONTEXT FibContext
8784 +AfaCommOpenAdapter (
8785 + IN PVOID AdapterArg
8789 +AfaCommCloseAdapter (
8790 + IN PVOID AdapterArg
8795 +AfaCommInterruptHost(
8797 + ADAPTER_EVENT AdapterEvent
8801 +#endif // _COMM_PROTO
8802 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comstruc.h linux/drivers/scsi/aacraid/include/comstruc.h
8803 --- linux-2.4.7/drivers/scsi/aacraid/include/comstruc.h Wed Dec 31 18:00:00 1969
8804 +++ linux/drivers/scsi/aacraid/include/comstruc.h Sat Jul 21 17:55:13 2001
8807 + * Adaptec aacraid device driver for Linux.
8809 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
8811 + * This program is free software; you can redistribute it and/or modify
8812 + * it under the terms of the GNU General Public License as published by
8813 + * the Free Software Foundation; either version 2, or (at your option)
8814 + * any later version.
8816 + * This program is distributed in the hope that it will be useful,
8817 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8818 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8819 + * GNU General Public License for more details.
8821 + * You should have received a copy of the GNU General Public License
8822 + * along with this program; see the file COPYING. If not, write to
8823 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
8828 + * Abstract: This module defines the data structures that make up the communication
8829 + * region for the FSA filesystem. This region is how the host based code
8830 + * communicates both control and data to the adapter based code.
8835 +#ifndef _COMM_STRUCT
8836 +#define _COMM_STRUCT
8838 +static char *ident_comstruc = "aacraid_ident comstruc.h 1.0.7 2000/10/11 Adaptec, Inc.";
8841 +// Define all the constants needed for the communication interface
8844 +// Define how many queue entries each queue will have and the total number of
8845 +// entries for the entire communication interface. Also define how many queues
8848 +#define NUMBER_OF_COMM_QUEUES 8 // 4 command; 4 response
8849 +#define HOST_HIGH_CMD_ENTRIES 4
8850 +#define HOST_NORM_CMD_ENTRIES 8
8851 +#define ADAP_HIGH_CMD_ENTRIES 4
8852 +#define ADAP_NORM_CMD_ENTRIES 512
8853 +#define HOST_HIGH_RESP_ENTRIES 4
8854 +#define HOST_NORM_RESP_ENTRIES 512
8855 +#define ADAP_HIGH_RESP_ENTRIES 4
8856 +#define ADAP_NORM_RESP_ENTRIES 8
8858 +#define TOTAL_QUEUE_ENTRIES \
8859 + (HOST_NORM_CMD_ENTRIES + HOST_HIGH_CMD_ENTRIES + ADAP_NORM_CMD_ENTRIES + ADAP_HIGH_CMD_ENTRIES + \
8860 + HOST_NORM_RESP_ENTRIES + HOST_HIGH_RESP_ENTRIES + ADAP_NORM_RESP_ENTRIES + ADAP_HIGH_RESP_ENTRIES)
8865 +// Set the queues on a 16 byte alignment
8866 +#define QUEUE_ALIGNMENT 16
8870 +// The queue headers define the Communication Region queues. These
8871 +// are physically contiguous and accessible by both the adapter and the
8872 +// host. Even though all queue headers are in the same contiguous block they will be
8873 +// represented as individual units in the data structures.
8876 +typedef AAC_UINT32 QUEUE_INDEX;
8878 +typedef QUEUE_INDEX *PQUEUE_INDEX;
8880 +typedef struct _QUEUE_ENTRY {
8882 + AAC_UINT32 Size; // Size in bytes of the Fib which this QE points to
8883 + AAC_UINT32 FibAddress; // Receiver addressable address of the FIB (low 32 address bits)
8887 +typedef QUEUE_ENTRY *PQUEUE_ENTRY;
8891 +// The adapter assumes the ProducerIndex and ConsumerIndex are grouped
8892 +// adjacently and in that order.
8894 +typedef struct _QUEUE_HEADERS {
8896 + PHYSICAL_ADDRESS LogicalHeaderAddress; // Address to hand the adapter to access to this queue head
8897 + PQUEUE_INDEX ProducerIndex; // The producer index for this queue (host address)
8898 + PQUEUE_INDEX ConsumerIndex; // The consumer index for this queue (host address)
8901 +typedef QUEUE_HEADERS *PQUEUE_HEADERS;
8904 +// Define all the events which the adapter would like to notify
8907 +typedef enum _ADAPTER_EVENT {
8908 + HostNormCmdQue = 1, // Change in host normal priority command queue
8909 + HostHighCmdQue, // Change in host high priority command queue
8910 + HostNormRespQue, // Change in host normal priority response queue
8911 + HostHighRespQue, // Change in host high priority response queue
8912 + AdapNormRespNotFull,
8913 + AdapHighRespNotFull,
8914 + AdapNormCmdNotFull,
8915 + AdapHighCmdNotFull,
8916 + SynchCommandComplete,
8917 + AdapInternalError = 0xfe // The adapter detected an internal error shutting down
8919 +} _E_ADAPTER_EVENT;
8921 +#ifdef AAC_32BIT_ENUMS
8922 +typedef _E_ADAPTER_EVENT ADAPTER_EVENT;
8924 +typedef AAC_UINT32 ADAPTER_EVENT;
8928 +// Define all the events the host wishes to notify the
8931 +typedef enum _HOST_2_ADAP_EVENT {
8932 + AdapNormCmdQue = 1,
8939 + HostNormRespNotFull,
8940 + HostHighRespNotFull,
8941 + HostNormCmdNotFull,
8942 + HostHighCmdNotFull,
8945 +} _E_HOST_2_ADAP_EVENT;
8947 +#ifdef AAC_32BIT_ENUMS
8948 +typedef _E_HOST_2_ADAP_EVENT HOST_2_ADAP_EVENT;
8950 +typedef AAC_UINT32 HOST_2_ADAP_EVENT;
8954 +// Define all the queues that the adapter and host use to communicate
8957 +typedef enum _QUEUE_TYPES {
8958 + HostNormCmdQueue = 1, // Adapter to host normal priority command traffic
8959 + HostHighCmdQueue, // Adapter to host high priority command traffic
8960 + AdapNormRespQueue, // Host to adapter normal priority response traffic
8961 + AdapHighRespQueue, // Host to adapter high priority response traffic
8962 + AdapNormCmdQueue, // Host to adapter normal priority command traffic
8963 + AdapHighCmdQueue, // Host to adapter high priority command traffic
8964 + HostNormRespQueue, // Adapter to host normal priority response traffic
8965 + HostHighRespQueue // Adapter to host high priority response traffic
8968 +#ifdef AAC_32BIT_ENUMS
8969 +typedef _E_QUEUE_TYPES QUEUE_TYPES;
8971 +typedef AAC_UINT32 QUEUE_TYPES;
8976 +// Assign type values to the FSA communication data structures
8979 +typedef enum _STRUCT_TYPES {
8985 +#ifdef AAC_32BIT_ENUMS
8986 +typedef _E_STRUCT_TYPES STRUCT_TYPES;
8988 +typedef AAC_UINT32 STRUCT_TYPES;
8992 +// Define the priority levels the FSA communication routines support.
8995 +typedef enum _COMM_PRIORITIES {
8998 +} _E_COMM_PRIORITIES;
9000 +#ifdef AAC_32BIT_ENUMS
9001 +typedef _E_COMM_PRIORITIES COMM_PRIORITIES;
9003 +typedef AAC_UINT32 COMM_PRIORITIES;
9009 +// Define the LIST_ENTRY structure. This structure is used on the NT side to link
9010 +// the FIBs together in a linked list. Since this structure gets compiled on the adapter
9011 +// as well, we need to define this structure for the adapter's use. If '_NT_DEF_'
9012 +// is defined, then this header is being included from the NT side, and therefore LIST_ENTRY
9013 +// is already defined.
9014 +#if !defined(_NTDEF_) && !defined(_WINNT_)
9015 +typedef struct _LIST_ENTRY {
9016 + struct _LIST_ENTRY *Flink;
9017 + struct _LIST_ENTRY *Blink;
9019 +typedef LIST_ENTRY *PLIST_ENTRY;
9024 +// Define the FIB. The FIB is the where all the requested data and
9025 +// command information are put to the application on the FSA adapter.
9028 +typedef struct _FIB_HEADER {
9029 + AAC_UINT32 XferState; // Current transfer state for this CCB
9030 + AAC_UINT16 Command; // Routing information for the destination
9031 + AAC_UINT8 StructType; // Type FIB
9032 + AAC_UINT8 Flags; // Flags for FIB
9033 + AAC_UINT16 Size; // Size of this FIB in bytes
9034 + AAC_UINT16 SenderSize; // Size of the FIB in the sender (for response sizing)
9035 + AAC_UINT32 SenderFibAddress; // Host defined data in the FIB
9036 + AAC_UINT32 ReceiverFibAddress; // Logical address of this FIB for the adapter
9037 + AAC_UINT32 SenderData; // Place holder for the sender to store data
9041 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9042 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9044 + LIST_ENTRY _FibLinks; // Used to link Adapter Initiated Fibs on the host
9046 +#else // The MIDL compiler does not support unions without a discriminant.
9047 + struct { // Since nothing during the midl compile actually looks into this
9048 + struct { // structure, this shoudl be ok.
9049 + AAC_UINT32 _ReceiverTimeStart; // Timestamp for receipt of fib
9050 + AAC_UINT32 _ReceiverTimeDone; // Timestamp for completion of fib
9057 +#define FibLinks _u._FibLinks
9060 +#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(FIB_HEADER))
9063 +typedef struct _FIB {
9065 +#ifdef BRIDGE //rma
9068 + FIB_HEADER Header;
9070 + AAC_UINT8 data[FIB_DATA_SIZE_IN_BYTES]; // Command specific data
9081 +typedef enum _FIB_COMMANDS {
9082 + TestCommandResponse = 1,
9083 + TestAdapterCommand = 2,
9085 + // Lowlevel and comm commands
9087 + LastTestCommand = 100,
9088 + ReinitHostNormCommandQueue = 101,
9089 + ReinitHostHighCommandQueue = 102,
9090 + ReinitHostHighRespQueue = 103,
9091 + ReinitHostNormRespQueue = 104,
9092 + ReinitAdapNormCommandQueue = 105,
9093 + ReinitAdapHighCommandQueue = 107,
9094 + ReinitAdapHighRespQueue = 108,
9095 + ReinitAdapNormRespQueue = 109,
9096 + InterfaceShutdown = 110,
9097 + DmaCommandFib = 120,
9098 + StartProfile = 121,
9099 + TermProfile = 122,
9101 + TakeABreakPt = 124,
9102 + RequestPerfData = 125,
9103 + SetInterruptDefTimer= 126,
9104 + SetInterruptDefCount= 127,
9105 + GetInterruptDefStatus= 128,
9106 + LastCommCommand = 129,
9108 + // Filesystem commands
9110 + NuFileSystem = 300,
9112 + HostFileSystem = 302,
9113 + LastFileSystemCommand = 303,
9115 + // Container Commands
9117 + ContainerCommand = 500,
9118 + ContainerCommand64 = 501,
9120 + // Cluster Commands
9122 + ClusterCommand = 550,
9124 + // Scsi Port commands (scsi passthrough)
9126 + ScsiPortCommand = 600,
9128 + // misc house keeping and generic adapter initiated commands
9131 + CheckRevision = 701,
9132 + FsaHostShutdown = 702,
9133 + RequestAdapterInfo = 703,
9134 + IsAdapterPaused = 704,
9135 + SendHostTime = 705,
9136 + LastMiscCommand = 706
9142 +typedef AAC_UINT16 FIB_COMMAND;
9145 +// Commands that will target the failover level on the FSA adapter
9148 +typedef enum _FIB_XFER_STATE {
9149 + HostOwned = (1<<0),
9150 + AdapterOwned = (1<<1),
9151 + FibInitialized = (1<<2),
9152 + FibEmpty = (1<<3),
9153 + AllocatedFromPool = (1<<4),
9154 + SentFromHost = (1<<5),
9155 + SentFromAdapter = (1<<6),
9156 + ResponseExpected = (1<<7),
9157 + NoResponseExpected = (1<<8),
9158 + AdapterProcessed = (1<<9),
9159 + HostProcessed = (1<<10),
9160 + HighPriority = (1<<11),
9161 + NormalPriority = (1<<12),
9163 + AsyncIo = (1<<13), // rpbfix: remove with new regime
9164 + PageFileIo = (1<<14), // rpbfix: remove with new regime
9165 + ShutdownRequest = (1<<15),
9166 + LazyWrite = (1<<16), // rpbfix: remove with new regime
9167 + AdapterMicroFib = (1<<17),
9168 + BIOSFibPath = (1<<18),
9169 + FastResponseCapable = (1<<19),
9170 + ApiFib = (1<<20) // Its an API Fib.
9172 +} _E_FIB_XFER_STATE;
9175 +typedef enum _FSA_ERRORS {
9178 + FSA_PENDING = 0x01,
9180 + FSA_INVALID_QUEUE = 0x03,
9181 + FSA_NOENTRIES = 0x04,
9182 + FSA_SENDFAILED = 0x05,
9183 + FSA_INVALID_QUEUE_PRIORITY = 0x06,
9184 + FSA_FIB_ALLOCATION_FAILED = 0x07,
9185 + FSA_FIB_DEALLOCATION_FAILED = 0x08
9191 +// The following defines needs to be updated any time there is an incompatible change made
9192 +// to the ADAPTER_INIT_STRUCT structure.
9194 +#define ADAPTER_INIT_STRUCT_REVISION 3
9196 +typedef struct _ADAPTER_INIT_STRUCT {
9197 + AAC_UINT32 InitStructRevision;
9198 + AAC_UINT32 MiniPortRevision;
9199 + AAC_UINT32 FilesystemRevision;
9200 + PAAC_VOID CommHeaderAddress;
9201 + PAAC_VOID FastIoCommAreaAddress;
9202 + PAAC_VOID AdapterFibsPhysicalAddress;
9203 + PAAC_VOID AdapterFibsVirtualAddress;
9204 + AAC_UINT32 AdapterFibsSize;
9205 + AAC_UINT32 AdapterFibAlign;
9206 + PAAC_VOID PrintfBufferAddress;
9207 + AAC_UINT32 PrintfBufferSize;
9208 + AAC_UINT32 HostPhysMemPages; // number of 4k pages of host physical memory
9209 + AAC_UINT32 HostElapsedSeconds; // number of seconds since 1970.
9210 +} ADAPTER_INIT_STRUCT;
9211 +typedef ADAPTER_INIT_STRUCT *PADAPTER_INIT_STRUCT;
9213 +#ifdef AAC_32BIT_ENUMS
9214 +typedef _E_FSA_ERRORS FSA_ERRORS;
9216 +typedef AAC_UINT32 FSA_ERRORS;
9219 +typedef enum _LOG_LEVEL {
9221 + LOG_INFORMATIONAL = 20,
9223 + LOG_LOW_ERROR = 40,
9224 + LOG_MEDIUM_ERROR = 50,
9225 + LOG_HIGH_ERROR = 60,
9228 + LOG_WINDBG_PRINT = 90
9231 +#ifdef AAC_32BIT_ENUMS
9232 +typedef _E_LOG_LEVEL LOG_LEVEL;
9234 +typedef AAC_UINT32 LOG_LEVEL;
9238 +#endif //_COMM_STRUCT
9241 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/comsup.h linux/drivers/scsi/aacraid/include/comsup.h
9242 --- linux-2.4.7/drivers/scsi/aacraid/include/comsup.h Wed Dec 31 18:00:00 1969
9243 +++ linux/drivers/scsi/aacraid/include/comsup.h Sat Jul 21 17:55:13 2001
9246 + * Adaptec aacraid device driver for Linux.
9248 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9250 + * This program is free software; you can redistribute it and/or modify
9251 + * it under the terms of the GNU General Public License as published by
9252 + * the Free Software Foundation; either version 2, or (at your option)
9253 + * any later version.
9255 + * This program is distributed in the hope that it will be useful,
9256 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9257 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9258 + * GNU General Public License for more details.
9260 + * You should have received a copy of the GNU General Public License
9261 + * along with this program; see the file COPYING. If not, write to
9262 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9267 + * Abstract: This module defines the data structures that make up the
9268 + * commuication region for the FSA filesystem. This region is
9269 + * how the host based code commuicates both control and data
9270 + * to the adapter based code.
9275 +#ifndef _COMM_SUP_DEF
9276 +#define _COMM_SUP_DEF
9278 +static char *ident_comsup = "aacraid_ident comsup.h 1.0.6 2000/10/09 Adaptec, Inc.";
9281 +// The adapter interface specs all queues to be located in the same physically
9282 +// contigous block. The host structure that defines the commuication queues will
9283 +// assume they are each a seperate physically contigous memory region that will
9284 +// support them all being one big contigous block.
9285 +// There is a command and response queue for each level and direction of
9286 +// commuication. These regions are accessed by both the host and adapter.
9288 +typedef struct _COMM_QUE {
9290 + PHYSICAL_ADDRESS LogicalAddress; // This is the address we give the adapter
9292 + PQUEUE_ENTRY BaseAddress; // This is the system virtual address
9293 + QUEUE_HEADERS Headers; // A pointer to the producer and consumer queue headers for this queue
9294 + ULONG QueueEntries; // Number of queue entries on this queue
9295 + OS_CV_T QueueFull; // Event to wait on if the queue is full
9296 + OS_CV_T CommandReady; // Indicates there is a Command ready from the adapter on this queue.
9297 + // This is only valid for adapter to host command queues.
9298 + OS_SPINLOCK *QueueLock; // Spinlock for this queue must take this lock before accessing the lock
9299 + KIRQL SavedIrql; // Previous IRQL when the spin lock is taken
9300 + ddi_softintr_t ConsumerRoutine; // The DPC routine which will consume entries off this queue
9301 + // Only queues which the host will be the consumer will this field be valid
9302 + LIST_ENTRY CommandQueue; // A queue of FIBs which need to be prcessed by the FS thread. This is
9303 + // only valid for command queues which receive entries from the adapter.
9304 + LIST_ENTRY OutstandingIoQueue; // A queue of outstanding fib's to the adapter.
9305 + ULONG NumOutstandingIos; // Number of entries on outstanding queue.
9307 + PVOID Adapter; // Back pointer to adapter structure
9310 +typedef COMM_QUE *PCOMM_QUE;
9313 +typedef struct _COMM_REGION {
9315 + COMM_QUE HostNormCmdQue; // Command queue for normal priority commands from the host
9316 + COMM_QUE HostNormRespQue; // A response for normal priority adapter responses
9318 + COMM_QUE HostHighCmdQue; // Command queue for high priority commands from the host
9319 + COMM_QUE HostHighRespQue; // A response for normal priority adapter responses
9321 + COMM_QUE AdapNormCmdQue; // Command queue for normal priority command from the adapter
9322 + COMM_QUE AdapNormRespQue; // A response for normal priority host responses
9324 + COMM_QUE AdapHighCmdQue; // Command queue for high priority command from the adapter
9325 + COMM_QUE AdapHighRespQue; // A response for high priority host responses
9328 + // The 2 threads below are the threads which handle command traffic from the
9329 + // the adapter. There is one for normal priority and one for high priority queues.
9330 + // These threads will wait on the commandready event for it's queue.
9333 + HANDLE NormCommandThread;
9334 + HANDLE HighCommandThread;
9337 + // This dpc routine will handle the setting the of not full event when the adapter
9338 + // lets us know the queue is not longer full via interrupt
9341 + KDPC QueueNotFullDpc;
9343 +#ifdef API_THROTTLE
9345 + // Support for data I/O throttling to improve CLI performance
9346 + // while the system is under load.
9347 + // This is the throttling mechanism built into the COMM layer.
9348 + // Look in commsup.c, dpcsup.c and comminit.c for use.
9351 + int ThrottleLimit; // Max queue depth of data ops allowed during throttle
9352 + int ThrottleOutstandingFibs; // Number of data FIBs outstanding to adapter
9353 + LARGE_INTEGER ThrottleTimeout; // Duration of a a throttle period
9354 + LARGE_INTEGER ThrottleWaitTimeout; // Timeout for a suspended threads to wait
9355 + BOOLEAN ThrottleActive; // Is there a current throttle active period ?
9356 + KTIMER ThrottleTimer; // Throttle timer to end a throttle period.
9357 + KDPC ThrottleDpc; // Throttle timer timeout DPC routine.
9358 + KSEMAPHORE ThrottleReleaseSema; // Semaphore callers of SendFib wait on during a throttle.
9360 + unsigned int ThrottleExceptionsCount; // Number of times throttle exception handler executed (0!)
9361 + unsigned int ThrottleTimerFires; // Debug info - #times throttle timer Dpc has fired
9362 + unsigned int ThrottleTimerSets; // Debug info - #times throttle timer was set
9364 + unsigned int ThrottledFibs;
9365 + unsigned int ThrottleTimedoutFibs;
9366 + unsigned int ApiFibs;
9367 + unsigned int NonPassiveFibs;
9368 + unsigned int TotalFibs;
9369 + unsigned int FSInfoFibs;
9371 +#endif // #ifdef API_THROTTLE
9374 +typedef COMM_REGION *PCOMM_REGION;
9376 +#endif // _COMM_SUP
9377 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsact.h linux/drivers/scsi/aacraid/include/fsact.h
9378 --- linux-2.4.7/drivers/scsi/aacraid/include/fsact.h Wed Dec 31 18:00:00 1969
9379 +++ linux/drivers/scsi/aacraid/include/fsact.h Sat Jul 21 17:55:13 2001
9382 + * Adaptec aacraid device driver for Linux.
9384 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9386 + * This program is free software; you can redistribute it and/or modify
9387 + * it under the terms of the GNU General Public License as published by
9388 + * the Free Software Foundation; either version 2, or (at your option)
9389 + * any later version.
9391 + * This program is distributed in the hope that it will be useful,
9392 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9393 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9394 + * GNU General Public License for more details.
9396 + * You should have received a copy of the GNU General Public License
9397 + * along with this program; see the file COPYING. If not, write to
9398 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9403 + * Abstract: Common container structures that are required to be
9404 + * known on both the host and adapter.
9411 +static char *ident_fsact = "aacraid_ident fsact.h 1.0.6 2000/10/09 Adaptec, Inc.";
9413 +//#include <comstruc.h>
9414 +//#include <fsatypes.h>
9415 +#include <protocol.h> // definitions for FSASTATUS
9419 + * Object-Server / Volume-Manager Dispatch Classes
9421 +typedef enum _VM_COMMANDS {
9424 + VM_ContainerConfig,
9426 + VM_FilesystemIoctl,
9428 + VM_CtBlockRead, // see protocol.h for BlockRead command layout
9429 + VM_CtBlockWrite, // see protocol.h for BlockWrite command layout
9430 + VM_SliceBlockRead, // raw access to configured "storage objects"
9431 + VM_SliceBlockWrite,
9432 + VM_DriveBlockRead, // raw access to physical devices
9433 + VM_DriveBlockWrite,
9434 + VM_EnclosureMgt, // enclosure management
9435 + VM_Unused, // used to be diskset management
9436 + VM_CtBlockVerify, // see protocol.h for BlockVerify command layout
9437 + VM_CtPerf, // performance test
9438 + VM_CtBlockRead64, // see protocol.h for BlockRead64 command layout
9439 + VM_CtBlockWrite64, // see protocol.h for BlockWrite64 command layout
9440 + VM_CtBlockVerify64, // see protocol.h for BlockVerify64 command layout
9441 + MAX_VMCOMMAND_NUM // used for sizing stats array - leave last
9444 +#ifdef AAC_32BIT_ENUMS
9445 +typedef _E_VMCOMMAND VMCOMMAND;
9447 +typedef AAC_UINT32 VMCOMMAND;
9453 +// Descriptive information (eg, vital stats)
9454 +// that a content manager might report. The
9455 +// FileArray filesystem component is one example
9456 +// of a content manager. Raw mode might be
9460 +struct FileSysInfo {
9462 + a) DOS usage - THINK ABOUT WHERE THIS MIGHT GO -- THXXX
9463 + b) FSA usage (implemented by ObjType and ContentState fields)
9466 + e) Max file system extension size - (fsMaxExtendSize * fsSpaceUnits)
9467 + f) I-node density - (computed from other fields)
9469 + AAC_UINT32 fsTotalSize; // consumed by fs, incl. metadata
9470 + AAC_UINT32 fsBlockSize;
9471 + AAC_UINT32 fsFragSize;
9472 + AAC_UINT32 fsMaxExtendSize;
9473 + AAC_UINT32 fsSpaceUnits;
9474 + AAC_UINT32 fsMaxNumFiles;
9475 + AAC_UINT32 fsNumFreeFiles;
9476 + AAC_UINT32 fsInodeDensity;
9477 +}; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9479 +union ContentManagerInfo {
9480 + struct FileSysInfo FileSys; // valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN)
9484 +// Query for "mountable" objects, ie, objects that are typically
9485 +// associated with a drive letter on the client (host) side.
9488 +typedef struct _MNTOBJ {
9490 + AAC_UINT32 ObjectId;
9491 + FSASTRING FileSystemName; // if applicable
9492 + ContainerCreationInfo CreateInfo; // if applicable
9493 + AAC_UINT32 Capacity;
9494 + FSAVOLTYPE VolType; // substrate structure
9495 + FTYPE ObjType; // FT_FILESYS, FT_DATABASE, etc.
9496 + AAC_UINT32 ContentState; // unready for mounting, readonly, etc.
9498 + union ContentManagerInfo
9499 + ObjExtension; // Info specific to content manager (eg, filesystem)
9501 + AAC_UINT32 AlterEgoId; // != ObjectId <==> snapshot or broken mirror exists
9506 +#define FSCS_READONLY 0x0002 // possible result of broken mirror
9510 +typedef struct _MNTINFO {
9512 + VMCOMMAND Command;
9514 + AAC_UINT32 MntCount;
9517 +typedef MNTINFO *PMNTINFO;
9519 +typedef struct _MNTINFORESPONSE {
9522 + FTYPE MntType; // should be same as that requested
9523 + AAC_UINT32 MntRespCount;
9524 + MNTOBJ MntTable[1];
9527 +typedef MNTINFORESPONSE *PMNTINFORESPONSE;
9531 +// The following command is sent to shut down each container.
9534 +typedef struct _CLOSECOMMAND {
9536 + VMCOMMAND Command;
9537 + AAC_UINT32 ContainerId;
9540 +typedef CLOSECOMMAND *PCLOSECOMMAND;
9543 +#endif /* _FSACT_H_ */
9546 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsafs.h linux/drivers/scsi/aacraid/include/fsafs.h
9547 --- linux-2.4.7/drivers/scsi/aacraid/include/fsafs.h Wed Dec 31 18:00:00 1969
9548 +++ linux/drivers/scsi/aacraid/include/fsafs.h Sat Jul 21 17:55:13 2001
9551 + * Adaptec aacraid device driver for Linux.
9553 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9555 + * This program is free software; you can redistribute it and/or modify
9556 + * it under the terms of the GNU General Public License as published by
9557 + * the Free Software Foundation; either version 2, or (at your option)
9558 + * any later version.
9560 + * This program is distributed in the hope that it will be useful,
9561 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9562 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9563 + * GNU General Public License for more details.
9565 + * You should have received a copy of the GNU General Public License
9566 + * along with this program; see the file COPYING. If not, write to
9567 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9572 + * Abstract: Common file system structures that are required to be
9573 + * known on both the host and adapter
9580 +#define _FSAFS_H_ 1
9582 +static char *ident_fsafs = "aacraid_ident fsafs.h 1.0.6 2000/10/09 Adaptec, Inc.";
9584 +#include <fsatypes.h> // core types, shared by client and server, eg, u_long
9587 + * Maximum number of filesystems.
9589 +#define NFILESYS 24
9592 + * File identifier.
9593 + * These are unique and self validating within a filesystem
9594 + * on a single machine and can persist across reboots.
9595 + * The hint field may be volatile and is not guaranteed to persist
9596 + * across reboots but is used to speed up the FID to file object translation
9597 + * if possible. The opaque f1 and f2 fields are guaranteed to uniquely identify
9598 + * the file object (assuming a filesystem context, i.e. driveno).
9601 + AAC_UINT32 hint; // last used hint for fast reclaim
9602 + AAC_UINT32 f1; // opaque
9603 + AAC_UINT32 f2; // opaque
9604 + } fileid_t; /* intra-filesystem file ID type */
9608 + * Generic file handle
9611 + fsid_t fh_fsid; /* File system id of mount point */
9612 + fileid_t fh_fid; /* File sys specific file id */
9614 +typedef struct fhandle fhandle_t;
9616 +#define FIDSIZE sizeof(fhandle_t)
9620 + AAC_INT8 fid_data[FIDSIZE];
9621 + struct fhandle fsafid;
9623 +} FSAFID; /* FSA File ID type */
9626 +#endif /* _FSAFS_H_ */
9628 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsaioctl.h linux/drivers/scsi/aacraid/include/fsaioctl.h
9629 --- linux-2.4.7/drivers/scsi/aacraid/include/fsaioctl.h Wed Dec 31 18:00:00 1969
9630 +++ linux/drivers/scsi/aacraid/include/fsaioctl.h Sat Jul 21 17:55:13 2001
9633 + * Adaptec aacraid device driver for Linux.
9635 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9637 + * This program is free software; you can redistribute it and/or modify
9638 + * it under the terms of the GNU General Public License as published by
9639 + * the Free Software Foundation; either version 2, or (at your option)
9640 + * any later version.
9642 + * This program is distributed in the hope that it will be useful,
9643 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9644 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9645 + * GNU General Public License for more details.
9647 + * You should have received a copy of the GNU General Public License
9648 + * along with this program; see the file COPYING. If not, write to
9649 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9654 + * Abstract: Defines the interface structures between user mode applications
9655 + * and the fsa driver. This structures are used in
9656 + * DeviceIoControl() calls.
9661 +#ifndef _FSAIOCTL_H_
9662 +#define _FSAIOCTL_H_
9664 +static char *ident_fsaioctl = "aacraid_ident fsaioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
9666 +#ifndef IOTRACEUSER
9671 +#define FILE_DEVICE_CONTROLLER 0x00000004
9674 +// Macro definition for defining IOCTL and FSCTL function control codes. Note
9675 +// that function codes 0-2047 are reserved for Microsoft Corporation, and
9676 +// 2048-4095 are reserved for customers.
9679 +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
9680 + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
9684 +// Define the method codes for how buffers are passed for I/O and FS controls
9687 +#define METHOD_BUFFERED 0
9690 +#define METHOD_NEITHER 3
9693 +// Define the access check value for any access
9696 +// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in
9697 +// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these
9698 +// constants *MUST* always be in sync.
9700 +#define FILE_ANY_ACCESS 0
9708 +typedef struct _UNIX_QUERY_DISK {
9709 + AAC_INT32 ContainerNumber;
9713 + AAC_BOOLEAN Valid;
9714 + AAC_BOOLEAN Locked;
9715 + AAC_BOOLEAN Deleted;
9716 + AAC_INT32 Instance;
9717 + AAC_INT8 diskDeviceName[10];
9718 + AAC_BOOLEAN UnMapped;
9720 +typedef UNIX_QUERY_DISK *PUNIX_QUERY_DISK;
9723 +typedef struct _DELETE_DISK {
9724 + AAC_UINT32 NtDiskNumber;
9725 + AAC_UINT32 ContainerNumber;
9727 +typedef DELETE_DISK *PDELETE_DISK;
9730 +#endif /*IOTRACEUSER*/
9732 +#define FSACTL_NULL_IO_TEST 0x43 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
9733 +#define FSACTL_SIM_IO_TEST 0x53 // CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
9736 +#define FSACTL_SENDFIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
9739 +#define FSACTL_GET_VAR 0x93
9740 +#define FSACTL_SET_VAR 0xa3
9741 +#define FSACTL_GET_FIBTIMES 0xb3
9742 +#define FSACTL_ZERO_FIBTIMES 0xc3
9745 +#define FSACTL_DELETE_DISK 0x163
9746 +#define FSACTL_QUERY_DISK 0x173
9749 +// AfaComm perfmon ioctls
9750 +#define FSACTL_GET_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, METHOD_BUFFERED, FILE_ANY_ACCESS)
9753 +#define FSACTL_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, 2085, METHOD_BUFFERED, FILE_ANY_ACCESS)
9756 +typedef struct _GET_ADAPTER_FIB_IOCTL {
9757 + char *AdapterFibContext;
9760 +} GET_ADAPTER_FIB_IOCTL, *PGET_ADAPTER_FIB_IOCTL;
9763 +// filesystem ioctls
9765 +#define FSACTL_OPEN_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2100, METHOD_BUFFERED, FILE_ANY_ACCESS)
9767 +#define FSACTL_GET_NEXT_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2101, METHOD_BUFFERED, FILE_ANY_ACCESS)
9769 +#define FSACTL_CLOSE_GET_ADAPTER_FIB CTL_CODE(FILE_DEVICE_CONTROLLER, 2102, METHOD_BUFFERED, FILE_ANY_ACCESS)
9771 +#define FSACTL_OPEN_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2103, METHOD_NEITHER, FILE_ANY_ACCESS)
9773 +#define FSACTL_CLOSE_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2104, METHOD_NEITHER, FILE_ANY_ACCESS)
9776 +#define FSACTL_MINIPORT_REV_CHECK CTL_CODE(FILE_DEVICE_CONTROLLER, 2107, METHOD_BUFFERED, FILE_ANY_ACCESS)
9779 +#define FSACTL_QUERY_ADAPTER_CONFIG CTL_CODE(FILE_DEVICE_CONTROLLER, 2113, METHOD_BUFFERED, FILE_ANY_ACCESS)
9782 +#define FSACTL_FORCE_DELETE_DISK CTL_CODE(FILE_DEVICE_CONTROLLER, 2120, METHOD_NEITHER, FILE_ANY_ACCESS)
9785 +#define FSACTL_AIF_THREAD CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, METHOD_NEITHER, FILE_ANY_ACCESS)
9788 +#endif // _FSAIOCTL_H_
9791 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsaport.h linux/drivers/scsi/aacraid/include/fsaport.h
9792 --- linux-2.4.7/drivers/scsi/aacraid/include/fsaport.h Wed Dec 31 18:00:00 1969
9793 +++ linux/drivers/scsi/aacraid/include/fsaport.h Sat Jul 21 17:55:13 2001
9796 + * Adaptec aacraid device driver for Linux.
9798 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9800 + * This program is free software; you can redistribute it and/or modify
9801 + * it under the terms of the GNU General Public License as published by
9802 + * the Free Software Foundation; either version 2, or (at your option)
9803 + * any later version.
9805 + * This program is distributed in the hope that it will be useful,
9806 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9807 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9808 + * GNU General Public License for more details.
9810 + * You should have received a copy of the GNU General Public License
9811 + * along with this program; see the file COPYING. If not, write to
9812 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
9817 + * Abstract: This module defines all of the globally used procedures in the FSA
9826 +static char *ident_fsaport = "aacraid_ident fsaport.h 1.0.6 2000/10/09 Adaptec, Inc.";
9829 +// The scatter/gather map context is the information we
9830 +// we need to keep the map and transfer data to and from the
9834 +typedef struct _SGMAP_CONTEXT {
9836 + caddr_t BaseAddress;
9838 + ULONG NumberMapRegs;
9840 + ULONG ByteCount; // Used to check the Mdl length.
9841 + BOOLEAN WriteToDevice;
9847 +typedef SGMAP_CONTEXT *PSGMAP_CONTEXT;
9849 +typedef struct _MAPFIB_CONTEXT {
9852 + ULONG NumberMapRegs;
9853 + PVOID FibVirtualAddress;
9855 + PVOID FibPhysicalAddress;
9859 +typedef MAPFIB_CONTEXT *PMAPFIB_CONTEXT;
9862 +(*PFSA_ALLOCATE_ADAPTER_COMM_AREA)(
9863 + PVOID AdapterExtension,
9864 + IN OUT PVOID *BaseAddress,
9866 + IN ULONG Alignment
9870 +(*PFSA_FREE_ADAPTER_COMM_AREA)(
9871 + PVOID AdapterExtension
9875 +(*PFSA_FREE_DMA_RESOURCES)(
9876 + IN PVOID AdapterExtension,
9877 + IN PSGMAP_CONTEXT SgMapContext
9881 +(*PFSA_ALLOCATE_AND_MAP_FIB_SPACE)(
9882 + IN PVOID AdapterExtension,
9883 + IN PMAPFIB_CONTEXT MapFibContext
9887 +(*PFSA_UNMAP_AND_FREE_FIB_SPACE)(
9888 + IN PVOID AdapterExtension,
9889 + IN PMAPFIB_CONTEXT MapFibContext
9893 +(*PFSA_INTERRUPT_ADAPTER)(
9894 + IN PVOID AdapterExtension
9898 +(*PFSA_NOTIFY_ADAPTER)(
9899 + IN PVOID AdapterExtension,
9900 + IN HOST_2_ADAP_EVENT AdapterEvent
9904 +(*PFSA_RESET_DEVICE)(
9905 + PVOID AdapterExtension
9909 +(*PFSA_BUILD_SGMAP)(
9910 + IN PVOID AdapterExtension,
9911 + IN PSGMAP_CONTEXT SgMapContext
9915 +(*PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR)(
9916 + IN PVOID AdapterExtension,
9917 + IN PVOID AdapterAddress
9921 +(*PFSA_INTERRUPT_HOST)(
9923 + ADAPTER_EVENT AdapterEvent
9927 +(*PFSA_ENABLE_INTERRUPT)(
9929 + ADAPTER_EVENT AdapterEvent,
9930 + BOOLEAN AtDeviceIrq
9935 +(*PFSA_DISABLE_INTERRUPT)(
9937 + ADAPTER_EVENT AdapterEvent,
9938 + BOOLEAN AtDeviceIrq
9942 +(*PFSA_OPEN_ADAPTER) (
9947 +(*PFSA_DEVICE_CONTROL) (
9949 + IN PAFA_IOCTL_CMD IoctlCmdPtr
9953 +(*PFSA_CLOSE_ADAPTER) (
9958 +(*PFSA_SEND_SYNCH_FIB) (
9960 + IN ULONG FibPhysicalAddress
9963 +typedef struct _FSAPORT_FUNCS {
9964 + ULONG SizeOfFsaPortFuncs;
9966 + PFSA_ALLOCATE_ADAPTER_COMM_AREA AllocateAdapterCommArea;
9967 + PFSA_FREE_ADAPTER_COMM_AREA FreeAdapterCommArea;
9968 + PFSA_FREE_DMA_RESOURCES FreeDmaResources;
9969 + PFSA_ALLOCATE_AND_MAP_FIB_SPACE AllocateAndMapFibSpace;
9970 + PFSA_UNMAP_AND_FREE_FIB_SPACE UnmapAndFreeFibSpace;
9971 + PFSA_INTERRUPT_ADAPTER InterruptAdapter;
9972 + PFSA_NOTIFY_ADAPTER NotifyAdapter;
9973 + PFSA_ENABLE_INTERRUPT EnableInterrupt;
9974 + PFSA_DISABLE_INTERRUPT DisableInterrupt;
9975 + PFSA_RESET_DEVICE ResetDevice;
9976 + PFSA_BUILD_SGMAP BuildSgMap;
9977 + PFSA_ADAPTER_ADDR_TO_SYSTEM_ADDR AdapterAddressToSystemAddress;
9979 + PFSA_INTERRUPT_HOST InterruptHost;
9980 + PFSA_OPEN_ADAPTER OpenAdapter;
9981 + PFSA_DEVICE_CONTROL DeviceControl;
9982 + PFSA_CLOSE_ADAPTER CloseAdapter;
9984 + PFSA_SEND_SYNCH_FIB SendSynchFib;
9987 +typedef FSAPORT_FUNCS *PFSAPORT_FUNCS;
9990 +(*PFSA_SETVAR_CALLBACK) (
9995 +typedef struct _FSA_USER_VAR {
9998 + PFSA_SETVAR_CALLBACK SetVarCallback;
10001 +typedef FSA_USER_VAR *PFSA_USER_VAR;
10003 +typedef struct _FSA_NEW_ADAPTER {
10004 + PVOID AdapterExtension;
10005 + PFSAPORT_FUNCS AdapterFuncs;
10007 + BOOLEAN AdapterInterruptsBelowDpc;
10008 + PFSA_USER_VAR AdapterUserVars;
10009 + ULONG AdapterUserVarsSize;
10011 +} FSA_NEW_ADAPTER;
10012 +typedef FSA_NEW_ADAPTER *PFSA_NEW_ADAPTER;
10014 +#define FSAFS_GET_NEXT_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
10015 +#define FSAFS_INIT_NEW_ADAPTER CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 2049, METHOD_NEITHER, FILE_ANY_ACCESS)
10018 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/fsatypes.h linux/drivers/scsi/aacraid/include/fsatypes.h
10019 --- linux-2.4.7/drivers/scsi/aacraid/include/fsatypes.h Wed Dec 31 18:00:00 1969
10020 +++ linux/drivers/scsi/aacraid/include/fsatypes.h Sat Jul 21 17:55:13 2001
10023 + * Adaptec aacraid device driver for Linux.
10025 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10027 + * This program is free software; you can redistribute it and/or modify
10028 + * it under the terms of the GNU General Public License as published by
10029 + * the Free Software Foundation; either version 2, or (at your option)
10030 + * any later version.
10032 + * This program is distributed in the hope that it will be useful,
10033 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10034 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10035 + * GNU General Public License for more details.
10037 + * You should have received a copy of the GNU General Public License
10038 + * along with this program; see the file COPYING. If not, write to
10039 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10044 + * Abstract: Define all shared data types here, ie, those
10045 + * types shared among several components, such
10046 + * as host (driver + apps), adapter, and BIOS.
10050 +#ifndef _FSATYPES_H
10051 +#define _FSATYPES_H
10053 +static char *ident_fsatype = "aacraid_ident fsatypes.h 1.0.6 2000/10/09 Adaptec, Inc.";
10055 +typedef AAC_UINT32 AAC_BOOLEAN;
10058 +// Define a 64-bit address structure for use on
10059 +// a 32-bit processor architecture.
10064 +} AAC_UINT64S, *PAAC_UINT64S;
10069 +// Container Types
10072 + AAC_UINT32 data[2]; // RMA FIX, make this a real serial number when we
10073 + // know what it looks like. Note, BIOS sees this
10074 + // definition and it must be coded in such a way
10075 + // that it appears to be 64 bits. ints are 16 bits
10076 + // in BIOS land; fortunately, longs are 32 bits.
10082 +// ***********************
10083 +// DON'T CHANGE THE ORDER, ctdevsw use this order to map the drivers
10084 +// ***********************
10085 +// drivers for CT_NONE to CT_PASSTHRU
10087 +typedef enum _FSAVOLTYPE {
10098 + CT_RAID10, // stripe of mirror
10099 + CT_RAID00, // stripe of stripe
10100 + CT_VOLUME_OF_MIRRORS, // volume of mirror
10101 + CT_PSEUDO_RAID3, // really raid4
10103 + CT_LAST_VOLUME_TYPE
10107 +#ifdef AAC_32BIT_ENUMS
10108 +typedef _E_FSAVOLTYPE FSAVOLTYPE;
10110 +typedef AAC_UINT32 FSAVOLTYPE;
10115 +// Types of objects addressable in some fashion by the client.
10116 +// This is a superset of those objects handled just by the filesystem
10117 +// and includes "raw" objects that an administrator would use to
10118 +// configure containers and filesystems.
10120 +typedef enum _FTYPE {
10121 + FT_REG = 1, // regular file
10122 + FT_DIR, // directory
10123 + FT_BLK, // "block" device - reserved
10124 + FT_CHR, // "character special" device - reserved
10125 + FT_LNK, // symbolic link
10126 + FT_SOCK, // socket
10128 + FT_FILESYS, // ADAPTEC's "FSA"(tm) filesystem
10129 + FT_DRIVE, // physical disk - addressable in scsi by bus/target/lun
10130 + FT_SLICE, // virtual disk - raw volume - slice
10131 + FT_PARTITION, // FSA partition - carved out of a slice - building block for containers
10132 + FT_VOLUME, // Container - Volume Set
10133 + FT_STRIPE, // Container - Stripe Set
10134 + FT_MIRROR, // Container - Mirror Set
10135 + FT_RAID5, // Container - Raid 5 Set
10136 + FT_DATABASE // Storage object with "foreign" content manager
10139 +#ifdef AAC_32BIT_ENUMS
10140 +typedef _E_FTYPE FTYPE;
10142 +typedef AAC_UINT32 FTYPE;
10148 +// Host side memory scatter gather list
10149 +// Used by the adapter for read, write, and readdirplus operations
10151 +typedef PAAC_UINT8 HOSTADDRESS;
10153 +typedef struct _SGENTRY {
10154 + HOSTADDRESS SgAddress; /* 32-bit Base address. */
10155 + AAC_UINT32 SgByteCount; /* Length. */
10157 +typedef SGENTRY *PSGENTRY;
10164 +// This is the SGMAP structure for all commands that use
10165 +// 32-bit addressing.
10167 +// Note that the upper 16 bits of SgCount are used as flags.
10168 +// Only the lower 16 bits of SgCount are actually used as the
10169 +// SG element count.
10171 +typedef struct _SGMAP {
10172 + AAC_UINT32 SgCount;
10173 + SGENTRY SgEntry[1];
10175 +typedef SGMAP *PSGMAP;
10182 +// This is the SGMAP structure for 64-bit container commands.
10184 +typedef struct _SGMAP64 {
10185 + AAC_UINT8 SgCount;
10186 + AAC_UINT8 SgSectorsPerPage;
10187 + AAC_UINT16 SgByteOffset; // For the first page
10188 + AAC_UINT64S SgEntry[1]; // Must be last entry
10190 +typedef SGMAP64 *PSGMAP64;
10196 +// attempt at common time structure across host and adapter
10198 +typedef struct __TIME_T {
10200 + AAC_UINT32 tv_sec; /* seconds (maybe, depends upon host) */
10201 + AAC_UINT32 tv_usec; /* and nanoseconds (maybe, depends upon host)*/
10204 +typedef TIME_T *PTIME_T;
10207 +#define timespec __TIME_T
10208 +#define ts_sec tv_sec
10209 +#define ts_nsec tv_usec
10215 +typedef struct _ContainerCreationInfo
10218 + AAC_UINT8 ViaBuildNumber; // e.g., 588
10219 + AAC_UINT8 MicroSecond; // e.g., 588
10220 + AAC_UINT8 Via; // e.g., 1 = FSU,
10222 + AAC_UINT8 YearsSince1900; // e.g., 1997 = 97
10223 + AAC_UINT32 Date; //
10224 + // unsigned Month :4; // 1 - 12
10225 + // unsigned Day :6; // 1 - 32
10226 + // unsigned Hour :6; // 0 - 23
10227 + // unsigned Minute :6; // 0 - 60
10228 + // unsigned Second :6; // 0 - 60
10229 + SerialNumberT ViaAdapterSerialNumber; // e.g., 0x1DEADB0BFAFAF001
10230 +} ContainerCreationInfo;
10233 +#endif // _FSATYPES_H
10236 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/linit.h linux/drivers/scsi/aacraid/include/linit.h
10237 --- linux-2.4.7/drivers/scsi/aacraid/include/linit.h Wed Dec 31 18:00:00 1969
10238 +++ linux/drivers/scsi/aacraid/include/linit.h Sat Jul 21 17:55:13 2001
10241 + * Adaptec aacraid device driver for Linux.
10243 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10245 + * This program is free software; you can redistribute it and/or modify
10246 + * it under the terms of the GNU General Public License as published by
10247 + * the Free Software Foundation; either version 2, or (at your option)
10248 + * any later version.
10250 + * This program is distributed in the hope that it will be useful,
10251 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10252 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10253 + * GNU General Public License for more details.
10255 + * You should have received a copy of the GNU General Public License
10256 + * along with this program; see the file COPYING. If not, write to
10257 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10262 + * Abstract: Header file for Linux Driver for Adaptec RAID Array Controller
10265 +/*------------------------------------------------------------------------------
10266 + * I N C L U D E S
10267 + *----------------------------------------------------------------------------*/
10272 +static char *ident_linith = "aacraid_ident linit.h 1.0.6 2000/10/09 Adaptec, Inc.";
10274 +#include <linux/config.h>
10276 +/*------------------------------------------------------------------------------
10278 + *----------------------------------------------------------------------------*/
10279 +/* Define the AAC SCSI Host Template structure. */
10280 +#define AAC_HOST_TEMPLATE_ENTRY \
10281 + { name: "AAC", /* Driver Name */ \
10282 + proc_info: AAC_ProcDirectoryInfo, /* ProcFS Info Func */ \
10283 + detect: AAC_DetectHostAdapter, /* Detect Host Adapter */ \
10284 + release: AAC_ReleaseHostAdapter, /* Release Host Adapter */ \
10285 + info: AAC_DriverInfo, /* Driver Info Function */ \
10286 + ioctl: AAC_Ioctl, /* ioctl Interface */ \
10287 + command: AAC_Command, /* unqueued command */ \
10288 + queuecommand: AAC_QueueCommand, /* Queue Command Function */ \
10289 + abort: AAC_AbortCommand, /* Abort Command Function */ \
10290 + reset: AAC_ResetCommand, /* Reset Command Function */ \
10291 + bios_param: AAC_BIOSDiskParameters, /* BIOS Disk Parameters */ \
10292 + can_queue: 1, /* Default initial value */ \
10293 + this_id: 0, /* Default initial value */ \
10294 + sg_tablesize: 0, /* Default initial value */ \
10295 + max_sectors: 128, /* max xfer size of 64k */ \
10296 + cmd_per_lun: 0, /* Default initial value */ \
10297 + present: 0, /* Default initial value */ \
10298 + unchecked_isa_dma: 0, /* Default Initial Value */ \
10299 + use_new_eh_code: 0, /* Default initial value */ \
10300 + eh_abort_handler: AAC_AbortCommand, /* New Abort Command func */ \
10301 + eh_strategy_handler: NULL, /* New Strategy Error Handler */ \
10302 + eh_device_reset_handler: NULL, /* New Device Reset Handler */ \
10303 + eh_bus_reset_handler: NULL, /* New Bus Reset Handler */ \
10304 + eh_host_reset_handler: NULL, /* New Host reset Handler */ \
10305 + use_clustering: ENABLE_CLUSTERING /* Disable Clustering */ \
10309 +/*------------------------------------------------------------------------------
10310 + * T Y P E D E F S / S T R U C T S
10311 + *----------------------------------------------------------------------------*/
10312 +typedef struct AAC_BIOS_DiskParameters
10317 +} AAC_BIOS_DiskParameters_T;
10320 +/*------------------------------------------------------------------------------
10321 + * P R O G R A M G L O B A L S
10322 + *----------------------------------------------------------------------------*/
10324 +const char *AAC_DriverInfo( struct Scsi_Host * );
10327 +/*------------------------------------------------------------------------------
10328 + * F U N C T I O N P R O T O T Y P E S
10329 + *----------------------------------------------------------------------------*/
10330 +/* Define prototypes for the AAC Driver Interface Functions. */
10331 +int AAC_DetectHostAdapter( Scsi_Host_Template * );
10332 +int AAC_ReleaseHostAdapter( struct Scsi_Host * );
10333 +int AAC_QueueCommand( Scsi_Cmnd *, void ( *CompletionRoutine )( Scsi_Cmnd * ) );
10334 +int AAC_Command( Scsi_Cmnd * );
10335 +int AAC_ResetCommand( Scsi_Cmnd *, unsigned int );
10336 +int AAC_BIOSDiskParameters( Disk *, kdev_t, int * );
10337 +int AAC_ProcDirectoryInfo( char *, char **, off_t, int, int, int );
10338 +int AAC_Ioctl( Scsi_Device *, int, void * );
10341 +void AAC_SelectQueueDepths( struct Scsi_Host *, Scsi_Device * );
10344 +int AAC_AbortCommand( Scsi_Cmnd *scsi_cmnd_ptr );
10346 +#endif /* _LINIT_H_ */
10347 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/monkerapi.h linux/drivers/scsi/aacraid/include/monkerapi.h
10348 --- linux-2.4.7/drivers/scsi/aacraid/include/monkerapi.h Wed Dec 31 18:00:00 1969
10349 +++ linux/drivers/scsi/aacraid/include/monkerapi.h Sat Jul 21 17:55:13 2001
10352 + * Adaptec aacraid device driver for Linux.
10354 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10356 + * This program is free software; you can redistribute it and/or modify
10357 + * it under the terms of the GNU General Public License as published by
10358 + * the Free Software Foundation; either version 2, or (at your option)
10359 + * any later version.
10361 + * This program is distributed in the hope that it will be useful,
10362 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10363 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10364 + * GNU General Public License for more details.
10366 + * You should have received a copy of the GNU General Public License
10367 + * along with this program; see the file COPYING. If not, write to
10368 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10373 + * Abstract: This module contains the definitions used by the Host Adapter
10374 + * Communications interface.
10375 + * This is the interface used for by host programs and the Adapter
10376 + * to communicate via synchronous commands via a shared set of registers
10377 + * on a platform (typically doorbells and mailboxes).
10380 +//**********************************************************************
10382 +// Monitor / Kernel API
10384 +// 03/24/1998 Bob Peret Initial creation
10386 +//**********************************************************************
10391 +static char *ident_monk = "aacraid_ident monkerapi.h 1.0.6 2000/10/09 Adaptec, Inc.";
10393 +#define BREAKPOINT_REQUEST 0x00000004
10394 +#define INIT_STRUCT_BASE_ADDRESS 0x00000005
10397 +#define SEND_SYNCHRONOUS_FIB 0x0000000c
10402 +// Adapter Status Register
10404 +// Phase Staus mailbox is 32bits:
10405 +// <31:16> = Phase Status
10408 +// The adapter reports is present state through the phase. Only
10409 +// a single phase should be ever be set. Each phase can have multiple
10410 +// phase status bits to provide more detailed information about the
10411 +// state of the board. Care should be taken to ensure that any phase status
10412 +// bits that are set when changing the phase are also valid for the new phase
10413 +// or be cleared out. Adapter software (monitor, iflash, kernel) is responsible
10414 +// for properly maintining the phase status mailbox when it is running.
10417 +// MONKER_API Phases
10419 +// Phases are bit oriented. It is NOT valid
10420 +// to have multiple bits set
10424 +#define SELF_TEST_FAILED 0x00000004
10427 +#define KERNEL_UP_AND_RUNNING 0x00000080
10428 +#define KERNEL_PANIC 0x00000100
10433 +// Doorbell bit defines
10437 +#define DoorBellPrintfDone (1<<5) // Host -> Adapter
10440 +#define DoorBellAdapterNormCmdReady (1<<1) // Adapter -> Host
10441 +#define DoorBellAdapterNormRespReady (1<<2) // Adapter -> Host
10442 +#define DoorBellAdapterNormCmdNotFull (1<<3) // Adapter -> Host
10443 +#define DoorBellAdapterNormRespNotFull (1<<4) // Adapter -> Host
10444 +#define DoorBellPrintfReady (1<<5) // Adapter -> Host
10447 +#endif // MONKER_H
10449 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/nodetype.h linux/drivers/scsi/aacraid/include/nodetype.h
10450 --- linux-2.4.7/drivers/scsi/aacraid/include/nodetype.h Wed Dec 31 18:00:00 1969
10451 +++ linux/drivers/scsi/aacraid/include/nodetype.h Sat Jul 21 17:55:13 2001
10454 + * Adaptec aacraid device driver for Linux.
10456 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10458 + * This program is free software; you can redistribute it and/or modify
10459 + * it under the terms of the GNU General Public License as published by
10460 + * the Free Software Foundation; either version 2, or (at your option)
10461 + * any later version.
10463 + * This program is distributed in the hope that it will be useful,
10464 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10465 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10466 + * GNU General Public License for more details.
10468 + * You should have received a copy of the GNU General Public License
10469 + * along with this program; see the file COPYING. If not, write to
10470 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10475 + * Abstract: This module defines all of the node type codes used in this development
10476 + * shell. Every major data structure in the file system is assigned a node
10477 + * type code that is. This code is the first CSHORT in the structure and is
10478 + * followed by a CSHORT containing the size, in bytes, of the structure.
10481 +#ifndef _NODETYPE_
10482 +#define _NODETYPE_
10484 +static char *ident_node = "aacraid_ident nodetype.h 1.0.6 2000/10/09 Adaptec, Inc.";
10486 +typedef CSHORT NODE_TYPE_CODE;
10489 +#define FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT ((NODE_TYPE_CODE)0x030b)
10490 +#define FSAFS_NTC_FIB_CONTEXT ((NODE_TYPE_CODE)0x030c)
10493 +typedef CSHORT NODE_BYTE_SIZE;
10497 +// The following definitions are used to generate meaningful blue bugcheck
10498 +// screens. On a bugcheck the file system can output 4 ulongs of useful
10499 +// information. The first ulong will have encoded in it a source file id
10500 +// (in the high word) and the line number of the bugcheck (in the low word).
10501 +// The other values can be whatever the caller of the bugcheck routine deems
10504 +// Each individual file that calls bugcheck needs to have defined at the
10505 +// start of the file a constant called BugCheckFileId with one of the
10506 +// FSAFS_BUG_CHECK_ values defined below and then use FsaBugCheck to bugcheck
10511 +#define FSAFS_BUG_CHECK_COMMSUP (0X001e0000)
10512 +#define FSAFS_BUG_CHECK_DPCSUP (0X001f0000)
10515 +#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); }
10518 +#endif // _NODETYPE_
10520 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/nvramioctl.h linux/drivers/scsi/aacraid/include/nvramioctl.h
10521 --- linux-2.4.7/drivers/scsi/aacraid/include/nvramioctl.h Wed Dec 31 18:00:00 1969
10522 +++ linux/drivers/scsi/aacraid/include/nvramioctl.h Sat Jul 21 17:55:13 2001
10525 + * Adaptec aacraid device driver for Linux.
10527 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10529 + * This program is free software; you can redistribute it and/or modify
10530 + * it under the terms of the GNU General Public License as published by
10531 + * the Free Software Foundation; either version 2, or (at your option)
10532 + * any later version.
10534 + * This program is distributed in the hope that it will be useful,
10535 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10536 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10537 + * GNU General Public License for more details.
10539 + * You should have received a copy of the GNU General Public License
10540 + * along with this program; see the file COPYING. If not, write to
10541 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10546 + * Abstract: This file defines the data structures related to querying
10547 + * and controlling the FSA NVRAM/WriteCache subsystem via the NVRAMIOCTL FIB.
10550 +#ifndef _NVRAMIOCTL_H_
10551 +#define _NVRAMIOCTL_H_ 1
10553 +static char *ident_nvram = "aacraid_ident nvramioctl.h 1.0.6 2000/10/09 Adaptec, Inc.";
10556 + * NVRAM/Write Cache subsystem states
10558 +typedef enum _NVSTATUS {
10559 + NVSTATUS_DISABLED = 0, // present, clean, not being used
10560 + NVSTATUS_ENABLED, // present, possibly dirty, ready for use
10561 + NVSTATUS_ERROR, // present, dirty, contains dirty data
10562 + // for bad/missing device
10563 + NVSTATUS_BATTERY, // present, bad or low battery, may contain dirty data
10564 + // for bad/missing device
10565 + NVSTATUS_UNKNOWN // present?????
10568 +#ifdef AAC_32BIT_ENUMS
10569 +typedef _E_NVSTATUS NVSTATUS;
10571 +typedef AAC_UINT32 NVSTATUS;
10575 + * NVRAM/Write Cache subsystem battery component states
10578 +//NB: this enum should be identical to battery_status in nvram.h
10579 +// or else collapsed into one enum someday
10580 +typedef enum _NVBATTSTATUS {
10581 + NVBATTSTATUS_NONE = 0, // battery has no power or is not present
10582 + NVBATTSTATUS_LOW, // battery is low on power
10583 + NVBATTSTATUS_OK, // battery is okay - normal operation possible only in this state
10584 + NVBATTSTATUS_RECONDITIONING // no battery present - reconditioning in process
10585 +} _E_NVBATTSTATUS;
10587 +#ifdef AAC_32BIT_ENUMS
10588 +typedef _E_NVBATTSTATUS NVBATTSTATUS;
10590 +typedef AAC_UINT32 NVBATTSTATUS;
10594 + * battery transition type
10596 +typedef enum _NVBATT_TRANSITION {
10597 + NVBATT_TRANSITION_NONE = 0, // battery now has no power or is not present
10598 + NVBATT_TRANSITION_LOW, // battery is now low on power
10599 + NVBATT_TRANSITION_OK // battery is now okay - normal operation possible only in this state
10600 +} _E_NVBATT_TRANSITION;
10602 +#ifdef AAC_32BIT_ENUMS
10603 +typedef _E_NVBATT_TRANSITION NVBATT_TRANSITION;
10605 +typedef AAC_UINT32 NVBATT_TRANSITION;
10609 + * NVRAM Info structure returned for NVRAM_GetInfo call
10611 +typedef struct _NVRAMDEVINFO {
10612 + AAC_UINT32 NV_Enabled; /* write caching enabled */
10613 + AAC_UINT32 NV_Error; /* device in error state */
10614 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10615 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10616 +} NVRAMDEVINFO, *PNVRAMDEVINFO;
10618 +typedef struct _NVRAMINFO {
10619 + NVSTATUS NV_Status; /* nvram subsystem status */
10620 + NVBATTSTATUS NV_BattStatus; /* battery status */
10621 + AAC_UINT32 NV_Size; /* size of WriteCache NVRAM in bytes */
10622 + AAC_UINT32 NV_BufSize; /* size of NVRAM buffers in bytes */
10623 + AAC_UINT32 NV_NBufs; /* number of NVRAM buffers */
10624 + AAC_UINT32 NV_NDirty; /* count of dirty NVRAM buffers */
10625 + AAC_UINT32 NV_NClean; /* count of clean NVRAM buffers */
10626 + AAC_UINT32 NV_NActive; /* count of NVRAM buffers being written */
10627 + AAC_UINT32 NV_NBrokered; /* count of brokered NVRAM buffers */
10628 + NVRAMDEVINFO NV_DevInfo[NFILESYS]; /* per device info */
10629 + AAC_UINT32 NV_BattNeedsReconditioning; /* boolean */
10630 + AAC_UINT32 NV_TotalSize; /* total size of all non-volatile memories in bytes */
10631 +} NVRAMINFO, *PNVRAMINFO;
10633 +#endif /* !_NVRAMIOCTL_H_ */
10636 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/osheaders.h linux/drivers/scsi/aacraid/include/osheaders.h
10637 --- linux-2.4.7/drivers/scsi/aacraid/include/osheaders.h Wed Dec 31 18:00:00 1969
10638 +++ linux/drivers/scsi/aacraid/include/osheaders.h Sat Jul 21 17:55:13 2001
10641 + * Adaptec aacraid device driver for Linux.
10643 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10645 + * This program is free software; you can redistribute it and/or modify
10646 + * it under the terms of the GNU General Public License as published by
10647 + * the Free Software Foundation; either version 2, or (at your option)
10648 + * any later version.
10650 + * This program is distributed in the hope that it will be useful,
10651 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10652 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10653 + * GNU General Public License for more details.
10655 + * You should have received a copy of the GNU General Public License
10656 + * along with this program; see the file COPYING. If not, write to
10657 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10662 + * Abstract: Holds all of the header file includes for a particular O/S flavor.
10665 +#ifndef _OSHEADERS_H_
10666 +#define _OSHEADERS_H_
10668 +static char *ident_oshead = "aacraid_ident osheaders.h 1.0.6 2000/10/09 Adaptec, Inc.";
10670 +#include <linux/autoconf.h> // retrieve the kernel configuration info
10671 +#if defined( CONFIG_MODVERSIONS ) && !defined( MODVERSIONS )
10672 +#define MODVERSIONS // force it on
10675 +#include <linux/version.h>
10677 +#if defined( MODVERSIONS ) && defined( MODULE )
10678 +#if DRIVER_KERNEL_CODE >= KERNEL_VERSION(2,2,12)
10680 +#include <linux/modversions-smp.h>
10681 +#elif defined( BOOT_DRIVER )
10682 +#include <linux/modversions-BOOT.h>
10684 +#include <linux/modversions-up.h>
10685 +#endif // ifdef CONFIG_SMP
10687 +#include <linux/modversions.h>
10692 +#include <linux/kernel.h>
10693 +#include <linux/config.h>
10694 +#include <linux/init.h>
10695 +#include <linux/types.h>
10696 +#include <linux/blk.h>
10697 +#include <linux/blkdev.h>
10698 +#include <linux/delay.h>
10699 +#include <linux/ioport.h>
10700 +#include <linux/mm.h>
10701 +#include <linux/sched.h>
10702 +#include <linux/stat.h>
10703 +#include <linux/pci.h>
10704 +#include <linux/interrupt.h>
10705 +#include <asm/dma.h>
10706 +#include <asm/io.h>
10707 +#include <linux/spinlock.h>
10708 +#include <asm/system.h>
10709 +#include <asm/bitops.h>
10710 +#include <asm/uaccess.h>
10711 +#include <linux/wait.h>
10712 +#include <linux/malloc.h>
10713 +#include <linux/tqueue.h>
10715 +#include <linux/tasks.h>
10717 +#include <ostypes.h>
10719 +#include "hosts.h"
10722 +#define intptr_t void *
10726 +#define cred_t void
10730 +#define paddr32_t unsigned
10734 +#define bzero(b,len) memset(b,0,len)
10738 +#define bcopy(src,dst,len) memcpy(dst,src,len )
10742 +#define DEVICE_NR(device) ( ( ( MAJOR( device ) & 7 ) << 4 ) + ( MINOR( device ) >> 4 ) )
10745 +typedef unsigned uint_t;
10758 +#define CMN_ERR_LEVEL CE_NOTE
10764 +// usage of READ & WRITE as a typedefs in protocol.h
10765 +// conflicts with <linux/fs.h> definition.
10774 +typedef struct aac_options
10776 + int message_level;
10777 + int reverse_scan;
10780 +#endif // _OSHEADERS_H_
10790 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/ostypes.h linux/drivers/scsi/aacraid/include/ostypes.h
10791 --- linux-2.4.7/drivers/scsi/aacraid/include/ostypes.h Wed Dec 31 18:00:00 1969
10792 +++ linux/drivers/scsi/aacraid/include/ostypes.h Sat Jul 21 17:55:13 2001
10795 + * Adaptec aacraid device driver for Linux.
10797 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10799 + * This program is free software; you can redistribute it and/or modify
10800 + * it under the terms of the GNU General Public License as published by
10801 + * the Free Software Foundation; either version 2, or (at your option)
10802 + * any later version.
10804 + * This program is distributed in the hope that it will be useful,
10805 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10806 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10807 + * GNU General Public License for more details.
10809 + * You should have received a copy of the GNU General Public License
10810 + * along with this program; see the file COPYING. If not, write to
10811 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10816 + * Abstract: Holds all of the O/S specific types.
10819 +/*------------------------------------------------------------------------------
10821 + *----------------------------------------------------------------------------*/
10822 +#ifndef _OSTYPES_H_
10823 +#define _OSTYPES_H_
10825 +static char *ident_ostypes = "aacraid_ident ostypes.h 1.0.7 2000/10/11 Adaptec, Inc.";
10827 +#include <linux/types.h>
10829 +#define MAXIMUM_NUM_CONTAINERS 64 // 4 Luns * 16 Targets
10830 +#define MAXIMUM_NUM_ADAPTERS 8
10832 +#define OS_ALLOC_MEM_SLEEP GFP_KERNEL
10834 +#define Os_remove_softintr OsSoftInterruptRemove
10835 +#define OsPrintf printk
10836 +#define FsaCommPrint
10838 +// the return values for copy_from_user & copy_to_user is the
10839 +// number of bytes not transferred. Thus if an internal error
10840 +// occurs, the return value is greater than zero.
10841 +#define COPYIN(SRC,DST,COUNT,FLAGS) copy_from_user(DST,SRC,COUNT)
10842 +#define COPYOUT(SRC,DST,COUNT,FLAGS) copy_to_user(DST,SRC,COUNT)
10844 +#define copyin(SRC,DST,COUNT) copy_from_user(DST,SRC,COUNT)
10845 +#define copyout(SRC,DST,COUNT) copy_to_user(DST,SRC,COUNT)
10847 +/*------------------------------------------------------------------------------
10848 + * S T R U C T S / T Y P E D E F S
10849 + *----------------------------------------------------------------------------*/
10850 +typedef struct OS_MUTEX
10852 + unsigned long lock_var;
10853 + wait_queue_head_t wq;
10857 +typedef struct OS_SPINLOCK
10859 + spinlock_t spin_lock;
10860 + unsigned cpu_lock_count[NR_CPUS];
10861 + unsigned long cpu_flags[NR_CPUS];
10862 + long lockout_count;
10865 +#ifdef CVLOCK_USE_SPINLOCK
10866 + typedef OS_SPINLOCK OS_CVLOCK;
10868 + typedef OS_MUTEX OS_CVLOCK;
10871 +typedef size_t OS_SIZE_T;
10873 +typedef struct OS_CV_T
10875 + unsigned long lock_var;
10876 + unsigned long type;
10877 + wait_queue_head_t wq;
10880 +struct fsa_scsi_hba {
10881 + void *CommonExtension;
10882 + unsigned long ContainerSize[MAXIMUM_NUM_CONTAINERS];
10883 + unsigned long ContainerType[MAXIMUM_NUM_CONTAINERS];
10884 + unsigned char ContainerValid[MAXIMUM_NUM_CONTAINERS];
10885 + unsigned char ContainerReadOnly[MAXIMUM_NUM_CONTAINERS];
10886 + unsigned char ContainerLocked[MAXIMUM_NUM_CONTAINERS];
10887 + unsigned char ContainerDeleted[MAXIMUM_NUM_CONTAINERS];
10888 + long ContainerDevNo[MAXIMUM_NUM_CONTAINERS];
10891 +typedef struct fsa_scsi_hba fsadev_t;
10893 +typedef struct OsKI
10895 + struct Scsi_Host *scsi_host_ptr;
10896 + void * dip; // #REVISIT#
10897 + fsadev_t fsa_dev;
10899 + int MiniPortIndex;
10902 +#define dev_info_t fsadev_t
10904 +typedef int OS_SPINLOCK_COOKIE;
10906 +typedef unsigned int OS_STATUS;
10908 +typedef struct tq_struct OS_SOFTINTR;
10910 +typedef OS_SOFTINTR *ddi_softintr_t;
10914 +//-----------------------------------------------------------------------------
10915 +// Conditional variable functions
10918 + OS_CV_T *cv_ptr );
10921 +//-----------------------------------------------------------------------------
10922 +// Printing functions
10923 +void printk_err(int flag, char *fmt, ...);
10925 +#define cmn_err printk_err
10929 +// just ignore these solaris ddi functions in the code
10931 +#define DDI_SUCCESS 0
10933 +#define ddi_add_softintr(A,B,C,D,E,F,G) OsSoftInterruptAdd(C,F,G)
10936 +#define ddi_remove_softintr(A) 0
10937 +#define ddi_get_soft_iblock_cookie(A, B, C) 0
10939 +#define ASSERT(expr) ((void) 0)
10940 +#define drv_usecwait udelay
10942 +#endif // _OSTYPES_H_
10943 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/pcisup.h linux/drivers/scsi/aacraid/include/pcisup.h
10944 --- linux-2.4.7/drivers/scsi/aacraid/include/pcisup.h Wed Dec 31 18:00:00 1969
10945 +++ linux/drivers/scsi/aacraid/include/pcisup.h Sat Jul 21 17:55:13 2001
10948 + * Adaptec aacraid device driver for Linux.
10950 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10952 + * This program is free software; you can redistribute it and/or modify
10953 + * it under the terms of the GNU General Public License as published by
10954 + * the Free Software Foundation; either version 2, or (at your option)
10955 + * any later version.
10957 + * This program is distributed in the hope that it will be useful,
10958 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10959 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10960 + * GNU General Public License for more details.
10962 + * You should have received a copy of the GNU General Public License
10963 + * along with this program; see the file COPYING. If not, write to
10964 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
10969 + * Abstract: This module defines functions that are defined in PciSup.c
10975 +static char *ident_pcisup = "aacraid_ident pcisup.h 1.0.6 2000/10/09 Adaptec, Inc.";
10979 + * define which interrupt handler needs to be installed
10985 +typedef struct _PCI_MINIPORT_COMMON_EXTENSION {
10986 + ULONG AdapterNumber; // Which FSA# this miniport is
10988 + ULONG PciBusNumber; // Which PCI bus we are located on
10989 + ULONG PciSlotNumber; // Whiat PCI slot we are in
10991 + PVOID Adapter; // Back pointer to Fsa adapter object
10992 + ULONG AdapterIndex; // Index into PlxAdapterTypes array
10993 + PDEVICE_OBJECT DeviceObject; // Pointer to our device object
10995 + FSAPORT_FUNCS AdapterFuncs;
10996 + ULONG FilesystemRevision; // Main driver's revision number
10999 + PADAPTER_INIT_STRUCT InitStruct; // Holds initialization info to communicate with adapter
11000 + PVOID PhysicalInitStruct; // Holds physical address of the init struct
11003 + PVOID PrintfBufferAddress; // pointer to buffer used for printf's from the adapter
11005 + BOOLEAN AdapterPrintfsToScreen;
11006 + BOOLEAN AdapterConfigured; // set to true when we know adapter can take FIBs
11010 + caddr_t CommAddress; // Base address of Comm area
11011 + paddr32_t CommPhysAddr; // Physical Address of Comm area
11014 + OsKI_t OsDep; // OS dependent kernel interfaces
11017 +} PCI_MINIPORT_COMMON_EXTENSION;
11019 +typedef PCI_MINIPORT_COMMON_EXTENSION *PPCI_MINIPORT_COMMON_EXTENSION;
11022 +(*PFSA_MINIPORT_INIT) (
11023 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
11024 + IN ULONG AdapterNumber,
11029 +typedef struct _FSA_MINIPORT {
11032 + USHORT SubVendorId;
11033 + USHORT SubSystemId;
11034 + PCHAR DevicePrefix;
11035 + PFSA_MINIPORT_INIT InitRoutine;
11036 + PCHAR DeviceName;
11040 +typedef FSA_MINIPORT *PFSA_MINIPORT;
11043 +#endif // _PCISUP_
11044 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/perfpack.h linux/drivers/scsi/aacraid/include/perfpack.h
11045 --- linux-2.4.7/drivers/scsi/aacraid/include/perfpack.h Wed Dec 31 18:00:00 1969
11046 +++ linux/drivers/scsi/aacraid/include/perfpack.h Sat Jul 21 17:55:13 2001
11049 + * Adaptec aacraid device driver for Linux.
11051 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11053 + * This program is free software; you can redistribute it and/or modify
11054 + * it under the terms of the GNU General Public License as published by
11055 + * the Free Software Foundation; either version 2, or (at your option)
11056 + * any later version.
11058 + * This program is distributed in the hope that it will be useful,
11059 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11060 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11061 + * GNU General Public License for more details.
11063 + * You should have received a copy of the GNU General Public License
11064 + * along with this program; see the file COPYING. If not, write to
11065 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11070 + * Abstract: This file defines the layout of the performance data that is passed
11071 + * back from the FSA filesystem driver.
11076 +#ifndef _FSA_PERFPACK_H_
11077 +#define _FSA_PERFPACK_H_ 1
11079 +static char *ident_perf = "aacraid_ident perfpack.h 1.0.6 2000/10/09 Adaptec, Inc.";
11081 +//#define FSA_DO_PERF 1 /* enable the engineering counters */
11083 +#ifdef FSA_DO_PERF
11085 +// engineering counters
11087 +typedef struct _FSA_PERF_DATA {
11095 + ULONG CreateFibs;
11097 + ULONG RemoveFibs;
11098 + ULONG RemoveDirs;
11099 + ULONG RenameFibs;
11100 + ULONG ReadDirPlus;
11102 + ULONG WriteBytes;
11104 +// NT FSA entry points
11105 + ULONG FsaFsdCreateCount;
11106 + ULONG FsaFsdCloseCount;
11107 + ULONG FsaFsdReadCount;
11108 + ULONG FsaFsdWriteCount;
11109 + ULONG FsaFsdQueryInformationCount;
11111 + struct _FsaFsdSetInfomation{
11112 + ULONG FsaSetAllocationInfoCount;
11113 + ULONG FsaSetBasicInfoCount;
11114 + ULONG FsaSetDispositionInfoCount;
11115 + ULONG FsaSetEndOfFileInfoCount;
11116 + ULONG FsaSetPositionInfoCount;
11117 + ULONG FsaSetRenameInfoCount;
11118 + ULONG FsaClearArchiveBitCount;
11121 + ULONG FsaFsdFlushBuffersCount;
11122 + ULONG FsaFsdQueryVolumeInfoCount;
11123 + ULONG FsaFsdSetVolumeInfoCount;
11124 + ULONG FsaFsdCleanupCount;
11125 + ULONG FsaFsdDirectoryControlCount;
11126 + ULONG FsaFsdFileSystemControlCount;
11127 + ULONG FsaFsdLockControlCount;
11128 + ULONG FsaFsdDeviceControlCount;
11129 + ULONG FsaFsdShutdownCount;
11130 + ULONG FsaFsdQuerySecurityInfo;
11131 + ULONG FsaFsdSetSecurityInfo;
11132 + ULONG FastIoCheckIfPossibleCount;
11133 + ULONG FastIoReadCount;
11134 + ULONG FastIoWriteCount;
11135 + ULONG FastIoQueryBasicInfoCount;
11136 + ULONG FastIoQueryStandardInfoCount;
11137 + ULONG FastIoLockCount;
11138 + ULONG FastIoUnlockSingleCount;
11139 + ULONG FastIoUnlockAllCount;
11140 + ULONG FastIoUnlockAllByKeyCount;
11141 + ULONG FastIoDeviceControlCount;
11144 +typedef FSA_PERF_DATA *PFSA_PERF_DATA;
11147 +#else /* FSA_DO_PERF */
11150 +// engineering performance counters are disabled
11152 +#define FSA_DO_PERF_INC(Counter) /* */
11153 +#define FSA_DO_FSP_PERF_INC(Counter) /* */
11155 +#endif /* FSA_DO_PERF */
11157 +#endif // _FSA_PERFPACK_H_
11158 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/port.h linux/drivers/scsi/aacraid/include/port.h
11159 --- linux-2.4.7/drivers/scsi/aacraid/include/port.h Wed Dec 31 18:00:00 1969
11160 +++ linux/drivers/scsi/aacraid/include/port.h Sat Jul 21 17:55:13 2001
11163 + * Adaptec aacraid device driver for Linux.
11165 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11167 + * This program is free software; you can redistribute it and/or modify
11168 + * it under the terms of the GNU General Public License as published by
11169 + * the Free Software Foundation; either version 2, or (at your option)
11170 + * any later version.
11172 + * This program is distributed in the hope that it will be useful,
11173 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11174 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11175 + * GNU General Public License for more details.
11177 + * You should have received a copy of the GNU General Public License
11178 + * along with this program; see the file COPYING. If not, write to
11179 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11184 + * Abstract: This module defines functions and structures that are in common among all miniports
11192 +static char *ident_porth = "aacraid_ident port.h 1.0.6 2000/10/09 Adaptec, Inc.";
11195 +#define AfaPortPrint if (AfaPortPrinting) DbgPrint
11196 +extern int AfaPortPrinting;
11198 +#define AfaPortPrint
11201 +extern int AfaPortPrinting;
11205 +AfaPortAllocateAdapterCommArea(
11207 + IN OUT PVOID *CommHeaderAddress,
11208 + IN ULONG CommAreaSize,
11209 + IN ULONG CommAreaAlignment
11214 +AfaPortFreeAdapterCommArea(
11220 +AfaPortBuildSgMap(
11222 + IN PSGMAP_CONTEXT SgMapContext
11227 +AfaPortFreeDmaResources(
11229 + IN PSGMAP_CONTEXT SgMapContext
11234 +AfaPortAllocateAndMapFibSpace(
11236 + IN PMAPFIB_CONTEXT MapFibContext
11241 +AfaPortUnmapAndFreeFibSpace(
11243 + IN PMAPFIB_CONTEXT MapFibContext
11249 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/protocol.h linux/drivers/scsi/aacraid/include/protocol.h
11250 --- linux-2.4.7/drivers/scsi/aacraid/include/protocol.h Wed Dec 31 18:00:00 1969
11251 +++ linux/drivers/scsi/aacraid/include/protocol.h Sat Jul 21 17:55:13 2001
11254 + * Adaptec aacraid device driver for Linux.
11256 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11258 + * This program is free software; you can redistribute it and/or modify
11259 + * it under the terms of the GNU General Public License as published by
11260 + * the Free Software Foundation; either version 2, or (at your option)
11261 + * any later version.
11263 + * This program is distributed in the hope that it will be useful,
11264 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11265 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11266 + * GNU General Public License for more details.
11268 + * You should have received a copy of the GNU General Public License
11269 + * along with this program; see the file COPYING. If not, write to
11270 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11275 + * Abstract: Defines the commands and command data which enables the nt
11276 + * filesystem driver to be the client of the fsa adapter
11277 + * filesystem. This protocol is largely modeled after the NFS
11278 + * V3 protocol with modifications allowed due to the unique
11279 + * client/server model FSA works under.
11285 +#ifndef _PROTOCOL_H_
11286 +#define _PROTOCOL_H_
11288 +static char *ident_protocol = "aacraid_ident protocol.h 1.0.6 2000/10/09 Adaptec, Inc.";
11290 +#include <fsafs.h> // definition of FSAFID; includes fsatypes.h
11291 +#include <nvramioctl.h> // for NVRAMINFO definition
11293 +// #define MDL_READ_WRITE
11296 +// Define the command values
11298 +typedef enum _FSA_COMMANDS {
11311 + RemoveDirectoryx, // bkpfix added x to this because already defined in nt
11315 + ReadDirectoryPlus,
11316 + FileSystemStatus,
11326 + SetFileSystemStatus,
11332 +#ifdef MDL_READ_WRITE
11334 + MdlWriteComplete,
11335 + MdlRead, // these are used solely for stats, Mdl really controlled by
11336 + MdlWrite, // flags field in Fib.
11341 + FaultInsertion, // Fault Insertion Command
11342 + CrazyCache, // crazycache
11343 + MAX_FSACOMMAND_NUM //CJ: used for sizing stats array - leave last
11346 +#ifdef AAC_32BIT_ENUMS
11347 +typedef _E_FSACOMMAND FSACOMMAND;
11349 +typedef AAC_UINT32 FSACOMMAND;
11355 +// Define the status returns
11357 +// See include\comm\errno.h for adapter kernel errno's
11358 +typedef enum _FSASTATUS {
11376 + ST_WOULDBLOCK = 35,
11377 + ST_NAMETOOLONG = 63,
11378 + ST_NOTEMPTY = 66,
11382 + ST_BADHANDLE = 10001,
11383 + ST_NOT_SYNC = 10002,
11384 + ST_BAD_COOKIE = 10003,
11385 + ST_NOTSUPP = 10004,
11386 + ST_TOOSMALL = 10005,
11387 + ST_SERVERFAULT = 10006,
11388 + ST_BADTYPE = 10007,
11389 + ST_JUKEBOX = 10008,
11390 + ST_NOTMOUNTED = 10009,
11391 + ST_MAINTMODE = 10010,
11392 + ST_STALEACL = 10011
11395 +#ifdef AAC_32BIT_ENUMS
11396 +typedef _E_FSASTATUS FSASTATUS;
11398 +typedef AAC_UINT32 FSASTATUS;
11402 +// On writes how does the client want the data written.
11405 +typedef enum _CACHELEVEL {
11410 +#ifdef AAC_32BIT_ENUMS
11411 +typedef _E_CACHELEVEL CACHELEVEL;
11413 +typedef AAC_UINT32 CACHELEVEL;
11417 +// Lets the client know at which level the data was commited on a write request
11420 +typedef enum _COMMITLEVEL {
11421 + CMFILE_SYNCH_NVRAM = 1,
11422 + CMDATA_SYNCH_NVRAM,
11428 +#ifdef AAC_32BIT_ENUMS
11429 +typedef _E_COMMITLEVEL COMMITLEVEL;
11431 +typedef AAC_UINT32 COMMITLEVEL;
11437 +// The following are all the different commands or FIBs which can be sent to the
11438 +// FSA filesystem. We will define a required subset which cannot return STATUS_NOT_IMPLEMENTED,
11439 +// but others outside that subset are allowed to return not implemented. The client is then
11440 +// responsible for dealing with the fact it is not implemented.
11442 +typedef AAC_INT8 FSASTRING[16];
11445 +typedef AAC_UINT32 BYTECOUNT; // only 32 bit-ism
11453 +typedef struct _BLOCKREAD { // variable size struct
11455 + FSACOMMAND Command;
11456 + AAC_UINT32 ContainerId;
11457 + BYTECOUNT BlockNumber;
11458 + BYTECOUNT ByteCount;
11459 + SGMAP SgMap; // Must be last in struct because it is variable
11462 +typedef BLOCKREAD *PBLOCKREAD;
11464 +typedef struct _BLOCKREADRESPONSE {
11466 + FSASTATUS Status;
11467 + BYTECOUNT ByteCount;
11469 +} BLOCKREADRESPONSE;
11470 +typedef BLOCKREADRESPONSE *PBLOCKREADRESPONSE;
11476 +typedef struct _BLOCKWRITE { // variable size struct
11478 + FSACOMMAND Command;
11479 + AAC_UINT32 ContainerId;
11480 + BYTECOUNT BlockNumber;
11481 + BYTECOUNT ByteCount;
11482 + CACHELEVEL Stable;
11483 + SGMAP SgMap; // Must be last in struct because it is variable
11486 +typedef BLOCKWRITE *PBLOCKWRITE;
11489 +typedef struct _BLOCKWRITERESPONSE {
11491 + FSASTATUS Status;
11492 + BYTECOUNT ByteCount;
11493 + COMMITLEVEL Committed;
11495 +} BLOCKWRITERESPONSE;
11496 +typedef BLOCKWRITERESPONSE *PBLOCKWRITERESPONSE;
11500 +#endif // _PROTOCOL_H_
11502 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/revision.h linux/drivers/scsi/aacraid/include/revision.h
11503 --- linux-2.4.7/drivers/scsi/aacraid/include/revision.h Wed Dec 31 18:00:00 1969
11504 +++ linux/drivers/scsi/aacraid/include/revision.h Sat Jul 21 17:55:13 2001
11507 + * Adaptec aacraid device driver for Linux.
11509 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11511 + * This program is free software; you can redistribute it and/or modify
11512 + * it under the terms of the GNU General Public License as published by
11513 + * the Free Software Foundation; either version 2, or (at your option)
11514 + * any later version.
11516 + * This program is distributed in the hope that it will be useful,
11517 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11518 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11519 + * GNU General Public License for more details.
11521 + * You should have received a copy of the GNU General Public License
11522 + * along with this program; see the file COPYING. If not, write to
11523 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11528 + * Abstract: This module contains all of the revision information for
11529 + * the FSA product, as well as the support routines for
11530 + * checking module compatibility.
11532 + * Before editing anything in this module, make sure that
11533 + * you read the comments. Some lines are changed automatically
11534 + * as part of the build, and should never be changed by hand.
11536 + * Routines (all inlines):
11538 + * RevGetBuildNumber - Retrieve current build number
11539 + * RevGetExternalRev - Retrieve revision for external use
11540 + * RevGetFullRevision - Retrieve full revision structure
11542 + * RevCheckCompatibility - Checks compatibility base on internal table
11544 + * RevCheckCompatibilityFullInfo - Check for static component
11545 + * RevGetCompInfoTableSize - Get size for static component table
11546 + * RevGetCompInfoTable - Get actual table to place on static component
11547 + * RevGetBuildNumberFromInfo - Get build number for static component.
11553 +#ifndef _REVISION_H
11554 +#define _REVISION_H
11556 +static char *ident_revision = "aacraid_ident revision.h 1.0.6 2000/10/09 Adaptec, Inc.";
11558 +#include "version.h" // revision numbers kept separate so they can be used by resource compiler as well
11560 +typedef int REV_BOOL;
11562 +#define REV_TRUE 1
11563 +#define REV_FALSE 0
11566 +// Define Revision Levels for this product
11568 +// IMPORTANT: Do NOT modify BUILD_NUMBER define, this is modified
11569 +// automatically by the build.
11571 +// Version is VMAJOR.MINOR-DASH TYPE (Build BUILD_NUMBER)
11573 +// IMPORTANT: Don't access these revisions directly. They can be
11574 +// accessed via, the RevGetXxxxx rouines.
11578 +#define REV_AS_LONGWORD \
11579 + ((REV_MAJOR << 24) | (REV_MINOR << 16) | (REV_TYPE << 8) | (REV_DASH))
11586 +// Enumerate the types of product levels we can have
11589 + RevType_Devo=1, // Development mode, testing all of latest
11590 + RevType_Alpha, // Alpha - Internal field test
11591 + RevType_Beta, // Beta - External field test
11592 + RevType_Release // Release - Retail version
11596 +// Define the basic structure for all revision information. Note
11597 +// that the ordering of the components is such that they should
11598 +// always increase. dash will be updated the most, then the version
11599 +// type, then minor and major.
11604 + unsigned char dash; // Dash version number
11605 + unsigned char type; // Type, 1=Devo, 2=Alpha, 3=Beta, 4=Release
11606 + unsigned char minor;// Minor version minor
11607 + unsigned char major;// Major version number
11608 + } comp; // Components to external viewed rev number
11609 + unsigned long ul; // External revision as single 32-bit value
11610 + } external; // External revision number (union)
11611 + unsigned long buildNumber; // Automatically generated build number
11616 +// Define simple routines to get basic revision information. The
11617 +// definitions should never be accessed directly. These routines
11618 +// are meant to be used to access all relevant information no matter
11621 +static inline unsigned long RevGetBuildNumber() {return REV_BUILD_NUMBER;}
11623 +static inline unsigned long RevGetExternalRev() {return REV_AS_LONGWORD;}
11627 +// Enumerate different components that may have to check
11628 +// compatibility. This list of components can be changed
11631 +// IMPORTANT: ONLY add to the END of this enum structure. Otherwise,
11632 +// incompatibilities between component rev checking will
11633 +// cause wrong checking results.
11636 + RevApplication = 1, // Any user End application
11637 + RevDkiCli, // ADAPTEC proprietary interface (knows FIBs)
11638 + RevNetService, // Network Service Revision (under API)
11639 + RevApi, // ADAPTEC User mode API
11640 + RevFileSysDriver, // FSA File System Driver
11641 + RevMiniportDriver, // FSA File System Miniport Driver
11642 + RevAdapterSW, // Adapter Software (or NT Simulator)
11643 + RevMonitor, // Monitor for adapter hardware (MON960 for now)
11644 + RevRemoteApi // The remote API.
11645 + // ALWAYS ADD NEW COMPONENTS HERE - AT END
11649 +// Define a structure so that we can create a compatibility table.
11652 + RevComponent A,B;
11653 + unsigned long BuildNumOfB_RequiredByA;
11654 + unsigned long BuildNumOfA_RequiredByB;
11655 +} RevCompareElement;
11658 +// Now, define the table. This table should only be included once,
11659 +// in one program. If it is linked from 2 modules, there will likely
11660 +// be a multiply defined symbol error from the linker.
11662 +// To fix this problem, REV_REFERENCE_ONLY can be defined. This will
11663 +// allow access to the revision information table without a redefinition
11666 +extern const int RevCompareTableLength;
11668 +extern const RevCompareElement RevCompareTable[];
11670 +/********************************************************************\
11671 +* Routine: RevCheckCompatibility(callerComp,compB,compB_BuildNumber)
11673 +* The following routine is used to check compatibility between
11674 +* the calling component and a component that has some dependencies
11675 +* on it. If this routine returns REV_FALSE, it is expected that the caller
11676 +* will send an appropriate incompatibility message and stop.
11678 +* This routine is only meant to check for compatibility in the
11679 +* absolute sense. If code wishes to execute a different path based
11680 +* on the CompB_BuildNumber, then this routine is not useful. The
11681 +* routine RevGetBuildNumber can be used to get the calling module's
11682 +* current build number for a comparison check.
11684 +* The return value is REV_TRUE, if compatibility is possible, and REV_FALSE
11685 +* if the components are definitely not compatible, or there is an
11686 +* error when trying to figure it out. To be more specific:
11688 +* 1) REV_TRUE if component B is newer than calling component. (In this
11689 +* case, the revision check done by component B with respect to
11690 +* this component will give the real compatibility information.
11691 +* It is the only one with the knowledge, since this component
11692 +* could not look into the future.)
11693 +* 2) REV_TRUE if calling component is more recent and table shows okay
11694 +* 3) REV_FALSE if calling component more recent and table show not okay
11695 +* 4) REV_FALSE if calling component is more recent and table entry to
11696 +* check does not exist.
11698 +* Note that the CompB_BuildNumber must be attained by the calling
11699 +* routine through some mechanism done by the caller.
11703 +* callerComp - Name of component making this call
11704 +* compB - Name of component to check compatibility with
11705 +* compB_BuildNumber - Build number to component B
11713 +* REV_TRUE - Component compatibility is possible, continue as usual. compB
11714 +* must give true compatibility information.
11715 +* REV_FALSE - Incompatible components, notify and end
11717 +\********************************************************************/
11718 +static inline REV_BOOL RevCheckCompatibility(
11719 + RevComponent callerComp,
11720 + RevComponent compB,
11721 + unsigned long compB_BuildNumber)
11724 + unsigned long RevForB;
11727 + // Compatibility check is possible, so we should continue. When
11728 + // compB makes this call in its own component, it will get the
11729 + // true compatibility information, since only it can know.
11731 + if (RevGetBuildNumber() < compB_BuildNumber) return REV_TRUE;
11734 + // Go through rev table. When the components are found in the
11735 + // same table entry, return the approprate number.
11737 + for (i=0; i<RevCompareTableLength; i++) {
11738 + if (RevCompareTable[i].A == callerComp) {
11739 + if (RevCompareTable[i].B == compB) {
11740 + RevForB = RevCompareTable[i].BuildNumOfB_RequiredByA;
11741 + return (compB_BuildNumber >= RevForB);
11743 + } else if (RevCompareTable[i].B == callerComp) {
11744 + if (RevCompareTable[i].A == compB) {
11745 + RevForB = RevCompareTable[i].BuildNumOfA_RequiredByB;
11746 + return (compB_BuildNumber >= RevForB);
11752 + // Uh oh! No relevant table entry was found (this should never
11755 + return REV_FALSE;
11760 +// Now create a structure that can be used by a FIB to check
11763 +typedef struct _RevCheck {
11764 + RevComponent callingComponent;
11765 + FsaRevision callingRevision;
11768 +typedef struct _RevCheckResp {
11769 + REV_BOOL possiblyCompatible;
11770 + FsaRevision adapterSWRevision;
11774 +#endif /* _REVISION_H */
11777 +// The following allows for inclusion of revision.h in other h
11778 +// files. when you include this file in another h file, simply
11779 +// define REV_REFERENCE_ONLY. This will be undefined later, so that
11780 +// the single C file inclusion in the module will be used to
11781 +// implement the global structures.
11783 +#ifndef REV_REFERENCE_ONLY
11784 +#ifndef _REVISION_H_GLOBAL
11785 +#define _REVISION_H_GLOBAL
11790 +// The following array is the table of compatibility. This table
11791 +// can be modified in two ways:
11793 +// 1) A component which has an incompatible change done to
11794 +// it, can get a new build number.
11796 +// 2) A new component can be added, requiring more entries
11797 +// to be place into this table.
11800 +// In case (1), you must change the revision number in the appropriate
11801 +// column, based on which component absolutely requires an upgrade.
11803 +// Example: A new FIB used by the API, in build number 105
11804 +// {RevApi, RevAdapterSW, 100, 100}
11805 +// ---> would be changed to <---
11806 +// {RevApi, RevAdapterSW, 105, 100}
11808 +// Example: A structure is changed for a FIB that only the API uses
11809 +// {RevApi, RevAdapterSW, 100, 100}
11810 +// ---> would be changed to <---
11811 +// {RevApi, RevAdapterSW, 105, 105}
11814 +// In case (2), the less common case, the enumerated list of
11815 +// components must be changed to include the new component. Then
11816 +// entries need to be placed into this table.
11818 +// Since the revisions must be communicated between the two
11819 +// components, it is likely that you would need to put in the
11820 +// current build number for both columns. That is the recommended
11821 +// way to start revision test.
11823 +const RevCompareElement RevCompareTable[] = {
11824 + // Component A Component B MinBForA MinAForB
11825 + // ----------- ----------- -------- --------
11826 + {RevApplication, RevApi, 2120, 2120 },
11827 + {RevDkiCli, RevApi, 2120, 2120 },
11828 + {RevDkiCli, RevFileSysDriver, 257, 257 },
11829 + {RevDkiCli, RevMiniportDriver, 257, 257 },
11830 + {RevDkiCli, RevAdapterSW, 257, 257 },
11831 + {RevApi, RevFileSysDriver, 2120, 2120 },
11832 + {RevApi, RevMiniportDriver, 2120, 2120 },
11833 + {RevApi, RevAdapterSW, 2120, 2120 },
11834 + {RevApi, RevNetService, 2120, 2120 },
11835 + {RevFileSysDriver, RevMiniportDriver, 100, 100 },
11836 + {RevFileSysDriver, RevAdapterSW, 257, 257 },
11837 + {RevMiniportDriver, RevAdapterSW, 257, 257 },
11838 + {RevMiniportDriver, RevMonitor, 100, 100 },
11839 + {RevApi, RevNetService, 2120, 2120 },
11840 + {RevApi, RevRemoteApi, 2120, 2120 },
11841 + {RevNetService, RevRemoteApi, 2120, 2120 }
11844 +const int RevCompareTableLength = sizeof(RevCompareTable)/sizeof(RevCompareElement);
11846 +#endif /* _REVISION_H_GLOBAL */
11847 +#endif /* REV_REFERENCE_ONLY */
11848 +#undef REV_REFERENCE_ONLY
11856 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/rx.h linux/drivers/scsi/aacraid/include/rx.h
11857 --- linux-2.4.7/drivers/scsi/aacraid/include/rx.h Wed Dec 31 18:00:00 1969
11858 +++ linux/drivers/scsi/aacraid/include/rx.h Sat Jul 21 17:55:13 2001
11861 + * Adaptec aacraid device driver for Linux.
11863 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11865 + * This program is free software; you can redistribute it and/or modify
11866 + * it under the terms of the GNU General Public License as published by
11867 + * the Free Software Foundation; either version 2, or (at your option)
11868 + * any later version.
11870 + * This program is distributed in the hope that it will be useful,
11871 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11872 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11873 + * GNU General Public License for more details.
11875 + * You should have received a copy of the GNU General Public License
11876 + * along with this program; see the file COPYING. If not, write to
11877 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11882 + * Abstract: Prototypes and data structures unique to the Rx based controller board.
11887 +static char *ident_rxh = "aacraid_ident rx.h 1.0.6 2000/10/09 Adaptec, Inc.";
11889 +typedef struct _Rx_ADAPTER_EXTENSION {
11892 + // The following must be first.
11894 + PPCI_MINIPORT_COMMON_EXTENSION Common;
11895 + struct _Rx_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
11896 + USHORT LocalMaskInterruptControl;
11897 + PRx_DEVICE_REGISTERS Device;
11899 +} Rx_ADAPTER_EXTENSION;
11902 +typedef Rx_ADAPTER_EXTENSION *PRx_ADAPTER_EXTENSION;
11911 +#define Rx_READ_UCHAR(AEP, CSR) *(volatile unsigned char *) &((AEP)->Device->CSR)
11915 +#define Rx_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
11916 +#define Rx_WRITE_UCHAR(AEP, CSR, Value) *(volatile unsigned char *) &((AEP)->Device->CSR) = (Value)
11919 +#define Rx_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
11921 +#endif /* LINUX */
11925 +RxInterruptAdapter(
11932 + IN HOST_2_ADAP_EVENT AdapterEvent
11941 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/rxcommon.h linux/drivers/scsi/aacraid/include/rxcommon.h
11942 --- linux-2.4.7/drivers/scsi/aacraid/include/rxcommon.h Wed Dec 31 18:00:00 1969
11943 +++ linux/drivers/scsi/aacraid/include/rxcommon.h Sat Jul 21 17:55:13 2001
11946 + * Adaptec aacraid device driver for Linux.
11948 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
11950 + * This program is free software; you can redistribute it and/or modify
11951 + * it under the terms of the GNU General Public License as published by
11952 + * the Free Software Foundation; either version 2, or (at your option)
11953 + * any later version.
11955 + * This program is distributed in the hope that it will be useful,
11956 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11957 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11958 + * GNU General Public License for more details.
11960 + * You should have received a copy of the GNU General Public License
11961 + * along with this program; see the file COPYING. If not, write to
11962 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
11967 + * Abstract: Structures and defines for the i960 Rx chip.
11972 +#ifndef _Rx_COMMON_H_
11973 +#define _Rx_COMMON_H_
11975 +static char *ident_rxcommon = "aacraid_ident rxcommon.h 1.0.6 2000/10/09 Adaptec, Inc.";
11978 +// Rx Message Unit Registers
11981 +typedef volatile struct _StructRxMURegisters {
11982 + // Local | PCI* | Name
11984 + unsigned ARSR; // 1300h | 00h | APIC Register Select Register
11985 + unsigned reserved0; // 1304h | 04h | Reserved
11986 + unsigned AWR; // 1308h | 08h | APIC Window Register
11987 + unsigned reserved1; // 130Ch | 0Ch | Reserved
11988 + unsigned IMRx[2]; // 1310h | 10h | Inbound Message Registers
11989 + unsigned OMRx[2]; // 1318h | 18h | Outbound Message Registers
11990 + unsigned IDR; // 1320h | 20h | Inbound Doorbell Register
11991 + unsigned IISR; // 1324h | 24h | Inbound Interrupt Status Register
11992 + unsigned IIMR; // 1328h | 28h | Inbound Interrupt Mask Register
11993 + unsigned ODR; // 132Ch | 2Ch | Outbound Doorbell Register
11994 + unsigned OISR; // 1330h | 30h | Outbound Interrupt Status Register
11995 + unsigned OIMR; // 1334h | 34h | Outbound Interrupt Mask Register
11996 + // * Must access trhough ATU Inbound Translation Window
11999 +typedef Rx_MU_CONFIG *PRx_MU_CONFIG;
12001 +typedef volatile struct _Rx_Inbound {
12003 + unsigned Mailbox[8];
12007 +typedef Rx_Inbound *PRx_Inbound;
12009 +#define InboundMailbox0 IndexRegs.Mailbox[0]
12010 +#define InboundMailbox1 IndexRegs.Mailbox[1]
12011 +#define InboundMailbox2 IndexRegs.Mailbox[2]
12012 +#define InboundMailbox3 IndexRegs.Mailbox[3]
12013 +#define InboundMailbox4 IndexRegs.Mailbox[4]
12017 +#define INBOUNDDOORBELL_0 0x00000001
12018 +#define INBOUNDDOORBELL_1 0x00000002
12019 +#define INBOUNDDOORBELL_2 0x00000004
12020 +#define INBOUNDDOORBELL_3 0x00000008
12021 +#define INBOUNDDOORBELL_4 0x00000010
12022 +#define INBOUNDDOORBELL_5 0x00000020
12023 +#define INBOUNDDOORBELL_6 0x00000040
12026 +#define OUTBOUNDDOORBELL_0 0x00000001
12027 +#define OUTBOUNDDOORBELL_1 0x00000002
12028 +#define OUTBOUNDDOORBELL_2 0x00000004
12029 +#define OUTBOUNDDOORBELL_3 0x00000008
12030 +#define OUTBOUNDDOORBELL_4 0x00000010
12033 +#define InboundDoorbellReg MUnit.IDR
12035 +#define OutboundDoorbellReg MUnit.ODR
12038 +typedef struct _Rx_DEVICE_REGISTERS {
12039 + Rx_MU_CONFIG MUnit; // 1300h - 1334h
12040 + unsigned reserved1[6]; // 1338h - 134ch
12041 + Rx_Inbound IndexRegs;
12042 +} Rx_DEVICE_REGISTERS;
12044 +typedef Rx_DEVICE_REGISTERS *PRx_DEVICE_REGISTERS;
12047 +#endif // _Rx_COMMON_H_
12050 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/sap1.h linux/drivers/scsi/aacraid/include/sap1.h
12051 --- linux-2.4.7/drivers/scsi/aacraid/include/sap1.h Wed Dec 31 18:00:00 1969
12052 +++ linux/drivers/scsi/aacraid/include/sap1.h Sat Jul 21 17:55:14 2001
12055 + * Adaptec aacraid device driver for Linux.
12057 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12059 + * This program is free software; you can redistribute it and/or modify
12060 + * it under the terms of the GNU General Public License as published by
12061 + * the Free Software Foundation; either version 2, or (at your option)
12062 + * any later version.
12064 + * This program is distributed in the hope that it will be useful,
12065 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12066 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12067 + * GNU General Public License for more details.
12069 + * You should have received a copy of the GNU General Public License
12070 + * along with this program; see the file COPYING. If not, write to
12071 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12076 + * Abstract: Prototypes and data structures unique to the Strong Arm based controller board.
12083 +static char *ident_sap1h = "aacraid_ident sap1.h 1.0.6 2000/10/09 Adaptec, Inc.";
12085 +#define Sa_MINIPORT_REVISION 1
12087 +typedef struct _Sa_ADAPTER_EXTENSION {
12090 + // The following must be first.
12092 + PPCI_MINIPORT_COMMON_EXTENSION Common;
12093 + struct _Sa_ADAPTER_EXTENSION *Next; // Next adapter miniport structure
12094 + USHORT LocalMaskInterruptControl;
12095 + PSa_DEVICE_REGISTERS Device;
12097 +} Sa_ADAPTER_EXTENSION;
12099 +typedef Sa_ADAPTER_EXTENSION *PSa_ADAPTER_EXTENSION;
12109 +#define Sa_READ_USHORT(AEP, CSR) *(volatile unsigned short *) &((AEP)->Device->CSR)
12110 +#define Sa_READ_ULONG(AEP, CSR) *(volatile unsigned int *) &((AEP)->Device->CSR)
12113 +#define Sa_WRITE_USHORT(AEP, CSR, Value) *(volatile unsigned short *) &((AEP)->Device->CSR) = (Value)
12114 +#define Sa_WRITE_ULONG(AEP, CSR, Value) *(volatile unsigned int *) &((AEP)->Device->CSR) = (Value)
12116 +#endif /* LINUX */
12120 +SaInterruptAdapter(
12127 + IN HOST_2_ADAP_EVENT AdapterEvent
12136 +#endif /* _SAP1_H_ */
12139 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/sap1common.h linux/drivers/scsi/aacraid/include/sap1common.h
12140 --- linux-2.4.7/drivers/scsi/aacraid/include/sap1common.h Wed Dec 31 18:00:00 1969
12141 +++ linux/drivers/scsi/aacraid/include/sap1common.h Sat Jul 21 17:55:14 2001
12144 + * Adaptec aacraid device driver for Linux.
12146 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12148 + * This program is free software; you can redistribute it and/or modify
12149 + * it under the terms of the GNU General Public License as published by
12150 + * the Free Software Foundation; either version 2, or (at your option)
12151 + * any later version.
12153 + * This program is distributed in the hope that it will be useful,
12154 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12155 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12156 + * GNU General Public License for more details.
12158 + * You should have received a copy of the GNU General Public License
12159 + * along with this program; see the file COPYING. If not, write to
12160 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12165 + * Abstract: Structures and defines for the Drawbridge and StrongArm110 chip.
12169 +#ifndef _Sa_COMMON_H_
12170 +#define _Sa_COMMON_H_
12172 +static char *ident_sap1common = "aacraid_ident sap1common.h 1.0.6 2000/10/09 Adaptec, Inc.";
12175 +// SaP1 Message Unit Registers
12178 +typedef volatile struct _StructSaDrawbridge_CSR_RegisterMap {
12180 + unsigned reserved[10]; // 00h-27h | Reserved
12181 + unsigned char LUT_Offset; // 28h | Looup Table Offset
12182 + unsigned char reserved1[3]; // 29h-2bh | Reserved
12183 + unsigned LUT_Data; // 2ch | Looup Table Data
12184 + unsigned reserved2[26]; // 30h-97h | Reserved
12185 + unsigned short PRICLEARIRQ; // 98h | Primary Clear Irq
12186 + unsigned short SECCLEARIRQ; // 9ah | Secondary Clear Irq
12187 + unsigned short PRISETIRQ; // 9ch | Primary Set Irq
12188 + unsigned short SECSETIRQ; // 9eh | Secondary Set Irq
12189 + unsigned short PRICLEARIRQMASK; // a0h | Primary Clear Irq Mask
12190 + unsigned short SECCLEARIRQMASK; // a2h | Secondary Clear Irq Mask
12191 + unsigned short PRISETIRQMASK; // a4h | Primary Set Irq Mask
12192 + unsigned short SECSETIRQMASK; // a6h | Secondary Set Irq Mask
12193 + unsigned MAILBOX0; // a8h | Scratchpad 0
12194 + unsigned MAILBOX1; // ach | Scratchpad 1
12195 + unsigned MAILBOX2; // b0h | Scratchpad 2
12196 + unsigned MAILBOX3; // b4h | Scratchpad 3
12197 + unsigned MAILBOX4; // b8h | Scratchpad 4
12198 + unsigned MAILBOX5; // bch | Scratchpad 5
12199 + unsigned MAILBOX6; // c0h | Scratchpad 6
12200 + unsigned MAILBOX7; // c4h | Scratchpad 7
12202 + unsigned ROM_Setup_Data; // c8h | Rom Setup and Data
12203 + unsigned ROM_Control_Addr; // cch | Rom Control and Address
12205 + unsigned reserved3[12]; // d0h-ffh | reserved
12206 + unsigned LUT[64]; // 100h-1ffh| Lookup Table Entries
12210 + // need to add DMA, I2O, UART, etc registers form 80h to 364h
12213 +}Sa_Drawbridge_CSR;
12215 +typedef Sa_Drawbridge_CSR *PSa_Drawbridge_CSR;
12218 +#define Mailbox0 SaDbCSR.MAILBOX0
12219 +#define Mailbox1 SaDbCSR.MAILBOX1
12220 +#define Mailbox2 SaDbCSR.MAILBOX2
12221 +#define Mailbox3 SaDbCSR.MAILBOX3
12222 +#define Mailbox4 SaDbCSR.MAILBOX4
12225 +#define Mailbox7 SaDbCSR.MAILBOX7
12227 +#define DoorbellReg_p SaDbCSR.PRISETIRQ
12228 +#define DoorbellReg_s SaDbCSR.SECSETIRQ
12229 +#define DoorbellClrReg_p SaDbCSR.PRICLEARIRQ
12232 +#define DOORBELL_0 0x00000001
12233 +#define DOORBELL_1 0x00000002
12234 +#define DOORBELL_2 0x00000004
12235 +#define DOORBELL_3 0x00000008
12236 +#define DOORBELL_4 0x00000010
12237 +#define DOORBELL_5 0x00000020
12238 +#define DOORBELL_6 0x00000040
12241 +#define PrintfReady DOORBELL_5
12242 +#define PrintfDone DOORBELL_5
12244 +typedef struct _Sa_DEVICE_REGISTERS {
12245 + Sa_Drawbridge_CSR SaDbCSR; // 98h - c4h
12246 +} Sa_DEVICE_REGISTERS;
12248 +typedef Sa_DEVICE_REGISTERS *PSa_DEVICE_REGISTERS;
12251 +#endif // _Sa_COMMON_H_
12254 diff -burN linux-2.4.7/drivers/scsi/aacraid/include/version.h linux/drivers/scsi/aacraid/include/version.h
12255 --- linux-2.4.7/drivers/scsi/aacraid/include/version.h Wed Dec 31 18:00:00 1969
12256 +++ linux/drivers/scsi/aacraid/include/version.h Sat Jul 21 17:55:14 2001
12259 + * Adaptec aacraid device driver for Linux.
12261 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12263 + * This program is free software; you can redistribute it and/or modify
12264 + * it under the terms of the GNU General Public License as published by
12265 + * the Free Software Foundation; either version 2, or (at your option)
12266 + * any later version.
12268 + * This program is distributed in the hope that it will be useful,
12269 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12270 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12271 + * GNU General Public License for more details.
12273 + * You should have received a copy of the GNU General Public License
12274 + * along with this program; see the file COPYING. If not, write to
12275 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12280 + * Abstract: Keeps track of build number for development purposes.
12283 +#ifndef _VERSION_H_
12284 +#define _VERSION_H_
12286 +static char *ident_version = "aacraid_ident version.h 1.0.6 2000/10/09 Adaptec, Inc.";
12288 +#include "build_number.h"
12290 +#define REV_MAJOR 2
12291 +#define REV_MINOR 1
12292 +#define REV_TYPE RevType_Release
12293 +#define REV_DASH 5
12295 +#define FSA_VERSION_STRING "2.1.5.3857\0"
12297 +#endif /* _VERSION_H_ */
12298 diff -burN linux-2.4.7/drivers/scsi/aacraid/linit.c linux/drivers/scsi/aacraid/linit.c
12299 --- linux-2.4.7/drivers/scsi/aacraid/linit.c Wed Dec 31 18:00:00 1969
12300 +++ linux/drivers/scsi/aacraid/linit.c Sat Jul 21 17:55:14 2001
12303 + * Adaptec aacraid device driver for Linux.
12305 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
12307 + * This program is free software; you can redistribute it and/or modify
12308 + * it under the terms of the GNU General Public License as published by
12309 + * the Free Software Foundation; either version 2, or (at your option)
12310 + * any later version.
12312 + * This program is distributed in the hope that it will be useful,
12313 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12314 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12315 + * GNU General Public License for more details.
12317 + * You should have received a copy of the GNU General Public License
12318 + * along with this program; see the file COPYING. If not, write to
12319 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
12324 + * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
12326 + * Provides the following driver entry points:
12327 + * AAC_DetectHostAdapter()
12328 + * AAC_ReleaseHostAdapter()
12329 + * AAC_QueueCommand()
12330 + * AAC_ResetCommand()
12331 + * AAC_BIOSDiskParameters()
12335 +static char *ident_linit = "aacraid_ident linit.c 1.0.6 2000/10/09 Adaptec, Inc.";
12337 +/*------------------------------------------------------------------------------
12339 + *----------------------------------------------------------------------------*/
12340 +#define AAC_DRIVER_VERSION "0.1.1"
12341 +#define AAC_DRIVER_BUILD_DATE __DATE__
12342 +#define MAX_DRIVER_QUEUE_DEPTH 500
12344 +/*------------------------------------------------------------------------------
12345 + * I N C L U D E S
12346 + *----------------------------------------------------------------------------*/
12347 +#include "osheaders.h"
12349 +#include "AacGenericTypes.h"
12352 +#include <linux/module.h>
12355 +#include "linit.h"
12356 +#include "aac_unix_defs.h"
12357 +#include "fsatypes.h"
12358 +#include "comstruc.h"
12359 +#include "fsaport.h"
12360 +#include "pcisup.h"
12362 +#include "afacomm.h"
12363 +#include "nodetype.h"
12364 +#include "comsup.h"
12365 +#include "adapter.h"
12367 +/*------------------------------------------------------------------------------
12369 + *----------------------------------------------------------------------------*/
12370 +extern FSA_MINIPORT MiniPorts[];
12371 +extern int CommPrinting;
12372 +extern char DescriptionString[];
12373 +extern char devicestr[];
12375 +/*------------------------------------------------------------------------------
12376 + * M O D U L E G L O B A L S
12377 + *----------------------------------------------------------------------------*/
12378 +aac_options_t g_options = { CMN_ERR_LEVEL, 0 }; // default message_level
12380 +char g_DriverName[] = { "aacraid" };
12381 +#define module_options aacraid_options
12382 +static char * aacraid_options = NULL;
12384 +PCI_MINIPORT_COMMON_EXTENSION *g_CommonExtensionPtrArray[ MAXIMUM_NUM_ADAPTERS ];
12385 +unsigned g_HostAdapterCount = 0;
12386 +unsigned g_chardev_major = 0;
12388 +int g_single_command_done = FALSE;
12390 +/*------------------------------------------------------------------------------
12391 + * F U N C T I O N P R O T O T Y P E S
12392 + *----------------------------------------------------------------------------*/
12394 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension,
12398 +int AacHba_ProbeContainers(
12399 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr );
12401 +int AacHba_DoScsiCmd(
12402 + Scsi_Cmnd *scsi_cmnd_ptr,
12405 +void AacHba_DetachAdapter(
12406 + IN PVOID AdapterArg );
12408 +int AacHba_ClassDriverInit(
12409 + PCI_MINIPORT_COMMON_EXTENSION * CommonExtensionPtr);
12411 +void AacHba_AbortScsiCommand(
12412 + Scsi_Cmnd *scsi_cmnd_ptr );
12415 +/*------------------------------------------------------------------------------
12416 + * L O C A L F U N C T I O N P R O T O T Y P E S
12417 + *----------------------------------------------------------------------------*/
12418 +static int parse_keyword(
12420 + char * keyword );
12422 +static void AAC_ParseDriverOptions(
12423 + char * cmnd_line_options_str );
12425 +static void AAC_AnnounceDriver( void );
12427 +int AAC_ChardevIoctl(
12428 + struct inode * inode_ptr,
12429 + struct file * file_ptr,
12430 + unsigned int cmd,
12431 + unsigned long arg );
12433 +int AAC_ChardevOpen(
12434 + struct inode * inode_ptr,
12435 + struct file * file_ptr );
12437 +int AAC_ChardevRelease(
12438 + struct inode * inode_ptr,
12439 + struct file * file_ptr );
12441 +struct file_operations AAC_fops = {
12442 + NULL, // module name
12448 + AAC_ChardevIoctl, // ioctl
12450 + AAC_ChardevOpen, // open
12452 + AAC_ChardevRelease, // release
12455 + NULL, // check media change
12456 + NULL, // revalidate
12460 +/*------------------------------------------------------------------------------
12461 + * F U N C T I O N S
12462 + *----------------------------------------------------------------------------*/
12463 +/*------------------------------------------------------------------------------
12464 + AAC_AnnounceDriver()
12466 + Announce the driver name, version and date.
12467 + *----------------------------------------------------------------------------*/
12468 +static void AAC_AnnounceDriver( void ){
12469 + printk(KERN_ALERT "%s, %s\n",
12470 + "aacraid raid driver version", AAC_DRIVER_BUILD_DATE );
12475 +/*------------------------------------------------------------------------------
12476 + AAC_DetectHostAdapter()
12478 + Probe for AAC Host Adapters initialize, register, and report the
12479 + configuration of each AAC Host Adapter found.
12483 + - Returns the number of adapters successfully initialized and
12485 + - Initialize all data necessary for this particular SCSI driver.
12487 + The detect routine must not call any of the mid level functions
12488 + to queue commands because things are not guaranteed to be set
12489 + up yet. The detect routine can send commands to the host adapter
12490 + as long as the program control will not be passed to scsi.c in
12491 + the processing of the command. Note especially that
12492 + scsi_malloc/scsi_free must not be called.
12493 + *----------------------------------------------------------------------------*/
12494 +int AAC_DetectHostAdapter (Scsi_Host_Template *HostTemplate)
12498 + uint16_t vendor_id, device_id, sub_vendor_id, sub_system_id;
12499 + struct Scsi_Host *host_ptr;
12500 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12501 + struct pci_dev *dev = NULL;
12502 + extern int NumMiniPorts;
12503 + fsadev_t *fsa_dev_ptr;
12504 + char *DeviceName;
12506 + struct pci_dev *devp;
12508 + int first_index, last_index, increment;
12510 + CommPrinting = TRUE;
12513 + EXPORT_NO_SYMBOLS;
12516 + AAC_AnnounceDriver();
12518 + /* setting up the proc directory structure */
12519 + HostTemplate->proc_name = "aacraid";
12521 + if( module_options != NULL ) AAC_ParseDriverOptions( module_options );
12523 + // NumMiniPorts & MiniPorts[] defined in aacid.c
12524 + if (g_options.reverse_scan == 0) {
12526 + last_index = NumMiniPorts;
12529 + first_index = NumMiniPorts -1;
12534 + for( index = first_index; index != last_index; index += increment )
12536 + device_id = MiniPorts[index].DeviceId;
12537 + vendor_id = MiniPorts[index].VendorId;
12538 + DeviceName = MiniPorts[index].DeviceName;
12539 + cmn_err(CE_DEBUG, "Checking %s %x/%x/%x/%x",
12540 + DeviceName, vendor_id, device_id,
12541 + MiniPorts[index].SubVendorId,
12542 + MiniPorts[index].SubSystemId);
12545 + // pci_find_device traverses the pci_devices linked list for devices
12546 + // with matching vendor and device ids.
12548 + dev = NULL; // start from beginning of list
12549 + while( ( dev = pci_find_device( vendor_id, device_id, dev ) ) )
12551 + if (pci_enable_device(dev)) continue;
12553 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor_id ) ){
12554 + cmn_err(CE_WARN, "pci_read_config_word SUBSYS_VENDOR_ID failed");
12557 + if( pci_read_config_word( dev, PCI_SUBSYSTEM_ID, &sub_system_id ) ){
12558 + cmn_err(CE_WARN, "pci_read_config_work SUBSYSTEM_ID failed");
12562 + cmn_err(CE_DEBUG, " found: %x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12563 + if( ( sub_vendor_id != MiniPorts[index].SubVendorId ) ||
12564 + ( sub_system_id != MiniPorts[index].SubSystemId ) ){
12569 + printk(KERN_ALERT "%s device detected\n", DeviceName );
12570 + cmn_err(CE_DEBUG, "%x/%x/%x/%x", vendor_id, device_id, sub_vendor_id, sub_system_id);
12572 + // Increment the host adapter count
12573 + g_HostAdapterCount++;
12575 + // scsi_register() allocates memory for a Scsi_Hosts structure and
12576 + // links it into the linked list of host adapters. This linked list
12577 + // contains the data for all possible <supported> scsi hosts.
12578 + // This is similar to the Scsi_Host_Template, except that we have
12579 + // one entry for each actual physical host adapter on the system,
12580 + // stored as a linked list. If there are two AAC boards, then we
12581 + // will need to make two Scsi_Host entries, but there will be only
12582 + // one Scsi_Host_Template entry. The second argument to scsi_register()
12583 + // specifies the size of the extra memory we want to hold any device
12584 + // specific information.
12585 + host_ptr = scsi_register( HostTemplate, sizeof( PCI_MINIPORT_COMMON_EXTENSION ) );
12587 + // These three parameters can be used to allow for wide SCSI
12588 + // and for host adapters that support multiple buses.
12589 + host_ptr->max_id = 17;
12590 + host_ptr->max_lun = 8;
12591 + host_ptr->max_channel = 1;
12594 + host_ptr->irq = dev->irq; // Adapter IRQ number
12595 + /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */
12596 + host_ptr->base = ( char * )(dev->resource[0].start);
12597 + scsi_set_pci_device(host_ptr, dev);
12599 + cmn_err( CE_DEBUG, "Device base address = 0x%lx [0x%lx]", host_ptr->base, dev->resource[0].start );
12600 + cmn_err( CE_DEBUG, "Device irq = 0x%lx", dev->irq );
12602 + // The unique_id field is a unique identifier that must be assigned
12603 + // so that we have some way of identifying each host adapter properly
12604 + // and uniquely. For hosts that do not support more than one card in the
12605 + // system, this does not need to be set. It is initialized to zero in
12606 + // scsi_register(). This is the value returned from OsGetDeviceInstance().
12608 + host_ptr->unique_id = g_HostAdapterCount - 1;
12609 + host_ptr->this_id = 16; // SCSI Id for the adapter itself
12611 + // Set the maximum number of simultaneous commands supported by the driver.
12612 + host_ptr->can_queue = MAX_DRIVER_QUEUE_DEPTH;
12614 + // Define the maximum number of scatter/gather elements supported by
12617 + host_ptr->sg_tablesize = 16;
12618 + host_ptr->max_sectors = 128;
12619 + host_ptr->cmd_per_lun = 1; // untagged queue depth
12621 + // This function is called after the device list has been built to find
12622 + // tagged queueing depth supported for each device.
12624 + host_ptr->select_queue_depths = AAC_SelectQueueDepths;
12625 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12627 + // attach a pointer back to Scsi_Host
12628 + CommonExtensionPtr->OsDep.scsi_host_ptr = host_ptr;
12629 + CommonExtensionPtr->OsDep.MiniPortIndex = index;
12631 + // Initialize the ordinal number of the device to -1
12632 + fsa_dev_ptr = &( CommonExtensionPtr->OsDep.fsa_dev );
12633 + for( ContainerId = 0; ContainerId < MAXIMUM_NUM_CONTAINERS; ContainerId++ )
12634 + fsa_dev_ptr->ContainerDevNo[ContainerId] = -1;
12636 + // Call initialization routine
12637 + cmn_err (CE_DEBUG, "Initializing Hardware...\n");
12638 + if( ( *MiniPorts[index].InitRoutine )
12639 + ( CommonExtensionPtr, host_ptr->unique_id, dev->bus->number, 0 ) != 0 )
12641 + // device initialization failed
12642 + cmn_err( CE_WARN, "%s:%d device initialization failed", DeviceName, host_ptr->unique_id );
12643 + scsi_unregister( host_ptr );
12644 + g_HostAdapterCount--;
12648 + cmn_err( CE_NOTE, "%s:%d device initialization successful", DeviceName, host_ptr->unique_id );
12649 + AacHba_ClassDriverInit( CommonExtensionPtr );
12650 + cmn_err(CE_NOTE, "%s:%d AacHba_ClassDriverInit complete", DeviceName, host_ptr->unique_id);
12651 + AacHba_ProbeContainers( CommonExtensionPtr );
12652 + g_CommonExtensionPtrArray[ g_HostAdapterCount - 1 ] = CommonExtensionPtr;
12656 + } /* end while */
12660 + if( g_HostAdapterCount ){
12661 + if( !( g_chardev_major = register_chrdev( 0, devicestr, &AAC_fops ) ) )
12662 + cmn_err( CE_WARN, "%s: unable to register %s device", DeviceName, devicestr);
12665 + HostTemplate->present = g_HostAdapterCount; // # of cards of this type found
12667 + return( g_HostAdapterCount );
12671 +/*------------------------------------------------------------------------------
12672 + AAC_ReleaseHostAdapter()
12674 + Release all resources previously acquired to support a specific Host
12675 + Adapter and unregister the AAC Host Adapter.
12676 + *----------------------------------------------------------------------------*/
12677 +int AAC_ReleaseHostAdapter(
12678 + struct Scsi_Host *host_ptr )
12679 +/*----------------------------------------------------------------------------*/
12681 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
12683 + cmn_err( CE_DEBUG, "AAC_ReleaseHostAdapter" );
12685 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )host_ptr->hostdata;
12687 + // kill any threads we started
12688 + kill_proc( CommonExtensionPtr->OsDep.thread_pid, SIGKILL, 0 );
12690 + // Call the comm layer to detach from this adapter
12691 + AacHba_DetachAdapter( CommonExtensionPtr->Adapter );
12693 + // remove interrupt binding
12694 + OsDetachInterrupt( CommonExtensionPtr->MiniPort );
12696 + SaDetachDevice( CommonExtensionPtr );
12698 + // unregister adapter
12699 + scsi_unregister( host_ptr );
12701 + if( g_chardev_major )
12703 + unregister_chrdev( g_chardev_major, devicestr );
12704 + g_chardev_major = 0;
12707 + return( 0 ); // #REVISIT# return code
12711 +/*------------------------------------------------------------------------------
12712 + AAC_QueueCommand()
12714 + Queues a command for execution by the associated Host Adapter.
12715 + *----------------------------------------------------------------------------*/
12716 +int AAC_QueueCommand(
12717 + Scsi_Cmnd *scsi_cmnd_ptr,
12718 + void ( *CompletionRoutine )( Scsi_Cmnd * ) )
12719 +/*----------------------------------------------------------------------------*/
12722 + scsi_cmnd_ptr->scsi_done = CompletionRoutine;
12724 + // AacHba_DoScsiCmd() handles command processing, setting the
12725 + // result code and calling completion routine.
12727 + if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 1 )) != 0 ) // call with wait = TRUE
12729 + if( (ret = AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 )) != 0 ) // call with wait = FALSE
12731 + cmn_err( CE_DEBUG, "AacHba_DoScsiCmd failed" );
12736 +/*------------------------------------------------------------------------------
12739 + Callback function for a non-queued command.
12742 + Sets g_single_command done to TRUE
12743 + *----------------------------------------------------------------------------*/
12745 + Scsi_Cmnd * scsi_cmnd_ptr )
12746 +/*----------------------------------------------------------------------------*/
12748 + g_single_command_done = TRUE;
12752 +/*------------------------------------------------------------------------------
12755 + Accepts a single command for execution by the associated Host Adapter.
12758 + Returns an int where:
12759 + Byte 0 = SCSI status code
12760 + Byte 1 = SCSI 1 byte message
12761 + Byte 2 = host error return
12762 + Byte 3 = mid level error return
12763 + *----------------------------------------------------------------------------*/
12765 + Scsi_Cmnd *scsi_cmnd_ptr )
12766 +/*----------------------------------------------------------------------------*/
12768 + scsi_cmnd_ptr->scsi_done = AAC_Done;
12770 + cmn_err( CE_DEBUG, "AAC_Command" );
12772 + // AacHba_DoScsiCmd() handles command processing, setting the
12773 + // result code and calling completion routine.
12774 + g_single_command_done = FALSE;
12776 + AacHba_DoScsiCmd( scsi_cmnd_ptr, 0 );
12777 + while( !g_single_command_done );
12778 + return( scsi_cmnd_ptr->result );
12782 +/*------------------------------------------------------------------------------
12783 + AAC_AbortCommand()
12785 + Abort command if possible.
12786 + *----------------------------------------------------------------------------*/
12787 +int AAC_AbortCommand(
12788 + Scsi_Cmnd *scsi_cmnd_ptr )
12789 +/*----------------------------------------------------------------------------*/
12791 + int target = scsi_cmnd_ptr->target;
12792 + int hba = scsi_cmnd_ptr->host->unique_id;
12794 + u_short interrupt_status;
12795 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12796 + char *DeviceName;
12798 + cmn_err( CE_WARN, "%s:%d ABORT", g_DriverName, hba, target );
12799 + AacHba_AbortScsiCommand( scsi_cmnd_ptr );
12801 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12802 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12805 + cmn_err( CE_WARN, "%s:%d Unable to abort command to target %d - "
12806 + "command already completed", DeviceName, hba, target);
12807 + result = SCSI_ABORT_NOT_RUNNING;
12809 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12810 + "no command found\n", DeviceName, hba, target);
12811 + result = SCSI_ABORT_NOT_RUNNING;
12813 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12814 + "command reset\n", DeviceName, hba, target);
12815 + result = SCSI_ABORT_PENDING;
12817 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d - "
12818 + "abort tag not supported\n", DeviceName, hba, target);
12819 + result = SCSI_ABORT_SNOOZE;
12821 + cmn_err(CE_WARN, "%s:%d Aborting command to target %d - pending",
12822 + DeviceName, hba, target);
12823 + result = SCSI_ABORT_PENDING;
12825 + cmn_err(CE_WARN, "%s:%d Unable to abort command to target %d",
12826 + DeviceName, hba, target);
12827 + result = SCSI_ABORT_BUSY;
12829 + cmn_err(CE_WARN, "%s:%d Aborted command to target %d\n",
12830 + DeviceName, hba, target);
12831 + result = SCSI_ABORT_SUCCESS;
12834 + // Abort not supported yet
12835 + result = SCSI_ABORT_BUSY;
12840 +/*------------------------------------------------------------------------------
12841 + AAC_ResetCommand()
12843 + Reset command handling.
12844 + *----------------------------------------------------------------------------*/
12845 +int AAC_ResetCommand(
12846 + struct scsi_cmnd *scsi_cmnd_ptr,
12847 + unsigned int reset_flags )
12848 +/*----------------------------------------------------------------------------*/
12850 + int target = scsi_cmnd_ptr->target;
12851 + int hba = scsi_cmnd_ptr->host->unique_id;
12852 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12853 + char *DeviceName;
12855 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( scsi_cmnd_ptr->host->hostdata );
12856 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12858 + cmn_err( CE_WARN, "%s:%d RESET", DeviceName, hba, target );
12860 + return SCSI_RESET_PUNT;
12864 +/*------------------------------------------------------------------------------
12867 + Returns the host adapter name
12868 + *----------------------------------------------------------------------------*/
12869 +const char *AAC_DriverInfo(
12870 + struct Scsi_Host *host_ptr )
12871 +/*----------------------------------------------------------------------------*/
12873 + PCI_MINIPORT_COMMON_EXTENSION *cep;
12874 + char *DeviceName;
12876 + cep = ( PCI_MINIPORT_COMMON_EXTENSION * )( host_ptr->hostdata );
12877 + DeviceName = MiniPorts[cep->OsDep.MiniPortIndex].DeviceName;
12879 + cmn_err( CE_DEBUG, "AAC_DriverInfo" );
12880 + return (DeviceName);
12884 +/*------------------------------------------------------------------------------
12885 + AAC_BIOSDiskParameters()
12887 + Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
12888 + The default disk geometry is 64 heads, 32 sectors, and the appropriate
12889 + number of cylinders so as not to exceed drive capacity. In order for
12890 + disks equal to or larger than 1 GB to be addressable by the BIOS
12891 + without exceeding the BIOS limitation of 1024 cylinders, Extended
12892 + Translation should be enabled. With Extended Translation enabled,
12893 + drives between 1 GB inclusive and 2 GB exclusive are given a disk
12894 + geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
12895 + are given a disk geometry of 255 heads and 63 sectors. However, if
12896 + the BIOS detects that the Extended Translation setting does not match
12897 + the geometry in the partition table, then the translation inferred
12898 + from the partition table will be used by the BIOS, and a warning may
12900 + *----------------------------------------------------------------------------*/
12901 +int AAC_BIOSDiskParameters(
12902 + Scsi_Disk *scsi_disk_ptr,
12904 + int *parameter_ptr )
12905 +/*----------------------------------------------------------------------------*/
12907 + AAC_BIOS_DiskParameters_T *disk_parameters =
12908 + ( AAC_BIOS_DiskParameters_T *)parameter_ptr;
12909 + struct buffer_head * buffer_head_ptr;
12911 + cmn_err( CE_DEBUG, "AAC_BIOSDiskParameters" );
12913 + // Assuming extended translation is enabled - #REVISIT#
12914 + if( scsi_disk_ptr->capacity >= 2 * 1024 * 1024 ) // 1 GB in 512 byte sectors
12916 + if( scsi_disk_ptr->capacity >= 4 * 1024 * 1024 ) // 2 GB in 512 byte sectors
12918 + disk_parameters->heads = 255;
12919 + disk_parameters->sectors = 63;
12923 + disk_parameters->heads = 128;
12924 + disk_parameters->sectors = 32;
12929 + disk_parameters->heads = 64;
12930 + disk_parameters->sectors = 32;
12933 + disk_parameters->cylinders = scsi_disk_ptr->capacity
12934 + /( disk_parameters->heads * disk_parameters->sectors );
12936 + // Read the first 1024 bytes from the disk device
12937 + buffer_head_ptr = bread(
12938 + MKDEV( MAJOR( device ),
12939 + MINOR( device ) & ~0x0F ),
12942 + if( buffer_head_ptr == NULL )
12945 + If the boot sector partition table is valid, search for a partition
12946 + table entry whose end_head matches one of the standard geometry
12947 + translations ( 64/32, 128/32, 255/63 ).
12949 + if( *( unsigned short * )( buffer_head_ptr->b_data + 0x1fe ) == 0xaa55 )
12951 + struct partition *first_partition_entry =
12952 + ( struct partition * )( buffer_head_ptr->b_data + 0x1be );
12953 + struct partition *partition_entry = first_partition_entry;
12954 + int saved_cylinders = disk_parameters->cylinders;
12955 + int partition_number;
12956 + unsigned char partition_entry_end_head, partition_entry_end_sector;
12958 + for( partition_number = 0; partition_number < 4; partition_number++ )
12960 + partition_entry_end_head = partition_entry->end_head;
12961 + partition_entry_end_sector = partition_entry->end_sector & 0x3f;
12963 + if( partition_entry_end_head == ( 64 - 1 ) )
12965 + disk_parameters->heads = 64;
12966 + disk_parameters->sectors = 32;
12969 + else if( partition_entry_end_head == ( 128 - 1 ) )
12971 + disk_parameters->heads = 128;
12972 + disk_parameters->sectors = 32;
12975 + else if( partition_entry_end_head == ( 255 - 1 ) )
12977 + disk_parameters->heads = 255;
12978 + disk_parameters->sectors = 63;
12981 + partition_entry++;
12984 + if( partition_number == 4 )
12986 + partition_entry_end_head = first_partition_entry->end_head;
12987 + partition_entry_end_sector = first_partition_entry->end_sector & 0x3f;
12990 + disk_parameters->cylinders = scsi_disk_ptr->capacity
12991 + /( disk_parameters->heads * disk_parameters->sectors );
12993 + if( ( partition_number < 4 ) && ( partition_entry_end_sector == disk_parameters->sectors ) )
12995 + if( disk_parameters->cylinders != saved_cylinders )
12996 + cmn_err( CE_DEBUG, "Adopting geometry: heads=%d, sectors=%d from partition table %d",
12997 + disk_parameters->heads, disk_parameters->sectors, partition_number );
12999 + else if( ( partition_entry_end_head > 0 ) || ( partition_entry_end_sector > 0 ) )
13001 + cmn_err( CE_DEBUG, "Strange geometry: heads=%d, sectors=%d in partition table %d",
13002 + partition_entry_end_head + 1, partition_entry_end_sector, partition_number );
13003 + cmn_err( CE_DEBUG, "Using geometry: heads=%d, sectors=%d",
13004 + disk_parameters->heads, disk_parameters->sectors );
13008 + brelse( buffer_head_ptr );
13014 +/*------------------------------------------------------------------------------
13015 + AAC_SelectQueueDepths()
13017 + Selects queue depths for each target device based on the host adapter's
13018 + total capacity and the queue depth supported by the target device.
13019 + A queue depth of one automatically disables tagged queueing.
13020 + *----------------------------------------------------------------------------*/
13021 +void AAC_SelectQueueDepths(
13022 + struct Scsi_Host * host_ptr,
13023 + Scsi_Device * scsi_device_ptr )
13024 +/*----------------------------------------------------------------------------*/
13026 + Scsi_Device * device_ptr;
13028 + cmn_err( CE_DEBUG, "AAC_SelectQueueDepths" );
13029 + cmn_err( CE_DEBUG, "Device # Q Depth Online" );
13030 + cmn_err( CE_DEBUG, "---------------------------" );
13031 + for( device_ptr = scsi_device_ptr; device_ptr != NULL; device_ptr = device_ptr->next )
13032 + if( device_ptr->host == host_ptr )
13034 + device_ptr->queue_depth = 10;
13035 + cmn_err( CE_DEBUG, " %2d %d %d",
13036 + device_ptr->id, device_ptr->queue_depth, device_ptr->online );
13041 +/*------------------------------------------------------------------------------
13042 + AAC_SearchBiosSignature()
13044 + Locate adapter signature in BIOS
13045 + *----------------------------------------------------------------------------*/
13046 +int AAC_SearchBiosSignature( void )
13047 +/*----------------------------------------------------------------------------*/
13053 + char name_buf[32];
13054 + int result = FALSE;
13056 + for( base = 0xc8000; base < 0xdffff; base += 0x4000 )
13058 + val = readb( base );
13059 + if( val != 0x55 )
13063 + namep = base + 0x1e;
13064 + memcpy_fromio( name_buf, namep, 32 );
13065 + name_buf[31] = '\0';
13067 + return( result );
13071 +/*------------------------------------------------------------------------------
13074 + Handle SCSI ioctls
13075 + *----------------------------------------------------------------------------*/
13077 + Scsi_Device * scsi_dev_ptr,
13080 +/*----------------------------------------------------------------------------*/
13082 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13084 + cmn_err( CE_DEBUG, "AAC_Ioctl" );
13085 + CommonExtensionPtr = ( PCI_MINIPORT_COMMON_EXTENSION * )scsi_dev_ptr->host->hostdata;
13086 + return( AacHba_Ioctl( CommonExtensionPtr, cmd, arg ) );
13091 +/*------------------------------------------------------------------------------
13092 + AAC_ChardevOpen()
13094 + Handle character device open
13098 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13099 + *----------------------------------------------------------------------------*/
13100 +int AAC_ChardevOpen(
13101 + struct inode * inode_ptr,
13102 + struct file * file_ptr )
13103 +/*----------------------------------------------------------------------------*/
13105 + unsigned minor_number;
13107 + cmn_err( CE_DEBUG, "AAC_ChardevOpen" );
13109 + // check device permissions in file_ptr->f_mode ??
13111 + // extract & check the minor number
13112 + minor_number = MINOR( inode_ptr->i_rdev );
13113 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13115 + cmn_err( CE_WARN, "AAC_ChardevOpen: Minor number %d not supported", minor_number );
13116 + return( -ENODEV );
13120 + MOD_INC_USE_COUNT;
13127 +/*------------------------------------------------------------------------------
13128 + AAC_ChardevRelease()
13130 + Handle character device release.
13134 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13135 + *----------------------------------------------------------------------------*/
13136 +int AAC_ChardevRelease(
13137 + struct inode * inode_ptr,
13138 + struct file * file_ptr )
13139 +/*----------------------------------------------------------------------------*/
13141 + cmn_err( CE_DEBUG, "AAC_ChardevRelease" );
13144 + MOD_DEC_USE_COUNT;
13151 +/*------------------------------------------------------------------------------
13152 + AAC_ChardevIoctl()
13154 + Handle character device interface ioctls
13158 + Returns 0 if successful, -ENODEV or -EINVAL otherwise
13159 + *----------------------------------------------------------------------------*/
13160 +int AAC_ChardevIoctl(
13161 + struct inode * inode_ptr,
13162 + struct file * file_ptr,
13163 + unsigned int cmd,
13164 + unsigned long arg )
13166 + unsigned minor_number;
13167 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtensionPtr;
13169 + cmn_err( CE_DEBUG, "AAC_ChardevIoctl" );
13171 + // check device permissions in file_ptr->f_mode ??
13173 + // extract & check the minor number
13174 + minor_number = MINOR( inode_ptr->i_rdev );
13175 + if( minor_number > ( g_HostAdapterCount - 1 ) )
13177 + cmn_err( CE_WARN, "AAC_ChardevIoctl: Minor number %d not supported", minor_number );
13178 + return( -ENODEV );
13181 + // get device pointer
13182 + CommonExtensionPtr = g_CommonExtensionPtrArray[ minor_number ];
13184 + // dispatch ioctl - AacHba_Ioctl() returns zero on success
13185 + if( AacHba_Ioctl( CommonExtensionPtr, cmd, ( void * )arg ) )
13186 + return( -EINVAL );
13192 +/*------------------------------------------------------------------------------
13195 + Look for the keyword in str_ptr
13200 + - return true and update the pointer str_ptr.
13203 + *----------------------------------------------------------------------------*/
13204 +static int parse_keyword(
13207 +/*----------------------------------------------------------------------------*/
13209 + char * ptr = *str_ptr;
13211 + while( *keyword != '\0' )
13213 + char string_char = *ptr++;
13214 + char keyword_char = *keyword++;
13216 + if ( ( string_char >= 'A' ) && ( string_char <= 'Z' ) )
13217 + string_char += 'a' - 'Z';
13218 + if( ( keyword_char >= 'A' ) && ( keyword_char <= 'Z' ) )
13219 + keyword_char += 'a' - 'Z';
13220 + if( string_char != keyword_char )
13228 +/*------------------------------------------------------------------------------
13229 + AAC_ParseDriverOptions()
13231 + For modules the usage is:
13232 + insmod -f aacraid.o 'aacraid_options="<option_name:argument>"'
13233 + *----------------------------------------------------------------------------*/
13234 +static void AAC_ParseDriverOptions(
13235 + char * cmnd_line_options_str )
13236 +/*----------------------------------------------------------------------------*/
13238 + int message_level;
13239 + int reverse_scan;
13243 + cp = cmnd_line_options_str;
13245 + cmn_err(CE_DEBUG, "AAC_ParseDriverOptions: <%s>", cp);
13248 + if( parse_keyword( &cp, "message_level:" ) ) {
13249 + message_level = simple_strtoul( cp, 0, 0 );
13250 + if( ( message_level < CE_TAIL ) && ( message_level >= 0 ) ) {
13251 + g_options.message_level = message_level;
13252 + cmn_err( CE_WARN, "%s: new message level = %d", g_DriverName, g_options.message_level );
13255 + cmn_err( CE_WARN, "%s: invalid message level = %d", g_DriverName, message_level );
13257 + } else if (parse_keyword( &cp, "reverse_scan:" ) ) {
13258 + reverse_scan = simple_strtoul( cp, 0, 0 );
13259 + if (reverse_scan) {
13260 + g_options.reverse_scan = 1;
13261 + cmn_err( CE_WARN, "%s: reversing device discovery order", g_DriverName, g_options.message_level );
13265 + cmn_err( CE_WARN, "%s: unknown command line option <%s>", g_DriverName, cp );
13269 + * skip to next option, accept " ", ";", and "," as delimiters
13271 + while ( *cp && (*cp != ' ') && (*cp != ';') && (*cp != ','))
13274 + if (*cp) /* skip over the delimiter */
13281 +/*------------------------------------------------------------------------------
13282 + Include Module support if requested.
13284 + To use the low level SCSI driver support using the linux kernel loadable
13285 + module interface we should initialize the global variable driver_interface
13286 + (datatype Scsi_Host_Template) and then include the file scsi_module.c.
13287 + This should also be wrapped in a #ifdef MODULE/#endif
13288 + *----------------------------------------------------------------------------*/
13292 + The Loadable Kernel Module Installation Facility may pass us
13293 + a pointer to a driver specific options string to be parsed,
13294 + we assign this to options string.
13296 +MODULE_PARM( module_options, "s" );
13298 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13300 +#include "scsi_module.c"
13303 +Scsi_Host_Template driver_template = AAC_HOST_TEMPLATE_ENTRY;
13305 +#include "scsi_module.c"
13308 +/*********************************************************************
13309 + AAC_ProcDirectoryInfo()
13311 + Implement /proc/scsi/<drivername>/<n>.
13312 + Used to export driver statistics and other infos to the world outside
13313 + the kernel using the proc file system. Also provides an interface to
13314 + feed the driver with information.
13318 + - if offset > 0 return 0
13319 + - if offset == 0 write data to proc_buffer and set the start_ptr to
13320 + beginning of proc_buffer, return the number of characters written.
13322 + - writes currently not supported, return 0
13323 +************************************************************/
13324 +int AAC_ProcDirectoryInfo(
13325 + char *proc_buffer, // read/write buffer
13326 + char **start_ptr, // start of valid data in the buffer
13327 + off_t offset, // offset from the beginning of the imaginary file
13328 + int bytes_available, // bytes available
13329 + int host_no, // SCSI host number
13330 + int write ) // direction of dataflow: TRUE for writes, FALSE for reads
13333 + cmn_err( CE_WARN, "AAC_ProcDirectoryInfo" );
13335 + if( ( write ) || ( offset > 0 ) )
13338 + *start_ptr = proc_buffer;
13340 + return( sprintf(&proc_buffer[length], "%s %d\n", "Raid Controller, scsi hba number", host_no ) );
13343 +void aac_allocate_SyncFibs (PCI_MINIPORT_COMMON_EXTENSION *CommonExtension)
13345 + void *BaseAddress;
13346 + ULONG PhysAddress;
13351 + AFA_COMM_ADAPTER *Adapter;
13352 + Adapter = CommonExtension->Adapter;
13355 + // Allocate 1 fib for synch fibs
13356 + // Allocate 1 page.
13357 + BaseAddress = OsAllocMemory ( PAGE_SIZE, OS_ALLOC_MEM_SLEEP);
13358 + bzero(BaseAddress, PAGE_SIZE);
13359 + PhysAddress = virt_to_phys (BaseAddress);
13360 + Adapter->SyncFib = BaseAddress;
13361 + Adapter->SyncFibPhysicalAddress = PhysAddress;
13362 + cmn_err(CE_DEBUG,"aac_allocate_SyncFibs: syncFib: vaddr: 0x%x paddr: 0x%x ", BaseAddress, PhysAddress);
13365 diff -burN linux-2.4.7/drivers/scsi/aacraid/osddi.c linux/drivers/scsi/aacraid/osddi.c
13366 --- linux-2.4.7/drivers/scsi/aacraid/osddi.c Wed Dec 31 18:00:00 1969
13367 +++ linux/drivers/scsi/aacraid/osddi.c Sat Jul 21 17:55:14 2001
13370 + * Adaptec aacraid device driver for Linux.
13372 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13374 + * This program is free software; you can redistribute it and/or modify
13375 + * it under the terms of the GNU General Public License as published by
13376 + * the Free Software Foundation; either version 2, or (at your option)
13377 + * any later version.
13379 + * This program is distributed in the hope that it will be useful,
13380 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13381 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13382 + * GNU General Public License for more details.
13384 + * You should have received a copy of the GNU General Public License
13385 + * along with this program; see the file COPYING. If not, write to
13386 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13391 + * Abstract: This file contains all the proceedures which use LINUX specific Device
13392 + * Driver Interfaces.
13396 +static char *ident_osddi = "aacraid_ident osddi.c 1.0.6 2000/10/09 Adaptec, Inc.";
13398 +#include "osheaders.h"
13400 +#include <linux/smp_lock.h>
13405 +#include "AacGenericTypes.h"
13406 +#include "aac_unix_defs.h"
13407 +#include "comstruc.h"
13408 +#include "monkerapi.h"
13409 +#include "protocol.h"
13410 +#include "fsafs.h"
13412 +#include "sap1common.h"
13413 +#include "fsaport.h"
13414 +#include "pcisup.h"
13416 +#include "nodetype.h"
13417 +#include "comsup.h"
13418 +#include "afacomm.h"
13419 +#include "adapter.h"
13425 + struct pt_regs *regs);
13430 + struct pt_regs *regs);
13432 +unsigned SaPciIsr (
13433 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13435 +unsigned RxPciIsr (
13436 + IN PSa_ADAPTER_EXTENSION AdapterExtension );
13439 +/*----------------------------------------------------------------------------*/
13440 +VOID AfaCommInterruptHost(
13441 + PVOID AdapterArg,
13442 + ADAPTER_EVENT AdapterEvent )
13443 +/*----------------------------------------------------------------------------*/
13445 + PAFA_COMM_ADAPTER Adapter = ( PAFA_COMM_ADAPTER ) AdapterArg;
13446 + PCOMM_REGION CommRegion = Adapter->CommRegion;
13448 + switch (AdapterEvent) {
13450 + case HostNormRespQue:
13451 + OsSoftInterruptTrigger( CommRegion->HostNormRespQue.ConsumerRoutine );
13453 + // #REVIEW# - what do we do with this
13454 + // if (FsaCommData.HardInterruptModeration)
13455 + // DisableInterrupt( Adapter, HostNormRespQue, TRUE );
13459 + case AdapNormCmdNotFull:
13460 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13463 + case HostNormCmdQue:
13464 + OsSoftInterruptTrigger( CommRegion->HostNormCmdQue.ConsumerRoutine );
13467 + case AdapNormRespNotFull:
13468 + OsSoftInterruptTrigger( CommRegion->QueueNotFullDpc );
13471 + // #REVIEW# - what do we do with these
13472 + case HostHighCmdQue:
13473 + case HostHighRespQue:
13474 + case AdapHighCmdNotFull:
13475 + case AdapHighRespNotFull:
13476 + case SynchCommandComplete:
13477 + case AdapInternalError:
13483 +// get the device name associated with this instance of the device
13484 +/*----------------------------------------------------------------------------*/
13485 +char *OsGetDeviceName(
13486 + void *AdapterExtension )
13487 +/*----------------------------------------------------------------------------*/
13489 + return( ( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13490 + OsDep.scsi_host_ptr->hostt->name );
13494 +/*----------------------------------------------------------------------------*/
13495 +int OsGetDeviceInstance(
13496 + void *AdapterExtension )
13497 +/*----------------------------------------------------------------------------*/
13499 + return( ( int )( ( Sa_ADAPTER_EXTENSION * )AdapterExtension )->Common->
13500 + OsDep.scsi_host_ptr->unique_id );
13504 +/*------------------------------------------------------------------------------
13505 + OsMapDeviceRegisters()
13508 + Return zero on success non-zero otherwise.
13509 + *----------------------------------------------------------------------------*/
13510 +int OsMapDeviceRegisters(
13511 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13512 +/*----------------------------------------------------------------------------*/
13514 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13516 + CommonExtension = AdapterExtension->Common;
13518 + if( AdapterExtension->Device = ( Sa_DEVICE_REGISTERS * )
13519 + ioremap( ( unsigned long )CommonExtension->OsDep.scsi_host_ptr->base, 8192 ) )
13521 + cmn_err( CE_WARN, "Device mapped to virtual address 0x%x", AdapterExtension->Device );
13526 + cmn_err( CE_WARN, "OsMapDeviceRegisters: ioremap() failed" );
13532 +/*------------------------------------------------------------------------------
13533 + OsUnMapDeviceRegisters()
13536 + *----------------------------------------------------------------------------*/
13537 +void OsUnMapDeviceRegisters(
13538 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13539 +/*----------------------------------------------------------------------------*/
13541 + iounmap( ( void * )AdapterExtension->Device );
13545 +/*----------------------------------------------------------------------------*/
13546 +int OsAttachInterrupt(
13547 + Sa_ADAPTER_EXTENSION *AdapterExtension ,
13549 +/*----------------------------------------------------------------------------*/
13551 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13555 + CommonExtension = AdapterExtension->Common;
13556 + irq_data = ( void * )AdapterExtension;
13558 + switch (WhichIsr) {
13560 + Isr = AacSaPciIsr;
13563 + Isr = AacRxPciIsr;
13566 + cmn_err(CE_WARN, "OsAttachInterrupt: invalid ISR case: 0x%x", WhichIsr);
13567 + return( FAILURE );
13572 + if ( OsRegisterInterrupt (
13573 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13574 + Isr, // handler function
13578 + cmn_err( CE_WARN, "OsAttachInterrupt: Failed for IRQ: 0x%x",
13579 + CommonExtension->OsDep.scsi_host_ptr->irq );
13580 + return( FAILURE );
13587 +/*----------------------------------------------------------------------------*/
13591 + struct pt_regs *regs)
13592 +/*----------------------------------------------------------------------------*/
13594 + // call the actual interrupt handler
13595 + SaPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13598 +/*----------------------------------------------------------------------------*/
13602 + struct pt_regs *regs)
13603 +/*----------------------------------------------------------------------------*/
13605 + // call the actual interrupt handler
13606 + RxPciIsr( ( Sa_ADAPTER_EXTENSION * )irq_data );
13610 +/*----------------------------------------------------------------------------*/
13611 +void OsDetachInterrupt(
13612 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13613 +/*----------------------------------------------------------------------------*/
13615 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13618 + CommonExtension = AdapterExtension->Common;
13619 + irq_data = ( void * )AdapterExtension;
13621 + OsUnregisterInterrupt (
13622 + CommonExtension->OsDep.scsi_host_ptr->irq, // interrupt number
13627 +/*----------------------------------------------------------------------------*/
13629 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13630 +/*----------------------------------------------------------------------------*/
13635 +/*----------------------------------------------------------------------------*/
13637 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13638 +/*----------------------------------------------------------------------------*/
13643 +/*----------------------------------------------------------------------------*/
13644 +void OsDetachDevice(
13645 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13646 +/*----------------------------------------------------------------------------*/
13648 + OsUnMapDeviceRegisters( AdapterExtension );
13652 +/*----------------------------------------------------------------------------*/
13653 +ULONG *OsAllocCommPhysMem(
13654 + Sa_ADAPTER_EXTENSION *AdapterExtension,
13656 + ULONG **virt_addr_pptr,
13657 + ULONG *phys_addr_ptr )
13658 +/*----------------------------------------------------------------------------*/
13660 + if( ( *virt_addr_pptr = ( ULONG * )OsAllocMemory( size, GFP_KERNEL ) ) )
13662 + *phys_addr_ptr = OsVirtToPhys( ( volatile void * )*virt_addr_pptr );
13663 + if( !*phys_addr_ptr )
13665 + cmn_err( CE_WARN, "OsAllocCommPhysMem: OsVirtToPhys failed" );
13668 + return( *virt_addr_pptr );
13674 +OsAifKernelThread(
13675 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13678 + struct fs_struct *fs;
13680 + struct task_struct *tsk;
13686 + * set up the name that will appear in 'ps'
13687 + * stored in task_struct.comm[16].
13690 + sprintf(tsk->comm, "AIFd");
13693 + // use_init_fs_context(); only exists in 2.2.13 onward.
13700 + * we were started as a result of loading the module.
13701 + * free all of user space pages
13710 + fs = init_task.fs;
13713 + tsk->session = 1;
13717 + atomic_inc(&fs->count);
13726 + NormCommandThread(AdapterExtension);
13727 + /* NOT REACHED */
13730 +/*----------------------------------------------------------------------------*/
13731 +void OsStartKernelThreads(
13732 + Sa_ADAPTER_EXTENSION *AdapterExtension )
13733 +/*----------------------------------------------------------------------------*/
13735 + PCI_MINIPORT_COMMON_EXTENSION *CommonExtension;
13736 + AFA_COMM_ADAPTER *Adapter;
13737 + extern void NormCommandThread(void *Adapter);
13739 + CommonExtension = AdapterExtension->Common;
13740 + Adapter = (AFA_COMM_ADAPTER *)CommonExtension->Adapter;
13743 + // Start thread which will handle interrupts for this adapter
13745 + //kthread_spawn(FsaCommIntrHandler, AdapterExtension, "fsaintr",0);
13748 + // Start thread which will handle AdapterInititatedFibs from this adapter
13750 + CommonExtension->OsDep.thread_pid =
13751 + kernel_thread( ( int ( * )( void * ) )OsAifKernelThread, Adapter, 0 );
13752 +// kernel_thread( ( int ( * )( void * ) )NormCommandThread, Adapter, 0 );
13755 +/*----------------------------------------------------------------------------*/
13756 +BOOLEAN AfaPortAllocateAndMapFibSpace(
13758 + IN PMAPFIB_CONTEXT MapFibContext )
13759 +/*----------------------------------------------------------------------------*/
13761 + PVOID BaseAddress;
13762 + ULONG PhysAddress;
13764 + if( !( BaseAddress = (ULONG *)OsAllocMemory( MapFibContext->Size, GFP_KERNEL ) ) )
13766 + cmn_err( CE_WARN, "AfaPortAllocateAndMapFibSpace: OsAllocMemory failed" );
13770 + PhysAddress = OsVirtToPhys( BaseAddress );
13772 + MapFibContext->FibVirtualAddress = BaseAddress;
13773 + MapFibContext->FibPhysicalAddress = (PVOID) PhysAddress;
13778 +/*----------------------------------------------------------------------------*/
13779 +BOOLEAN AfaPortUnmapAndFreeFibSpace(
13781 + IN PMAPFIB_CONTEXT MapFibContext )
13782 +/*----------------------------------------------------------------------------*/
13784 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13786 + OsFreeMemory( MapFibContext->FibVirtualAddress, 0 );
13791 +/*----------------------------------------------------------------------------*/
13792 +BOOLEAN AfaPortFreeAdapterCommArea(
13794 +/*----------------------------------------------------------------------------*/
13796 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
13798 + OsFreeMemory( CommonExtension->CommAddress, 0 );
13804 +/* ================================================================================ */
13806 + * Not sure if the functions below here ever get called in the current code
13807 + * These probably should be a different file.
13810 +ddi_dma_attr_t AfaPortDmaAttributes = {
13811 + //rpbfix : we may want something different for I/O
13828 +AfaPortBuildSgMap(
13830 + IN PSGMAP_CONTEXT SgMapContext
13835 +Routine Description:
13837 + This routine build a scatter gather map using the information
13838 + in the SgMapContext.
13842 + AdapterExtension - Pointer to adapter extension structure.
13843 + SgMapContext - Pointer to the SgMapContext for the request.
13851 + printk( KERN_ALERT "AfaPortBuildSgMap: unimplemented function called" );
13852 + return (STATUS_UNSUCCESSFUL);
13856 +AfaPortFreeDmaResources(
13858 + IN PSGMAP_CONTEXT SgMapContext
13863 +Routine Description:
13865 + Given a pointer to the IRP context will free all reserved DMA resources allocated for
13866 + the completed IO operation.
13870 + Fib - Pointer to the Fib the caller wishes to have transfered over to the adapter.
13871 + Context - Pointer to the Irp Context we use to store the dma mapping information
13872 + we need to do and complete the IO.
13881 diff -burN linux-2.4.7/drivers/scsi/aacraid/osfuncs.c linux/drivers/scsi/aacraid/osfuncs.c
13882 --- linux-2.4.7/drivers/scsi/aacraid/osfuncs.c Wed Dec 31 18:00:00 1969
13883 +++ linux/drivers/scsi/aacraid/osfuncs.c Sat Jul 21 17:55:14 2001
13886 + * Adaptec aacraid device driver for Linux.
13888 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
13890 + * This program is free software; you can redistribute it and/or modify
13891 + * it under the terms of the GNU General Public License as published by
13892 + * the Free Software Foundation; either version 2, or (at your option)
13893 + * any later version.
13895 + * This program is distributed in the hope that it will be useful,
13896 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13897 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13898 + * GNU General Public License for more details.
13900 + * You should have received a copy of the GNU General Public License
13901 + * along with this program; see the file COPYING. If not, write to
13902 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
13907 + * Abstract: Holds all of the O/S specific interface functions.
13911 +static char *ident_osfuncs = "aacraid_ident osfuncs.c 1.0.6 2000/10/09 Adaptec, Inc.";
13913 +#include "osheaders.h"
13915 +//static LKINFO_DECL(fsa_locks, "fsa_locks",0);
13917 +extern aac_options_t g_options;
13919 +OS_SOFTINTR g_idle_task = { 0, 0, 0, 0 };
13920 +wait_queue_t * g_wait_queue_ptr = NULL;
13921 +wait_queue_t g_wait;
13923 +void OsTimeoutHandler(
13924 + struct semaphore * sem );
13926 +int * OsIdleTask( void * data );
13928 +//-----------------------------------------------------------------------------
13929 +// Memory Allocation functions
13931 +/*----------------------------------------------------------------------------*/
13932 +void * OsAllocMemory(
13934 + unsigned int Flags )
13935 +/*----------------------------------------------------------------------------*/
13939 + if( !( mem_ptr = kmalloc( Size, GFP_KERNEL ) ) )
13940 + cmn_err( CE_WARN, "OsAllocMemory: FAILED\n" );
13941 + return( mem_ptr );
13945 +/*----------------------------------------------------------------------------*/
13946 +void OsFreeMemory(
13949 +/*----------------------------------------------------------------------------*/
13955 +/*----------------------------------------------------------------------------*/
13956 +int OsRegisterInterrupt(
13957 + unsigned int irq, // interrupt number
13958 + void ( *handler )( int, void*, struct pt_regs * ), // handler function
13959 + void *irq_data ) // argument to handler function
13960 +/*----------------------------------------------------------------------------*/
13962 + return( request_irq (irq, handler, SA_INTERRUPT | SA_SHIRQ, "aacraid", irq_data ) );
13966 +/*----------------------------------------------------------------------------*/
13967 +void OsUnregisterInterrupt(
13968 + unsigned int irq, // interrupt number
13970 +/*----------------------------------------------------------------------------*/
13973 + irq, // interrupt number
13978 +/*----------------------------------------------------------------------------*/
13979 +unsigned long OsVirtToPhys(
13980 + void * virtual_address )
13981 +/*----------------------------------------------------------------------------*/
13983 + return( virt_to_phys( virtual_address ) );
13987 +//-----------------------------------------------------------------------------
13988 +// MUTEX functions
13990 +/*----------------------------------------------------------------------------*/
13991 +OS_STATUS OsMutexInit(
13993 + OS_SPINLOCK_COOKIE Cookie )
13994 +/*----------------------------------------------------------------------------*/
13996 + Mutex->lock_var = 0;
13997 + // bzero (&Mutex->wq, sizeof (Mutex->wq));
13998 + init_waitqueue_head (&Mutex->wq);
14003 +/*----------------------------------------------------------------------------*/
14004 +void OsMutexDestroy(
14005 + OS_MUTEX *Mutex )
14006 +/*----------------------------------------------------------------------------*/
14011 +/*----------------------------------------------------------------------------*/
14012 +void OsMutexAcquire(
14013 + OS_MUTEX *Mutex )
14014 +/*----------------------------------------------------------------------------*/
14016 + // wait_queue_t wait = { current, NULL };
14017 + unsigned long time_stamp;
14019 + DECLARE_WAITQUEUE (wait, current);
14021 + time_stamp = jiffies;
14023 + if( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14025 + if( in_interrupt() )
14026 + panic( "OsMutexAcquire going to sleep at interrupt time\n" );
14027 + current->state = TASK_INTERRUPTIBLE;
14028 + add_wait_queue( &( Mutex->wq ), &wait );
14029 + while( test_and_set_bit( 0, &( Mutex->lock_var ) ) != 0 )
14031 + remove_wait_queue( &( Mutex->wq ), &wait );
14034 + if( ( jiffies - 1 ) > time_stamp )
14035 + cmn_err( CE_WARN, "Mutex %ld locked out for %ld ticks",
14036 + Mutex, jiffies - time_stamp );
14040 +/*----------------------------------------------------------------------------*/
14041 +void OsMutexRelease(
14042 + OS_MUTEX *Mutex )
14043 +/*----------------------------------------------------------------------------*/
14045 + if( test_and_clear_bit( 0, &( Mutex->lock_var ) ) == 0 )
14046 + cmn_err( CE_WARN, "OsMutexRelease: mutex not locked" );
14047 + wake_up_interruptible( &( Mutex->wq ) );
14050 +// see man hierarchy(D5)
14051 +#define FSA_LOCK 1
14053 +//-----------------------------------------------------------------------------
14054 +// Spinlock functions
14056 +/*----------------------------------------------------------------------------*/
14057 +OS_SPINLOCK * OsSpinLockAlloc( void )
14058 +/*----------------------------------------------------------------------------*/
14060 + OS_SPINLOCK *SpinLock;
14064 + SpinLock = ( OS_SPINLOCK * )kmalloc( sizeof( OS_SPINLOCK ), GFP_KERNEL );
14066 + if (SpinLock == NULL)
14067 + cmn_err (CE_WARN, "WARNING: OsSpinLockAlloc Failed!!!");
14069 + SpinLock->spin_lock = SPIN_LOCK_UNLOCKED;
14070 + for( i = 0; i < NR_CPUS; i++ )
14071 + SpinLock->cpu_lock_count[ i ] = 0;
14072 + return( SpinLock );
14076 +/*----------------------------------------------------------------------------*/
14077 +OS_STATUS OsSpinLockInit(
14078 + OS_SPINLOCK *SpinLock,
14079 + OS_SPINLOCK_COOKIE Cookie )
14080 +/*----------------------------------------------------------------------------*/
14086 +/*----------------------------------------------------------------------------*/
14087 +void OsSpinLockDestroy(
14088 + OS_SPINLOCK *SpinLock )
14089 +/*----------------------------------------------------------------------------*/
14091 + kfree( SpinLock );
14096 +/*----------------------------------------------------------------------------*/
14097 +void OsSpinLockAcquire(
14098 + OS_SPINLOCK *SpinLock )
14099 +/*----------------------------------------------------------------------------*/
14105 + cpu_id = smp_processor_id();
14106 + if( SpinLock->cpu_lock_count[ cpu_id ] ){
14107 + cmn_err (CE_PANIC, "CPU %d trying to acquire lock again: lock count = %d\n",
14108 + cpu_id, SpinLock->cpu_lock_count[ cpu_id ]);
14111 + spin_lock_irqsave( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14112 + SpinLock->cpu_lock_count[ cpu_id ]++;
14115 + cmn_err( CE_WARN, "OsSpinLockAcquire: lock does not exist" );
14120 +/*----------------------------------------------------------------------------*/
14121 +void OsSpinLockRelease(
14122 + OS_SPINLOCK *SpinLock )
14123 +/*----------------------------------------------------------------------------*/
14129 + cpu_id = smp_processor_id();
14130 + SpinLock->cpu_lock_count[ cpu_id ]--;
14131 + spin_unlock_irqrestore( &( SpinLock->spin_lock ), SpinLock->cpu_flags[ cpu_id ] );
14134 + cmn_err( CE_WARN, "OsSpinLockRelease: lock does not exist" );
14138 +/*----------------------------------------------------------------------------*/
14139 +int OsSpinLockOwned(
14140 + OS_SPINLOCK *SpinLock )
14141 +/*----------------------------------------------------------------------------*/
14144 + if( SpinLock->spin_lock.lock != 0 )
14152 +//-----------------------------------------------------------------------------
14153 +// CvLock functions
14155 +/*----------------------------------------------------------------------------*/
14156 +OS_CVLOCK *OsCvLockAlloc( void )
14158 + OS_CVLOCK *cv_lock;
14161 +#ifdef CVLOCK_USE_SPINLOCK
14162 + cv_lock = OsSpinLockAlloc();
14164 + cv_lock = ( OS_CVLOCK * )kmalloc( sizeof( OS_CVLOCK ), GFP_KERNEL );
14165 + cv_lock->wq = NULL;
14166 + cv_lock->lock_var = 0;
14169 + return( cv_lock );
14173 +/*----------------------------------------------------------------------------*/
14174 +OS_STATUS OsCvLockInit(
14175 + OS_CVLOCK *cv_lock,
14176 + OS_SPINLOCK_COOKIE Cookie )
14177 +/*----------------------------------------------------------------------------*/
14183 +/*----------------------------------------------------------------------------*/
14184 +void OsCvLockDestroy(
14185 + OS_CVLOCK *cv_lock )
14186 +/*----------------------------------------------------------------------------*/
14189 + kfree( cv_lock );
14194 +/*----------------------------------------------------------------------------*/
14195 +void OsCvLockAcquire (OS_CVLOCK *cv_lock)
14197 +#ifdef CVLOCK_USE_SPINLOCK
14198 + OsSpinLockAcquire( cv_lock );
14200 + OsMutexAcquire( cv_lock );
14205 +/*----------------------------------------------------------------------------*/
14206 +void OsCvLockRelease(
14207 + OS_CVLOCK *cv_lock )
14208 +/*----------------------------------------------------------------------------*/
14210 +#ifdef CVLOCK_USE_SPINLOCK
14211 + OsSpinLockRelease( cv_lock );
14213 + OsMutexRelease( cv_lock );
14218 +/*----------------------------------------------------------------------------*/
14219 +int OsCvLockOwned(
14220 + OS_CVLOCK *cv_lock )
14221 +/*----------------------------------------------------------------------------*/
14227 +//-----------------------------------------------------------------------------
14228 +// Conditional variable functions
14230 +/*----------------------------------------------------------------------------*/
14232 + OS_CV_T *cv_ptr )
14233 +/*----------------------------------------------------------------------------*/
14235 + cv_ptr->lock_var = 1;
14236 + init_waitqueue_head (&cv_ptr->wq);
14240 +/*----------------------------------------------------------------------------*/
14241 +void OsCv_destroy(
14242 + OS_CV_T *cv_ptr )
14243 +/*----------------------------------------------------------------------------*/
14248 +/*______________________________________________________________________________
14251 + -----------------------------------------------------------------------------*/
14252 +OsCv_wait (OS_CV_T *cv_ptr, OS_CVLOCK *cv_lock_ptr)
14254 + unsigned long flags;
14256 + DECLARE_WAITQUEUE (wait, current);
14258 + if( in_interrupt() )
14259 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14261 + cv_ptr->type = TASK_UNINTERRUPTIBLE;
14262 + current->state = TASK_UNINTERRUPTIBLE;
14264 + add_wait_queue( &cv_ptr->wq, &wait );
14266 + OsCvLockRelease( cv_lock_ptr );
14269 + while( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 )
14271 + if( in_interrupt() )
14272 + panic( "OsCv_wait going to sleep at interrupt time\n" );
14276 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14278 + OsCvLockAcquire( cv_lock_ptr );
14282 +/*----------------------------------------------------------------------------*/
14283 +int OsCv_wait_sig(
14285 + OS_CVLOCK *cv_lock_ptr )
14286 +/*----------------------------------------------------------------------------*/
14288 + unsigned long flags;
14289 + int signal_state = 1;
14291 + DECLARE_WAITQUEUE (wait, current);
14293 + if( in_interrupt() )
14294 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14296 + cv_ptr->type = TASK_INTERRUPTIBLE;
14297 + current->state = TASK_INTERRUPTIBLE;
14299 + add_wait_queue( &( cv_ptr->wq ), &wait );
14301 + OsCvLockRelease( cv_lock_ptr );
14304 + while( ( test_and_set_bit( 0, &( cv_ptr->lock_var ) ) != 0 ) &&
14305 + ( !signal_pending( current ) ) )
14307 + if( in_interrupt() )
14308 + panic( "OsCv_wait_sig going to sleep at interrupt time\n" );
14312 + if( signal_pending( current ) )
14313 + signal_state = 0;
14315 + remove_wait_queue( &( cv_ptr->wq ), &wait );
14317 + OsCvLockAcquire( cv_lock_ptr );
14318 + return( signal_state );
14322 +/*----------------------------------------------------------------------------*/
14324 + OS_CV_T *cv_ptr )
14325 +/*----------------------------------------------------------------------------*/
14328 + clear_bit( 0, &( cv_ptr->lock_var ) );
14329 + if( cv_ptr->type == TASK_INTERRUPTIBLE )
14330 + wake_up_interruptible( &( cv_ptr->wq ) );
14332 + wake_up( &( cv_ptr->wq ) );
14337 +// return time in seconds
14338 +/*----------------------------------------------------------------------------*/
14339 +unsigned long OsGetSeconds( void )
14340 +/*----------------------------------------------------------------------------*/
14342 + return( jiffies/HZ );
14346 +//-----------------------------------------------------------------------------
14347 +// Deferred procedure call functions
14349 +// create a soft interrupt object
14350 +/*----------------------------------------------------------------------------*/
14351 +int OsSoftInterruptAdd(
14352 + OS_SOFTINTR **ptr,
14355 +/*----------------------------------------------------------------------------*/
14357 + OS_SOFTINTR *tmp_ptr;
14359 + if( !( tmp_ptr = ( OS_SOFTINTR * )kmalloc( sizeof( OS_SOFTINTR ), GFP_KERNEL ) ) )
14361 + tmp_ptr->routine = handler;
14362 + tmp_ptr->data = data;
14363 + tmp_ptr->sync = 0;
14371 + Use kernel_thread( ( int ( * )( void * ) )OsIdleTask, NULL, 0 ); to start
14373 +/*----------------------------------------------------------------------------*/
14374 +int * OsIdleTask( void * data )
14375 +/*----------------------------------------------------------------------------*/
14377 + DECLARE_WAITQUEUE (wait, current);
14381 + current->state = TASK_INTERRUPTIBLE;
14382 + add_wait_queue( &g_wait_queue_ptr, &wait );
14384 + remove_wait_queue( &g_wait_queue_ptr, &wait );
14385 + wait.task = current;
14386 + wait.task_list.next = NULL;
14392 +// dispatch a soft interrupt
14393 +/*----------------------------------------------------------------------------*/
14394 +void OsSoftInterruptTrigger(
14395 + OS_SOFTINTR *soft_intr_ptr )
14396 +/*----------------------------------------------------------------------------*/
14398 + // call the completion routine directly
14399 + soft_intr_ptr->routine( soft_intr_ptr->data );
14403 +// delete a soft interrupt object
14404 +/*----------------------------------------------------------------------------*/
14405 +void OsSoftInterruptRemove(
14406 + OS_SOFTINTR *arg )
14407 +/*----------------------------------------------------------------------------*/
14415 +/*----------------------------------------------------------------------------*/
14417 + unsigned time ) // in seconds
14418 +/*----------------------------------------------------------------------------*/
14420 + struct semaphore sem;
14421 + struct timer_list timer_var;
14423 + init_MUTEX_LOCKED (&sem);
14425 + // if( in_interrupt() )
14426 + // panic( "OsSleep going to sleep at interrupt time\n" );
14428 + init_timer( &timer_var );
14429 + timer_var.function = ( void ( * )( unsigned long ) )OsTimeoutHandler;
14430 + timer_var.data = ( unsigned long )&sem;
14431 + timer_var.expires = jiffies + time * HZ;
14433 + add_timer( &timer_var );
14436 + del_timer( &timer_var );
14440 +/*----------------------------------------------------------------------------*/
14441 +void OsTimeoutHandler(
14442 + struct semaphore * sem )
14443 +/*----------------------------------------------------------------------------*/
14445 + if( sem != NULL )
14450 +/*----------------------------------------------------------------------------*/
14455 +/*----------------------------------------------------------------------------*/
14460 + va_start(ap, fmt);
14461 + (void) vsprintf(buf, fmt, ap);
14464 + if( flag <= g_options.message_level )
14465 + printk(KERN_ALERT "%s\n", buf);
14468 +/* void aac_show_tasks (struct list_head *our_tasks){ */
14470 +/* cmn_err (CE_DEBUG, "Entering aac_show_tasks"); */
14472 +/* if (our_tasks->next == NULL || our_tasks->next == 0) */
14473 +/* cmn_err (CE_DEBUG, "list_head->next is NULL or 0"); */
14475 +/* cmn_err (CE_DEBUG, "list_head->next: 0x%x", our_tasks->next); */
14477 +/* if (our_tasks->prev == NULL || our_tasks->prev == 0) */
14478 +/* cmn_err (CE_DEBUG, "list_head->prev is NULL or 0"); */
14480 +/* cmn_err (CE_DEBUG, "list_head->prev: 0x%x", our_tasks->prev); */
14483 diff -burN linux-2.4.7/drivers/scsi/aacraid/ossup.c linux/drivers/scsi/aacraid/ossup.c
14484 --- linux-2.4.7/drivers/scsi/aacraid/ossup.c Wed Dec 31 18:00:00 1969
14485 +++ linux/drivers/scsi/aacraid/ossup.c Sat Jul 21 17:55:14 2001
14488 + * Adaptec aacraid device driver for Linux.
14490 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14492 + * This program is free software; you can redistribute it and/or modify
14493 + * it under the terms of the GNU General Public License as published by
14494 + * the Free Software Foundation; either version 2, or (at your option)
14495 + * any later version.
14497 + * This program is distributed in the hope that it will be useful,
14498 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14499 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14500 + * GNU General Public License for more details.
14502 + * You should have received a copy of the GNU General Public License
14503 + * along with this program; see the file COPYING. If not, write to
14504 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14513 +static char *ident_ossup = "aacraid_ident ossup.c 1.0.6 2000/10/09 Adaptec, Inc.";
14515 +#include "osheaders.h"
14517 +#include "aac_unix_defs.h"
14522 + IN PZONE_HEADER Zone,
14523 + IN ULONG BlockSize,
14524 + IN PVOID InitialSegment,
14525 + IN ULONG InitialSegmentSize
14530 +Routine Description:
14532 + This function initializes a zone header. Once successfully
14533 + initialized, blocks can be allocated and freed from the zone, and
14534 + the zone can be extended.
14538 + Zone - Supplies the address of a zone header to be initialized.
14540 + BlockSize - Supplies the block size of the allocatable unit within
14541 + the zone. The size must be larger that the size of the
14542 + initial segment, and must be 64-bit aligned.
14544 + InitialSegment - Supplies the address of a segment of storage. The
14545 + first ZONE_SEGMENT_HEADER-sized portion of the segment
14546 + is used by the zone allocator. The remainder of
14547 + the segment is carved up into fixed size
14548 + (BlockSize) blocks and is made available for
14549 + allocation and deallocation from the zone. The
14550 + address of the segment must be aligned on a 64-bit
14553 + InitialSegmentSize - Supplies the size in bytes of the InitialSegment.
14557 + STATUS_UNSUCCESSFUL - BlockSize or InitialSegment was not aligned on
14558 + 64-bit boundaries, or BlockSize was larger than
14559 + the initial segment size.
14561 + STATUS_SUCCESS - The zone was successfully initialized.
14570 + Zone->BlockSize = BlockSize;
14572 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList;
14573 + ((PZONE_SEGMENT_HEADER) InitialSegment)->SegmentList.Next = NULL;
14574 + ((PZONE_SEGMENT_HEADER) InitialSegment)->Reserved = NULL;
14576 + Zone->FreeList.Next = NULL;
14578 + p = (PCHAR)InitialSegment + sizeof(ZONE_SEGMENT_HEADER);
14580 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14581 + i <= InitialSegmentSize - BlockSize;
14584 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14585 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14588 + Zone->TotalSegmentSize = i;
14591 + DbgPrint( "EX: ExInitializeZone( %lx, %lx, %lu, %lu, %lx )\n",
14592 + Zone, InitialSegment, InitialSegmentSize,
14597 + return STATUS_SUCCESS;
14602 + IN PZONE_HEADER Zone,
14603 + IN PVOID Segment,
14604 + IN ULONG SegmentSize
14609 +Routine Description:
14611 + This function extends a zone by adding another segment's worth of
14612 + blocks to the zone.
14616 + Zone - Supplies the address of a zone header to be extended.
14618 + Segment - Supplies the address of a segment of storage. The first
14619 + ZONE_SEGMENT_HEADER-sized portion of the segment is used by the
14620 + zone allocator. The remainder of the segment is carved up
14621 + into fixed-size (BlockSize) blocks and is added to the
14622 + zone. The address of the segment must be aligned on a 64-
14625 + SegmentSize - Supplies the size in bytes of Segment.
14629 + STATUS_UNSUCCESSFUL - BlockSize or Segment was not aligned on
14630 + 64-bit boundaries, or BlockSize was larger than
14631 + the segment size.
14633 + STATUS_SUCCESS - The zone was successfully extended.
14642 + ((PZONE_SEGMENT_HEADER) Segment)->SegmentList.Next = Zone->SegmentList.Next;
14643 + Zone->SegmentList.Next = &((PZONE_SEGMENT_HEADER) Segment)->SegmentList;
14645 + p = (PCHAR)Segment + sizeof(ZONE_SEGMENT_HEADER);
14647 + for (i = sizeof(ZONE_SEGMENT_HEADER);
14648 + i <= SegmentSize - Zone->BlockSize;
14649 + i += Zone->BlockSize
14652 + ((PSINGLE_LIST_ENTRY)p)->Next = Zone->FreeList.Next;
14653 + Zone->FreeList.Next = (PSINGLE_LIST_ENTRY)p;
14654 + p += Zone->BlockSize;
14656 + Zone->TotalSegmentSize += i;
14659 + DbgPrint( "EX: ExExtendZone( %lx, %lx, %lu, %lu, %lx )\n",
14660 + Zone, Segment, SegmentSize, Zone->BlockSize, p
14664 + return STATUS_SUCCESS;
14671 +/* Function: InqStrCopy()
14673 + * Arguments: [2] pointer to char
14675 + * Purpose: Copy a String from one location to another
14676 + * without copying \0
14679 +InqStrCopy(char *a, char *b)
14682 + while(*a != (char)0)
14686 diff -burN linux-2.4.7/drivers/scsi/aacraid/port.c linux/drivers/scsi/aacraid/port.c
14687 --- linux-2.4.7/drivers/scsi/aacraid/port.c Wed Dec 31 18:00:00 1969
14688 +++ linux/drivers/scsi/aacraid/port.c Sat Jul 21 17:55:14 2001
14691 + * Adaptec aacraid device driver for Linux.
14693 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14695 + * This program is free software; you can redistribute it and/or modify
14696 + * it under the terms of the GNU General Public License as published by
14697 + * the Free Software Foundation; either version 2, or (at your option)
14698 + * any later version.
14700 + * This program is distributed in the hope that it will be useful,
14701 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14702 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14703 + * GNU General Public License for more details.
14705 + * You should have received a copy of the GNU General Public License
14706 + * along with this program; see the file COPYING. If not, write to
14707 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
14712 + * Abstract: All support routines for FSA communication which are miniport specific.
14716 +static char *ident_port = "aacraid_ident port.c 1.0.7 2000/10/11 Adaptec, Inc.";
14718 +#include "osheaders.h"
14721 +#include "AacGenericTypes.h"
14723 +#include "aac_unix_defs.h"
14725 +#include "fsatypes.h"
14726 +#include "comstruc.h"
14727 +#include "protocol.h"
14729 +#include "fsaport.h"
14730 +#include "fsaioctl.h"
14732 +#include "pcisup.h"
14735 +int AfaPortPrinting = 1;
14737 +extern AAC_STATUS AfaPort_Err_Adapter_Printf;
14738 +extern AAC_STATUS AfaPort_Warn_Adapter_Printf;
14739 +extern AAC_STATUS AfaPort_Info_Adapter_Printf;
14740 +extern AAC_STATUS AfaPort_Err_FastAfa_Load_Driver;
14746 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
14747 + IN AAC_STATUS ErrorCode,
14748 + IN PUCHAR StringBuffer,
14749 + IN ULONG StringLength
14753 +Routine Description:
14755 + Does all of the work to log an error log entry
14758 + CommonExtension - Pointer to the adapter that caused the error.
14760 + ErrorCode - Which error is being logged.
14762 + StringBuffer - Pointer to optional String for error log entry.
14764 + StringLength - Length of StringBuffer.
14777 +AfaPortGetNextAdapterNumber(
14778 + IN PDRIVER_OBJECT DriverObject,
14779 + OUT PDEVICE_OBJECT *FsaDeviceObject,
14780 + OUT PFILE_OBJECT *FileObject,
14781 + OUT PULONG AdapterNumber
14786 +AfaPortAllocateAdapterCommArea(
14788 + IN OUT PVOID *CommHeaderAddress,
14789 + IN ULONG CommAreaSize,
14790 + IN ULONG CommAreaAlignment
14793 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
14794 + PVOID BaseAddress;
14795 + PHYSICAL_ADDRESS PhysicalBaseAddress;
14796 + ULONG TotalSize, BytesToAlign;
14797 + size_t RealLength;
14799 +// ULONG SizeOfFastIoComm = sizeof(FASTIO_STRUCT);
14800 +// ULONG AdapterFibsSize = PAGE_SIZE;
14801 + ULONG AdapterFibsSize = 4096;
14802 + ULONG PrintfBufferSize = 256;
14803 + PADAPTER_INIT_STRUCT InitStruct;
14804 + extern int MiniPortRevision;
14805 + ULONG PhysAddress;
14807 +// TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14808 +// SizeOfFastIoComm + PrintfBufferSize;
14809 + TotalSize = AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT) + CommAreaSize + CommAreaAlignment +
14810 + PrintfBufferSize;
14813 + OsAllocCommPhysMem(CommonExtension->MiniPort, TotalSize, &BaseAddress, &PhysAddress);
14815 + CommonExtension->CommAddress = BaseAddress;
14816 + CommonExtension->CommPhysAddr = PhysAddress;
14817 + CommonExtension->CommSize = TotalSize;
14819 + PhysicalBaseAddress.HighPart = 0;
14820 + PhysicalBaseAddress.LowPart = PhysAddress;
14822 + CommonExtension->InitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(BaseAddress) + AdapterFibsSize);
14823 + CommonExtension->PhysicalInitStruct = (PADAPTER_INIT_STRUCT)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize);
14825 + InitStruct = CommonExtension->InitStruct;
14827 + InitStruct->InitStructRevision = ADAPTER_INIT_STRUCT_REVISION;
14828 + InitStruct->MiniPortRevision = MiniPortRevision;
14829 + InitStruct->FilesystemRevision = CommonExtension->FilesystemRevision;
14832 + // Adapter Fibs are the first thing allocated so that they start page aligned
14834 + InitStruct->AdapterFibsVirtualAddress = BaseAddress;
14835 + InitStruct->AdapterFibsPhysicalAddress = (PVOID) PhysicalBaseAddress.LowPart;
14836 + InitStruct->AdapterFibsSize = AdapterFibsSize;
14837 + InitStruct->AdapterFibAlign = sizeof(FIB);
14840 + // Increment the base address by the amount already used
14842 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14843 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + AdapterFibsSize + sizeof(ADAPTER_INIT_STRUCT));
14846 + // Align the beginning of Headers to CommAreaAlignment
14848 + BytesToAlign = (CommAreaAlignment - ((ULONG)(BaseAddress) & (CommAreaAlignment - 1)));
14849 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + BytesToAlign);
14850 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + BytesToAlign);
14853 + // Fill in addresses of the Comm Area Headers and Queues
14855 + *CommHeaderAddress = BaseAddress;
14856 + InitStruct->CommHeaderAddress = (PVOID)PhysicalBaseAddress.LowPart;
14859 + // Increment the base address by the size of the CommArea
14861 + BaseAddress = (PVOID)((PUCHAR)(BaseAddress) + CommAreaSize);
14862 + PhysicalBaseAddress.LowPart = (ULONG)((PUCHAR)(PhysicalBaseAddress.LowPart) + CommAreaSize);
14866 + // Place the Printf buffer area after the Fast I/O comm area.
14868 + CommonExtension->PrintfBufferAddress = (PVOID)(BaseAddress);
14869 + InitStruct->PrintfBufferAddress = (PVOID)PhysicalBaseAddress.LowPart;
14870 + InitStruct->PrintfBufferSize = PrintfBufferSize;
14871 + bzero (BaseAddress, PrintfBufferSize);
14873 + AfaPortPrint("FsaAllocateAdapterCommArea: allocated a common buffer of 0x%x bytes from address 0x%x to address 0x%x\n",
14874 + TotalSize, InitStruct->AdapterFibsVirtualAddress,
14875 + (PUCHAR)(InitStruct->AdapterFibsVirtualAddress) + TotalSize);
14877 + AfaPortPrint("Mapped on to PCI address 0x%x\n", InitStruct->AdapterFibsPhysicalAddress);
14884 + IN PDEVICE_OBJECT DeviceObject,
14889 +Routine Description:
14891 + The routine will get called each time a user issues a CreateFile on the DeviceObject
14894 + The main purpose of this routine is to set up any data structures that may be needed
14895 + to handle any requests made on this DeviceObject.
14899 + DeviceObject - Pointer to device object representing adapter
14901 + Irp - Pointer to Irp that caused this open
14906 + Status value returned from File system driver AdapterOpen
14915 + IN PDEVICE_OBJECT DeviceObject,
14920 +Routine Description:
14922 + This routine will get called each time a user issues a CloseHandle on the DeviceObject
14925 + The main purpose of this routine is to cleanup any data structures that have been set up
14926 + while this FileObject has been opened.
14930 + DeviceObject - Pointer to device object representing adapter
14932 + Irp - Pointer to Irp that caused this close
14936 + Status value returned from File system driver AdapterClose
14945 +AfaPortDeviceControl (
14946 + IN PDEVICE_OBJECT DeviceObject,
14954 +AfaPortGetMaxPhysicalPage(
14955 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
14959 +Routine Description:
14961 + This routine determines the max physical page in host memory.
14969 + Max physical page in host memory.
14977 diff -burN linux-2.4.7/drivers/scsi/aacraid/rx.c linux/drivers/scsi/aacraid/rx.c
14978 --- linux-2.4.7/drivers/scsi/aacraid/rx.c Wed Dec 31 18:00:00 1969
14979 +++ linux/drivers/scsi/aacraid/rx.c Sat Jul 21 17:55:14 2001
14982 + * Adaptec aacraid device driver for Linux.
14984 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
14986 + * This program is free software; you can redistribute it and/or modify
14987 + * it under the terms of the GNU General Public License as published by
14988 + * the Free Software Foundation; either version 2, or (at your option)
14989 + * any later version.
14991 + * This program is distributed in the hope that it will be useful,
14992 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14993 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14994 + * GNU General Public License for more details.
14996 + * You should have received a copy of the GNU General Public License
14997 + * along with this program; see the file COPYING. If not, write to
14998 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15003 + * Abstract: Hardware miniport for Drawbridge specific hardware functions.
15007 +static char *ident_rx = "aacraid_ident rx.c 1.0.7 2000/10/11 Adaptec, Inc.";
15009 +#include "osheaders.h"
15012 +#include "AacGenericTypes.h"
15014 +#include "aac_unix_defs.h"
15016 +#include "fsatypes.h"
15017 +#include "comstruc.h"
15018 +#include "fsact.h"
15019 +#include "protocol.h"
15021 +#define DEFINE_PCI_IDS
15022 +#include "rxcommon.h"
15023 +#include "monkerapi.h"
15025 +#include "fsaport.h"
15026 +#include "fsaioctl.h"
15028 +#include "pcisup.h"
15033 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15035 +// #define RxBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15037 +#define RxBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15039 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15043 +// The list of all the Rx adapter structures
15046 +PRx_ADAPTER_EXTENSION RxAdapterList;
15050 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15051 + IN ULONG AdapterNumber,
15059 + ULONG FibPhysicalAddress
15062 +FSA_USER_VAR RxUserVars[] = {
15063 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15068 +// Declare private use routines for this modual
15073 + IN PRx_ADAPTER_EXTENSION AdapterExtension
15078 +Routine Description:
15080 + The Isr routine for fsa Rx based adapter boards.
15087 + TRUE - if the interrupt was handled by this isr
15088 + FALSE - if the interrupt was not handled by this isr
15093 + ULONG DoorbellBits;
15094 + UCHAR InterruptStatus, Mask;
15095 + u_int OurInterrupt = INTR_UNCLAIMED;
15097 + //cmn_err(CE_WARN, "RxPciIsr entered\n");
15099 + InterruptStatus = Rx_READ_UCHAR(AdapterExtension, MUnit.OISR);
15102 + // Read mask and invert because drawbridge is reversed.
15104 + // This allows us to only service interrupts that have been enabled.
15107 + Mask = ~(Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR));
15109 + // Check to see if this is our interrupt. If it isn't just return FALSE.
15112 + if (InterruptStatus & Mask) {
15114 + DoorbellBits = Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg);
15116 + OurInterrupt = INTR_CLAIMED;
15118 + if (DoorbellBits & DoorBellPrintfReady) {
15120 + ULONG Length, Level;
15121 + unsigned char *cp;
15123 + cp = AdapterExtension->Common->PrintfBufferAddress;
15126 + // The size of the Printfbuffer is set in port.c
15127 + // There is no variable or define for it
15129 + if (Length > 255)
15132 + if (cp[Length] != 0) {
15133 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
15137 + if (Level == LOG_HIGH_ERROR)
15138 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15140 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
15142 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
15144 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellPrintfReady); //clear PrintfReady
15146 + Rx_WRITE_ULONG(AdapterExtension, InboundDoorbellReg,DoorBellPrintfDone);
15149 + } else if (DoorbellBits & DoorBellAdapterNormCmdReady) { // Adapter -> Host Normal Command Ready
15151 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
15152 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdReady);
15154 + } else if (DoorbellBits & DoorBellAdapterNormRespReady) { // Adapter -> Host Normal Response Ready
15156 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
15157 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR,DoorBellAdapterNormRespReady);
15159 + } else if (DoorbellBits & DoorBellAdapterNormCmdNotFull) { // Adapter -> Host Normal Command Not Full
15161 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
15162 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
15164 + } else if (DoorbellBits & DoorBellAdapterNormRespNotFull) { // Adapter -> Host Normal Response Not Full
15166 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
15167 + Rx_WRITE_ULONG(AdapterExtension, MUnit.ODR, DoorBellAdapterNormRespNotFull);
15172 + return(OurInterrupt);
15176 +RxEnableInterrupt(
15178 + ADAPTER_EVENT AdapterEvent,
15179 + BOOLEAN AtDeviceIrq
15183 +Routine Description:
15185 + This routine will enable the corresponding adapter event to cause an interrupt on
15190 + AdapterExtension - Which adapter to enable.
15192 + AdapterEvent - Which adapter event.
15194 + AtDeviceIrq - Whether the system is in DEVICE irql
15202 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15203 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15205 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15206 + switch (AdapterEvent) {
15208 + case HostNormCmdQue:
15210 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_1);
15214 + case HostNormRespQue:
15216 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_2);
15220 + case AdapNormCmdNotFull:
15222 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_3);
15226 + case AdapNormRespNotFull:
15228 + AdapterExtension->LocalMaskInterruptControl &= ~(OUTBOUNDDOORBELL_4);
15237 +RxDisableInterrupt(
15239 + ADAPTER_EVENT AdapterEvent,
15240 + BOOLEAN AtDeviceIrq
15244 +Routine Description:
15246 + This routine will disable the corresponding adapter event to cause an interrupt on
15251 + AdapterExtension - Which adapter to enable.
15253 + AdapterEvent - Which adapter event.
15255 + AtDeviceIrq - Whether the system is in DEVICE irql
15263 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15264 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15266 + //cmn_err(CE_WARN, "RxEnableInterrupt");
15268 + switch (AdapterEvent) {
15271 + case HostNormCmdQue:
15273 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_1);
15277 + case HostNormRespQue:
15279 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_2);
15283 + case AdapNormCmdNotFull:
15285 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_3);
15290 + case AdapNormRespNotFull:
15292 + AdapterExtension->LocalMaskInterruptControl |= (OUTBOUNDDOORBELL_4);
15303 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension
15306 + PRx_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
15309 + // Free the register mapping.
15312 + OsDetachDevice( AdapterExtension);
15314 + OsFreeMemory( AdapterExtension, sizeof(Rx_ADAPTER_EXTENSION) );
15320 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15321 + IN ULONG AdapterNumber,
15328 +Routine Description:
15330 + Scans the PCI bus looking for the Rx card. When found all resources for the
15331 + device will be allocated and the interrupt vectors and csrs will be allocated and
15334 + The device_interface in the commregion will be allocated and linked to the comm region.
15341 + TRUE - if the device was setup with not problems
15342 + FALSE - if the device could not be mapped and init successfully
15347 + AAC_STATUS Status;
15348 + PRx_ADAPTER_EXTENSION AdapterExtension = NULL;
15349 + FSA_NEW_ADAPTER NewAdapter;
15350 + ULONG StartTime, EndTime, WaitTime;
15351 + ULONG InitStatus;
15356 + AfaPortPrint("In init device.\n");
15358 + //cmn_err(CE_WARN, "In RxInitDevice");
15360 +// AdapterExtension->Common->AdapterIndex = AdapterIndex;
15361 + CommonExtension->AdapterNumber = AdapterNumber;
15364 + CommonExtension->PciBusNumber = PciBus;
15365 + CommonExtension->PciSlotNumber = PciSlot;
15368 + AdapterExtension = OsAllocMemory( sizeof(Rx_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
15369 + AdapterExtension->Common = CommonExtension;
15370 + CommonExtension->MiniPort = AdapterExtension;
15372 + instance = OsGetDeviceInstance(AdapterExtension);
15373 + name = OsGetDeviceName(AdapterExtension);
15375 + // Map in the registers from the adapter, register space 0 is config space,
15376 + // register space 1 is the memery space.
15379 + if (OsMapDeviceRegisters(AdapterExtension)) {
15381 + cmn_err(CE_CONT, "%s%d: can't map device registers\n",
15382 + OsGetDeviceName(AdapterExtension), instance);
15387 + // Check to see if the board failed any self tests.
15390 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
15392 + cmn_err(CE_CONT, "%s%d: adapter self-test failed\n",
15393 + OsGetDeviceName(AdapterExtension), instance);
15397 + //cmn_err(CE_WARN, "RxInitDevice: %s%d: adapter passwd self-test\n",
15398 + // OsGetDeviceName(AdapterExtension), instance);
15401 + // Check to see if the board panic'd while booting.
15404 + if (Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
15406 + cmn_err(CE_CONT, "%s%d: adapter kernel panic'd\n",
15407 + OsGetDeviceName(AdapterExtension), instance);
15412 + StartTime = OsGetSeconds();
15417 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
15420 + while (!(Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) {
15422 + EndTime = OsGetSeconds();
15424 + WaitTime = EndTime - StartTime;
15426 + if ( WaitTime > (3 * 10) ) {
15428 + InitStatus = Rx_READ_ULONG( AdapterExtension, IndexRegs.Mailbox[7]) >> 16;
15430 + cmn_err(CE_CONT, "%s%d: adapter kernel failed to start, init status = %d\n",
15431 + OsGetDeviceName(AdapterExtension), instance, InitStatus);
15437 + if (OsAttachInterrupt(AdapterExtension,RxISR)) {
15438 + cmn_err(CE_WARN, "%s%d RxInitDevice: failed OsAttachIntterupt", name, instance);
15443 + if (OsAttachDMA(AdapterExtension)) {
15444 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
15449 + // Fill in the function dispatch table.
15452 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
15453 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
15454 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
15455 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
15456 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
15457 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
15458 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
15459 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = RxInterruptAdapter;
15460 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = RxEnableInterrupt;
15461 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = RxDisableInterrupt;
15462 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = RxNotifyAdapter;
15463 + AdapterExtension->Common->AdapterFuncs.ResetDevice = RxResetDevice;
15464 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
15466 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = RxSendSynchFib;
15468 + NewAdapter.AdapterExtension = CommonExtension;
15469 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
15470 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
15471 + NewAdapter.AdapterUserVars = RxUserVars;
15472 + NewAdapter.AdapterUserVarsSize = sizeof(RxUserVars) / sizeof(FSA_USER_VAR);
15474 + NewAdapter.Dip = CommonExtension->OsDep.dip;
15477 + if (AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
15479 + cmn_err(CE_WARN, "AfaCommInitNewAdapter failed\n");
15480 + return (FAILURE);
15484 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
15486 + if (AdapterExtension->Common->Adapter == NULL) {
15488 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
15489 + cmn_err(CE_WARN, "%s%d RxInitDevice: No Adapter pointer", name, instance);
15492 + return (FAILURE);
15497 + // Start any kernel threads needed
15499 + OsStartKernelThreads(AdapterExtension);
15502 + // Tell the adapter that all is configure, and it can start accepting requests
15505 + RxStartAdapter(AdapterExtension);
15513 + // Put this adapter into the list of Rx adapters
15516 + AdapterExtension->Next = RxAdapterList;
15517 + RxAdapterList = AdapterExtension;
15519 + AdapterExtension->Common->AdapterConfigured = TRUE;
15524 + // Call the disk layer to initialize itself.
15527 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
15533 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
15537 + OsAttachHBA(AdapterExtension);
15544 + PRx_ADAPTER_EXTENSION AdapterExtension
15547 + ULONG ReturnStatus;
15548 + LARGE_INTEGER HostTime;
15549 + ULONG ElapsedSeconds;
15550 + PADAPTER_INIT_STRUCT InitStruct;
15552 + //cmn_err(CE_WARN, "RxStartAdapter");
15554 + // Fill in the remaining pieces of the InitStruct.
15557 + InitStruct = AdapterExtension->Common->InitStruct;
15559 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
15561 + ElapsedSeconds = OsGetSeconds();
15563 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
15566 + // Tell the adapter we are back and up and running so it will scan its command
15567 + // queues and enable our interrupts
15570 + AdapterExtension->LocalMaskInterruptControl =
15571 + (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
15574 + // First clear out all interrupts. Then enable the one's that we can handle.
15577 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xff);
15578 + Rx_WRITE_ULONG( AdapterExtension, MUnit.ODR, 0xffffffff);
15579 +// Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR, ~(UCHAR)OUTBOUND_DOORBELL_INTERRUPT_MASK);
15580 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR, 0xfb);
15582 + RxSendSynchCommand(AdapterExtension,
15583 + INIT_STRUCT_BASE_ADDRESS,
15584 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
15602 +RxInterruptAdapter(
15607 +Routine Description:
15609 + The will cause the adapter to take a break point.
15621 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15622 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15624 + ULONG ReturnStatus;
15626 + RxSendSynchCommand(AdapterExtension,
15627 + BREAKPOINT_REQUEST,
15639 + IN HOST_2_ADAP_EVENT AdapterEvent
15643 +Routine Description:
15645 + Will read the adapter CSRs to find the reason the adapter has
15650 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
15658 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15659 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15660 + ULONG ReturnStatus;
15662 + //cmn_err(CE_WARN, "RxNotifyAdapter %d", AdapterEvent);
15664 + switch (AdapterEvent) {
15665 + case AdapNormCmdQue:
15667 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_1);
15670 + case HostNormRespNotFull:
15672 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_4);
15675 + case AdapNormRespQue:
15677 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_2);
15680 + case HostNormCmdNotFull:
15682 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_3);
15685 + case HostShutdown:
15687 +// RxSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
15692 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_6);
15695 + case AdapPrintfDone:
15696 + Rx_WRITE_ULONG(AdapterExtension, MUnit.IDR,INBOUNDDOORBELL_5);
15701 + RxBugCheck(0,0,0);
15702 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
15708 +RxSendSynchCommand(
15711 + ULONG Parameter1,
15712 + ULONG Parameter2,
15713 + ULONG Parameter3,
15714 + ULONG Parameter4,
15715 + PULONG ReturnStatus
15719 +Routine Description:
15721 + This routine will send a synchronous comamnd to the adapter and wait for its
15726 + AdapterExtension - Pointer to adapter extension structure.
15727 + Command - Which command to send
15728 + Parameter1 - 4 - Parameters for command
15729 + ReturnStatus - return status from adapter after completion of command
15738 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) Arg1;
15739 + ULONG StartTime,EndTime,WaitTime;
15740 + BOOLEAN CommandSucceeded;
15742 + //cmn_err(CE_WARN, "RxSendSyncCommand");
15744 + // Write the Command into Mailbox 0
15747 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox0, Command);
15750 + // Write the parameters into Mailboxes 1 - 4
15753 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox1, Parameter1);
15754 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox2, Parameter2);
15755 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox3, Parameter3);
15756 + Rx_WRITE_ULONG( AdapterExtension, InboundMailbox4, Parameter4);
15759 + // Clear the synch command doorbell to start on a clean slate.
15762 + Rx_WRITE_ULONG( AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15765 + // disable doorbell interrupts
15768 + Rx_WRITE_UCHAR( AdapterExtension, MUnit.OIMR,
15769 + Rx_READ_UCHAR(AdapterExtension, MUnit.OIMR) | 0x04);
15772 + // force the completion of the mask register write before issuing the interrupt.
15775 + Rx_READ_UCHAR ( AdapterExtension, MUnit.OIMR);
15778 + // Signal that there is a new synch command
15781 + Rx_WRITE_ULONG( AdapterExtension, InboundDoorbellReg, INBOUNDDOORBELL_0);
15783 + CommandSucceeded = FALSE;
15785 + StartTime = OsGetSeconds();
15788 + while (WaitTime < 30) { // wait up to 30 seconds
15790 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
15793 + // Mon110 will set doorbell0 bit when it has completed the command.
15796 + if (Rx_READ_ULONG(AdapterExtension, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
15799 + // clear the doorbell.
15802 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15804 + CommandSucceeded = TRUE;
15808 + EndTime = OsGetSeconds();
15809 + WaitTime = EndTime - StartTime;
15813 + if (CommandSucceeded != TRUE) {
15816 + // restore interrupt mask even though we timed out
15819 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15820 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15822 + return (STATUS_IO_TIMEOUT);
15827 + // Pull the synch status from Mailbox 0.
15830 + *ReturnStatus = Rx_READ_ULONG(AdapterExtension, IndexRegs.Mailbox[0]);
15833 + // Clear the synch command doorbell.
15836 + Rx_WRITE_ULONG(AdapterExtension, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
15839 + // restore interrupt mask
15842 + Rx_WRITE_UCHAR(AdapterExtension, MUnit.OIMR,
15843 + Rx_READ_ULONG(AdapterExtension, MUnit.OIMR) & 0xfb);
15846 + // Return SUCCESS
15849 + return (STATUS_SUCCESS);
15856 + ULONG FibPhysicalAddress
15860 +Routine Description:
15862 + This routine will send a synchronous fib to the adapter and wait for its
15867 + AdapterExtension - Pointer to adapter extension structure.
15868 + FibPhysicalAddress - Physical address of fib to send.
15877 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
15878 + PRx_ADAPTER_EXTENSION AdapterExtension = (PRx_ADAPTER_EXTENSION) CommonExtension->MiniPort;
15879 + ULONG returnStatus;
15881 + if (RxSendSynchCommand( AdapterExtension,
15882 + SEND_SYNCHRONOUS_FIB,
15883 + FibPhysicalAddress,
15887 + &returnStatus ) != STATUS_SUCCESS ) {
15898 diff -burN linux-2.4.7/drivers/scsi/aacraid/sap1sup.c linux/drivers/scsi/aacraid/sap1sup.c
15899 --- linux-2.4.7/drivers/scsi/aacraid/sap1sup.c Wed Dec 31 18:00:00 1969
15900 +++ linux/drivers/scsi/aacraid/sap1sup.c Sat Jul 21 17:55:14 2001
15903 + * Adaptec aacraid device driver for Linux.
15905 + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
15907 + * This program is free software; you can redistribute it and/or modify
15908 + * it under the terms of the GNU General Public License as published by
15909 + * the Free Software Foundation; either version 2, or (at your option)
15910 + * any later version.
15912 + * This program is distributed in the hope that it will be useful,
15913 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
15914 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15915 + * GNU General Public License for more details.
15917 + * You should have received a copy of the GNU General Public License
15918 + * along with this program; see the file COPYING. If not, write to
15919 + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
15924 + * Abstract: Drawbridge specific support functions
15928 +static char *ident_sap1 = "aacraid_ident sap1sup.c 1.0.7 2000/10/11 Adaptec, Inc.";
15930 +#include "osheaders.h"
15933 +#include "AacGenericTypes.h"
15935 +#include "aac_unix_defs.h"
15937 +#include "fsatypes.h"
15938 +#include "comstruc.h"
15939 +#include "fsact.h"
15940 +#include "protocol.h"
15942 +#define DEFINE_PCI_IDS
15943 +#include "sap1common.h"
15944 +#include "monkerapi.h"
15946 +#include "fsaport.h"
15947 +#include "fsaioctl.h"
15950 +#include "pcisup.h"
15955 +#include "nodetype.h"
15956 +#include "comsup.h"
15957 +#include "afacomm.h"
15958 +#include "adapter.h"
15960 +#define BugCheckFileId (FSAFS_BUG_CHECK_CYCLONESUP)
15962 +// #define SaBugCheck(A,B,C) { KeBugCheckEx(0x00000AFA, __LINE__, (ULONG)A, (ULONG)B,(ULONG)C ); }
15964 +#define SaBugCheck(A, B, C) { cmn_err(CE_PANIC, "aacdisk : line %s, 0x%x, 0x%x, 0x%x ", __LINE__, A, B, C); }
15966 +#define NUM_TICKS_PER_SECOND (1000 * 1000 * 10) /* time is in 100 nanoseconds */
15968 +int MiniPortRevision = Sa_MINIPORT_REVISION;
15972 +// The list of all the Sa adapter structures
15975 +PSa_ADAPTER_EXTENSION SaAdapterList;
15979 + IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
15980 + IN ULONG AdapterNumber,
15988 + ULONG FibPhysicalAddress
15991 +FSA_USER_VAR SaUserVars[] = {
15992 + { "AfaPortPrinting", (PULONG)&AfaPortPrinting, NULL },
15997 +// Declare private use routines for this modual
16003 +Routine Description:
16005 + The Isr routine for fsa Sa based adapter boards.
16012 + TRUE - if the interrupt was handled by this isr
16013 + FALSE - if the interrupt was not handled by this isr
16017 +SaPciIsr (IN PSa_ADAPTER_EXTENSION AdapterExtension)
16019 + USHORT InterruptStatus, Mask;
16020 + u_int OurInterrupt = INTR_UNCLAIMED;
16022 + InterruptStatus = Sa_READ_USHORT( AdapterExtension, DoorbellReg_p);
16025 + // Read mask and invert because drawbridge is reversed.
16027 + // This allows us to only service interrupts that have been enabled.
16030 + Mask = ~(Sa_READ_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK));
16032 + // Check to see if this is our interrupt. If it isn't just return FALSE.
16035 + if (InterruptStatus & Mask) {
16037 + OurInterrupt = INTR_CLAIMED;
16039 + if (InterruptStatus & PrintfReady) {
16041 + ULONG Length, Level;
16042 + unsigned char *cp;
16044 + cp = AdapterExtension->Common->PrintfBufferAddress;
16047 + // The size of the Printbuffer is set in port.c
16048 + // There is no variable or define for it
16050 + if (Length > 255)
16053 + if (cp[Length] != 0) {
16054 + // cmn_err (CE_NOTE, "byte %d is 0x%x, should be 0", Length, cp[Length]);
16058 + if (Level == LOG_HIGH_ERROR)
16059 + cmn_err (CE_WARN, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16061 + cmn_err (CE_NOTE, "%s:%s", OsGetDeviceName(AdapterExtension), AdapterExtension->Common->PrintfBufferAddress);
16063 + bzero (AdapterExtension->Common->PrintfBufferAddress, 256);
16065 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,PrintfReady); //clear PrintfReady
16067 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,PrintfDone);
16069 + } else if (InterruptStatus & DOORBELL_1) { // Adapter -> Host Normal Command Ready
16071 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormCmdQue);
16072 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_1);
16074 + } else if (InterruptStatus & DOORBELL_2) { // Adapter -> Host Normal Response Ready
16076 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, HostNormRespQue);
16077 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p,DOORBELL_2);
16079 + } else if (InterruptStatus & DOORBELL_3) { // Adapter -> Host Normal Command Not Full
16081 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormCmdNotFull);
16082 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_3);
16084 + } else if (InterruptStatus & DOORBELL_4) { // Adapter -> Host Normal Response Not Full
16086 + AdapterExtension->Common->AdapterFuncs.InterruptHost(AdapterExtension->Common->Adapter, AdapNormRespNotFull);
16087 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_4);
16092 + return(OurInterrupt);
16098 +Routine Description:
16100 + This routine will enable the corresponding adapter event to cause an interrupt on
16105 + AdapterExtension - Which adapter to enable.
16107 + AdapterEvent - Which adapter event.
16109 + AtDeviceIrq - Whether the system is in DEVICE irql
16117 +SaEnableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16119 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16120 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16122 + switch (AdapterEvent) {
16124 + case HostNormCmdQue:
16126 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_1 );
16130 + case HostNormRespQue:
16132 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_2 );
16136 + case AdapNormCmdNotFull:
16138 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_3 );
16142 + case AdapNormRespNotFull:
16144 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK, DOORBELL_4 );
16156 +Routine Description:
16158 + This routine will disable the corresponding adapter event to cause an interrupt on
16163 + AdapterExtension - Which adapter to enable.
16165 + AdapterEvent - Which adapter event.
16167 + AtDeviceIrq - Whether the system is in DEVICE irql
16175 +SaDisableInterrupt (PVOID Arg1, ADAPTER_EVENT AdapterEvent, BOOLEAN AtDeviceIrq)
16177 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16178 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16180 + switch (AdapterEvent) {
16183 + case HostNormCmdQue:
16185 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_1 );
16189 + case HostNormRespQue:
16191 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_2 );
16195 + case AdapNormCmdNotFull:
16197 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_3 );
16202 + case AdapNormRespNotFull:
16204 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, DOORBELL_4 );
16213 +SaDetachDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension)
16215 + PSa_ADAPTER_EXTENSION AdapterExtension = CommonExtension->MiniPort;
16218 + // Free the register mapping.
16221 + OsDetachDevice(AdapterExtension);
16223 + OsFreeMemory( AdapterExtension, sizeof(Sa_ADAPTER_EXTENSION) );
16230 +Routine Description:
16232 + Scans the PCI bus looking for the Sa card. When found all resources for the
16233 + device will be allocated and the interrupt vectors and csrs will be allocated and
16236 + The device_interface in the commregion will be allocated and linked to the comm region.
16243 + TRUE - if the device was setup with not problems
16244 + FALSE - if the device could not be mapped and init successfully
16248 +SaInitDevice (IN PPCI_MINIPORT_COMMON_EXTENSION CommonExtension,
16249 + IN ULONG AdapterNumber, IN ULONG PciBus,
16250 + IN ULONG PciSlot)
16252 + AAC_STATUS Status;
16253 + PSa_ADAPTER_EXTENSION AdapterExtension = NULL;
16254 + FSA_NEW_ADAPTER NewAdapter;
16255 + ULONG StartTime, EndTime, WaitTime;
16256 + ULONG InitStatus;
16260 + AfaPortPrint("In init device.\n");
16262 + CommonExtension->AdapterNumber = AdapterNumber;
16264 + CommonExtension->PciBusNumber = PciBus;
16265 + CommonExtension->PciSlotNumber = PciSlot;
16267 + AdapterExtension = OsAllocMemory( sizeof(Sa_ADAPTER_EXTENSION), OS_ALLOC_MEM_SLEEP );
16268 + AdapterExtension->Common = CommonExtension;
16269 + CommonExtension->MiniPort = AdapterExtension;
16271 + instance = OsGetDeviceInstance(AdapterExtension);
16272 + name = OsGetDeviceName(AdapterExtension);
16275 + // Map in the registers from the adapter, register space 0 is config space,
16276 + // register space 1 is the memery space.
16279 + if (OsMapDeviceRegisters(AdapterExtension)){
16280 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsMapDeviceRegisters", name, instance);
16286 + // Check to see if the board failed any self tests.
16289 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & SELF_TEST_FAILED) {
16291 + cmn_err(CE_WARN, "%s%d: adapter self-test failed\n",
16297 + // Check to see if the board panic'd while booting.
16300 + if (Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_PANIC) {
16302 + cmn_err(CE_WARN, "%s%d: adapter kernel panic'd\n",
16308 + StartTime = OsGetSeconds();
16313 + // Wait for the adapter to be up and running. Wait up until 3 minutes.
16316 + while (!(Sa_READ_ULONG( AdapterExtension, Mailbox7) & KERNEL_UP_AND_RUNNING)) {
16318 + EndTime = OsGetSeconds();
16320 + WaitTime = EndTime - StartTime;
16322 + if ( WaitTime > (3 * 60) ) {
16324 + InitStatus = Sa_READ_ULONG( AdapterExtension, Mailbox7) >> 16;
16326 + cmn_err(CE_WARN, "%s%d: adapter kernel failed to start, init status = %d\n",
16327 + name, instance, InitStatus);
16333 + if (OsAttachInterrupt(AdapterExtension, SaISR)) {
16334 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachIntterupt", name, instance);
16338 + if (OsAttachDMA(AdapterExtension)) {
16339 + cmn_err(CE_WARN, "%s%d SaInitDevice: failed OsAttachDMA", name, instance);
16345 + // Fill in the function dispatch table.
16348 + AdapterExtension->Common->AdapterFuncs.SizeOfFsaPortFuncs = sizeof(FSAPORT_FUNCS);
16349 + AdapterExtension->Common->AdapterFuncs.AllocateAdapterCommArea = AfaPortAllocateAdapterCommArea;
16350 + AdapterExtension->Common->AdapterFuncs.FreeAdapterCommArea = AfaPortFreeAdapterCommArea;
16351 + AdapterExtension->Common->AdapterFuncs.BuildSgMap = AfaPortBuildSgMap;
16352 + AdapterExtension->Common->AdapterFuncs.FreeDmaResources = AfaPortFreeDmaResources;
16353 + AdapterExtension->Common->AdapterFuncs.AllocateAndMapFibSpace = AfaPortAllocateAndMapFibSpace;
16354 + AdapterExtension->Common->AdapterFuncs.UnmapAndFreeFibSpace = AfaPortUnmapAndFreeFibSpace;
16355 + AdapterExtension->Common->AdapterFuncs.InterruptAdapter = SaInterruptAdapter;
16356 + AdapterExtension->Common->AdapterFuncs.EnableInterrupt = SaEnableInterrupt;
16357 + AdapterExtension->Common->AdapterFuncs.DisableInterrupt = SaDisableInterrupt;
16358 + AdapterExtension->Common->AdapterFuncs.NotifyAdapter = SaNotifyAdapter;
16359 + AdapterExtension->Common->AdapterFuncs.ResetDevice = SaResetDevice;
16360 + AdapterExtension->Common->AdapterFuncs.InterruptHost = NULL;
16362 + AdapterExtension->Common->AdapterFuncs.SendSynchFib = SaSendSynchFib;
16364 + NewAdapter.AdapterExtension = CommonExtension;
16365 + NewAdapter.AdapterFuncs = &AdapterExtension->Common->AdapterFuncs;
16366 + NewAdapter.AdapterInterruptsBelowDpc = FALSE;
16367 + NewAdapter.AdapterUserVars = SaUserVars;
16368 + NewAdapter.AdapterUserVarsSize = sizeof(SaUserVars) / sizeof(FSA_USER_VAR);
16370 + NewAdapter.Dip = CommonExtension->OsDep.dip;
16373 + if ( AfaCommInitNewAdapter( &NewAdapter ) == NULL) {
16374 + cmn_err(CE_WARN, "SaInitDevice: AfaCommInitNewAdapter failed\n");
16375 + return (FAILURE);
16379 + AdapterExtension->Common->Adapter = NewAdapter.Adapter;
16381 + if (AdapterExtension->Common->Adapter == NULL) {
16383 + AfaPortLogError(AdapterExtension->Common, FAILURE, NULL, 0);
16384 + cmn_err(CE_WARN, "%s%d SaInitDevice: No Adapter pointer", name, instance);
16386 + return (FAILURE);
16391 + // Start any kernel threads needed
16392 + OsStartKernelThreads(AdapterExtension);
16395 + // Tell the adapter that all is configure, and it can start accepting requests
16398 + SaStartAdapter(AdapterExtension);
16403 + // Put this adapter into the list of Sa adapters
16406 + AdapterExtension->Next = SaAdapterList;
16407 + SaAdapterList = AdapterExtension;
16409 + AdapterExtension->Common->AdapterConfigured = TRUE;
16414 + // Call the disk layer to initialize itself.
16417 + AfaDiskInitNewAdapter( AdapterExtension->Common->AdapterNumber, AdapterExtension->Common->Adapter );
16423 + AdapterExtension->Common->AdapterPrintfsToScreen = FALSE;
16425 + OsAttachHBA(AdapterExtension);
16431 + return (FAILURE);
16437 +SaStartAdapter (PSa_ADAPTER_EXTENSION AdapterExtension)
16439 + ULONG ReturnStatus;
16440 + LARGE_INTEGER HostTime;
16441 + ULONG ElapsedSeconds;
16442 + PADAPTER_INIT_STRUCT InitStruct;
16445 + // Fill in the remaining pieces of the InitStruct.
16448 + InitStruct = AdapterExtension->Common->InitStruct;
16450 + InitStruct->HostPhysMemPages = AfaPortGetMaxPhysicalPage(AdapterExtension->Common);
16452 + ElapsedSeconds = OsGetSeconds();
16454 + InitStruct->HostElapsedSeconds = ElapsedSeconds;
16457 + // Tell the adapter we are back and up and running so it will scan its command
16458 + // queues and enable our interrupts
16461 + AdapterExtension->LocalMaskInterruptControl =
16462 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
16466 + // First clear out all interrupts. Then enable the one's that we can handle.
16469 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRISETIRQMASK, (USHORT) 0xffff );
16470 + Sa_WRITE_USHORT( AdapterExtension, SaDbCSR.PRICLEARIRQMASK,
16471 + (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4) );
16473 + SaSendSynchCommand(AdapterExtension,
16474 + INIT_STRUCT_BASE_ADDRESS,
16475 + (ULONG) AdapterExtension->Common->PhysicalInitStruct,
16485 +SaResetDevice (PVOID Arg1){
16492 +Routine Description:
16494 + The will cause the adapter to take a break point.
16506 +SaInterruptAdapter (PVOID Arg1)
16508 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16509 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16511 + ULONG ReturnStatus;
16513 + SaSendSynchCommand(AdapterExtension,
16514 + BREAKPOINT_REQUEST,
16526 +Routine Description:
16528 + Will read the adapter CSRs to find the reason the adapter has
16533 + AdapterEvent - Enumerated type the returns the reason why we were interrutped.
16541 +SaNotifyAdapter (PVOID Arg1, IN HOST_2_ADAP_EVENT AdapterEvent)
16543 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16544 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16545 + ULONG ReturnStatus;
16547 + switch (AdapterEvent) {
16548 + case AdapNormCmdQue:
16550 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_1);
16553 + case HostNormRespNotFull:
16555 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_4);
16558 + case AdapNormRespQue:
16560 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_2);
16563 + case HostNormCmdNotFull:
16565 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_3);
16568 + case HostShutdown:
16570 +// SaSendSynchCommand(AdapterExtension, HOST_CRASHING, 0, 0, 0, 0, &ReturnStatus);
16575 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_6);
16578 + case AdapPrintfDone:
16579 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s,DOORBELL_5);
16584 + SaBugCheck(0,0,0);
16585 + AfaPortPrint("Notify requested with an invalid request 0x%x.\n",AdapterEvent);
16593 +Routine Description:
16595 + This routine will send a synchronous comamnd to the adapter and wait for its
16600 + AdapterExtension - Pointer to adapter extension structure.
16601 + Command - Which command to send
16602 + Parameter1 - 4 - Parameters for command
16603 + ReturnStatus - return status from adapter after completion of command
16612 +SaSendSynchCommand(
16615 + ULONG Parameter1,
16616 + ULONG Parameter2,
16617 + ULONG Parameter3,
16618 + ULONG Parameter4,
16619 + PULONG ReturnStatus
16622 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) Arg1;
16623 + ULONG StartTime,EndTime,WaitTime;
16624 + BOOLEAN CommandSucceeded;
16627 + // Write the Command into Mailbox 0
16630 + Sa_WRITE_ULONG( AdapterExtension, Mailbox0, Command);
16633 + // Write the parameters into Mailboxes 1 - 4
16636 + Sa_WRITE_ULONG( AdapterExtension, Mailbox1, Parameter1);
16637 + Sa_WRITE_ULONG( AdapterExtension, Mailbox2, Parameter2);
16638 + Sa_WRITE_ULONG( AdapterExtension, Mailbox3, Parameter3);
16639 + Sa_WRITE_ULONG( AdapterExtension, Mailbox4, Parameter4);
16642 + // Clear the synch command doorbell to start on a clean slate.
16645 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16648 + // Signal that there is a new synch command
16651 + Sa_WRITE_USHORT( AdapterExtension, DoorbellReg_s, DOORBELL_0);
16653 + CommandSucceeded = FALSE;
16655 + StartTime = OsGetSeconds();
16658 + while (WaitTime < 30) { // wait up to 30 seconds
16660 + drv_usecwait(5); // delay 5 microseconds to let Mon960 get info.
16663 + // Mon110 will set doorbell0 bit when it has completed the command.
16666 + if( Sa_READ_USHORT( AdapterExtension, DoorbellReg_p) & DOORBELL_0 ) {
16668 + CommandSucceeded = TRUE;
16672 + EndTime = OsGetSeconds();
16673 + WaitTime = EndTime - StartTime;
16677 + if (CommandSucceeded != TRUE) {
16679 + return (STATUS_IO_TIMEOUT);
16684 + // Clear the synch command doorbell.
16687 + Sa_WRITE_USHORT( AdapterExtension, DoorbellClrReg_p, DOORBELL_0);
16690 + // Pull the synch status from Mailbox 0.
16693 + *ReturnStatus = Sa_READ_ULONG( AdapterExtension, Mailbox0);
16696 + // Return SUCCESS
16699 + return (STATUS_SUCCESS);
16706 +Routine Description:
16708 + This routine will send a synchronous fib to the adapter and wait for its
16713 + AdapterExtension - Pointer to adapter extension structure.
16714 + FibPhysicalAddress - Physical address of fib to send.
16723 +SaSendSynchFib (PVOID Arg1, ULONG FibPhysicalAddress)
16725 + PPCI_MINIPORT_COMMON_EXTENSION CommonExtension = (PPCI_MINIPORT_COMMON_EXTENSION) Arg1;
16726 + PSa_ADAPTER_EXTENSION AdapterExtension = (PSa_ADAPTER_EXTENSION) CommonExtension->MiniPort;
16727 + ULONG returnStatus;
16729 + if (SaSendSynchCommand( AdapterExtension,
16730 + SEND_SYNCHRONOUS_FIB,
16731 + FibPhysicalAddress,
16735 + &returnStatus ) != STATUS_SUCCESS ) {
16747 + PVOID AdapterExtension,
16748 + ULONG *MappedBuffer)
16755 + PVOID AdapterExtension,
16756 + ULONG *MappedBuffer)