BusLogic.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:180k
- /*
- Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
- Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
- 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.
- 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, Jin-Lon Hon, 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.
- Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
- Manager available as freely redistributable source code.
- */
- #define BusLogic_DriverVersion "2.1.15"
- #define BusLogic_DriverDate "17 August 1998"
- #include <linux/version.h>
- #include <linux/module.h>
- #include <linux/config.h>
- #include <linux/init.h>
- #include <linux/types.h>
- #include <linux/blk.h>
- #include <linux/blkdev.h>
- #include <linux/delay.h>
- #include <linux/ioport.h>
- #include <linux/mm.h>
- #include <linux/sched.h>
- #include <linux/stat.h>
- #include <linux/pci.h>
- #include <linux/spinlock.h>
- #include <asm/dma.h>
- #include <asm/io.h>
- #include <asm/system.h>
- #include "scsi.h"
- #include "hosts.h"
- #include "sd.h"
- #include "BusLogic.h"
- #include "FlashPoint.c"
- /*
- BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
- Options specifications provided via the Linux Kernel Command Line or via
- the Loadable Kernel Module Installation Facility.
- */
- static int
- BusLogic_DriverOptionsCount;
- /*
- BusLogic_DriverOptions is an array of Driver Options structures representing
- BusLogic Driver Options specifications provided via the Linux Kernel Command
- Line or via the Loadable Kernel Module Installation Facility.
- */
- static BusLogic_DriverOptions_T
- BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
- /*
- BusLogic can be assigned a string by insmod.
- */
- #ifdef MODULE
- static char *BusLogic;
- MODULE_PARM(BusLogic, "s");
- #endif
- /*
- BusLogic_ProbeOptions is a set of Probe Options to be applied across
- all BusLogic Host Adapters.
- */
- static BusLogic_ProbeOptions_T
- BusLogic_ProbeOptions;
- /*
- BusLogic_GlobalOptions is a set of Global Options to be applied across
- all BusLogic Host Adapters.
- */
- static BusLogic_GlobalOptions_T
- BusLogic_GlobalOptions;
- /*
- BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
- are pointers to the first and last registered BusLogic Host Adapters.
- */
- static BusLogic_HostAdapter_T
- *BusLogic_FirstRegisteredHostAdapter,
- *BusLogic_LastRegisteredHostAdapter;
- /*
- BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
- */
- static int
- BusLogic_ProbeInfoCount;
- /*
- BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
- to be checked for potential BusLogic Host Adapters. It is initialized by
- interrogating the PCI Configuration Space on PCI machines as well as from the
- list of standard BusLogic I/O Addresses.
- */
- static BusLogic_ProbeInfo_T
- *BusLogic_ProbeInfoList;
- /*
- BusLogic_CommandFailureReason holds a string identifying the reason why a
- call to BusLogic_Command failed. It is only non-NULL when BusLogic_Command
- returns a failure code.
- */
- static char
- *BusLogic_CommandFailureReason;
- /*
- BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
- Name, Copyright Notice, and Electronic Mail Address.
- */
- static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *HostAdapter)
- {
- BusLogic_Announce("***** BusLogic SCSI Driver Version "
- BusLogic_DriverVersion " of "
- BusLogic_DriverDate " *****n", HostAdapter);
- BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
- "<lnz@dandelion.com>n", HostAdapter);
- }
- /*
- BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
- Driver and Host Adapter.
- */
- const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
- {
- BusLogic_HostAdapter_T *HostAdapter =
- (BusLogic_HostAdapter_T *) Host->hostdata;
- return HostAdapter->FullModelName;
- }
- /*
- BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
- BusLogic Host Adapters.
- */
- static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
- {
- HostAdapter->Next = NULL;
- if (BusLogic_FirstRegisteredHostAdapter == NULL)
- {
- BusLogic_FirstRegisteredHostAdapter = HostAdapter;
- BusLogic_LastRegisteredHostAdapter = HostAdapter;
- }
- else
- {
- BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
- BusLogic_LastRegisteredHostAdapter = HostAdapter;
- }
- }
- /*
- BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
- registered BusLogic Host Adapters.
- */
- static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
- {
- if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
- {
- BusLogic_FirstRegisteredHostAdapter =
- BusLogic_FirstRegisteredHostAdapter->Next;
- if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
- BusLogic_LastRegisteredHostAdapter = NULL;
- }
- else
- {
- BusLogic_HostAdapter_T *PreviousHostAdapter =
- BusLogic_FirstRegisteredHostAdapter;
- while (PreviousHostAdapter != NULL &&
- PreviousHostAdapter->Next != HostAdapter)
- PreviousHostAdapter = PreviousHostAdapter->Next;
- if (PreviousHostAdapter != NULL)
- PreviousHostAdapter->Next = HostAdapter->Next;
- }
- HostAdapter->Next = NULL;
- }
- /*
- BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
- for Host Adapter from the BlockSize bytes located at BlockPointer. The newly
- created CCBs are added to Host Adapter's free list.
- */
- static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter,
- void *BlockPointer, int BlockSize)
- {
- BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) BlockPointer;
- memset(BlockPointer, 0, BlockSize);
- CCB->AllocationGroupHead = true;
- while ((BlockSize -= sizeof(BusLogic_CCB_T)) >= 0)
- {
- CCB->Status = BusLogic_CCB_Free;
- CCB->HostAdapter = HostAdapter;
- if (BusLogic_FlashPointHostAdapterP(HostAdapter))
- {
- CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
- CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
- }
- CCB->Next = HostAdapter->Free_CCBs;
- CCB->NextAll = HostAdapter->All_CCBs;
- HostAdapter->Free_CCBs = CCB;
- HostAdapter->All_CCBs = CCB;
- HostAdapter->AllocatedCCBs++;
- CCB++;
- }
- }
- /*
- BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
- */
- static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
- {
- int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
- while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
- {
- void *BlockPointer = kmalloc(BlockSize,
- (HostAdapter->BounceBuffersRequired
- ? GFP_ATOMIC | GFP_DMA
- : GFP_ATOMIC));
- if (BlockPointer == NULL)
- {
- BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHINGn",
- HostAdapter);
- return false;
- }
- BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
- }
- return true;
- }
- /*
- BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
- */
- static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
- {
- BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
- HostAdapter->All_CCBs = NULL;
- HostAdapter->Free_CCBs = NULL;
- while ((CCB = NextCCB) != NULL)
- {
- NextCCB = CCB->NextAll;
- if (CCB->AllocationGroupHead)
- kfree(CCB);
- }
- }
- /*
- BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter. If
- allocation fails and there are no remaining CCBs available, the Driver Queue
- Depth is decreased to a known safe value to avoid potential deadlocks when
- multiple host adapters share the same IRQ Channel.
- */
- static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
- int AdditionalCCBs,
- boolean SuccessMessageP)
- {
- int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
- int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
- if (AdditionalCCBs <= 0) return;
- while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs)
- {
- void *BlockPointer = kmalloc(BlockSize,
- (HostAdapter->BounceBuffersRequired
- ? GFP_ATOMIC | GFP_DMA
- : GFP_ATOMIC));
- if (BlockPointer == NULL) break;
- BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
- }
- if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
- {
- if (SuccessMessageP)
- BusLogic_Notice("Allocated %d additional CCBs (total now %d)n",
- HostAdapter,
- HostAdapter->AllocatedCCBs - PreviouslyAllocated,
- HostAdapter->AllocatedCCBs);
- return;
- }
- BusLogic_Notice("Failed to allocate additional CCBsn", HostAdapter);
- if (HostAdapter->DriverQueueDepth >
- HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
- {
- HostAdapter->DriverQueueDepth =
- HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
- HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
- }
- }
- /*
- BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
- allocating more memory from the Kernel if necessary. The Host Adapter's
- Lock should already have been acquired by the caller.
- */
- static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T
- *HostAdapter)
- {
- static unsigned long SerialNumber = 0;
- BusLogic_CCB_T *CCB;
- CCB = HostAdapter->Free_CCBs;
- if (CCB != NULL)
- {
- CCB->SerialNumber = ++SerialNumber;
- HostAdapter->Free_CCBs = CCB->Next;
- CCB->Next = NULL;
- if (HostAdapter->Free_CCBs == NULL)
- BusLogic_CreateAdditionalCCBs(HostAdapter,
- HostAdapter->IncrementalCCBs,
- true);
- return CCB;
- }
- BusLogic_CreateAdditionalCCBs(HostAdapter,
- HostAdapter->IncrementalCCBs,
- true);
- CCB = HostAdapter->Free_CCBs;
- if (CCB == NULL) return NULL;
- CCB->SerialNumber = ++SerialNumber;
- HostAdapter->Free_CCBs = CCB->Next;
- CCB->Next = NULL;
- return CCB;
- }
- /*
- BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
- free list. The Host Adapter's Lock should already have been acquired by the
- caller.
- */
- static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
- {
- BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
- CCB->Command = NULL;
- CCB->Status = BusLogic_CCB_Free;
- CCB->Next = HostAdapter->Free_CCBs;
- HostAdapter->Free_CCBs = CCB;
- }
- /*
- BusLogic_Command sends the command OperationCode to HostAdapter, optionally
- providing ParameterLength bytes of ParameterData and receiving at most
- ReplyLength bytes of ReplyData; any excess reply data is received but
- discarded.
- On success, this function returns the number of reply bytes read from
- the Host Adapter (including any discarded data); on failure, it returns
- -1 if the command was invalid, or -2 if a timeout occurred.
- BusLogic_Command is called exclusively during host adapter detection and
- initialization, so performance and latency are not critical, and exclusive
- access to the Host Adapter hardware is assumed. Once the host adapter and
- driver are initialized, the only Host Adapter command that is issued is the
- single byte Execute Mailbox Command operation code, which does not require
- waiting for the Host Adapter Ready bit to be set in the Status Register.
- */
- static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
- BusLogic_OperationCode_T OperationCode,
- void *ParameterData,
- int ParameterLength,
- void *ReplyData,
- int ReplyLength)
- {
- unsigned char *ParameterPointer = (unsigned char *) ParameterData;
- unsigned char *ReplyPointer = (unsigned char *) ReplyData;
- BusLogic_StatusRegister_T StatusRegister;
- BusLogic_InterruptRegister_T InterruptRegister;
- ProcessorFlags_T ProcessorFlags = 0;
- int ReplyBytes = 0, Result;
- long TimeoutCounter;
- /*
- Clear out the Reply Data if provided.
- */
- if (ReplyLength > 0)
- memset(ReplyData, 0, ReplyLength);
- /*
- If the IRQ Channel has not yet been acquired, then interrupts must be
- disabled while issuing host adapter commands since a Command Complete
- interrupt could occur if the IRQ Channel was previously enabled by another
- BusLogic Host Adapter or another driver sharing the same IRQ Channel.
- */
- if (!HostAdapter->IRQ_ChannelAcquired)
- {
- save_flags(ProcessorFlags);
- cli();
- }
- /*
- Wait for the Host Adapter Ready bit to be set and the Command/Parameter
- Register Busy bit to be reset in the Status Register.
- */
- TimeoutCounter = 10000;
- while (--TimeoutCounter >= 0)
- {
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (StatusRegister.Bits.HostAdapterReady &&
- !StatusRegister.Bits.CommandParameterRegisterBusy)
- break;
- udelay(100);
- }
- if (TimeoutCounter < 0)
- {
- BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
- Result = -2;
- goto Done;
- }
- /*
- Write the OperationCode to the Command/Parameter Register.
- */
- HostAdapter->HostAdapterCommandCompleted = false;
- BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
- /*
- Write any additional Parameter Bytes.
- */
- TimeoutCounter = 10000;
- while (ParameterLength > 0 && --TimeoutCounter >= 0)
- {
- /*
- Wait 100 microseconds to give the Host Adapter enough time to determine
- whether the last value written to the Command/Parameter Register was
- valid or not. If the Command Complete bit is set in the Interrupt
- Register, then the Command Invalid bit in the Status Register will be
- reset if the Operation Code or Parameter was valid and the command
- has completed, or set if the Operation Code or Parameter was invalid.
- If the Data In Register Ready bit is set in the Status Register, then
- the Operation Code was valid, and data is waiting to be read back
- from the Host Adapter. Otherwise, wait for the Command/Parameter
- Register Busy bit in the Status Register to be reset.
- */
- udelay(100);
- InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (InterruptRegister.Bits.CommandComplete) break;
- if (HostAdapter->HostAdapterCommandCompleted) break;
- if (StatusRegister.Bits.DataInRegisterReady) break;
- if (StatusRegister.Bits.CommandParameterRegisterBusy) continue;
- BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
- ParameterLength--;
- }
- if (TimeoutCounter < 0)
- {
- BusLogic_CommandFailureReason =
- "Timeout waiting for Parameter Acceptance";
- Result = -2;
- goto Done;
- }
- /*
- The Modify I/O Address command does not cause a Command Complete Interrupt.
- */
- if (OperationCode == BusLogic_ModifyIOAddress)
- {
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (StatusRegister.Bits.CommandInvalid)
- {
- BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
- Result = -1;
- goto Done;
- }
- if (BusLogic_GlobalOptions.TraceConfiguration)
- BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
- "(Modify I/O Address)n", HostAdapter,
- OperationCode, StatusRegister.All);
- Result = 0;
- goto Done;
- }
- /*
- Select an appropriate timeout value for awaiting command completion.
- */
- switch (OperationCode)
- {
- case BusLogic_InquireInstalledDevicesID0to7:
- case BusLogic_InquireInstalledDevicesID8to15:
- case BusLogic_InquireTargetDevices:
- /* Approximately 60 seconds. */
- TimeoutCounter = 60*10000;
- break;
- default:
- /* Approximately 1 second. */
- TimeoutCounter = 10000;
- break;
- }
- /*
- Receive any Reply Bytes, waiting for either the Command Complete bit to
- be set in the Interrupt Register, or for the Interrupt Handler to set the
- Host Adapter Command Completed bit in the Host Adapter structure.
- */
- while (--TimeoutCounter >= 0)
- {
- InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (InterruptRegister.Bits.CommandComplete) break;
- if (HostAdapter->HostAdapterCommandCompleted) break;
- if (StatusRegister.Bits.DataInRegisterReady)
- {
- if (++ReplyBytes <= ReplyLength)
- *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
- else BusLogic_ReadDataInRegister(HostAdapter);
- }
- if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
- StatusRegister.Bits.HostAdapterReady) break;
- udelay(100);
- }
- if (TimeoutCounter < 0)
- {
- BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
- Result = -2;
- goto Done;
- }
- /*
- Clear any pending Command Complete Interrupt.
- */
- BusLogic_InterruptReset(HostAdapter);
- /*
- Provide tracing information if requested.
- */
- if (BusLogic_GlobalOptions.TraceConfiguration)
- {
- int i;
- BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
- HostAdapter, OperationCode,
- StatusRegister.All, ReplyLength, ReplyBytes);
- if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
- for (i = 0; i < ReplyLength; i++)
- BusLogic_Notice(" %02X", HostAdapter,
- ((unsigned char *) ReplyData)[i]);
- BusLogic_Notice("n", HostAdapter);
- }
- /*
- Process Command Invalid conditions.
- */
- if (StatusRegister.Bits.CommandInvalid)
- {
- /*
- Some early BusLogic Host Adapters may not recover properly from
- a Command Invalid condition, so if this appears to be the case,
- a Soft Reset is issued to the Host Adapter. Potentially invalid
- commands are never attempted after Mailbox Initialization is
- performed, so there should be no Host Adapter state lost by a
- Soft Reset in response to a Command Invalid condition.
- */
- udelay(1000);
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (StatusRegister.Bits.CommandInvalid ||
- StatusRegister.Bits.Reserved ||
- StatusRegister.Bits.DataInRegisterReady ||
- StatusRegister.Bits.CommandParameterRegisterBusy ||
- !StatusRegister.Bits.HostAdapterReady ||
- !StatusRegister.Bits.InitializationRequired ||
- StatusRegister.Bits.DiagnosticActive ||
- StatusRegister.Bits.DiagnosticFailure)
- {
- BusLogic_SoftReset(HostAdapter);
- udelay(1000);
- }
- BusLogic_CommandFailureReason = "Command Invalid";
- Result = -1;
- goto Done;
- }
- /*
- Handle Excess Parameters Supplied conditions.
- */
- if (ParameterLength > 0)
- {
- BusLogic_CommandFailureReason = "Excess Parameters Supplied";
- Result = -1;
- goto Done;
- }
- /*
- Indicate the command completed successfully.
- */
- BusLogic_CommandFailureReason = NULL;
- Result = ReplyBytes;
- /*
- Restore the interrupt status if necessary and return.
- */
- Done:
- if (!HostAdapter->IRQ_ChannelAcquired)
- restore_flags(ProcessorFlags);
- return Result;
- }
- /*
- BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
- of I/O Address and Bus Probe Information to be checked for potential BusLogic
- Host Adapters.
- */
- static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)
- {
- BusLogic_ProbeInfo_T *ProbeInfo;
- if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;
- ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
- ProbeInfo->IO_Address = IO_Address;
- }
- /*
- BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
- Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
- only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
- */
- static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
- *PrototypeHostAdapter)
- {
- /*
- If BusLogic Driver Options specifications requested that ISA Bus Probes
- be inhibited, do not proceed further.
- */
- if (BusLogic_ProbeOptions.NoProbeISA) return;
- /*
- Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
- */
- if (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe330
- : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
- BusLogic_AppendProbeAddressISA(0x330);
- if (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe334
- : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
- BusLogic_AppendProbeAddressISA(0x334);
- if (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe230
- : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
- BusLogic_AppendProbeAddressISA(0x230);
- if (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe234
- : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
- BusLogic_AppendProbeAddressISA(0x234);
- if (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe130
- : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
- BusLogic_AppendProbeAddressISA(0x130);
- if (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe134
- : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
- BusLogic_AppendProbeAddressISA(0x134);
- }
- #ifdef CONFIG_PCI
- /*
- BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
- of increasing PCI Bus and Device Number.
- */
- static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,
- int ProbeInfoCount)
- {
- int LastInterchange = ProbeInfoCount-1, Bound, j;
- while (LastInterchange > 0)
- {
- Bound = LastInterchange;
- LastInterchange = 0;
- for (j = 0; j < Bound; j++)
- {
- BusLogic_ProbeInfo_T *ProbeInfo1 = &ProbeInfoList[j];
- BusLogic_ProbeInfo_T *ProbeInfo2 = &ProbeInfoList[j+1];
- if (ProbeInfo1->Bus > ProbeInfo2->Bus ||
- (ProbeInfo1->Bus == ProbeInfo2->Bus &&
- (ProbeInfo1->Device > ProbeInfo2->Device)))
- {
- BusLogic_ProbeInfo_T TempProbeInfo;
- memcpy(&TempProbeInfo, ProbeInfo1, sizeof(BusLogic_ProbeInfo_T));
- memcpy(ProbeInfo1, ProbeInfo2, sizeof(BusLogic_ProbeInfo_T));
- memcpy(ProbeInfo2, &TempProbeInfo, sizeof(BusLogic_ProbeInfo_T));
- LastInterchange = j;
- }
- }
- }
- }
- /*
- BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
- and Bus Probe Information to be checked for potential BusLogic MultiMaster
- SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
- machines as well as from the list of standard BusLogic MultiMaster ISA
- I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
- */
- static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
- *PrototypeHostAdapter)
- {
- BusLogic_ProbeInfo_T *PrimaryProbeInfo =
- &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
- int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
- int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
- boolean ForceBusDeviceScanningOrder = false;
- boolean ForceBusDeviceScanningOrderChecked = false;
- boolean StandardAddressSeen[6];
- PCI_Device_T *PCI_Device = NULL;
- int i;
- if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
- BusLogic_ProbeInfoCount++;
- for (i = 0; i < 6; i++)
- StandardAddressSeen[i] = false;
- /*
- Iterate over the MultiMaster PCI Host Adapters. For each enumerated host
- adapter, determine whether its ISA Compatible I/O Port is enabled and if
- so, whether it is assigned the Primary I/O Address. A host adapter that is
- assigned the Primary I/O Address will always be the preferred boot device.
- The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
- Address, then any other PCI host adapters, and finally any host adapters
- located at the remaining standard ISA I/O Addresses. When a PCI host
- adapter is found with its ISA Compatible I/O Port enabled, a command is
- issued to disable the ISA Compatible I/O Port, and it is noted that the
- particular standard ISA I/O Address need not be probed.
- */
- PrimaryProbeInfo->IO_Address = 0;
- while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
- PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
- PCI_Device)) != NULL)
- {
- BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
- BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
- BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
- unsigned char Bus = PCI_Device->bus->number;
- unsigned char Device = PCI_Device->devfn >> 3;
- unsigned int IRQ_Channel;
- unsigned long BaseAddress0;
- unsigned long BaseAddress1;
- BusLogic_IO_Address_T IO_Address;
- BusLogic_PCI_Address_T PCI_Address;
- if (pci_enable_device(PCI_Device))
- continue;
-
- IRQ_Channel = PCI_Device->irq;
- IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
- PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
- if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
- {
- BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
- "MultiMaster Host Adaptern", NULL, BaseAddress0);
- BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%Xn",
- NULL, Bus, Device, IO_Address);
- continue;
- }
- if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO)
- {
- BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
- "MultiMaster Host Adaptern", NULL, BaseAddress1);
- BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%Xn",
- NULL, Bus, Device, PCI_Address);
- continue;
- }
- if (IRQ_Channel == 0)
- {
- BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
- "MultiMaster Host Adaptern", NULL, IRQ_Channel);
- BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%Xn",
- NULL, Bus, Device, IO_Address);
- continue;
- }
- if (BusLogic_GlobalOptions.TraceProbe)
- {
- BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
- "detected atn", NULL);
- BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
- "0x%X PCI Address 0x%Xn", NULL,
- Bus, Device, IO_Address, PCI_Address);
- }
- /*
- Issue the Inquire PCI Host Adapter Information command to determine
- the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
- known and enabled, note that the particular Standard ISA I/O
- Address should not be probed.
- */
- HostAdapter->IO_Address = IO_Address;
- BusLogic_InterruptReset(HostAdapter);
- if (BusLogic_Command(HostAdapter,
- BusLogic_InquirePCIHostAdapterInformation,
- NULL, 0, &PCIHostAdapterInformation,
- sizeof(PCIHostAdapterInformation))
- == sizeof(PCIHostAdapterInformation))
- {
- if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
- StandardAddressSeen[PCIHostAdapterInformation
- .ISACompatibleIOPort] = true;
- }
- else PCIHostAdapterInformation.ISACompatibleIOPort =
- BusLogic_IO_Disable;
- /*
- Issue the Modify I/O Address command to disable the ISA Compatible
- I/O Port.
- */
- ModifyIOAddressRequest = BusLogic_IO_Disable;
- BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
- &ModifyIOAddressRequest,
- sizeof(ModifyIOAddressRequest), NULL, 0);
- /*
- For the first MultiMaster Host Adapter enumerated, issue the Fetch
- Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
- for the setting of the "Use Bus And Device # For PCI Scanning Seq."
- option. Issue the Inquire Board ID command since this option is
- only valid for the BT-948/958/958D.
- */
- if (!ForceBusDeviceScanningOrderChecked)
- {
- BusLogic_FetchHostAdapterLocalRAMRequest_T
- FetchHostAdapterLocalRAMRequest;
- BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
- BusLogic_BoardID_T BoardID;
- FetchHostAdapterLocalRAMRequest.ByteOffset =
- BusLogic_AutoSCSI_BaseOffset + 45;
- FetchHostAdapterLocalRAMRequest.ByteCount =
- sizeof(AutoSCSIByte45);
- BusLogic_Command(HostAdapter,
- BusLogic_FetchHostAdapterLocalRAM,
- &FetchHostAdapterLocalRAMRequest,
- sizeof(FetchHostAdapterLocalRAMRequest),
- &AutoSCSIByte45, sizeof(AutoSCSIByte45));
- BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
- NULL, 0, &BoardID, sizeof(BoardID));
- if (BoardID.FirmwareVersion1stDigit == '5')
- ForceBusDeviceScanningOrder =
- AutoSCSIByte45.ForceBusDeviceScanningOrder;
- ForceBusDeviceScanningOrderChecked = true;
- }
- /*
- Determine whether this MultiMaster Host Adapter has its ISA
- Compatible I/O Port enabled and is assigned the Primary I/O Address.
- If it does, then it is the Primary MultiMaster Host Adapter and must
- be recognized first. If it does not, then it is added to the list
- for probing after any Primary MultiMaster Host Adapter is probed.
- */
- if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
- {
- PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
- PrimaryProbeInfo->IO_Address = IO_Address;
- PrimaryProbeInfo->PCI_Address = PCI_Address;
- PrimaryProbeInfo->Bus = Bus;
- PrimaryProbeInfo->Device = Device;
- PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
- PCIMultiMasterCount++;
- }
- else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
- {
- BusLogic_ProbeInfo_T *ProbeInfo =
- &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
- ProbeInfo->IO_Address = IO_Address;
- ProbeInfo->PCI_Address = PCI_Address;
- ProbeInfo->Bus = Bus;
- ProbeInfo->Device = Device;
- ProbeInfo->IRQ_Channel = IRQ_Channel;
- NonPrimaryPCIMultiMasterCount++;
- PCIMultiMasterCount++;
- }
- else BusLogic_Warning("BusLogic: Too many Host Adapters "
- "detectedn", NULL);
- }
- /*
- If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
- for the first enumerated MultiMaster Host Adapter, and if that host adapter
- is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
- Host Adapters in the order of increasing PCI Bus and Device Number. In
- that case, sort the probe information into the same order the BIOS uses.
- If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
- Host Adapters in the order they are enumerated by the PCI BIOS, and hence
- no sorting is necessary.
- */
- if (ForceBusDeviceScanningOrder)
- BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
- NonPrimaryPCIMultiMasterIndex],
- NonPrimaryPCIMultiMasterCount);
- /*
- If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
- then the Primary I/O Address must be probed explicitly before any PCI
- host adapters are probed.
- */
- if (!BusLogic_ProbeOptions.NoProbeISA)
- if (PrimaryProbeInfo->IO_Address == 0 &&
- (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe330
- : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
- {
- PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
- PrimaryProbeInfo->IO_Address = 0x330;
- }
- /*
- Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
- omitting the Primary I/O Address which has already been handled.
- */
- if (!BusLogic_ProbeOptions.NoProbeISA)
- {
- if (!StandardAddressSeen[1] &&
- (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe334
- : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
- BusLogic_AppendProbeAddressISA(0x334);
- if (!StandardAddressSeen[2] &&
- (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe230
- : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
- BusLogic_AppendProbeAddressISA(0x230);
- if (!StandardAddressSeen[3] &&
- (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe234
- : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
- BusLogic_AppendProbeAddressISA(0x234);
- if (!StandardAddressSeen[4] &&
- (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe130
- : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
- BusLogic_AppendProbeAddressISA(0x130);
- if (!StandardAddressSeen[5] &&
- (BusLogic_ProbeOptions.LimitedProbeISA
- ? BusLogic_ProbeOptions.Probe134
- : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
- BusLogic_AppendProbeAddressISA(0x134);
- }
- /*
- Iterate over the older non-compliant MultiMaster PCI Host Adapters,
- noting the PCI bus location and assigned IRQ Channel.
- */
- PCI_Device = NULL;
- while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
- PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
- PCI_Device)) != NULL)
- {
- unsigned char Bus = PCI_Device->bus->number;
- unsigned char Device = PCI_Device->devfn >> 3;
- unsigned int IRQ_Channel = PCI_Device->irq;
- BusLogic_IO_Address_T IO_Address = pci_resource_start(PCI_Device, 0);
- if (pci_enable_device(PCI_Device))
- continue;
- if (IO_Address == 0 || IRQ_Channel == 0) continue;
- for (i = 0; i < BusLogic_ProbeInfoCount; i++)
- {
- BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[i];
- if (ProbeInfo->IO_Address == IO_Address &&
- ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
- {
- ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
- ProbeInfo->PCI_Address = 0;
- ProbeInfo->Bus = Bus;
- ProbeInfo->Device = Device;
- ProbeInfo->IRQ_Channel = IRQ_Channel;
- break;
- }
- }
- }
- return PCIMultiMasterCount;
- }
- /*
- BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
- and Bus Probe Information to be checked for potential BusLogic FlashPoint
- Host Adapters by interrogating the PCI Configuration Space. It returns the
- number of FlashPoint Host Adapters found.
- */
- static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
- *PrototypeHostAdapter)
- {
- int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
- PCI_Device_T *PCI_Device = NULL;
- /*
- Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
- */
- while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
- PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
- PCI_Device)) != NULL)
- {
- unsigned char Bus = PCI_Device->bus->number;
- unsigned char Device = PCI_Device->devfn >> 3;
- unsigned int IRQ_Channel = PCI_Device->irq;
- unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
- unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
- BusLogic_IO_Address_T IO_Address = BaseAddress0;
- BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
- if (pci_enable_device(PCI_Device))
- continue;
- #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
- if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
- {
- BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
- "FlashPoint Host Adaptern", NULL, BaseAddress0);
- BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%Xn",
- NULL, Bus, Device, IO_Address);
- continue;
- }
- if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO)
- {
- BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
- "FlashPoint Host Adaptern", NULL, BaseAddress1);
- BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%Xn",
- NULL, Bus, Device, PCI_Address);
- continue;
- }
- if (IRQ_Channel == 0)
- {
- BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
- "FlashPoint Host Adaptern", NULL, IRQ_Channel);
- BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%Xn",
- NULL, Bus, Device, IO_Address);
- continue;
- }
- if (BusLogic_GlobalOptions.TraceProbe)
- {
- BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
- "detected atn", NULL);
- BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
- "0x%X PCI Address 0x%Xn", NULL,
- Bus, Device, IO_Address, PCI_Address);
- }
- if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
- {
- BusLogic_ProbeInfo_T *ProbeInfo =
- &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
- ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
- ProbeInfo->IO_Address = IO_Address;
- ProbeInfo->PCI_Address = PCI_Address;
- ProbeInfo->Bus = Bus;
- ProbeInfo->Device = Device;
- ProbeInfo->IRQ_Channel = IRQ_Channel;
- FlashPointCount++;
- }
- else BusLogic_Warning("BusLogic: Too many Host Adapters "
- "detectedn", NULL);
- #else
- BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
- "PCI Bus %d Device %dn", NULL, Bus, Device);
- BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, "
- "but FlashPointn", NULL, IO_Address, PCI_Address, IRQ_Channel);
- BusLogic_Error("BusLogic: support was omitted in this kernel "
- "configuration.n", NULL);
- #endif
- }
- /*
- The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
- increasing PCI Bus and Device Number, so sort the probe information into
- the same order the BIOS uses.
- */
- BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
- FlashPointCount);
- return FlashPointCount;
- }
- /*
- BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
- Probe Information to be checked for potential BusLogic SCSI Host Adapters by
- interrogating the PCI Configuration Space on PCI machines as well as from the
- list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
- FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
- probe for FlashPoint Host Adapters first unless the BIOS primary disk is
- controlled by the first PCI MultiMaster Host Adapter, in which case
- MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
- specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
- a particular probe order.
- */
- static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
- *PrototypeHostAdapter)
- {
- /*
- If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
- Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
- */
- if (!BusLogic_ProbeOptions.NoProbePCI && pci_present())
- {
- if (BusLogic_ProbeOptions.MultiMasterFirst)
- {
- BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
- BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
- }
- else if (BusLogic_ProbeOptions.FlashPointFirst)
- {
- BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
- BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
- }
- else
- {
- int FlashPointCount =
- BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
- int PCIMultiMasterCount =
- BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
- if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
- {
- BusLogic_ProbeInfo_T *ProbeInfo =
- &BusLogic_ProbeInfoList[FlashPointCount];
- BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
- BusLogic_FetchHostAdapterLocalRAMRequest_T
- FetchHostAdapterLocalRAMRequest;
- BusLogic_BIOSDriveMapByte_T Drive0MapByte;
- while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
- ProbeInfo++;
- HostAdapter->IO_Address = ProbeInfo->IO_Address;
- FetchHostAdapterLocalRAMRequest.ByteOffset =
- BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
- FetchHostAdapterLocalRAMRequest.ByteCount =
- sizeof(Drive0MapByte);
- BusLogic_Command(HostAdapter,
- BusLogic_FetchHostAdapterLocalRAM,
- &FetchHostAdapterLocalRAMRequest,
- sizeof(FetchHostAdapterLocalRAMRequest),
- &Drive0MapByte, sizeof(Drive0MapByte));
- /*
- If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
- is controlled by this PCI MultiMaster Host Adapter, then
- reverse the probe order so that MultiMaster Host Adapters are
- probed before FlashPoint Host Adapters.
- */
- if (Drive0MapByte.DiskGeometry !=
- BusLogic_BIOS_Disk_Not_Installed)
- {
- BusLogic_ProbeInfo_T
- SavedProbeInfo[BusLogic_MaxHostAdapters];
- int MultiMasterCount =
- BusLogic_ProbeInfoCount - FlashPointCount;
- memcpy(SavedProbeInfo,
- BusLogic_ProbeInfoList,
- BusLogic_ProbeInfoCount
- * sizeof(BusLogic_ProbeInfo_T));
- memcpy(&BusLogic_ProbeInfoList[0],
- &SavedProbeInfo[FlashPointCount],
- MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
- memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
- &SavedProbeInfo[0],
- FlashPointCount * sizeof(BusLogic_ProbeInfo_T));
- }
- }
- }
- }
- else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
- }
- #endif /* CONFIG_PCI */
- /*
- BusLogic_Failure prints a standardized error message, and then returns false.
- */
- static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
- char *ErrorMessage)
- {
- BusLogic_AnnounceDriver(HostAdapter);
- if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
- {
- BusLogic_Error("While configuring BusLogic PCI Host Adapter atn",
- HostAdapter);
- BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:n",
- HostAdapter, HostAdapter->Bus, HostAdapter->Device,
- HostAdapter->IO_Address, HostAdapter->PCI_Address);
- }
- else BusLogic_Error("While configuring BusLogic Host Adapter at "
- "I/O Address 0x%X:n", HostAdapter,
- HostAdapter->IO_Address);
- BusLogic_Error("%s FAILED - DETACHINGn", HostAdapter, ErrorMessage);
- if (BusLogic_CommandFailureReason != NULL)
- BusLogic_Error("ADDITIONAL FAILURE INFO - %sn", HostAdapter,
- BusLogic_CommandFailureReason);
- return false;
- }
- /*
- BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
- */
- static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
- {
- BusLogic_StatusRegister_T StatusRegister;
- BusLogic_InterruptRegister_T InterruptRegister;
- BusLogic_GeometryRegister_T GeometryRegister;
- /*
- FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter))
- {
- FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
- FlashPointInfo->BaseAddress =
- (BusLogic_Base_Address_T) HostAdapter->IO_Address;
- FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
- FlashPointInfo->Present = false;
- if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
- FlashPointInfo->Present))
- {
- BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
- "PCI Bus %d Device %dn", HostAdapter,
- HostAdapter->Bus, HostAdapter->Device);
- BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
- "but FlashPointn", HostAdapter,
- HostAdapter->IO_Address, HostAdapter->PCI_Address);
- BusLogic_Error("BusLogic: Probe Function failed to validate it.n",
- HostAdapter);
- return false;
- }
- if (BusLogic_GlobalOptions.TraceProbe)
- BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Foundn",
- HostAdapter, HostAdapter->IO_Address);
- /*
- Indicate the Host Adapter Probe completed successfully.
- */
- return true;
- }
- /*
- Read the Status, Interrupt, and Geometry Registers to test if there are I/O
- ports that respond, and to check the values to determine if they are from a
- BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
- case there is definitely no BusLogic Host Adapter at this base I/O Address.
- The test here is a subset of that used by the BusLogic Host Adapter BIOS.
- */
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
- GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
- if (BusLogic_GlobalOptions.TraceProbe)
- BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
- "Geometry 0x%02Xn", HostAdapter,
- HostAdapter->IO_Address, StatusRegister.All,
- InterruptRegister.All, GeometryRegister.All);
- if (StatusRegister.All == 0 ||
- StatusRegister.Bits.DiagnosticActive ||
- StatusRegister.Bits.CommandParameterRegisterBusy ||
- StatusRegister.Bits.Reserved ||
- StatusRegister.Bits.CommandInvalid ||
- InterruptRegister.Bits.Reserved != 0)
- return false;
- /*
- Check the undocumented Geometry Register to test if there is an I/O port
- that responded. Adaptec Host Adapters do not implement the Geometry
- Register, so this test helps serve to avoid incorrectly recognizing an
- Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
- series does respond to the Geometry Register I/O port, but it will be
- rejected later when the Inquire Extended Setup Information command is
- issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
- BusLogic clone that implements the same interface as earlier BusLogic
- Host Adapters, including the undocumented commands, and is therefore
- supported by this driver. However, the AMI FastDisk always returns 0x00
- upon reading the Geometry Register, so the extended translation option
- should always be left disabled on the AMI FastDisk.
- */
- if (GeometryRegister.All == 0xFF) return false;
- /*
- Indicate the Host Adapter Probe completed successfully.
- */
- return true;
- }
- /*
- BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
- and waits for Host Adapter Diagnostics to complete. If HardReset is true, a
- Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
- Soft Reset is performed which only resets the Host Adapter without forcing a
- SCSI Bus Reset.
- */
- static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
- *HostAdapter,
- boolean HardReset)
- {
- BusLogic_StatusRegister_T StatusRegister;
- int TimeoutCounter;
- /*
- FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter))
- {
- FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
- FlashPointInfo->HostSoftReset = !HardReset;
- FlashPointInfo->ReportDataUnderrun = true;
- HostAdapter->CardHandle =
- FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
- if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
- /*
- Indicate the Host Adapter Hard Reset completed successfully.
- */
- return true;
- }
- /*
- Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host
- Adapter should respond by setting Diagnostic Active in the Status Register.
- */
- if (HardReset)
- BusLogic_HardReset(HostAdapter);
- else BusLogic_SoftReset(HostAdapter);
- /*
- Wait until Diagnostic Active is set in the Status Register.
- */
- TimeoutCounter = 5*10000;
- while (--TimeoutCounter >= 0)
- {
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (StatusRegister.Bits.DiagnosticActive) break;
- udelay(100);
- }
- if (BusLogic_GlobalOptions.TraceHardwareReset)
- BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
- "Status 0x%02Xn", HostAdapter,
- HostAdapter->IO_Address, StatusRegister.All);
- if (TimeoutCounter < 0) return false;
- /*
- Wait 100 microseconds to allow completion of any initial diagnostic
- activity which might leave the contents of the Status Register
- unpredictable.
- */
- udelay(100);
- /*
- Wait until Diagnostic Active is reset in the Status Register.
- */
- TimeoutCounter = 10*10000;
- while (--TimeoutCounter >= 0)
- {
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (!StatusRegister.Bits.DiagnosticActive) break;
- udelay(100);
- }
- if (BusLogic_GlobalOptions.TraceHardwareReset)
- BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
- "Status 0x%02Xn", HostAdapter,
- HostAdapter->IO_Address, StatusRegister.All);
- if (TimeoutCounter < 0) return false;
- /*
- Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
- or Data In Register Ready bits is set in the Status Register.
- */
- TimeoutCounter = 10000;
- while (--TimeoutCounter >= 0)
- {
- StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
- if (StatusRegister.Bits.DiagnosticFailure ||
- StatusRegister.Bits.HostAdapterReady ||
- StatusRegister.Bits.DataInRegisterReady)
- break;
- udelay(100);
- }
- if (BusLogic_GlobalOptions.TraceHardwareReset)
- BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
- "Status 0x%02Xn", HostAdapter,
- HostAdapter->IO_Address, StatusRegister.All);
- if (TimeoutCounter < 0) return false;
- /*
- If Diagnostic Failure is set or Host Adapter Ready is reset, then an
- error occurred during the Host Adapter diagnostics. If Data In Register
- Ready is set, then there is an Error Code available.
- */
- if (StatusRegister.Bits.DiagnosticFailure ||
- !StatusRegister.Bits.HostAdapterReady)
- {
- BusLogic_CommandFailureReason = NULL;
- BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
- BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02Xn",
- HostAdapter, StatusRegister.All);
- if (StatusRegister.Bits.DataInRegisterReady)
- {
- unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
- BusLogic_Error("HOST ADAPTER ERROR CODE = %dn",
- HostAdapter, ErrorCode);
- }
- return false;
- }
- /*
- Indicate the Host Adapter Hard Reset completed successfully.
- */
- return true;
- }
- /*
- BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
- Host Adapter.
- */
- static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
- {
- BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
- BusLogic_RequestedReplyLength_T RequestedReplyLength;
- boolean Result = true;
- /*
- FlashPoint Host Adapters do not require this protection.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
- /*
- Issue the Inquire Extended Setup Information command. Only genuine
- BusLogic Host Adapters and true clones support this command. Adaptec 1542C
- series Host Adapters that respond to the Geometry Register I/O port will
- fail this command.
- */
- RequestedReplyLength = sizeof(ExtendedSetupInformation);
- if (BusLogic_Command(HostAdapter,
- BusLogic_InquireExtendedSetupInformation,
- &RequestedReplyLength,
- sizeof(RequestedReplyLength),
- &ExtendedSetupInformation,
- sizeof(ExtendedSetupInformation))
- != sizeof(ExtendedSetupInformation))
- Result = false;
- /*
- Provide tracing information if requested and return.
- */
- if (BusLogic_GlobalOptions.TraceProbe)
- BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %sn", HostAdapter,
- HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
- return Result;
- }
- /*
- BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
- from Host Adapter and initializes the Host Adapter structure.
- */
- static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
- *HostAdapter)
- {
- BusLogic_BoardID_T BoardID;
- BusLogic_Configuration_T Configuration;
- BusLogic_SetupInformation_T SetupInformation;
- BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
- BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
- BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
- BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
- BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
- BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
- BusLogic_AutoSCSIData_T AutoSCSIData;
- BusLogic_GeometryRegister_T GeometryRegister;
- BusLogic_RequestedReplyLength_T RequestedReplyLength;
- unsigned char *TargetPointer, Character;
- int TargetID, i;
- /*
- Configuration Information for FlashPoint Host Adapters is provided in the
- FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
- Initialize fields in the Host Adapter structure from the FlashPoint_Info
- structure.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter))
- {
- FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
- TargetPointer = HostAdapter->ModelName;
- *TargetPointer++ = 'B';
- *TargetPointer++ = 'T';
- *TargetPointer++ = '-';
- for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
- *TargetPointer++ = FlashPointInfo->ModelNumber[i];
- *TargetPointer++ = ' ';
- strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
- HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
- HostAdapter->ExtendedTranslationEnabled =
- FlashPointInfo->ExtendedTranslationEnabled;
- HostAdapter->ParityCheckingEnabled =
- FlashPointInfo->ParityCheckingEnabled;
- HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
- HostAdapter->LevelSensitiveInterrupt = true;
- HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
- HostAdapter->HostDifferentialSCSI = false;
- HostAdapter->HostSupportsSCAM = true;
- HostAdapter->HostUltraSCSI = true;
- HostAdapter->ExtendedLUNSupport = true;
- HostAdapter->TerminationInfoValid = true;
- HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
- HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
- HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
- HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
- HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
- HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
- HostAdapter->MaxLogicalUnits = 32;
- HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
- HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
- HostAdapter->DriverQueueDepth = 255;
- HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
- HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
- HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
- HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
- HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
- HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
- HostAdapter->TaggedQueuingPermitted = 0xFFFF;
- goto Common;
- }
- /*
- Issue the Inquire Board ID command.
- */
- if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
- &BoardID, sizeof(BoardID)) != sizeof(BoardID))
- return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
- /*
- Issue the Inquire Configuration command.
- */
- if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
- &Configuration, sizeof(Configuration))
- != sizeof(Configuration))
- return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
- /*
- Issue the Inquire Setup Information command.
- */
- RequestedReplyLength = sizeof(SetupInformation);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &SetupInformation, sizeof(SetupInformation))
- != sizeof(SetupInformation))
- return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
- /*
- Issue the Inquire Extended Setup Information command.
- */
- RequestedReplyLength = sizeof(ExtendedSetupInformation);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &ExtendedSetupInformation,
- sizeof(ExtendedSetupInformation))
- != sizeof(ExtendedSetupInformation))
- return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
- /*
- Issue the Inquire Firmware Version 3rd Digit command.
- */
- FirmwareVersion3rdDigit = ' ';
- if (BoardID.FirmwareVersion1stDigit > '0')
- if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
- NULL, 0, &FirmwareVersion3rdDigit,
- sizeof(FirmwareVersion3rdDigit))
- != sizeof(FirmwareVersion3rdDigit))
- return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
- /*
- Issue the Inquire Host Adapter Model Number command.
- */
- if (ExtendedSetupInformation.BusType == 'A' &&
- BoardID.FirmwareVersion1stDigit == '2')
- /* BusLogic BT-542B ISA 2.xx */
- strcpy(HostAdapterModelNumber, "542B");
- else if (ExtendedSetupInformation.BusType == 'E' &&
- BoardID.FirmwareVersion1stDigit == '2' &&
- (BoardID.FirmwareVersion2ndDigit <= '1' ||
- (BoardID.FirmwareVersion2ndDigit == '2' &&
- FirmwareVersion3rdDigit == '0')))
- /* BusLogic BT-742A EISA 2.1x or 2.20 */
- strcpy(HostAdapterModelNumber, "742A");
- else if (ExtendedSetupInformation.BusType == 'E' &&
- BoardID.FirmwareVersion1stDigit == '0')
- /* AMI FastDisk EISA Series 441 0.x */
- strcpy(HostAdapterModelNumber, "747A");
- else
- {
- RequestedReplyLength = sizeof(HostAdapterModelNumber);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &HostAdapterModelNumber,
- sizeof(HostAdapterModelNumber))
- != sizeof(HostAdapterModelNumber))
- return BusLogic_Failure(HostAdapter,
- "INQUIRE HOST ADAPTER MODEL NUMBER");
- }
- /*
- BusLogic MultiMaster Host Adapters can be identified by their model number
- and the major version number of their firmware as follows:
- 5.xx BusLogic "W" Series Host Adapters:
- BT-948/958/958D
- 4.xx BusLogic "C" Series Host Adapters:
- BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
- 3.xx BusLogic "S" Series Host Adapters:
- BT-747S/747D/757S/757D/445S/545S/542D
- BT-542B/742A (revision H)
- 2.xx BusLogic "A" Series Host Adapters:
- BT-542B/742A (revision G and below)
- 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
- */
- /*
- Save the Model Name and Host Adapter Name in the Host Adapter structure.
- */
- TargetPointer = HostAdapter->ModelName;
- *TargetPointer++ = 'B';
- *TargetPointer++ = 'T';
- *TargetPointer++ = '-';
- for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
- {
- Character = HostAdapterModelNumber[i];
- if (Character == ' ' || Character == ' ') break;
- *TargetPointer++ = Character;
- }
- *TargetPointer++ = ' ';
- /*
- Save the Firmware Version in the Host Adapter structure.
- */
- TargetPointer = HostAdapter->FirmwareVersion;
- *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
- *TargetPointer++ = '.';
- *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
- if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != ' ')
- *TargetPointer++ = FirmwareVersion3rdDigit;
- *TargetPointer = ' ';
- /*
- Issue the Inquire Firmware Version Letter command.
- */
- if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
- {
- if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
- NULL, 0, &FirmwareVersionLetter,
- sizeof(FirmwareVersionLetter))
- != sizeof(FirmwareVersionLetter))
- return BusLogic_Failure(HostAdapter,
- "INQUIRE FIRMWARE VERSION LETTER");
- if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != ' ')
- *TargetPointer++ = FirmwareVersionLetter;
- *TargetPointer = ' ';
- }
- /*
- Save the Host Adapter SCSI ID in the Host Adapter structure.
- */
- HostAdapter->SCSI_ID = Configuration.HostAdapterID;
- /*
- Determine the Bus Type and save it in the Host Adapter structure, determine
- and save the IRQ Channel if necessary, and determine and save the DMA
- Channel for ISA Host Adapters.
- */
- HostAdapter->HostAdapterBusType =
- BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
- if (HostAdapter->IRQ_Channel == 0)
- {
- if (Configuration.IRQ_Channel9)
- HostAdapter->IRQ_Channel = 9;
- else if (Configuration.IRQ_Channel10)
- HostAdapter->IRQ_Channel = 10;
- else if (Configuration.IRQ_Channel11)
- HostAdapter->IRQ_Channel = 11;
- else if (Configuration.IRQ_Channel12)
- HostAdapter->IRQ_Channel = 12;
- else if (Configuration.IRQ_Channel14)
- HostAdapter->IRQ_Channel = 14;
- else if (Configuration.IRQ_Channel15)
- HostAdapter->IRQ_Channel = 15;
- }
- if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
- {
- if (Configuration.DMA_Channel5)
- HostAdapter->DMA_Channel = 5;
- else if (Configuration.DMA_Channel6)
- HostAdapter->DMA_Channel = 6;
- else if (Configuration.DMA_Channel7)
- HostAdapter->DMA_Channel = 7;
- }
- /*
- Determine whether Extended Translation is enabled and save it in
- the Host Adapter structure.
- */
- GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
- HostAdapter->ExtendedTranslationEnabled =
- GeometryRegister.Bits.ExtendedTranslationEnabled;
- /*
- Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
- SCSI flag, Differential SCSI flag, SCAM Supported flag, and
- Ultra SCSI flag in the Host Adapter structure.
- */
- HostAdapter->HostAdapterScatterGatherLimit =
- ExtendedSetupInformation.ScatterGatherLimit;
- HostAdapter->DriverScatterGatherLimit =
- HostAdapter->HostAdapterScatterGatherLimit;
- if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
- HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
- if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
- HostAdapter->LevelSensitiveInterrupt = true;
- HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
- HostAdapter->HostDifferentialSCSI =
- ExtendedSetupInformation.HostDifferentialSCSI;
- HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
- HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
- /*
- Determine whether Extended LUN Format CCBs are supported and save the
- information in the Host Adapter structure.
- */
- if (HostAdapter->FirmwareVersion[0] == '5' ||
- (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
- HostAdapter->ExtendedLUNSupport = true;
- /*
- Issue the Inquire PCI Host Adapter Information command to read the
- Termination Information from "W" series MultiMaster Host Adapters.
- */
- if (HostAdapter->FirmwareVersion[0] == '5')
- {
- if (BusLogic_Command(HostAdapter,
- BusLogic_InquirePCIHostAdapterInformation,
- NULL, 0, &PCIHostAdapterInformation,
- sizeof(PCIHostAdapterInformation))
- != sizeof(PCIHostAdapterInformation))
- return BusLogic_Failure(HostAdapter,
- "INQUIRE PCI HOST ADAPTER INFORMATION");
- /*
- Save the Termination Information in the Host Adapter structure.
- */
- if (PCIHostAdapterInformation.GenericInfoValid)
- {
- HostAdapter->TerminationInfoValid = true;
- HostAdapter->LowByteTerminated =
- PCIHostAdapterInformation.LowByteTerminated;
- HostAdapter->HighByteTerminated =
- PCIHostAdapterInformation.HighByteTerminated;
- }
- }
- /*
- Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
- from "W" and "C" series MultiMaster Host Adapters.
- */
- if (HostAdapter->FirmwareVersion[0] >= '4')
- {
- FetchHostAdapterLocalRAMRequest.ByteOffset =
- BusLogic_AutoSCSI_BaseOffset;
- FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
- if (BusLogic_Command(HostAdapter,
- BusLogic_FetchHostAdapterLocalRAM,
- &FetchHostAdapterLocalRAMRequest,
- sizeof(FetchHostAdapterLocalRAMRequest),
- &AutoSCSIData, sizeof(AutoSCSIData))
- != sizeof(AutoSCSIData))
- return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
- /*
- Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
- Information in the Host Adapter structure.
- */
- HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
- HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
- if (HostAdapter->FirmwareVersion[0] == '4')
- {
- HostAdapter->TerminationInfoValid = true;
- HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
- HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
- }
- /*
- Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
- Disconnect Permitted, Ultra Permitted, and SCAM Information in the
- Host Adapter structure.
- */
- HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
- HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
- HostAdapter->SynchronousPermitted =
- AutoSCSIData.SynchronousPermitted;
- HostAdapter->DisconnectPermitted =
- AutoSCSIData.DisconnectPermitted;
- if (HostAdapter->HostUltraSCSI)
- HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
- if (HostAdapter->HostSupportsSCAM)
- {
- HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
- HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
- }
- }
- /*
- Initialize fields in the Host Adapter structure for "S" and "A" series
- MultiMaster Host Adapters.
- */
- if (HostAdapter->FirmwareVersion[0] < '4')
- {
- if (SetupInformation.SynchronousInitiationEnabled)
- {
- HostAdapter->SynchronousPermitted = 0xFF;
- if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
- {
- if (ExtendedSetupInformation.Misc.FastOnEISA)
- HostAdapter->FastPermitted = 0xFF;
- if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
- HostAdapter->WidePermitted = 0xFF;
- }
- }
- HostAdapter->DisconnectPermitted = 0xFF;
- HostAdapter->ParityCheckingEnabled =
- SetupInformation.ParityCheckingEnabled;
- HostAdapter->BusResetEnabled = true;
- }
- /*
- Determine the maximum number of Target IDs and Logical Units supported by
- this driver for Wide and Narrow Host Adapters.
- */
- HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
- HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
- /*
- Select appropriate values for the Mailbox Count, Driver Queue Depth,
- Initial CCBs, and Incremental CCBs variables based on whether or not Strict
- Round Robin Mode is supported. If Strict Round Robin Mode is supported,
- then there is no performance degradation in using the maximum possible
- number of Outgoing and Incoming Mailboxes and allowing the Tagged and
- Untagged Queue Depths to determine the actual utilization. If Strict Round
- Robin Mode is not supported, then the Host Adapter must scan all the
- Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
- cause a substantial performance penalty. The host adapters actually have
- room to store the following number of CCBs internally; that is, they can
- internally queue and manage this many active commands on the SCSI bus
- simultaneously. Performance measurements demonstrate that the Driver Queue
- Depth should be set to the Mailbox Count, rather than the Host Adapter
- Queue Depth (internal CCB capacity), as it is more efficient to have the
- queued commands waiting in Outgoing Mailboxes if necessary than to block
- the process in the higher levels of the SCSI Subsystem.
- 192 BT-948/958/958D
- 100 BT-946C/956C/956CD/747C/757C/757CD/445C
- 50 BT-545C/540CF
- 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
- */
- if (HostAdapter->FirmwareVersion[0] == '5')
- HostAdapter->HostAdapterQueueDepth = 192;
- else if (HostAdapter->FirmwareVersion[0] == '4')
- HostAdapter->HostAdapterQueueDepth =
- (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
- else HostAdapter->HostAdapterQueueDepth = 30;
- if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
- {
- HostAdapter->StrictRoundRobinModeSupport = true;
- HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
- }
- else
- {
- HostAdapter->StrictRoundRobinModeSupport = false;
- HostAdapter->MailboxCount = 32;
- }
- HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
- HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
- HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
- /*
- Tagged Queuing support is available and operates properly on all "W" series
- MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
- firmware version 4.22 and above, and on "S" series MultiMaster Host
- Adapters with firmware version 3.35 and above.
- */
- HostAdapter->TaggedQueuingPermitted = 0;
- switch (HostAdapter->FirmwareVersion[0])
- {
- case '5':
- HostAdapter->TaggedQueuingPermitted = 0xFFFF;
- break;
- case '4':
- if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
- HostAdapter->TaggedQueuingPermitted = 0xFFFF;
- break;
- case '3':
- if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
- HostAdapter->TaggedQueuingPermitted = 0xFFFF;
- break;
- }
- /*
- Determine the Host Adapter BIOS Address if the BIOS is enabled and
- save it in the Host Adapter structure. The BIOS is disabled if the
- BIOS_Address is 0.
- */
- HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
- /*
- ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
- */
- if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
- (void *) high_memory > (void *) MAX_DMA_ADDRESS)
- HostAdapter->BounceBuffersRequired = true;
- /*
- BusLogic BT-445S Host Adapters prior to board revision E have a hardware
- bug whereby when the BIOS is enabled, transfers to/from the same address
- range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
- functioning BT-445S Host Adapters have firmware version 3.37, so require
- that ISA Bounce Buffers be used for the buggy BT-445S models if there is
- more than 16MB memory.
- */
- if (HostAdapter->BIOS_Address > 0 &&
- strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
- strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
- (void *) high_memory > (void *) MAX_DMA_ADDRESS)
- HostAdapter->BounceBuffersRequired = true;
- /*
- Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
- */
- Common:
- /*
- Initialize the Host Adapter Full Model Name from the Model Name.
- */
- strcpy(HostAdapter->FullModelName, "BusLogic ");
- strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
- /*
- Select an appropriate value for the Tagged Queue Depth either from a
- BusLogic Driver Options specification, or based on whether this Host
- Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth
- is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
- Initialize the Untagged Queue Depth.
- */
- for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
- {
- unsigned char QueueDepth = 0;
- if (HostAdapter->DriverOptions != NULL &&
- HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
- QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
- else if (HostAdapter->BounceBuffersRequired)
- QueueDepth = BusLogic_TaggedQueueDepthBB;
- HostAdapter->QueueDepth[TargetID] = QueueDepth;
- }
- if (HostAdapter->BounceBuffersRequired)
- HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
- else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
- if (HostAdapter->DriverOptions != NULL)
- HostAdapter->CommonQueueDepth =
- HostAdapter->DriverOptions->CommonQueueDepth;
- if (HostAdapter->CommonQueueDepth > 0 &&
- HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
- HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
- /*
- Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
- Therefore, mask the Tagged Queuing Permitted Default bits with the
- Disconnect/Reconnect Permitted bits.
- */
- HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
- /*
- Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
- Options Tagged Queuing specification.
- */
- if (HostAdapter->DriverOptions != NULL)
- HostAdapter->TaggedQueuingPermitted =
- (HostAdapter->DriverOptions->TaggedQueuingPermitted &
- HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
- (HostAdapter->TaggedQueuingPermitted &
- ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
- /*
- Select appropriate values for the Error Recovery Strategy array
- either from a BusLogic Driver Options specification, or using
- BusLogic_ErrorRecovery_Default.
- */
- for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
- if (HostAdapter->DriverOptions != NULL)
- HostAdapter->ErrorRecoveryStrategy[TargetID] =
- HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID];
- else HostAdapter->ErrorRecoveryStrategy[TargetID] =
- BusLogic_ErrorRecovery_Default;
- /*
- Select an appropriate value for Bus Settle Time either from a BusLogic
- Driver Options specification, or from BusLogic_DefaultBusSettleTime.
- */
- if (HostAdapter->DriverOptions != NULL &&
- HostAdapter->DriverOptions->BusSettleTime > 0)
- HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
- else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
- /*
- Indicate reading the Host Adapter Configuration completed successfully.
- */
- return true;
- }
- /*
- BusLogic_ReportHostAdapterConfiguration reports the configuration of
- Host Adapter.
- */
- static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T
- *HostAdapter)
- {
- unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
- unsigned short SynchronousPermitted, FastPermitted;
- unsigned short UltraPermitted, WidePermitted;
- unsigned short DisconnectPermitted, TaggedQueuingPermitted;
- boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
- boolean CommonErrorRecovery;
- char SynchronousString[BusLogic_MaxTargetDevices+1];
- char WideString[BusLogic_MaxTargetDevices+1];
- char DisconnectString[BusLogic_MaxTargetDevices+1];
- char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
- char ErrorRecoveryString[BusLogic_MaxTargetDevices+1];
- char *SynchronousMessage = SynchronousString;
- char *WideMessage = WideString;
- char *DisconnectMessage = DisconnectString;
- char *TaggedQueuingMessage = TaggedQueuingString;
- char *ErrorRecoveryMessage = ErrorRecoveryString;
- int TargetID;
- BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adaptern",
- HostAdapter, HostAdapter->ModelName,
- BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
- (HostAdapter->HostWideSCSI ? " Wide" : ""),
- (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
- (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
- BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, "
- "IRQ Channel: %d/%sn", HostAdapter,
- HostAdapter->FirmwareVersion,
- HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
- (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
- if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
- {
- BusLogic_Info(" DMA Channel: ", HostAdapter);
- if (HostAdapter->DMA_Channel > 0)
- BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
- else BusLogic_Info("None, ", HostAdapter);
- if (HostAdapter->BIOS_Address > 0)
- BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
- HostAdapter->BIOS_Address);
- else BusLogic_Info("BIOS Address: None, ", HostAdapter);
- }
- else
- {
- BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ",
- HostAdapter, HostAdapter->Bus, HostAdapter->Device);
- if (HostAdapter->PCI_Address > 0)
- BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
- else BusLogic_Info("Unassigned, ", HostAdapter);
- }
- BusLogic_Info("Host Adapter SCSI ID: %dn", HostAdapter,
- HostAdapter->SCSI_ID);
- BusLogic_Info(" Parity Checking: %s, Extended Translation: %sn",
- HostAdapter,
- (HostAdapter->ParityCheckingEnabled
- ? "Enabled" : "Disabled"),
- (HostAdapter->ExtendedTranslationEnabled
- ? "Enabled" : "Disabled"));
- AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
- SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
- FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
- UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
- if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
- (HostAdapter->FirmwareVersion[0] >= '4' ||
- HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
- BusLogic_FlashPointHostAdapterP(HostAdapter))
- {
- CommonSynchronousNegotiation = false;
- if (SynchronousPermitted == 0)
- {
- SynchronousMessage = "Disabled";
- CommonSynchronousNegotiation = true;
- }
- else if (SynchronousPermitted == AllTargetsMask)
- {
- if (FastPermitted == 0)
- {
- SynchronousMessage = "Slow";
- CommonSynchronousNegotiation = true;
- }
- else if (FastPermitted == AllTargetsMask)
- {
- if (UltraPermitted == 0)
- {
- SynchronousMessage = "Fast";
- CommonSynchronousNegotiation = true;
- }
- else if (UltraPermitted == AllTargetsMask)
- {
- SynchronousMessage = "Ultra";
- CommonSynchronousNegotiation = true;
- }
- }
- }
- if (!CommonSynchronousNegotiation)
- {
- for (TargetID = 0;
- TargetID < HostAdapter->MaxTargetDevices;
- TargetID++)
- SynchronousString[TargetID] =
- ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
- (!(FastPermitted & (1 << TargetID)) ? 'S' :
- (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
- SynchronousString[HostAdapter->SCSI_ID] = '#';
- SynchronousString[HostAdapter->MaxTargetDevices] = ' ';
- }
- }
- else SynchronousMessage =
- (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
- WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
- if (WidePermitted == 0)
- WideMessage = "Disabled";
- else if (WidePermitted == AllTargetsMask)
- WideMessage = "Enabled";
- else
- {
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- WideString[TargetID] =
- ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
- WideString[HostAdapter->SCSI_ID] = '#';
- WideString[HostAdapter->MaxTargetDevices] = ' ';
- }
- DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
- if (DisconnectPermitted == 0)
- DisconnectMessage = "Disabled";
- else if (DisconnectPermitted == AllTargetsMask)
- DisconnectMessage = "Enabled";
- else
- {
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- DisconnectString[TargetID] =
- ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
- DisconnectString[HostAdapter->SCSI_ID] = '#';
- DisconnectString[HostAdapter->MaxTargetDevices] = ' ';
- }
- TaggedQueuingPermitted =
- HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
- if (TaggedQueuingPermitted == 0)
- TaggedQueuingMessage = "Disabled";
- else if (TaggedQueuingPermitted == AllTargetsMask)
- TaggedQueuingMessage = "Enabled";
- else
- {
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- TaggedQueuingString[TargetID] =
- ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
- TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
- TaggedQueuingString[HostAdapter->MaxTargetDevices] = ' ';
- }
- BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %sn",
- HostAdapter, SynchronousMessage, WideMessage);
- BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %sn",
- HostAdapter, DisconnectMessage, TaggedQueuingMessage);
- if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
- {
- BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, "
- "Mailboxes: %dn", HostAdapter,
- HostAdapter->DriverScatterGatherLimit,
- HostAdapter->HostAdapterScatterGatherLimit,
- HostAdapter->MailboxCount);
- BusLogic_Info(" Driver Queue Depth: %d, "
- "Host Adapter Queue Depth: %dn",
- HostAdapter, HostAdapter->DriverQueueDepth,
- HostAdapter->HostAdapterQueueDepth);
- }
- else BusLogic_Info(" Driver Queue Depth: %d, "
- "Scatter/Gather Limit: %d segmentsn",
- HostAdapter, HostAdapter->DriverQueueDepth,
- HostAdapter->DriverScatterGatherLimit);
- BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
- CommonTaggedQueueDepth = true;
- for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
- {
- CommonTaggedQueueDepth = false;
- break;
- }
- if (CommonTaggedQueueDepth)
- {
- if (HostAdapter->QueueDepth[0] > 0)
- BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
- else BusLogic_Info("Automatic", HostAdapter);
- }
- else BusLogic_Info("Individual", HostAdapter);
- BusLogic_Info(", Untagged Queue Depth: %dn", HostAdapter,
- HostAdapter->UntaggedQueueDepth);
- CommonErrorRecovery = true;
- for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
- HostAdapter->ErrorRecoveryStrategy[0])
- {
- CommonErrorRecovery = false;
- break;
- }
- if (CommonErrorRecovery)
- ErrorRecoveryMessage =
- BusLogic_ErrorRecoveryStrategyNames[
- HostAdapter->ErrorRecoveryStrategy[0]];
- else
- {
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- ErrorRecoveryString[TargetID] =
- BusLogic_ErrorRecoveryStrategyLetters[
- HostAdapter->ErrorRecoveryStrategy[TargetID]];
- ErrorRecoveryString[HostAdapter->SCSI_ID] = '#';
- ErrorRecoveryString[HostAdapter->MaxTargetDevices] = ' ';
- }
- BusLogic_Info(" Error Recovery Strategy: %s, SCSI Bus Reset: %sn",
- HostAdapter, ErrorRecoveryMessage,
- (HostAdapter->BusResetEnabled ? "Enabled" : "Disabled"));
- if (HostAdapter->TerminationInfoValid)
- {
- if (HostAdapter->HostWideSCSI)
- BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
- (HostAdapter->LowByteTerminated
- ? (HostAdapter->HighByteTerminated
- ? "Both Enabled" : "Low Enabled")
- : (HostAdapter->HighByteTerminated
- ? "High Enabled" : "Both Disabled")));
- else BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
- (HostAdapter->LowByteTerminated ?
- "Enabled" : "Disabled"));
- if (HostAdapter->HostSupportsSCAM)
- BusLogic_Info(", SCAM: %s", HostAdapter,
- (HostAdapter->SCAM_Enabled
- ? (HostAdapter->SCAM_Level2
- ? "Enabled, Level 2" : "Enabled, Level 1")
- : "Disabled"));
- BusLogic_Info("n", HostAdapter);
- }
- /*
- Indicate reporting the Host Adapter configuration completed successfully.
- */
- return true;
- }
- /*
- BusLogic_AcquireResources acquires the system resources necessary to use
- Host Adapter.
- */
- static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
- {
- if (HostAdapter->IRQ_Channel == 0)
- {
- BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHINGn",
- HostAdapter);
- return false;
- }
- /*
- Acquire shared access to the IRQ Channel.
- */
- if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
- SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0)
- {
- BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHINGn",
- HostAdapter, HostAdapter->IRQ_Channel);
- return false;
- }
- HostAdapter->IRQ_ChannelAcquired = true;
- /*
- Acquire exclusive access to the DMA Channel.
- */
- if (HostAdapter->DMA_Channel > 0)
- {
- if (request_dma(HostAdapter->DMA_Channel,
- HostAdapter->FullModelName) < 0)
- {
- BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHINGn",
- HostAdapter, HostAdapter->DMA_Channel);
- return false;
- }
- set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
- enable_dma(HostAdapter->DMA_Channel);
- HostAdapter->DMA_ChannelAcquired = true;
- }
- /*
- Indicate the System Resource Acquisition completed successfully,
- */
- return true;
- }
- /*
- BusLogic_ReleaseResources releases any system resources previously acquired
- by BusLogic_AcquireResources.
- */
- static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
- {
- /*
- Release shared access to the IRQ Channel.
- */
- if (HostAdapter->IRQ_ChannelAcquired)
- free_irq(HostAdapter->IRQ_Channel, HostAdapter);
- /*
- Release exclusive access to the DMA Channel.
- */
- if (HostAdapter->DMA_ChannelAcquired)
- free_dma(HostAdapter->DMA_Channel);
- }
- /*
- BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
- function called during SCSI Host Adapter detection which modifies the state
- of the Host Adapter from its initial power on or hard reset state.
- */
- static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
- *HostAdapter)
- {
- BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
- BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
- BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
- int TargetID;
- /*
- Initialize the pointers to the first and last CCBs that are queued for
- completion processing.
- */
- HostAdapter->FirstCompletedCCB = NULL;
- HostAdapter->LastCompletedCCB = NULL;
- /*
- Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
- Command Successful Flag, Active Commands, and Commands Since Reset
- for each Target Device.
- */
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- {
- HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
- HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
- HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
- HostAdapter->ActiveCommands[TargetID] = 0;
- HostAdapter->CommandsSinceReset[TargetID] = 0;
- }
- /*
- FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
- /*
- Initialize the Outgoing and Incoming Mailbox pointers.
- */
- HostAdapter->FirstOutgoingMailbox =
- (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace;
- HostAdapter->LastOutgoingMailbox =
- HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
- HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
- HostAdapter->FirstIncomingMailbox =
- (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
- HostAdapter->LastIncomingMailbox =
- HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
- HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
- /*
- Initialize the Outgoing and Incoming Mailbox structures.
- */
- memset(HostAdapter->FirstOutgoingMailbox, 0,
- HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
- memset(HostAdapter->FirstIncomingMailbox, 0,
- HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
- /*
- Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
- */
- ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
- ExtendedMailboxRequest.BaseMailboxAddress =
- Virtual_to_Bus(HostAdapter->FirstOutgoingMailbox);
- if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
- &ExtendedMailboxRequest,
- sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
- /*
- Enable Strict Round Robin Mode if supported by the Host Adapter. In
- Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
- Mailbox for each new command, rather than scanning through all the
- Outgoing Mailboxes to find any that have new commands in them. Strict
- Round Robin Mode is significantly more efficient.
- */
- if (HostAdapter->StrictRoundRobinModeSupport)
- {
- RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
- if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
- &RoundRobinModeRequest,
- sizeof(RoundRobinModeRequest), NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
- }
- /*
- For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
- Format command to allow 32 Logical Units per Target Device.
- */
- if (HostAdapter->ExtendedLUNSupport)
- {
- SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
- if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
- &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
- NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
- }
- /*
- Announce Successful Initialization.
- */
- Done:
- if (!HostAdapter->HostAdapterInitialized)
- {
- BusLogic_Info("*** %s Initialized Successfully ***n",
- HostAdapter, HostAdapter->FullModelName);
- BusLogic_Info("n", HostAdapter);
- }
- else BusLogic_Warning("*** %s Initialized Successfully ***n",
- HostAdapter, HostAdapter->FullModelName);
- HostAdapter->HostAdapterInitialized = true;
- /*
- Indicate the Host Adapter Initialization completed successfully.
- */
- return true;
- }
- /*
- BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
- through Host Adapter.
- */
- static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
- *HostAdapter)
- {
- BusLogic_InstalledDevices_T InstalledDevices;
- BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
- BusLogic_SetupInformation_T SetupInformation;
- BusLogic_SynchronousPeriod_T SynchronousPeriod;
- BusLogic_RequestedReplyLength_T RequestedReplyLength;
- int TargetID;
- /*
- Wait a few seconds between the 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.
- */
- BusLogic_Delay(HostAdapter->BusSettleTime);
- /*
- FlashPoint Host Adapters do not provide for Target Device Inquiry.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
- /*
- Inhibit the Target Device Inquiry if requested.
- */
- if (HostAdapter->DriverOptions != NULL &&
- HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
- return true;
- /*
- Issue the Inquire Target Devices command for host adapters with firmware
- version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
- for older host adapters. This is necessary to force Synchronous Transfer
- Negotiation so that the Inquire Setup Information and Inquire Synchronous
- Period commands will return valid data. The Inquire Target Devices command
- is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
- Logical Unit 0 of each Target Device.
- */
- if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
- {
- if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
- &InstalledDevices, sizeof(InstalledDevices))
- != sizeof(InstalledDevices))
- return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- HostAdapter->TargetFlags[TargetID].TargetExists =
- (InstalledDevices & (1 << TargetID) ? true : false);
- }
- else
- {
- if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
- NULL, 0, &InstalledDevicesID0to7,
- sizeof(InstalledDevicesID0to7))
- != sizeof(InstalledDevicesID0to7))
- return BusLogic_Failure(HostAdapter,
- "INQUIRE INSTALLED DEVICES ID 0 TO 7");
- for (TargetID = 0; TargetID < 8; TargetID++)
- HostAdapter->TargetFlags[TargetID].TargetExists =
- (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
- }
- /*
- Issue the Inquire Setup Information command.
- */
- RequestedReplyLength = sizeof(SetupInformation);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &SetupInformation, sizeof(SetupInformation))
- != sizeof(SetupInformation))
- return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- HostAdapter->SynchronousOffset[TargetID] =
- (TargetID < 8
- ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
- : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
- if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- HostAdapter->TargetFlags[TargetID].WideTransfersActive =
- (TargetID < 8
- ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
- ? true : false)
- : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
- ? true : false));
- /*
- Issue the Inquire Synchronous Period command.