/* * vmscsi-- Miniport driver for the Buslogic BT 958 SCSI Controller * under Windows 2000/XP/Server 2003 * * Based in parts on the buslogic driver for the same device * available with the GNU Linux Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ //_________________________________________________________________________________________ // // File description :The header file the driver for BusLogic-958 SCSI Host adapter card. // The technical reference for this driver is at : // // Author: Namita Lal, Sirish Raghuram ( Calsoft Pvt Ltd) // Date: 10th June 2002 // Status: Released // Revision History: Changed queue depth to 191 - June 2002 // //_________________________________________________________________________________________ // Prototype for functions #pragma once #include #include #include #include #include //#include //#include "miniport.h" //#include "scsi.h" //#include "scsiwmi.h" //_________________________________________________________________________________________ // #defines //_________________________________________________________________________________________ // Debug levels #define ERROR 1 #define WARNING 2 #define TRACE 3 #define INFO 4 // Max transfer size #define MAX_TRANSFER_SIZE 64 * 1024 // flag to turn on Scatter gather support #define SG_SUPPORT 1 // flag to turn on tagged command queuing #define TAG_QUEUING 1 #define BUSLOGIC_MAXIMUM_TAGS 128 // Define the maximum, maximum automatic, minimum automatic, and default Queue // Depth to allow for Target Devices depending on whether or not they support // Tagged Queuing and whether or not ISA Bounce Buffers are required. #define BusLogic_MaxTaggedQueueDepth 128 // Define the default amount of time in seconds to wait between a Host Adapter // Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI commands. // Some SCSI devices get confused if they receive SCSI commands too soon after // a SCSI Bus Reset. #define BusLogic_DefaultBusSettleTime 2 // Define the maximum number of Target Devices supported by this driver. #define BusLogic_MaxTargetDevices 16 // Define the maximum number of Logical unit supported/Target Devices supported by this driver. #define BusLogic_MaxLogicalUnits 32 // Define the maximum number of Mailboxes that should be used for MultiMaster // Host Adapters. This number is chosen to be larger than the maximum Host // Adapter Queue Depth and small enough so that the Host Adapter structure // does not cross an allocation block size boundary. #define BusLogic_MaxMailboxes 211 // Define the Fetch Host Adapter Local RAM request type. #define BusLogic_BIOS_BaseOffset 0 #define BusLogic_AutoSCSI_BaseOffset 64 // Define the SCSI Command Descriptor Block (CDB). #define BusLogic_CDB_MaxLength 12 // Define the maximum number of Scatter/Gather Segments used by this driver. // For optimal performance, it is important that this limit be at least as // large as the largest single request generated by the I/O Subsystem. #define BusLogic_ScatterGatherLimit 128 #define MAX_SG_LIMIT BusLogic_ScatterGatherLimit #define BusLogic_AggressiveRoundRobinMode 0 #define BusLogic_StrictRoundRobinMode 1 // Define the Codes for byte 3 (Request sense allocation length) of the CCB structure. #define BusLogic_Allocate14Bytes 0x00 #define BusLogic_DisableAutoReqSense 0x01 //_________________________________________________________________________________________ //_________________________________________________________________________________________ // typedef //_________________________________________________________________________________________ typedef enum { BusLogic_TestCommandCompleteInterrupt = 0x00, BusLogic_InitializeMailbox = 0x01, BusLogic_ExecuteMailboxCommand = 0x02, BusLogic_ExecuteBIOSCommand = 0x03, BusLogic_InquireBoardID = 0x04, BusLogic_EnableOutgoingMailboxAvailableInt = 0x05, BusLogic_SetSCSISelectionTimeout = 0x06, BusLogic_SetPreemptTimeOnBus = 0x07, BusLogic_SetTimeOffBus = 0x08, BusLogic_SetBusTransferRate = 0x09, BusLogic_InquireInstalledDevicesID0to7 =0x0A, BusLogic_InquireConfiguration = 0x0B, BusLogic_EnableTargetMode = 0x0C, BusLogic_InquireSetupInformation = 0x0D, BusLogic_WriteAdapterLocalRAM = 0x1A, BusLogic_ReadAdapterLocalRAM = 0x1B, BusLogic_WriteBusMasterChipFIFO = 0x1C, BusLogic_ReadBusMasterChipFIFO = 0x1D, BusLogic_EchoCommandData = 0x1F, BusLogic_HostAdapterDiagnostic = 0x20, BusLogic_SetAdapterOptions = 0x21, BusLogic_InquireInstalledDevicesID8to15 = 0x23, BusLogic_InquireTargetDevices = 0x24, BusLogic_DisableHostAdapterInterrupt = 0x25, BusLogic_InitializeExtendedMailbox = 0x81, BusLogic_ExecuteSCSICommand = 0x83, BusLogic_InquireFirmwareVersion3rdDigit = 0x84, BusLogic_InquireFirmwareVersionLetter = 0x85, BusLogic_InquirePCIHostAdapterInformation = 0x86, BusLogic_InquireHostAdapterModelNumber =0x8B, BusLogic_InquireSynchronousPeriod = 0x8C, BusLogic_InquireExtendedSetupInformation = 0x8D, BusLogic_EnableStrictRoundRobinMode = 0x8F, BusLogic_StoreHostAdapterLocalRAM = 0x90, BusLogic_FetchHostAdapterLocalRAM = 0x91, BusLogic_StoreLocalDataInEEPROM = 0x92, BusLogic_UploadAutoSCSICode = 0x94, BusLogic_ModifyIOAddress = 0x95, BusLogic_SetCCBFormat = 0x96, BusLogic_WriteInquiryBuffer = 0x9A, BusLogic_ReadInquiryBuffer = 0x9B, BusLogic_FlashROMUploadDownload = 0xA7, BusLogic_ReadSCAMData = 0xA8, BusLogic_WriteSCAMData = 0xA9 }BusLogic_OperationCode_T; // Define the Requested Reply Length type used by the Inquire Setup Information, // Inquire Host Adapter Model Number, Inquire Synchronous Period, and Inquire // Extended Setup Information commands. typedef UCHAR BusLogic_RequestedReplyLength_T; // Define a 32 bit Bus Address data type. typedef unsigned int BusLogic_BusAddress_T; // Define the Inquire Host Adapter Model Number reply type. typedef UCHAR BusLogic_HostAdapterModelNumber_T[5]; // Define the Inquire Firmware Version 3rd Digit reply type. typedef UCHAR BusLogic_FirmwareVersion3rdDigit_T; // Define the Inquire Firmware Version Letter reply type. typedef UCHAR BusLogic_FirmwareVersionLetter_T; // Define a 32 bit Byte Count data type. typedef unsigned int BusLogic_ByteCount_T; typedef struct BusLogic_FetchHostAdapterLocalRAMRequest { UCHAR ByteOffset; // Byte 0 UCHAR ByteCount; // Byte 1 } BusLogic_FetchHostAdapterLocalRAMRequest_T; // Define the Inquire PCI Host Adapter Information reply type. The ISA // Compatible I/O Port values are defined here and are also used with // the Modify I/O Address command. typedef enum BusLogic_ISACompatibleIOPort { BusLogic_IO_330 = 0, BusLogic_IO_334 = 1, BusLogic_IO_230 = 2, BusLogic_IO_234 = 3, BusLogic_IO_130 = 4, BusLogic_IO_134 = 5, BusLogic_IO_Disable = 6, BusLogic_IO_Disable2 = 7 } BusLogic_ISACompatibleIOPort_T; #pragma pack (1) typedef struct BusLogic_PCIHostAdapterInformation { UCHAR ISACompatibleIOPort; /* Byte 0 */ UCHAR PCIAssignedIRQChannel; /* Byte 1 */ BOOLEAN LowByteTerminated:1; /* Byte 2 Bit 0 */ BOOLEAN HighByteTerminated:1; /* Byte 2 Bit 1 */ UCHAR :2; /* Byte 2 Bits 2-3 */ BOOLEAN JP1:1; /* Byte 2 Bit 4 */ BOOLEAN JP2:1; /* Byte 2 Bit 5 */ BOOLEAN JP3:1; /* Byte 2 Bit 6 */ BOOLEAN GenericInfoValid:1; /* Byte 2 Bit 7 */ UCHAR :8; /* Byte 3 */ }BusLogic_PCIHostAdapterInformation_T; // Define the Inquire Board ID reply structure. typedef struct BusLogic_BoardID { UCHAR BoardType; /* Byte 0 */ UCHAR CustomFeatures; /* Byte 1 */ UCHAR FirmwareVersion1stDigit; /* Byte 2 */ UCHAR FirmwareVersion2ndDigit; /* Byte 3 */ } BusLogic_BoardID_T; #pragma pack () // Define the Host Adapter Target Flags structure. typedef struct BusLogic_TargetFlags { BOOLEAN TargetExists:1; BOOLEAN TaggedQueuingSupported:1; BOOLEAN WideTransfersSupported:1; BOOLEAN TaggedQueuingActive:1; BOOLEAN WideTransfersActive:1; BOOLEAN CommandSuccessfulFlag:1; BOOLEAN TargetInfoReported:1; } BusLogic_TargetFlags_T; // Define the Host Adapter Target Statistics structure. #define BusLogic_SizeBuckets 10 // Define a 10^18 Statistics Byte Counter data type. typedef struct BusLogic_ByteCounter { unsigned int Units; unsigned int Billions; }BusLogic_ByteCounter_T; typedef unsigned int BusLogic_CommandSizeBuckets_T[BusLogic_SizeBuckets]; typedef struct BusLogic_TargetStatistics { unsigned int CommandsAttempted; unsigned int CommandsCompleted; unsigned int ReadCommands; unsigned int WriteCommands; BusLogic_ByteCounter_T TotalBytesRead; BusLogic_ByteCounter_T TotalBytesWritten; BusLogic_CommandSizeBuckets_T ReadCommandSizeBuckets; BusLogic_CommandSizeBuckets_T WriteCommandSizeBuckets; unsigned short CommandAbortsRequested; unsigned short CommandAbortsAttempted; unsigned short CommandAbortsCompleted; unsigned short BusDeviceResetsRequested; unsigned short BusDeviceResetsAttempted; unsigned short BusDeviceResetsCompleted; unsigned short HostAdapterResetsRequested; unsigned short HostAdapterResetsAttempted; unsigned short HostAdapterResetsCompleted; } BusLogic_TargetStatistics_T; #pragma pack (1) // Define the Inquire Configuration reply structure. typedef struct BusLogic_Configuration { UCHAR :5; /* Byte 0 Bits 0-4 */ BOOLEAN DMA_Channel5:1; /* Byte 0 Bit 5 */ BOOLEAN DMA_Channel6:1; /* Byte 0 Bit 6 */ BOOLEAN DMA_Channel7:1; /* Byte 0 Bit 7 */ BOOLEAN IRQ_Channel9:1; /* Byte 1 Bit 0 */ BOOLEAN IRQ_Channel10:1; /* Byte 1 Bit 1 */ BOOLEAN IRQ_Channel11:1; /* Byte 1 Bit 2 */ BOOLEAN IRQ_Channel12:1; /* Byte 1 Bit 3 */ UCHAR :1; /* Byte 1 Bit 4 */ BOOLEAN IRQ_Channel14:1; /* Byte 1 Bit 5 */ BOOLEAN IRQ_Channel15:1; /* Byte 1 Bit 6 */ UCHAR :1; /* Byte 1 Bit 7 */ UCHAR HostAdapterID:4; /* Byte 2 Bits 0-3 */ UCHAR :4; /* Byte 2 Bits 4-7 */ }BusLogic_Configuration_T; // Define the Inquire Setup Information reply structure. typedef struct BusLogic_SynchronousValue { UCHAR Offset:4; /* Bits 0-3 */ UCHAR TransferPeriod:3; /* Bits 4-6 */ BOOLEAN Synchronous:1; /* Bit 7 */ }BusLogic_SynchronousValue_T; typedef BusLogic_SynchronousValue_T BusLogic_SynchronousValues8_T[8]; typedef struct BusLogic_SetupInformation { BOOLEAN SynchronousInitiationEnabled:1; /* Byte 0 Bit 0 */ BOOLEAN ParityCheckingEnabled:1; /* Byte 0 Bit 1 */ UCHAR :6; /* Byte 0 Bits 2-7 */ UCHAR BusTransferRate; /* Byte 1 */ UCHAR PreemptTimeOnBus; /* Byte 2 */ UCHAR TimeOffBus; /* Byte 3 */ UCHAR MailboxCount; /* Byte 4 */ UCHAR MailboxAddress[3]; /* Bytes 5-7 */ BusLogic_SynchronousValues8_T SynchronousValuesID0to7; /* Bytes 8-15 */ UCHAR DisconnectPermittedID0to7; /* Byte 16 */ UCHAR Signature; /* Byte 17 */ UCHAR CharacterD; /* Byte 18 */ UCHAR HostBusType; /* Byte 19 */ UCHAR WideTransfersPermittedID0to7; /* Byte 20 */ UCHAR WideTransfersActiveID0to7; /* Byte 21 */ BusLogic_SynchronousValues8_T SynchronousValuesID8to15;/* Bytes 22-29 */ UCHAR DisconnectPermittedID8to15; /* Byte 30 */ UCHAR :8; /* Byte 31 */ UCHAR WideTransfersPermittedID8to15; /* Byte 32 */ UCHAR WideTransfersActiveID8to15; /* Byte 33 */ }BusLogic_SetupInformation_T; // Something has to be done about the packing mechanism of these structures - Namita // Define the Inquire Extended Setup Information reply structure. typedef struct BusLogic_ExtendedSetupInformation { UCHAR BusType; // Byte 0 UCHAR BIOS_Address; // Byte 1 unsigned short ScatterGatherLimit; // Bytes 2-3 UCHAR MailboxCount; // Byte 4 BusLogic_BusAddress_T BaseMailboxAddress; // Bytes 5-8 struct { UCHAR :2; // Byte 9 Bits 0-1 BOOLEAN FastOnEISA:1; // Byte 9 Bit 2 UCHAR :3; // Byte 9 Bits 3-5 BOOLEAN LevelSensitiveInterrupt:1; // Byte 9 Bit 6 UCHAR :1; } Misc; // Byte 9 Bit 7 UCHAR FirmwareRevision[3]; // Bytes 10-12 BOOLEAN HostWideSCSI:1; // Byte 13 Bit 0 BOOLEAN HostDifferentialSCSI:1; // Byte 13 Bit 1 BOOLEAN HostSupportsSCAM:1; // Byte 13 Bit 2 BOOLEAN HostUltraSCSI:1; // Byte 13 Bit 3 BOOLEAN HostSmartTermination:1; // Byte 13 Bit 4 UCHAR :3; // Byte 13 Bits 5-7 }BusLogic_ExtendedSetupInformation_T; // Define the Host Adapter Local RAM AutoSCSI structure. typedef struct BusLogic_AutoSCSIData { UCHAR InternalFactorySignature[2];/* Bytes 0-1 */ UCHAR InformationByteCount; /* Byte 2 */ UCHAR HostAdapterType[6]; /* Bytes 3-8 */ UCHAR :8; /* Byte 9 */ UCHAR FloppyEnabled:1; /* Byte 10 Bit 0 */ UCHAR FloppySecondary:1; /* Byte 10 Bit 1 */ UCHAR LevelSensitiveInterrupt:1; /* Byte 10 Bit 2 */ UCHAR :2; /* Byte 10 Bits 3-4 */ UCHAR SystemRAMAreaForBIOS:3; /* Byte 10 Bits 5-7 */ UCHAR DMA_Channel:7; /* Byte 11 Bits 0-6 */ UCHAR DMA_AutoConfiguration:1; /* Byte 11 Bit 7 */ UCHAR IRQ_Channel:7; /* Byte 12 Bits 0-6 */ UCHAR IRQ_AutoConfiguration:1; /* Byte 12 Bit 7 */ UCHAR DMA_TransferRate; /* Byte 13 */ UCHAR SCSI_ID; /* Byte 14 */ UCHAR LowByteTerminated:1; /* Byte 15 Bit 0 */ UCHAR ParityCheckingEnabled:1; /* Byte 15 Bit 1 */ UCHAR HighByteTerminated:1; /* Byte 15 Bit 2 */ UCHAR NoisyCablingEnvironment:1; /* Byte 15 Bit 3 */ UCHAR FastSynchronousNegotiation:1; /* Byte 15 Bit 4 */ UCHAR BusResetEnabled:1; /* Byte 15 Bit 5 */ UCHAR :1; /* Byte 15 Bit 6 */ UCHAR ActiveNegationEnabled:1; /* Byte 15 Bit 7 */ UCHAR BusOnDelay; /* Byte 16 */ UCHAR BusOffDelay; /* Byte 17 */ UCHAR HostAdapterBIOSEnabled:1; /* Byte 18 Bit 0 */ UCHAR BIOSRedirectionOfINT19Enabled:1; /* Byte 18 Bit 1 */ UCHAR ExtendedTranslationEnabled:1; /* Byte 18 Bit 2 */ UCHAR MapRemovableAsFixedEnabled:1; /* Byte 18 Bit 3 */ UCHAR :1; /* Byte 18 Bit 4 */ UCHAR BIOSSupportsMoreThan2DrivesEnabled:1;/* Byte 18 Bit 5 */ UCHAR BIOSInterruptModeEnabled:1; /* Byte 18 Bit 6 */ UCHAR FlopticalSupportEnabled:1; /* Byte 19 Bit 7 */ unsigned short DeviceEnabled:16; /* Bytes 19-20 */ unsigned short WidePermitted:16; /* Bytes 21-22 */ unsigned short FastPermitted:16; /* Bytes 23-24 */ unsigned short SynchronousPermitted:16; /* Bytes 25-26 */ unsigned short DisconnectPermitted:16; /* Bytes 27-28 */ unsigned short SendStartUnitCommand:16; /* Bytes 29-30 */ unsigned short IgnoreInBIOSScan:16; /* Bytes 31-32 */ UCHAR PCIInterruptPin:2; /* Byte 33 Bits 0-1 */ UCHAR HostAdapterIOPortAddress:2; /* Byte 33 Bits 2-3 */ UCHAR StrictRoundRobinModeEnabled:1; /* Byte 33 Bit 4 */ UCHAR VESABusSpeedGreaterThan33MHz:1; /* Byte 33 Bit 5 */ UCHAR VESABurstWriteEnabled:1; /* Byte 33 Bit 6 */ UCHAR VESABurstReadEnabled:1; /* Byte 33 Bit 7 */ unsigned short UltraPermitted:16; /* Bytes 34-35 */ unsigned int :32; /* Bytes 36-39 */ UCHAR :8; /* Byte 40 */ UCHAR AutoSCSIMaximumLUN; /* Byte 41 */ UCHAR :1; /* Byte 42 Bit 0 */ UCHAR SCAM_Dominant:1; /* Byte 42 Bit 1 */ UCHAR SCAM_Enabled:1; /* Byte 42 Bit 2 */ UCHAR SCAM_Level2:1; /* Byte 42 Bit 3 */ UCHAR :4; /* Byte 42 Bits 4-7 */ UCHAR INT13ExtensionEnabled:1; /* Byte 43 Bit 0 */ UCHAR :1; /* Byte 43 Bit 1 */ UCHAR CDROMBootEnabled:1; /* Byte 43 Bit 2 */ UCHAR :5; /* Byte 43 Bits 3-7 */ UCHAR BootTargetID:4; /* Byte 44 Bits 0-3 */ UCHAR BootChannel:4; /* Byte 44 Bits 4-7 */ UCHAR ForceBusDeviceScanningOrder:1; /* Byte 45 Bit 0 */ UCHAR :7; /* Byte 45 Bits 1-7 */ unsigned short NonTaggedToAlternateLUNPermitted; /* Bytes 46-47 */ unsigned short RenegotiateSyncAfterCheckCondition; /* Bytes 48-49 */ UCHAR Reserved[10]; /* Bytes 50-59 */ UCHAR ManufacturingDiagnostic[2]; /* Bytes 60-61 */ unsigned short Checksum:16; /* Bytes 62-63 */ }BusLogic_AutoSCSIData_T; #pragma pack() // Define the Outgoing Mailbox Action Codes. typedef enum { BusLogic_OutgoingMailboxFree = 0x00, BusLogic_MailboxStartCommand = 0x01, BusLogic_MailboxAbortCommand = 0x02 }BusLogic_ActionCode_T; // Define the Incoming Mailbox Completion Codes. The MultiMaster Firmware // only uses codes 0 - 4. The FlashPoint SCCB Manager has no mailboxes, so // completion codes are stored in the CCB; it only uses codes 1, 2, 4, and 5. typedef enum { BusLogic_IncomingMailboxFree = 0x00, BusLogic_CommandCompletedWithoutError = 0x01, BusLogic_CommandAbortedAtHostRequest = 0x02, BusLogic_AbortedCommandNotFound = 0x03, BusLogic_CommandCompletedWithError = 0x04, BusLogic_InvalidCCB = 0x05 }BusLogic_CompletionCode_T; // Define the Command Control Block (CCB) Opcodes. typedef enum { BusLogic_InitiatorCCB = 0x00, BusLogic_TargetCCB = 0x01, BusLogic_InitiatorCCB_ScatterGather = 0x02, BusLogic_InitiatorCCB_ResidualDataLength = 0x03, BusLogic_InitiatorCCB_ScatterGatherResidual = 0x04, BusLogic_BusDeviceReset = 0x81 }BusLogic_CCB_Opcode_T; // Define the CCB Data Direction Codes. typedef enum { BusLogic_UncheckedDataTransfer = 0, BusLogic_DataInLengthChecked = 1, BusLogic_DataOutLengthChecked = 2, BusLogic_NoDataTransfer = 3 }BusLogic_DataDirection_T; // Define the Host Adapter Status Codes. The MultiMaster Firmware does not // return status code 0x0C; it uses 0x12 for both overruns and underruns. typedef enum { BusLogic_CommandCompletedNormally = 0x00, BusLogic_LinkedCommandCompleted = 0x0A, BusLogic_LinkedCommandCompletedWithFlag = 0x0B, BusLogic_DataUnderRun = 0x0C, BusLogic_SCSISelectionTimeout = 0x11, BusLogic_DataOverRun = 0x12, BusLogic_UnexpectedBusFree = 0x13, BusLogic_InvalidBusPhaseRequested = 0x14, BusLogic_InvalidOutgoingMailboxActionCode = 0x15, BusLogic_InvalidCommandOperationCode = 0x16, BusLogic_LinkedCCBhasInvalidLUN = 0x17, BusLogic_InvalidCommandParameter = 0x1A, BusLogic_AutoRequestSenseFailed = 0x1B, BusLogic_TaggedQueuingMessageRejected = 0x1C, BusLogic_UnsupportedMessageReceived = 0x1D, BusLogic_HostAdapterHardwareFailed = 0x20, BusLogic_TargetFailedResponseToATN = 0x21, BusLogic_HostAdapterAssertedRST = 0x22, BusLogic_OtherDeviceAssertedRST = 0x23, BusLogic_TargetDeviceReconnectedImproperly = 0x24, BusLogic_HostAdapterAssertedBusDeviceReset = 0x25, BusLogic_AbortQueueGenerated = 0x26, BusLogic_HostAdapterSoftwareError = 0x27, BusLogic_HostAdapterHardwareTimeoutError= 0x30, BusLogic_SCSIParityErrorDetected = 0x34 }BusLogic_HostAdapterStatus_T; // Define the SCSI Target Device Status Codes. typedef enum { BusLogic_OperationGood = 0x00, BusLogic_CheckCondition = 0x02, BusLogic_DeviceBusy = 0x08 }BusLogic_TargetDeviceStatus_T; // Define the Queue Tag Codes. typedef enum { BusLogic_SimpleQueueTag = 0, BusLogic_HeadOfQueueTag = 1, BusLogic_OrderedQueueTag = 2, BusLogic_ReservedQT = 3 }BusLogic_QueueTag_T; // Define the Scatter/Gather Segment structure required by the MultiMaster // Firmware Interface and the FlashPoint SCCB Manager. typedef struct BusLogic_ScatterGatherSegment { BusLogic_ByteCount_T SegmentByteCount; /* Bytes 0-3 */ BusLogic_BusAddress_T SegmentDataPointer; /* Bytes 4-7 */ }BusLogic_ScatterGatherSegment_T; typedef UCHAR SCSI_CDB_T[BusLogic_CDB_MaxLength]; // Define the Driver CCB Status Codes. typedef enum { BusLogic_CCB_Free = 0, BusLogic_CCB_Active = 1, BusLogic_CCB_Completed = 2, BusLogic_CCB_Reset = 3 }BusLogic_CCB_Status_T; // Define the 32 Bit Mode Command Control Block (CCB) structure. The first 40 // bytes are defined by the MultiMaster Firmware The remaining components are // defined by the Scsi MiniportDriver. // Extended LUN Format CCBs differ from Legacy LUN Format 32 Bit Mode // CCBs only in having the TagEnable and QueueTag fields moved from byte 17 to // byte 1, and the Logical Unit field in byte 17 expanded to 6 bits. In theory, // Extended LUN Format CCBs can support up to 64 Logical Units, but in practice // many devices will respond improperly to Logical Units between 32 and 63, and // the SCSI-2 specification defines Bit 5 as LUNTAR. Extended LUN Format CCBs // are used by recent versions of the MultiMaster Firmware. // Since 64 Logical Units are unlikely to be needed in practice, and // since they are problematic for the above reasons, and since limiting them to // 5 bits simplifies the CCB structure definition, this driver only supports // 32 Logical Units per Target Device. typedef struct BusLogic_CCB { UCHAR Opcode; /* Byte 0 */ UCHAR :3; /* Byte 1 Bits 0-2 */ UCHAR DataDirection:2; /* Byte 1 Bits 3-4 */ UCHAR TagEnable:1; /* Byte 1 Bit 5 */ UCHAR QueueTag:2; /* Byte 1 Bits 6-7 */ UCHAR CDB_Length; /* Byte 2 */ UCHAR SenseDataLength; /* Byte 3 */ BusLogic_ByteCount_T DataLength; /* Bytes 4-7 */ BusLogic_BusAddress_T DataPointer;/* Bytes 8-11 */ UCHAR :8; /* Byte 12 */ UCHAR :8; /* Byte 13 */ UCHAR HostAdapterStatus; /* Byte 14 */ UCHAR TargetDeviceStatus; /* Byte 15 */ UCHAR TargetID; /* Byte 16 */ UCHAR LogicalUnit:5; /* Byte 17 Bits 0-4 */ UCHAR LegacyTagEnable:1; /* Byte 17 Bit 5 */ UCHAR LegacyQueueTag:2; /* Byte 17 Bits 6-7 */ SCSI_CDB_T CDB; /* Bytes 18-29 */ UCHAR :8; /* Byte 30 */ UCHAR :8; /* Byte 31 */ unsigned int :32; /* Bytes 32-35 */ BusLogic_BusAddress_T SenseDataPointer;/* Bytes 36-39 */ // BusLogic Driver Defined Portion. BusLogic_CCB_Status_T Status; unsigned long SerialNumber; struct BusLogic_HostAdapter *HostAdapter; struct BusLogic_CCB *Next; BusLogic_ScatterGatherSegment_T ScatterGatherList[BusLogic_ScatterGatherLimit]; BusLogic_CompletionCode_T CompletionCode; // Pointer to the CCB PVOID SrbAddress; PVOID AbortSrb; }BusLogic_CCB_T, *PBuslogic_CCB_T; #pragma pack(1) // Define the 32 Bit Mode Outgoing Mailbox structure. typedef struct BusLogic_OutgoingMailbox { BusLogic_BusAddress_T CCB;/* Bytes 0-3 */ UCHAR :8; /* Bytes 4 */ UCHAR :8; /* Bytes 5 */ UCHAR :8; /* Bytes 6 */ UCHAR ActionCode; /* Byte 7 */ }BusLogic_OutgoingMailbox_T; // Define the 32 Bit Mode Incoming Mailbox structure. typedef struct BusLogic_IncomingMailbox { BusLogic_BusAddress_T CCB; /* Bytes 0-3 */ UCHAR HostAdapterStatus; /* Byte 4 */ UCHAR TargetDeviceStatus; /* Byte 5 */ UCHAR :8; /* Byte 6 */ UCHAR CompletionCode; /* Byte 7 */ }BusLogic_IncomingMailbox_T; #pragma pack () // // The following structure is allocated // from noncached memory as data will be DMA'd to // and from it. typedef struct _NONCACHED_EXTENSION { // Physical base address of mailboxes ULONG MailboxPA; // Mailboxes UCHAR MailboxOut[BusLogic_MaxMailboxes * sizeof(BusLogic_OutgoingMailbox_T)]; UCHAR MailboxIn[BusLogic_MaxMailboxes * sizeof(BusLogic_IncomingMailbox_T)]; } NONCACHED_EXTENSION, *PNONCACHED_EXTENSION; // Define the types of BusLogic Host Adapters that are supported and the number // of I/O Addresses required by each type. typedef enum { BusLogic_MultiMaster = 1, BusLogic_FlashPoint = 2 }BusLogic_HostAdapterType_T; // Define the possible Host Adapter Bus Types. typedef enum { BusLogic_Unknown_Bus = 0, BusLogic_ISA_Bus = 1, BusLogic_EISA_Bus = 2, BusLogic_PCI_Bus = 3, BusLogic_VESA_Bus = 4, BusLogic_MCA_Bus = 5 }BusLogic_HostAdapterBusType_T; #if 0 static char *BusLogic_HostAdapterBusNames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" }; #endif static BusLogic_HostAdapterBusType_T BusLogic_HostAdapterBusTypes[] ={ BusLogic_VESA_Bus, /* BT-4xx */ BusLogic_ISA_Bus, /* BT-5xx */ BusLogic_MCA_Bus, /* BT-6xx */ BusLogic_EISA_Bus, /* BT-7xx */ BusLogic_Unknown_Bus, /* BT-8xx */ BusLogic_PCI_Bus /* BT-9xx */ }; // Define the BusLogic Driver Host Adapter structure typedef struct BusLogic_HostAdapter { BusLogic_HostAdapterType_T HostAdapterType; BusLogic_HostAdapterBusType_T HostAdapterBusType; UCHAR ModelName[9]; UCHAR FirmwareVersion[6]; UCHAR FullModelName[18]; UCHAR Bus; PUCHAR IO_Address; UCHAR IRQ_Channel; UCHAR SCSI_ID; BOOLEAN ExtendedTranslationEnabled:1; BOOLEAN ParityCheckingEnabled:1; BOOLEAN BusResetEnabled:1; BOOLEAN LevelSensitiveInterrupt:1; BOOLEAN HostWideSCSI:1; BOOLEAN HostDifferentialSCSI:1; BOOLEAN HostSupportsSCAM:1; BOOLEAN HostUltraSCSI:1; BOOLEAN ExtendedLUNSupport:1; BOOLEAN TerminationInfoValid:1; BOOLEAN LowByteTerminated:1; BOOLEAN HighByteTerminated:1; BOOLEAN BounceBuffersRequired:1; BOOLEAN StrictRoundRobinModeSupport:1; BOOLEAN SCAM_Enabled:1; BOOLEAN SCAM_Level2:1; BOOLEAN HostAdapterInitialized:1; BOOLEAN HostAdapterExternalReset:1; BOOLEAN HostAdapterInternalError:1; BOOLEAN ProcessCompletedCCBsActive; volatile BOOLEAN HostAdapterCommandCompleted; unsigned short HostAdapterScatterGatherLimit; unsigned short DriverScatterGatherLimit; UCHAR MaxTargetDevices; UCHAR MaxLogicalUnits; unsigned short DriverQueueDepth; unsigned short HostAdapterQueueDepth; unsigned short UntaggedQueueDepth; unsigned short CommonQueueDepth; unsigned short BusSettleTime; unsigned short SynchronousPermitted; unsigned short FastPermitted; unsigned short UltraPermitted; unsigned short WidePermitted; unsigned short DisconnectPermitted; unsigned short TaggedQueuingPermitted; unsigned short ExternalHostAdapterResets; unsigned short HostAdapterInternalErrors; unsigned short TargetDeviceCount; BusLogic_BusAddress_T BIOS_Address; BusLogic_CCB_T *FirstCompletedCCB; BusLogic_CCB_T *LastCompletedCCB; BusLogic_CCB_T *BusDeviceResetPendingCCB[BusLogic_MaxTargetDevices]; BusLogic_TargetFlags_T TargetFlags[BusLogic_MaxTargetDevices]; UCHAR SynchronousPeriod[BusLogic_MaxTargetDevices]; UCHAR SynchronousOffset[BusLogic_MaxTargetDevices]; UCHAR ActiveCommandsPerTarget[BusLogic_MaxTargetDevices]; UCHAR ActiveCommandsPerLun[BusLogic_MaxTargetDevices][BusLogic_MaxLogicalUnits]; unsigned int CommandsSinceReset[BusLogic_MaxTargetDevices]; unsigned long LastSequencePoint[BusLogic_MaxTargetDevices]; unsigned long LastResetAttempted[BusLogic_MaxTargetDevices]; unsigned long LastResetCompleted[BusLogic_MaxTargetDevices]; UCHAR MailboxCount; BusLogic_OutgoingMailbox_T *FirstOutgoingMailbox; BusLogic_OutgoingMailbox_T *LastOutgoingMailbox; BusLogic_OutgoingMailbox_T *NextOutgoingMailbox; BusLogic_IncomingMailbox_T *FirstIncomingMailbox; BusLogic_IncomingMailbox_T *LastIncomingMailbox; BusLogic_IncomingMailbox_T *NextIncomingMailbox; BusLogic_TargetStatistics_T TargetStatistics[BusLogic_MaxTargetDevices]; }BusLogic_HostAdapter_T; // Buslogic specific port driver device object extension. typedef struct _HW_DEVICE_EXTENSION { BusLogic_HostAdapter_T hcs; PNONCACHED_EXTENSION NoncachedExtension; SCSI_WMILIB_CONTEXT WmiLibContext; } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION; // Define a structure for the SCSI Inquiry command results. #pragma pack (1) typedef struct SCSI_Inquiry { UCHAR PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */ UCHAR PeripheralQualifier:3; /* Byte 0 Bits 5-7 */ UCHAR DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */ BOOLEAN RMB:1; /* Byte 1 Bit 7 */ UCHAR ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */ UCHAR ECMA_Version:3; /* Byte 2 Bits 3-5 */ UCHAR ISO_Version:2; /* Byte 2 Bits 6-7 */ UCHAR ResponseDataFormat:4; /* Byte 3 Bits 0-3 */ UCHAR :2; /* Byte 3 Bits 4-5 */ BOOLEAN TrmIOP:1; /* Byte 3 Bit 6 */ BOOLEAN AENC:1; /* Byte 3 Bit 7 */ UCHAR AdditionalLength; /* Byte 4 */ UCHAR :8; /* Byte 5 */ UCHAR :8; /* Byte 6 */ BOOLEAN SftRe:1; /* Byte 7 Bit 0 */ BOOLEAN CmdQue:1; /* Byte 7 Bit 1 */ BOOLEAN :1; /* Byte 7 Bit 2 */ BOOLEAN Linked:1; /* Byte 7 Bit 3 */ BOOLEAN Sync:1; /* Byte 7 Bit 4 */ BOOLEAN WBus16:1; /* Byte 7 Bit 5 */ BOOLEAN WBus32:1; /* Byte 7 Bit 6 */ BOOLEAN RelAdr:1; /* Byte 7 Bit 7 */ UCHAR VendorIdentification[8];/* Bytes 8-15 */ UCHAR ProductIdentification[16];/* Bytes 16-31 */ UCHAR ProductRevisionLevel[4];/* Bytes 32-35 */ }SCSI_Inquiry_T; typedef struct BusLogic_WmiExtendedSetupInformation { UCHAR BusType; // Byte 0 UCHAR BIOS_Address; // Byte 1 unsigned short ScatterGatherLimit; // Bytes 2-3 UCHAR MailboxCount; // Byte 4 BusLogic_BusAddress_T BaseMailboxAddress; // Bytes 5-8 BOOLEAN FastOnEISA; // Byte 9 BOOLEAN LevelSensitiveInterrupt; // Byte 10 UCHAR FirmwareRevision[3]; // Bytes 11-14 BOOLEAN HostWideSCSI; // Byte 15 BOOLEAN HostDifferentialSCSI; // Byte 16 BOOLEAN HostSupportsSCAM; // Byte 17 BOOLEAN HostUltraSCSI; // Byte 18 BOOLEAN HostSmartTermination; // Byte 19 }BusLogic_WmiExtendedSetupInformation_T, *PBusLogic_WmiExtendedSetupInformation_T; #pragma pack () //_________________________________________________________________________________________ // function declarations //_________________________________________________________________________________________ ULONG NTAPI DriverEntry(IN PVOID DriverObject, IN PVOID Argument2 ); ULONG NTAPI BT958HwFindAdapter(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again ); BOOLEAN NTAPI BT958HwInitialize(IN PVOID HwDeviceExtension); BOOLEAN NTAPI BT958HwStartIO(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb ); BOOLEAN NTAPI BT958HwInterrupt(IN PVOID HwDeviceExtension); BOOLEAN NTAPI BT958HwResetBus(IN PVOID HwDeviceExtension, IN ULONG PathId ); SCSI_ADAPTER_CONTROL_STATUS NTAPI BT958HwAdapterControl(IN PVOID HwDeviceExtension, IN SCSI_ADAPTER_CONTROL_TYPE ControlType, IN PVOID Parameters ); #if 0 BOOLEAN BT958WmiSrb(IN PHW_DEVICE_EXTENSION HwDeviceExtension, IN OUT PSCSI_WMI_REQUEST_BLOCK Srb); #endif void BT958WmiInitialize( IN PHW_DEVICE_EXTENSION HwDeviceExtension); BOOLEAN Buslogic_InitBT958(PHW_DEVICE_EXTENSION deviceExtension, PPORT_CONFIGURATION_INFORMATION ConfigInfo); BOOLEAN BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter); BOOLEAN BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter, BOOLEAN HardReset); BOOLEAN BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter); int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter, BusLogic_OperationCode_T OperationCode, void *ParameterData, int ParameterLength, void *ReplyData, int ReplyLength); BOOLEAN BusLogic_ReadHostAdapterConfiguration( BusLogic_HostAdapter_T *HostAdapter); BOOLEAN BusLogic_InitializeHostAdapter(PHW_DEVICE_EXTENSION deviceExtension, PPORT_CONFIGURATION_INFORMATION ConfigInfo); BOOLEAN BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T *HostAdapter); int BusLogic_QueueCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PBuslogic_CCB_T ccb); BOOLEAN BusLogic_WriteOutgoingMailbox(PHW_DEVICE_EXTENSION deviceExtension , BusLogic_ActionCode_T ActionCode, BusLogic_CCB_T *CCB); void BusLogic_ScanIncomingMailboxes(PHW_DEVICE_EXTENSION deviceExtension); void BusLogic_QueueCompletedCCB(PHW_DEVICE_EXTENSION deviceExtension, BusLogic_CCB_T *CCB); void BusLogic_ProcessCompletedCCBs(PHW_DEVICE_EXTENSION deviceExtension); UCHAR BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter, BusLogic_HostAdapterStatus_T HostAdapterStatus, BusLogic_TargetDeviceStatus_T TargetDeviceStatus, UCHAR SenseDataLength); BOOLEAN BusLogic_SendBusDeviceReset(IN PVOID HwDeviceExtension, PSCSI_REQUEST_BLOCK Srb); static UCHAR ReadBusLogicPort(PUCHAR adr ) { return ScsiPortReadPortUchar( adr ); } static VOID WriteBusLogicPort(UCHAR data, PUCHAR adr) { ScsiPortWritePortUchar(adr, data); } //_________________________________________________________________________________________ // Declarations for the device registers and reading and writing to them //_________________________________________________________________________________________ // Define the BusLogic SCSI Host Adapter I/O Register Offsets. #define BusLogic_ControlRegisterOffset 0 // WO register #define BusLogic_StatusRegisterOffset 0 // RO register #define BusLogic_CommandParameterRegisterOffset 1 // WO register #define BusLogic_DataInRegisterOffset 1 // RO register #define BusLogic_InterruptRegisterOffset 2 // RO register #define BusLogic_GeometryRegisterOffset 3 // RO register // Define the structure of the write-only Control Register. typedef union BusLogic_ControlRegister { UCHAR All; struct { UCHAR :4; // Bits 0-3 BOOLEAN SCSIBusReset:1; // Bit 4 BOOLEAN InterruptReset:1; // Bit 5 BOOLEAN SoftReset:1; // Bit 6 BOOLEAN HardReset:1; // Bit 7 } Bits; }BusLogic_ControlRegister_T; // Define the structure of the read-only Status Register. typedef union BusLogic_StatusRegister { UCHAR All; struct { BOOLEAN CommandInvalid:1; // Bit 0 BOOLEAN Reserved:1; // Bit 1 BOOLEAN DataInRegisterReady:1; // Bit 2 BOOLEAN CommandParameterRegisterBusy:1; // Bit 3 BOOLEAN HostAdapterReady:1; // Bit 4 BOOLEAN InitializationRequired:1; // Bit 5 BOOLEAN DiagnosticFailure:1; // Bit 6 BOOLEAN DiagnosticActive:1; // Bit 7 } Bits; }BusLogic_StatusRegister_T; // Define the structure of the read-only Interrupt Register. typedef union BusLogic_InterruptRegister { UCHAR All; struct { BOOLEAN IncomingMailboxLoaded:1; // Bit 0 BOOLEAN OutgoingMailboxAvailable:1; // Bit 1 BOOLEAN CommandComplete:1; // Bit 2 BOOLEAN ExternalBusReset:1; // Bit 3 UCHAR Reserved:3; // Bits 4-6 BOOLEAN InterruptValid:1; // Bit 7 } Bits; }BusLogic_InterruptRegister_T; // Define the possible Host Adapter BIOS Disk Geometry Translations. typedef enum BusLogic_BIOS_DiskGeometryTranslation { BusLogic_BIOS_Disk_Not_Installed = 0, BusLogic_BIOS_Disk_Installed_64x32 = 1, BusLogic_BIOS_Disk_Installed_128x32 = 2, BusLogic_BIOS_Disk_Installed_255x63 = 3 }BusLogic_BIOS_DiskGeometryTranslation_T; // Define the structure of the read-only Geometry Register typedef union BusLogic_GeometryRegister { UCHAR All; struct { BusLogic_BIOS_DiskGeometryTranslation_T Drive0Geometry:2; // Bits 0-1 BusLogic_BIOS_DiskGeometryTranslation_T Drive1Geometry:2; // Bits 2-3 UCHAR :3; // Bits 4-6 BOOLEAN ExtendedTranslationEnabled:1; // Bit 7 } Bits; } BusLogic_GeometryRegister_T; static void BusLogic_InterruptReset(BusLogic_HostAdapter_T *HostAdapter) { BusLogic_ControlRegister_T ControlRegister; ControlRegister.All = 0; ControlRegister.Bits.InterruptReset = TRUE; WriteBusLogicPort(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset); } static void BusLogic_SoftReset(BusLogic_HostAdapter_T *HostAdapter) { BusLogic_ControlRegister_T ControlRegister; ControlRegister.All = 0; ControlRegister.Bits.SoftReset = TRUE; WriteBusLogicPort(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset); } static void BusLogic_HardReset(BusLogic_HostAdapter_T *HostAdapter) { BusLogic_ControlRegister_T ControlRegister; ControlRegister.All = 0; ControlRegister.Bits.HardReset = TRUE; WriteBusLogicPort(ControlRegister.All, HostAdapter->IO_Address + BusLogic_ControlRegisterOffset); } static UCHAR BusLogic_ReadStatusRegister(BusLogic_HostAdapter_T *HostAdapter) { return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_StatusRegisterOffset); } static UCHAR BusLogic_ReadInterruptRegister(BusLogic_HostAdapter_T *HostAdapter) { return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_InterruptRegisterOffset); } static UCHAR BusLogic_ReadGeometryRegister(BusLogic_HostAdapter_T *HostAdapter) { return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_GeometryRegisterOffset); } static UCHAR BusLogic_ReadDataInRegister(BusLogic_HostAdapter_T *HostAdapter) { return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_DataInRegisterOffset); } static void BusLogic_WriteCommandParameterRegister(BusLogic_HostAdapter_T *HostAdapter, UCHAR Value) { WriteBusLogicPort(Value, HostAdapter->IO_Address + BusLogic_CommandParameterRegisterOffset); } // BusLogic_StartMailboxCommand issues an Execute Mailbox Command, which // notifies the Host Adapter that an entry has been made in an Outgoing // Mailbox. static void BusLogic_StartMailboxCommand(BusLogic_HostAdapter_T *HostAdapter) { BusLogic_WriteCommandParameterRegister(HostAdapter, BusLogic_ExecuteMailboxCommand); } // Define the Inquire Synchronous Period reply type. For each Target Device, // a byte is returned which represents the Synchronous Transfer Period in units // of 10 nanoseconds. typedef UCHAR BusLogic_SynchronousPeriod_T[BusLogic_MaxTargetDevices]; // Define the Inquire Installed Devices ID 0 to 7 and Inquire Installed // Devices ID 8 to 15 reply type. For each Target Device, a byte is returned // where bit 0 set indicates that Logical Unit 0 exists, bit 1 set indicates // that Logical Unit 1 exists, and so on. typedef UCHAR BusLogic_InstalledDevices8_T[8]; // Define the Inquire Target Devices reply type. Inquire Target Devices only // tests Logical Unit 0 of each Target Device unlike the Inquire Installed // Devices commands which test Logical Units 0 - 7. Two bytes are returned, // where byte 0 bit 0 set indicates that Target Device 0 exists, and so on. typedef unsigned short BusLogic_InstalledDevices_T; // Define the Initialize Extended Mailbox request structure. #pragma pack (1) typedef struct BusLogic_ExtendedMailboxRequest { UCHAR MailboxCount; /* Byte 0 */ ULONG BaseMailboxAddress; /* Bytes 1-4 */ }BusLogic_ExtendedMailboxRequest_T; #pragma pack () // Define the Set CCB Format request type. Extended LUN Format CCBs are // necessary to support more than 8 Logical Units per Target Device. typedef enum BusLogic_SetCCBFormatRequest { BusLogic_LegacyLUNFormatCCB = 0, BusLogic_ExtendedLUNFormatCCB = 1 }BusLogic_SetCCBFormatRequest_T; //______________________________________________________________________________________ // Statistics //______________________________________________________________________________________ // BusLogic_IncrementByteCounter increments Byte Counter by Amount. static void BusLogic_IncrementByteCounter(BusLogic_ByteCounter_T *ByteCounter, unsigned int Amount) { ByteCounter->Units += Amount; if (ByteCounter->Units > 999999999) { ByteCounter->Units -= 1000000000; ByteCounter->Billions++; } } // BusLogic_IncrementSizeBucket increments the Bucket for Amount. static void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T CommandSizeBuckets, unsigned int Amount) { int Index = 0; if (Amount < 8*1024) { if (Amount < 2*1024) Index = (Amount < 1*1024 ? 0 : 1); else Index = (Amount < 4*1024 ? 2 : 3); } else if (Amount < 128*1024) { if (Amount < 32*1024) Index = (Amount < 16*1024 ? 4 : 5); else Index = (Amount < 64*1024 ? 6 : 7); } else Index = (Amount < 256*1024 ? 8 : 9); CommandSizeBuckets[Index]++; } // BusLogic_IncrementErrorCounter increments Error Counter by 1, stopping at // 65535 rather than wrapping around to 0. static void BusLogic_IncrementErrorCounter(unsigned short *ErrorCounter) { if (*ErrorCounter < 65535) (*ErrorCounter)++; } //____________________________________________________________________________________________