/* Linux Driver for BusLogic MultiMaster SCSI Host Adapters Copyright 1995 by Leonard N. Zubkoff This program is free software; you may redistribute and/or modify it under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation, provided that none of the source code or runtime copyright notices are removed or modified. 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 complete details. The author respectfully requests that any modifications to this software be sent directly to him for evaluation and testing. Special thanks to Wayne Yen and Alex Win of BusLogic, whose advice has been invaluable, to David Gentzel, for writing the original Linux BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site. */ /* Define types for some of the structures that interface with the rest of the Linux Kernel and SCSI Subsystem. */ typedef struct pt_regs Registers_T; typedef Scsi_Host_Template SCSI_Host_Template_T; typedef struct Scsi_Host SCSI_Host_T; typedef struct scsi_device SCSI_Device_T; typedef struct scsi_disk SCSI_Disk_T; typedef struct scsi_cmnd SCSI_Command_T; typedef struct scatterlist SCSI_ScatterList_T; typedef int KernelDevice_T; /* Define prototypes for the BusLogic Driver Interface Functions. */ const char *BusLogic_DriverInfo(SCSI_Host_T *); int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *); int BusLogic_ReleaseHostAdapter(SCSI_Host_T *); int BusLogic_QueueCommand(SCSI_Command_T *, void (*CompletionRoutine)(SCSI_Command_T *)); int BusLogic_AbortCommand(SCSI_Command_T *); int BusLogic_ResetCommand(SCSI_Command_T *, unsigned int); int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *); /* Define the BusLogic SCSI Host Template structure. */ #define BUSLOGIC \ { NULL, /* Next */ \ NULL, /* Usage Count Pointer */ \ "BusLogic", /* Driver Name */ \ BusLogic_DetectHostAdapter, /* Detect Host Adapter */ \ BusLogic_ReleaseHostAdapter, /* Release Host Adapter */ \ BusLogic_DriverInfo, /* Driver Info Function */ \ NULL, /* Command Function */ \ BusLogic_QueueCommand, /* Queue Command Function */ \ BusLogic_AbortCommand, /* Abort Command Function */ \ BusLogic_ResetCommand, /* Reset Command Function */ \ NULL, /* Slave Attach Function */ \ BusLogic_BIOSDiskParameters, /* Disk BIOS Parameters */ \ 0, /* Can Queue */ \ 0, /* This ID */ \ 0, /* Scatter/Gather Table Size */ \ 0, /* SCSI Commands per LUN */ \ 0, /* Present */ \ 1, /* Default Unchecked ISA DMA */ \ ENABLE_CLUSTERING } /* Enable Clustering */ /* BusLogic_DriverVersion protects the private portion of this file. */ #ifdef BusLogic_DriverVersion /* Define the maximum number of BusLogic Host Adapters that are supported. */ #define BusLogic_MaxHostAdapters 10 /* Define the maximum number of I/O Addresses that may be probed. */ #define BusLogic_IO_MaxProbeAddresses 16 /* Define the maximum number of Target Devices supported by this driver. */ #define BusLogic_MaxTargetDevices 16 /* 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 maximum single request generated by the I/O Subsystem. */ #define BusLogic_ScatterGatherLimit 128 /* Define the maximum, preferred, 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 63 #define BusLogic_PreferredTaggedQueueDepth 28 #define BusLogic_TaggedQueueDepth_BB 2 #define BusLogic_UntaggedQueueDepth 3 /* 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 possible Probe Options. */ #define BusLogic_NoProbe 1 #define BusLogic_NoProbeISA 2 #define BusLogic_NoSortPCI 4 /* Define the possible Local Options. */ #define BusLogic_InhibitTargetInquiry 1 /* Define the possible Global Options. */ #define BusLogic_TraceProbe 1 #define BusLogic_TraceHardReset 2 #define BusLogic_TraceConfiguration 4 #define BusLogic_TraceErrors 8 #define BusLogic_TraceQueueDepths 16 /* Define the possible Error Recovery Strategy Options. */ #define BusLogic_ErrorRecovery_Default 0 #define BusLogic_ErrorRecovery_HardReset 1 #define BusLogic_ErrorRecovery_BusDeviceReset 2 #define BusLogic_ErrorRecovery_None 3 static char *BusLogic_ErrorRecoveryStrategyNames[] = { "Default", "Hard Reset", "Bus Device Reset", "None" }, *BusLogic_ErrorRecoveryStrategyLetters[] = { "D", "H", "B", "N" }; /* Define a boolean data type. */ #define false 0 #define true 1 typedef unsigned char boolean; /* Define a 32 bit bus address data type. */ typedef unsigned int bus_address_t; /* Define the maxiumu number of IRQ Channels. */ #define NR_IRQS 16 /* Define the BusLogic SCSI Host Adapter I/O Register Offsets. */ #define BusLogic_IO_PortCount 4 /* I/O Registers */ #define BusLogic_ControlRegister 0 /* WO register */ #define BusLogic_StatusRegister 0 /* RO register */ #define BusLogic_CommandParameterRegister 1 /* WO register */ #define BusLogic_DataInRegister 1 /* RO register */ #define BusLogic_InterruptRegister 2 /* RO register */ #define BusLogic_GeometryRegister 3 /* RO register */ /* Define the bits in the write-only Control Register. */ #define BusLogic_ReservedCR 0x0F #define BusLogic_SCSIBusReset 0x10 #define BusLogic_InterruptReset 0x20 #define BusLogic_SoftReset 0x40 #define BusLogic_HardReset 0x80 /* Define the bits in the read-only Status Register. */ #define BusLogic_CommandInvalid 0x01 #define BusLogic_ReservedSR 0x02 #define BusLogic_DataInRegisterReady 0x04 #define BusLogic_CommandParameterRegisterBusy 0x08 #define BusLogic_HostAdapterReady 0x10 #define BusLogic_InitializationRequired 0x20 #define BusLogic_DiagnosticFailure 0x40 #define BusLogic_DiagnosticActive 0x80 /* Define the bits in the read-only Interrupt Register. */ #define BusLogic_IncomingMailboxLoaded 0x01 #define BusLogic_OutgoingMailboxAvailable 0x02 #define BusLogic_CommandComplete 0x04 #define BusLogic_SCSIResetState 0x08 #define BusLogic_ReservedIR 0x70 #define BusLogic_InterruptValid 0x80 /* Define the bits in the read-only Geometry Register. */ #define BusLogic_Drive0Geometry 0x03 #define BusLogic_Drive1Geometry 0x0C #define BusLogic_ReservedGR 0x70 #define BusLogic_ExtendedTranslationEnabled 0x80 /* Define the BusLogic SCSI Host Adapter Command Register Operation Codes. */ 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_InquireGenericIOPortInformation = 0x86, BusLogic_InquireControllerModelNumber = 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 Inquire Board ID reply structure. */ typedef struct BusLogic_BoardID { unsigned char BoardType; /* Byte 0 */ unsigned char CustomFeatures; /* Byte 1 */ unsigned char FirmwareVersion1stDigit; /* Byte 2 */ unsigned char FirmwareVersion2ndDigit; /* Byte 3 */ } BusLogic_BoardID_T; /* 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 unsigned char 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 bit 0 set indicates that Target Device 0 exists, and so on. */ typedef unsigned short BusLogic_InstalledDevices_T; /* Define the Inquire Configuration reply structure. */ typedef struct BusLogic_Configuration { unsigned char :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 */ unsigned char :1; /* Byte 1 Bit 4 */ boolean IRQ_Channel14:1; /* Byte 1 Bit 5 */ boolean IRQ_Channel15:1; /* Byte 1 Bit 6 */ unsigned char :1; /* Byte 1 Bit 7 */ unsigned char HostAdapterID:4; /* Byte 2 Bits 0-3 */ unsigned char :4; /* Byte 2 Bits 4-7 */ } BusLogic_Configuration_T; /* Define the Inquire Setup Information reply structure. */ typedef struct BusLogic_SynchronousValue { unsigned char Offset:4; /* Bits 0-3 */ unsigned char TransferPeriod:3; /* Bits 4-6 */ boolean Synchronous:1; /* Bit 7 */ } BusLogic_SynchronousValue_T; typedef BusLogic_SynchronousValue_T BusLogic_SynchronousValues8_T[8]; typedef BusLogic_SynchronousValue_T BusLogic_SynchronousValues_T[BusLogic_MaxTargetDevices]; typedef struct BusLogic_SetupInformation { boolean SynchronousInitiationEnabled:1; /* Byte 0 Bit 0 */ boolean ParityCheckEnabled:1; /* Byte 0 Bit 1 */ unsigned char :6; /* Byte 0 Bits 2-7 */ unsigned char BusTransferRate; /* Byte 1 */ unsigned char PreemptTimeOnBus; /* Byte 2 */ unsigned char TimeOffBus; /* Byte 3 */ unsigned char MailboxCount; /* Byte 4 */ unsigned char MailboxAddress[3]; /* Bytes 5-7 */ BusLogic_SynchronousValues8_T SynchronousValuesID0to7; /* Bytes 8-15 */ unsigned char DisconnectPermittedID0to7; /* Byte 16 */ unsigned char Signature; /* Byte 17 */ unsigned char CharacterD; /* Byte 18 */ unsigned char HostBusType; /* Byte 19 */ unsigned char :8; /* Byte 20 */ unsigned char :8; /* Byte 21 */ BusLogic_SynchronousValues8_T SynchronousValuesID8to15; /* Bytes 22-29 */ unsigned char DisconnectPermittedID8to15; /* Byte 30 */ } BusLogic_SetupInformation_T; /* Define the Initialize Extended Mailbox request structure. */ typedef struct BusLogic_ExtendedMailboxRequest { unsigned char MailboxCount; /* Byte 0 */ bus_address_t BaseMailboxAddress __attribute__ ((packed)); /* Bytes 1-4 */ } BusLogic_ExtendedMailboxRequest_T; /* Define the Inquire Firmware Version 3rd Digit reply type. */ typedef unsigned char BusLogic_FirmwareVersion3rdDigit_T; /* Define the Inquire Firmware Version Letter reply type. */ typedef unsigned char BusLogic_FirmwareVersionLetter_T; /* Define the Inquire Generic I/O Port Information reply type. */ typedef struct BusLogic_GenericIOPortInformation { unsigned char ISACompatibleIOPort; /* Byte 0 */ unsigned char PCIAssignedIRQChannel; /* Byte 1 */ boolean LowByteTerminated:1; /* Byte 2 Bit 0 */ boolean HighByteTerminated:1; /* Byte 2 Bit 1 */ unsigned char :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 Valid:1; /* Byte 2 Bit 7 */ unsigned char :8; /* Byte 3 */ } BusLogic_GenericIOPortInformation_T; /* Define the Inquire Controller Model Number reply type. */ typedef unsigned char BusLogic_ControllerModelNumber_T[5]; /* 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 unsigned char BusLogic_SynchronousPeriod_T[BusLogic_MaxTargetDevices]; /* Define the Inquire Extended Setup Information reply structure. */ typedef struct BusLogic_ExtendedSetupInformation { unsigned char BusType; /* Byte 0 */ unsigned char BIOS_Address; /* Byte 1 */ unsigned short ScatterGatherLimit; /* Bytes 2-3 */ unsigned char MailboxCount; /* Byte 4 */ bus_address_t BaseMailboxAddress __attribute__ ((packed)); /* Bytes 5-8 */ struct { unsigned char :6; /* Byte 9 Bits 0-5 */ boolean LevelSensitiveInterrupts:1; /* Byte 9 Bit 6 */ unsigned char :1; } Misc; /* Byte 9 Bit 7 */ unsigned char FirmwareRevision[3]; /* Bytes 10-12 */ boolean HostWideSCSI:1; /* Byte 13 Bit 0 */ boolean HostDifferentialSCSI:1; /* Byte 13 Bit 1 */ boolean HostAutomaticConfiguration:1; /* Byte 13 Bit 2 */ boolean HostUltraSCSI:1; /* Byte 13 Bit 3 */ boolean HostSmartTermination:1; /* Byte 13 Bit 4 */ unsigned char :3; /* Byte 13 Bits 5-7 */ } BusLogic_ExtendedSetupInformation_T; /* Define the Enable Strict Round Robin Mode request type. */ #define BusLogic_AggressiveRoundRobinMode 0x00 #define BusLogic_StrictRoundRobinMode 0x01 typedef unsigned char BusLogic_RoundRobinModeRequest_T; /* Define the Fetch Host Adapter Local RAM request type. */ #define BusLogic_BIOS_BaseOffset 0 #define BusLogic_AutoSCSI_BaseOffset 64 typedef struct BusLogic_FetchHostAdapterLocalRAMRequest { unsigned char ByteOffset; /* Byte 0 */ unsigned char ByteCount; /* Byte 1 */ } BusLogic_FetchHostAdapterLocalRAMRequest_T; /* Define the Host Adapter Local RAM Auto SCSI Byte 15 reply structure. */ typedef struct BusLogic_AutoSCSIByte15 { unsigned char LowByteTerminated:1; /* Bit 0 */ unsigned char :1; /* Bit 1 */ unsigned char HighByteTerminated:1; /* Bit 2 */ unsigned char :5; /* Bits 3-7 */ } BusLogic_AutoSCSIByte15_T; /* Define the Host Adapter Local RAM Auto SCSI Byte 45 reply structure. */ typedef struct BusLogic_AutoSCSIByte45 { unsigned char ForceBusDeviceScanningOrder:1; /* Bit 0 */ unsigned char :7; /* Bits 1-7 */ } BusLogic_AutoSCSIByte45_T; /* Define the Modify I/O Address request type. On PCI Host Adapters, the Modify I/O Address command allows modification of the ISA compatible I/O Address that the Host Adapter responds to; it does not affect the PCI compliant I/O Address assigned at system initialization. */ #define BusLogic_ModifyIO_330 0x00 #define BusLogic_ModifyIO_334 0x01 #define BusLogic_ModifyIO_230 0x02 #define BusLogic_ModifyIO_234 0x03 #define BusLogic_ModifyIO_130 0x04 #define BusLogic_ModifyIO_134 0x05 #define BusLogic_ModifyIO_Disable 0x06 #define BusLogic_ModifyIO_Disable2 0x07 typedef unsigned char BusLogic_ModifyIOAddressRequest_T; /* Define the Set CCB Format request type. 64 LUN Format CCBs are necessary to support 64 Logical Units per Target Device. 8 LUN Format CCBs only support 8 Logical Units per Target Device. */ #define BusLogic_8LUNFormatCCB 0x00 #define BusLogic_64LUNFormatCCB 0x01 typedef unsigned char BusLogic_SetCCBFormatRequest_T; /* Define the Requested Reply Length type used by the Inquire Setup Information, Inquire Controller Model Number, Inquire Synchronous Period, and Inquire Extended Setup Information commands. */ typedef unsigned char BusLogic_RequestedReplyLength_T; /* Define a Lock data structure. Until a true symmetric multiprocessing kernel with fine grained locking is available, acquiring the lock is implemented as saving the processor flags and disabling interrupts, and releasing the lock restores the saved processor flags. */ typedef unsigned long BusLogic_Lock_T; /* Define the Outgoing Mailbox Action Codes. */ typedef enum { BusLogic_OutgoingMailboxFree = 0, BusLogic_MailboxStartCommand = 1, BusLogic_MailboxAbortCommand = 2 } BusLogic_ActionCode_T; /* Define the Incoming Mailbox Completion Codes. */ typedef enum { BusLogic_IncomingMailboxFree = 0, BusLogic_CommandCompletedWithoutError = 1, BusLogic_CommandAbortedAtHostRequest = 2, BusLogic_AbortedCommandNotFound = 3, BusLogic_CommandCompletedWithError = 4 } 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 = 0x00, BusLogic_DataInLengthChecked = 0x01, BusLogic_DataOutLengthChecked = 0x02, BusLogic_NoDataTransfer = 0x03 } BusLogic_DataDirection_T; /* Define the Host Adapter Status Codes. */ typedef enum { BusLogic_CommandCompletedNormally = 0x00, BusLogic_LinkedCommandCompleted = 0x0A, BusLogic_LinkedCommandCompletedWithFlag = 0x0B, BusLogic_SCSISelectionTimeout = 0x11, BusLogic_DataOverUnderRun = 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 = 0x00, BusLogic_HeadOfQueueTag = 0x01, BusLogic_OrderedQueueTag = 0x02, BusLogic_ReservedQT = 0x03 } BusLogic_QueueTag_T; /* Define the SCSI Command Descriptor Block (CDB). */ #define BusLogic_CDB_MaxLength 12 typedef unsigned char SCSI_CDB_T[BusLogic_CDB_MaxLength]; /* Define the Scatter/Gather Segment structure required by the Host Adapter Firmware Interface. */ typedef struct BusLogic_ScatterGatherSegment { unsigned int SegmentByteCount; /* Bytes 0-3 */ bus_address_t SegmentDataPointer; /* Bytes 4-7 */ } BusLogic_ScatterGatherSegment_T; /* Define the 32 Bit Mode Command Control Block (CCB) structure. The first 40 bytes are defined by the Host Adapter Firmware Interface. The remaining components are defined by the Linux BusLogic Driver. 64 LUN Format CCBs differ from standard 8 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; unfortunately, using a union of structs containing enumeration type bitfields to provide both definitions leads to packing problems, so the following definition is used which requires setting TagEnable to Logical Unit bit 5 in 64 LUN Format CCBs. */ typedef struct BusLogic_CCB { /* BusLogic Host Adapter Firmware Portion. */ BusLogic_CCB_Opcode_T Opcode:8; /* Byte 0 */ unsigned char :3; /* Byte 1 Bits 0-2 */ BusLogic_DataDirection_T DataDirection:2; /* Byte 1 Bits 3-4 */ boolean TagEnable64LUN:1; /* Byte 1 Bit 5 */ BusLogic_QueueTag_T QueueTag64LUN:2; /* Byte 1 Bits 6-7 */ unsigned char CDB_Length; /* Byte 2 */ unsigned char SenseDataLength; /* Byte 3 */ unsigned int DataLength; /* Bytes 4-7 */ bus_address_t DataPointer; /* Bytes 8-11 */ unsigned char :8; /* Byte 12 */ unsigned char :8; /* Byte 13 */ BusLogic_HostAdapterStatus_T HostAdapterStatus:8; /* Byte 14 */ BusLogic_TargetDeviceStatus_T TargetDeviceStatus:8; /* Byte 15 */ unsigned char TargetID; /* Byte 16 */ unsigned char LogicalUnit:5; /* Byte 17 Bits 0-4 */ boolean TagEnable:1; /* Byte 17 Bit 5 */ BusLogic_QueueTag_T QueueTag:2; /* Byte 17 Bits 6-7 */ SCSI_CDB_T CDB; /* Bytes 18-29 */ unsigned char :8; /* Byte 30 */ unsigned char :8; /* Byte 31 */ unsigned int :32; /* Bytes 32-35 */ bus_address_t SenseDataPointer; /* Bytes 36-39 */ /* BusLogic Linux Driver Portion. */ struct BusLogic_HostAdapter *HostAdapter; SCSI_Command_T *Command; enum { BusLogic_CCB_Free = 0, BusLogic_CCB_Active = 1, BusLogic_CCB_Completed = 2, BusLogic_CCB_Reset = 3 } Status; BusLogic_CompletionCode_T MailboxCompletionCode; unsigned long SerialNumber; struct BusLogic_CCB *Next; struct BusLogic_CCB *NextAll; BusLogic_ScatterGatherSegment_T ScatterGatherList[BusLogic_ScatterGatherLimit]; } BusLogic_CCB_T; /* Define the 32 Bit Mode Outgoing Mailbox structure. */ typedef struct BusLogic_OutgoingMailbox { bus_address_t CCB; /* Bytes 0-3 */ unsigned int :24; /* Byte 4 */ BusLogic_ActionCode_T ActionCode:8; /* Bytes 5-7 */ } BusLogic_OutgoingMailbox_T; /* Define the 32 Bit Mode Incoming Mailbox structure. */ typedef struct BusLogic_IncomingMailbox { bus_address_t CCB; /* Bytes 0-3 */ BusLogic_HostAdapterStatus_T HostAdapterStatus:8; /* Byte 4 */ BusLogic_TargetDeviceStatus_T TargetDeviceStatus:8; /* Byte 5 */ unsigned char :8; /* Byte 6 */ BusLogic_CompletionCode_T CompletionCode:8; /* Byte 7 */ } BusLogic_IncomingMailbox_T; /* Define the possible Bus Types. */ typedef enum { BusLogic_Unknown_Bus = 0, BusLogic_ISA_Bus = 1, BusLogic_MCA_Bus = 2, BusLogic_EISA_Bus = 3, BusLogic_VESA_Bus = 4, BusLogic_PCI_Bus = 5 } BusLogic_BusType_T; static char *BusLogic_BusNames[] = { "Unknown", "ISA", "MCA", "EISA", "VESA", "PCI" }; /* Define the Linux BusLogic Driver Command Line Entry structure. */ typedef struct BusLogic_CommandLineEntry { unsigned int IO_Address; unsigned short TaggedQueueDepth; unsigned short BusSettleTime; unsigned short LocalOptions; unsigned short TaggedQueuingPermitted; unsigned short TaggedQueuingPermittedMask; unsigned char ErrorRecoveryStrategy[BusLogic_MaxTargetDevices]; } BusLogic_CommandLineEntry_T; /* Define the Linux BusLogic Driver Host Adapter structure. */ typedef struct BusLogic_HostAdapter { SCSI_Host_T *SCSI_Host; unsigned int IO_Address; unsigned char HostNumber; unsigned char ModelName[9]; unsigned char FirmwareVersion[6]; unsigned char ControllerName[18]; unsigned char InterruptLabel[62]; unsigned char IRQ_Channel; unsigned char DMA_Channel; unsigned char SCSI_ID; BusLogic_BusType_T BusType:3; boolean IRQ_ChannelAcquired:1; boolean DMA_ChannelAcquired:1; boolean SynchronousInitiation:1; boolean ParityChecking:1; boolean ExtendedTranslation:1; boolean LevelSensitiveInterrupts:1; boolean HostWideSCSI:1; boolean HostDifferentialSCSI:1; boolean HostAutomaticConfiguration:1; boolean HostUltraSCSI:1; boolean TerminationInfoValid:1; boolean LowByteTerminated:1; boolean HighByteTerminated:1; boolean BounceBuffersRequired:1; boolean StrictRoundRobinModeSupport:1; boolean Host64LUNSupport:1; boolean HostAdapterResetRequested:1; volatile boolean HostAdapterCommandCompleted:1; unsigned short HostAdapterScatterGatherLimit; unsigned short DriverScatterGatherLimit; unsigned short MaxTargetDevices; unsigned short MaxLogicalUnits; unsigned short MailboxCount; unsigned short InitialCCBs; unsigned short IncrementalCCBs; unsigned short TotalQueueDepth; unsigned short TaggedQueueDepth; unsigned short UntaggedQueueDepth; unsigned short BusSettleTime; unsigned short LocalOptions; unsigned short DisconnectPermitted; unsigned short TaggedQueuingPermitted; bus_address_t BIOS_Address; BusLogic_InstalledDevices_T InstalledDevices; BusLogic_SynchronousValues_T SynchronousValues; BusLogic_SynchronousPeriod_T SynchronousPeriod; BusLogic_CommandLineEntry_T *CommandLineEntry; struct BusLogic_HostAdapter *Next; BusLogic_CCB_T *All_CCBs; BusLogic_CCB_T *Free_CCBs; BusLogic_CCB_T *BusDeviceResetPendingCCB[BusLogic_MaxTargetDevices]; unsigned char ErrorRecoveryStrategy[BusLogic_MaxTargetDevices]; unsigned char TaggedQueuingActive[BusLogic_MaxTargetDevices]; unsigned char CommandSuccessfulFlag[BusLogic_MaxTargetDevices]; unsigned char ActiveCommandCount[BusLogic_MaxTargetDevices]; unsigned long TotalCommandCount[BusLogic_MaxTargetDevices]; unsigned long LastSequencePoint[BusLogic_MaxTargetDevices]; unsigned long LastResetTime[BusLogic_MaxTargetDevices]; 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_HostAdapter_T; /* Define a structure for the BIOS Disk Parameters. */ typedef struct BIOS_DiskParameters { int Heads; int Sectors; int Cylinders; } BIOS_DiskParameters_T; /* BusLogic_AcquireHostAdapterLock acquires exclusive access to Host Adapter. */ static inline void BusLogic_AcquireHostAdapterLock(BusLogic_HostAdapter_T *HostAdapter, BusLogic_Lock_T *Lock) { save_flags(*Lock); cli(); } /* BusLogic_ReleaseHostAdapterLock releases exclusive access to Host Adapter. */ static inline void BusLogic_ReleaseHostAdapterLock(BusLogic_HostAdapter_T *HostAdapter, BusLogic_Lock_T *Lock) { restore_flags(*Lock); } /* BusLogic_AcquireHostAdapterLockID acquires exclusive access to Host Adapter, but is only called when interrupts are disabled. */ static inline void BusLogic_AcquireHostAdapterLockID(BusLogic_HostAdapter_T *HostAdapter, BusLogic_Lock_T *Lock) { } /* BusLogic_ReleaseHostAdapterLockID releases exclusive access to Host Adapter, but is only called when interrupts are disabled. */ static inline void BusLogic_ReleaseHostAdapterLockID(BusLogic_HostAdapter_T *HostAdapter, BusLogic_Lock_T *Lock) { } /* Define functions to provide an abstraction for reading and writing the Host Adapter I/O Registers. */ static inline void BusLogic_WriteControlRegister(BusLogic_HostAdapter_T *HostAdapter, unsigned char Value) { outb(Value, HostAdapter->IO_Address + BusLogic_ControlRegister); } static inline unsigned char BusLogic_ReadStatusRegister(BusLogic_HostAdapter_T *HostAdapter) { return inb(HostAdapter->IO_Address + BusLogic_StatusRegister); } static inline void BusLogic_WriteCommandParameterRegister(BusLogic_HostAdapter_T *HostAdapter, unsigned char Value) { outb(Value, HostAdapter->IO_Address + BusLogic_CommandParameterRegister); } static inline unsigned char BusLogic_ReadDataInRegister(BusLogic_HostAdapter_T *HostAdapter) { return inb(HostAdapter->IO_Address + BusLogic_DataInRegister); } static inline unsigned char BusLogic_ReadInterruptRegister(BusLogic_HostAdapter_T *HostAdapter) { return inb(HostAdapter->IO_Address + BusLogic_InterruptRegister); } static inline unsigned char BusLogic_ReadGeometryRegister(BusLogic_HostAdapter_T *HostAdapter) { return inb(HostAdapter->IO_Address + BusLogic_GeometryRegister); } /* BusLogic_StartMailboxCommand issues an Execute Mailbox Command, which notifies the Host Adapter that an entry has been made in an Outgoing Mailbox. */ static inline void BusLogic_StartMailboxCommand(BusLogic_HostAdapter_T *HostAdapter) { BusLogic_WriteCommandParameterRegister(HostAdapter, BusLogic_ExecuteMailboxCommand); } /* BusLogic_Delay waits for Seconds to elapse. */ static inline void BusLogic_Delay(int Seconds) { unsigned long TimeoutJiffies = jiffies + Seconds * HZ; unsigned long ProcessorFlags; save_flags(ProcessorFlags); sti(); while (jiffies < TimeoutJiffies) barrier(); restore_flags(ProcessorFlags); } /* Virtual_to_Bus and Bus_to_Virtual map between Kernel Virtual Addresses and PCI/VLB/EISA/ISA Bus Addresses. */ static inline bus_address_t Virtual_to_Bus(void *VirtualAddress) { return (bus_address_t) VirtualAddress; } static inline void *Bus_to_Virtual(bus_address_t BusAddress) { return (void *) BusAddress; } /* Define prototypes for the forward referenced BusLogic Driver Internal Functions. */ static void BusLogic_InterruptHandler(int, Registers_T *); static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *, SCSI_Command_T *, unsigned int); #endif /* BusLogic_DriverVersion */