patch-2.0.34 linux/drivers/scsi/BusLogic.c
Next file: linux/drivers/scsi/BusLogic.h
Previous file: linux/drivers/pci/pci.c
Back to the patch index
Back to the overall index
- Lines: 4240
- Date:
Wed Jun 3 15:17:48 1998
- Orig file:
v2.0.33/linux/drivers/scsi/BusLogic.c
- Orig date:
Mon Aug 11 00:10:00 1997
diff -u --recursive --new-file v2.0.33/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
@@ -2,12 +2,11 @@
Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
- Copyright 1995 by Leonard N. Zubkoff <lnz@dandelion.com>
+ 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, provided that none of the source code or runtime
- copyright notices are removed or modified.
+ 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
@@ -27,17 +26,17 @@
*/
-#define BusLogic_DriverVersion "2.0.10"
-#define BusLogic_DriverDate "11 August 1997"
+#define BusLogic_DriverVersion "2.0.14"
+#define BusLogic_DriverDate "29 April 1998"
+#include <linux/version.h>
#include <linux/module.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/ioport.h>
-#include <linux/kernel_stat.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/stat.h>
@@ -45,30 +44,43 @@
#include <linux/bios32.h>
#include <asm/dma.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/system.h>
#include "scsi.h"
#include "hosts.h"
#include "sd.h"
#include "BusLogic.h"
+#include "FlashPoint.c"
/*
- BusLogic_CommandLineEntryCount is a count of the number of "BusLogic="
- entries provided on the Linux Kernel Command Line.
+ 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_CommandLineEntryCount = 0;
+ BusLogic_DriverOptionsCount = 0;
/*
- BusLogic_CommandLineEntries is an array of Command Line Entry structures
- representing the "BusLogic=" entries provided on the Linux Kernel Command
- Line.
+ 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_CommandLineEntry_T
- BusLogic_CommandLineEntries[BusLogic_MaxHostAdapters];
+static BusLogic_DriverOptions_T
+ BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
+
+
+/*
+ BusLogic_Options can be assigned a string by the Loadable Kernel Module
+ Installation Facility to be parsed for BusLogic Driver Options
+ specifications.
+*/
+
+static char
+ *BusLogic_Options = NULL;
/*
@@ -77,7 +89,7 @@
*/
static BusLogic_ProbeOptions_T
- BusLogic_ProbeOptions = { 0 };
+ BusLogic_ProbeOptions = { 0 };
/*
@@ -86,24 +98,25 @@
*/
static BusLogic_GlobalOptions_T
- BusLogic_GlobalOptions = { 0 };
+ BusLogic_GlobalOptions = { 0 };
/*
- BusLogic_RegisteredHostAdapters is an array of linked lists of all the
- registered BusLogic Host Adapters, indexed by IRQ Channel.
+ BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
+ are pointers to the first and last registered BusLogic Host Adapters.
*/
static BusLogic_HostAdapter_T
- *BusLogic_RegisteredHostAdapters[NR_IRQS] = { NULL };
+ *BusLogic_FirstRegisteredHostAdapter = NULL,
+ *BusLogic_LastRegisteredHostAdapter = NULL;
/*
- BusLogic_ProbeInfoCount is the numbers of entries in BusLogic_ProbeInfoList.
+ BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
*/
static int
- BusLogic_ProbeInfoCount = 0;
+ BusLogic_ProbeInfoCount = 0;
/*
@@ -114,7 +127,7 @@
*/
static BusLogic_ProbeInfo_T
- BusLogic_ProbeInfoList[BusLogic_MaxHostAdapters] = { { 0 } };
+ *BusLogic_ProbeInfoList = NULL;
/*
@@ -128,16 +141,6 @@
/*
- BusLogic_FirstCompletedCCB and BusLogic_LastCompletedCCB are pointers
- to the first and last CCBs that are queued for completion processing.
-*/
-
-static BusLogic_CCB_T
- *BusLogic_FirstCompletedCCB = NULL,
- *BusLogic_LastCompletedCCB = NULL;
-
-
-/*
BusLogic_ProcDirectoryEntry is the BusLogic /proc/scsi directory entry.
*/
@@ -156,7 +159,7 @@
BusLogic_Announce("***** BusLogic SCSI Driver Version "
BusLogic_DriverVersion " of "
BusLogic_DriverDate " *****\n", HostAdapter);
- BusLogic_Announce("Copyright 1995 by Leonard N. Zubkoff "
+ BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
"<lnz@dandelion.com>\n", HostAdapter);
}
@@ -182,16 +185,16 @@
static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
{
HostAdapter->Next = NULL;
- if (BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel] != NULL)
+ if (BusLogic_FirstRegisteredHostAdapter == NULL)
+ {
+ BusLogic_FirstRegisteredHostAdapter = HostAdapter;
+ BusLogic_LastRegisteredHostAdapter = HostAdapter;
+ }
+ else
{
- BusLogic_HostAdapter_T *LastHostAdapter =
- BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel];
- BusLogic_HostAdapter_T *NextHostAdapter;
- while ((NextHostAdapter = LastHostAdapter->Next) != NULL)
- LastHostAdapter = NextHostAdapter;
- LastHostAdapter->Next = HostAdapter;
+ BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
+ BusLogic_LastRegisteredHostAdapter = HostAdapter;
}
- else BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel] = HostAdapter;
}
@@ -202,101 +205,55 @@
static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
{
- if (BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel] != HostAdapter)
+ if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
{
- BusLogic_HostAdapter_T *LastHostAdapter =
- BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel];
- while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter)
- LastHostAdapter = LastHostAdapter->Next;
- if (LastHostAdapter != NULL)
- LastHostAdapter->Next = HostAdapter->Next;
+ BusLogic_FirstRegisteredHostAdapter =
+ BusLogic_FirstRegisteredHostAdapter->Next;
+ if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
+ BusLogic_LastRegisteredHostAdapter = NULL;
}
- else BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel] =
- HostAdapter->Next;
- HostAdapter->Next = NULL;
-}
-
-
-/*
- BusLogic_CreateMailboxes allocates the Outgoing and Incoming Mailboxes for
- Host Adapter.
-*/
-
-static boolean BusLogic_CreateMailboxes(BusLogic_HostAdapter_T *HostAdapter)
-{
- /*
- FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
- /*
- Allocate space for the Outgoing and Incoming Mailboxes.
- */
- HostAdapter->FirstOutgoingMailbox =
- (BusLogic_OutgoingMailbox_T *)
- scsi_init_malloc(HostAdapter->MailboxCount
- * (sizeof(BusLogic_OutgoingMailbox_T)
- + sizeof(BusLogic_IncomingMailbox_T)),
- (HostAdapter->BounceBuffersRequired
- ? GFP_ATOMIC | GFP_DMA
- : GFP_ATOMIC));
- if (HostAdapter->FirstOutgoingMailbox == NULL)
+ else
{
- BusLogic_Error("UNABLE TO ALLOCATE MAILBOXES - DETACHING\n",
- HostAdapter, HostAdapter->HostNumber);
- return false;
+ BusLogic_HostAdapter_T *PreviousHostAdapter =
+ BusLogic_FirstRegisteredHostAdapter;
+ while (PreviousHostAdapter != NULL &&
+ PreviousHostAdapter->Next != HostAdapter)
+ PreviousHostAdapter = PreviousHostAdapter->Next;
+ if (PreviousHostAdapter != NULL)
+ PreviousHostAdapter->Next = HostAdapter->Next;
}
- HostAdapter->LastOutgoingMailbox =
- HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
- HostAdapter->FirstIncomingMailbox =
- (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
- HostAdapter->LastIncomingMailbox =
- HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
- return true;
-}
-
-
-/*
- BusLogic_DestroyMailboxes deallocates the Outgoing and Incoming Mailboxes
- for Host Adapter.
-*/
-
-static void BusLogic_DestroyMailboxes(BusLogic_HostAdapter_T *HostAdapter)
-{
- if (HostAdapter->FirstOutgoingMailbox == NULL) return;
- scsi_init_free((char *) HostAdapter->FirstOutgoingMailbox,
- HostAdapter->MailboxCount
- * (sizeof(BusLogic_OutgoingMailbox_T)
- + sizeof(BusLogic_IncomingMailbox_T)));
+ HostAdapter->Next = NULL;
}
/*
- BusLogic_CreateCCB allocates and initializes a single Command Control
- Block (CCB) for Host Adapter, and adds it to Host Adapter's free list.
-*/
-
-static boolean BusLogic_CreateCCB(BusLogic_HostAdapter_T *HostAdapter)
-{
- BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
- scsi_init_malloc(sizeof(BusLogic_CCB_T),
- (HostAdapter->BounceBuffersRequired
- ? GFP_ATOMIC | GFP_DMA
- : GFP_ATOMIC));
- if (CCB == NULL) return false;
- memset(CCB, 0, sizeof(BusLogic_CCB_T));
- CCB->HostAdapter = HostAdapter;
- CCB->Status = BusLogic_CCB_Free;
- if (BusLogic_FlashPointHostAdapterP(HostAdapter))
- {
- CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
- CCB->BaseAddress = HostAdapter->IO_Address;
+ 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++;
}
- CCB->Next = HostAdapter->Free_CCBs;
- CCB->NextAll = HostAdapter->All_CCBs;
- HostAdapter->Free_CCBs = CCB;
- HostAdapter->All_CCBs = CCB;
- HostAdapter->AllocatedCCBs++;
- return true;
}
@@ -306,14 +263,21 @@
static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
{
- int Allocated;
- for (Allocated = 0; Allocated < HostAdapter->InitialCCBs; Allocated++)
- if (!BusLogic_CreateCCB(HostAdapter))
- {
- BusLogic_Error("UNABLE TO ALLOCATE CCB %d - DETACHING\n",
- HostAdapter, Allocated);
- return false;
- }
+ 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 - DETACHING\n",
+ HostAdapter);
+ return false;
+ }
+ BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
+ }
return true;
}
@@ -330,7 +294,8 @@
while ((CCB = NextCCB) != NULL)
{
NextCCB = CCB->NextAll;
- scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T));
+ if (CCB->AllocationGroupHead)
+ kfree(CCB);
}
}
@@ -346,18 +311,35 @@
int AdditionalCCBs,
boolean SuccessMessageP)
{
- int Allocated;
+ int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
+ int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
if (AdditionalCCBs <= 0) return;
- for (Allocated = 0; Allocated < AdditionalCCBs; Allocated++)
- if (!BusLogic_CreateCCB(HostAdapter)) break;
- if (Allocated > 0 && SuccessMessageP)
- BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
- HostAdapter, Allocated, HostAdapter->AllocatedCCBs);
- if (Allocated > 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 CCBs\n", HostAdapter);
- HostAdapter->DriverQueueDepth =
- HostAdapter->AllocatedCCBs - (HostAdapter->MaxTargetDevices - 1);
- HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
+ if (HostAdapter->DriverQueueDepth >
+ HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
+ {
+ HostAdapter->DriverQueueDepth =
+ HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
+ HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
+ }
}
@@ -413,47 +395,6 @@
/*
- BusLogic_CreateTargetDeviceStatistics creates the Target Device Statistics
- structure for Host Adapter.
-*/
-
-static boolean BusLogic_CreateTargetDeviceStatistics(BusLogic_HostAdapter_T
- *HostAdapter)
-{
- HostAdapter->TargetDeviceStatistics =
- (BusLogic_TargetDeviceStatistics_T *)
- scsi_init_malloc(HostAdapter->MaxTargetDevices
- * sizeof(BusLogic_TargetDeviceStatistics_T),
- GFP_ATOMIC);
- if (HostAdapter->TargetDeviceStatistics == NULL)
- {
- BusLogic_Error("UNABLE TO ALLOCATE TARGET DEVICE STATISTICS - "
- "DETACHING\n", HostAdapter, HostAdapter->HostNumber);
- return false;
- }
- memset(HostAdapter->TargetDeviceStatistics, 0,
- HostAdapter->MaxTargetDevices
- * sizeof(BusLogic_TargetDeviceStatistics_T));
- return true;
-}
-
-
-/*
- BusLogic_DestroyTargetDeviceStatistics destroys the Target Device Statistics
- structure for Host Adapter.
-*/
-
-static void BusLogic_DestroyTargetDeviceStatistics(BusLogic_HostAdapter_T
- *HostAdapter)
-{
- if (HostAdapter->TargetDeviceStatistics == NULL) return;
- scsi_init_free((char *) HostAdapter->TargetDeviceStatistics,
- HostAdapter->MaxTargetDevices
- * sizeof(BusLogic_TargetDeviceStatistics_T));
-}
-
-
-/*
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
@@ -482,7 +423,7 @@
unsigned char *ReplyPointer = (unsigned char *) ReplyData;
BusLogic_StatusRegister_T StatusRegister;
BusLogic_InterruptRegister_T InterruptRegister;
- unsigned long ProcessorFlags = 0;
+ ProcessorFlags_T ProcessorFlags = 0;
int ReplyBytes = 0, Result;
long TimeoutCounter;
/*
@@ -494,7 +435,7 @@
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 other driver sharing the same IRQ Channel.
+ BusLogic Host Adapter or another driver sharing the same IRQ Channel.
*/
if (!HostAdapter->IRQ_ChannelAcquired)
{
@@ -572,7 +513,7 @@
Result = -1;
goto Done;
}
- if (BusLogic_GlobalOptions.Bits.TraceConfiguration)
+ if (BusLogic_GlobalOptions.TraceConfiguration)
BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
"(Modify I/O Address)\n", HostAdapter,
OperationCode, StatusRegister.All);
@@ -607,9 +548,11 @@
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 (++ReplyBytes <= ReplyLength)
+ *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
+ else BusLogic_ReadDataInRegister(HostAdapter);
+ }
if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
StatusRegister.Bits.HostAdapterReady) break;
udelay(100);
@@ -621,34 +564,24 @@
goto Done;
}
/*
- If testing Command Complete Interrupts, wait a short while in case the
- loop immediately above terminated due to the Command Complete bit being
- set in the Interrupt Register, but the interrupt hasn't actually been
- processed yet. Otherwise, acknowledging the interrupt here could prevent
- the interrupt test from succeeding.
- */
- if (OperationCode == BusLogic_TestCommandCompleteInterrupt)
- udelay(10000);
- /*
Clear any pending Command Complete Interrupt.
*/
BusLogic_InterruptReset(HostAdapter);
/*
Provide tracing information if requested.
*/
- if (BusLogic_GlobalOptions.Bits.TraceConfiguration)
- if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
- {
- 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);
- }
+ 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.
*/
@@ -705,38 +638,63 @@
/*
+ 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(void)
+static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
+ *PrototypeHostAdapter)
{
- int StandardAddressIndex;
- /*
- If BusLogic_Setup has provided an I/O Address probe list, do not override
- the Kernel Command Line specifications.
- */
- if (BusLogic_ProbeInfoCount > 0) return;
/*
- If a Kernel Command Line specification has requested that ISA Bus Probes
+ If BusLogic Driver Options specifications requested that ISA Bus Probes
be inhibited, do not proceed further.
*/
- if (BusLogic_ProbeOptions.Bits.NoProbeISA) return;
+ if (BusLogic_ProbeOptions.NoProbeISA) return;
/*
Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
*/
- StandardAddressIndex = 0;
- while (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters &&
- StandardAddressIndex < BusLogic_ISA_StandardAddressesCount)
- {
- BusLogic_ProbeInfo_T *ProbeInfo =
- &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->IO_Address =
- BusLogic_ISA_StandardAddresses[StandardAddressIndex++];
- ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
- }
+ 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);
}
@@ -783,25 +741,26 @@
I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
*/
-static int BusLogic_InitializeMultiMasterProbeInfo(void)
+static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
+ *PrototypeHostAdapter)
{
- boolean StandardAddressSeen[BusLogic_ISA_StandardAddressesCount];
BusLogic_ProbeInfo_T *PrimaryProbeInfo =
&BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
boolean ForceBusDeviceScanningOrder = false;
boolean ForceBusDeviceScanningOrderChecked = false;
- unsigned char Bus, DeviceFunction, IRQ_Channel;
+ boolean StandardAddressSeen[6];
+ unsigned char Bus, DeviceFunction;
unsigned int BaseAddress0, BaseAddress1;
+ unsigned char IRQ_Channel;
BusLogic_IO_Address_T IO_Address;
BusLogic_PCI_Address_T PCI_Address;
unsigned short Index = 0;
- int StandardAddressIndex, i;
- if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
- return 0;
+ int i;
+ if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
BusLogic_ProbeInfoCount++;
- for (i = 0; i < BusLogic_ISA_StandardAddressesCount; i++)
+ for (i = 0; i < 6; i++)
StandardAddressSeen[i] = false;
/*
Iterate over the MultiMaster PCI Host Adapters. For each enumerated host
@@ -826,8 +785,7 @@
pcibios_read_config_byte(Bus, DeviceFunction,
PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
{
- BusLogic_HostAdapter_T HostAdapterPrototype;
- BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
+ BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
unsigned char Device = DeviceFunction >> 3;
@@ -859,7 +817,7 @@
NULL, Bus, Device, IO_Address);
continue;
}
- if (BusLogic_GlobalOptions.Bits.TraceProbe)
+ if (BusLogic_GlobalOptions.TraceProbe)
{
BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
"detected at\n", NULL);
@@ -871,17 +829,17 @@
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 need not be probed.
+ 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 <
- BusLogic_ISA_StandardAddressesCount)
+ if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
StandardAddressSeen[PCIHostAdapterInformation
.ISACompatibleIOPort] = true;
}
@@ -933,10 +891,10 @@
*/
if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
{
- PrimaryProbeInfo->IO_Address = IO_Address;
- PrimaryProbeInfo->PCI_Address = PCI_Address;
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;
@@ -946,10 +904,10 @@
{
BusLogic_ProbeInfo_T *ProbeInfo =
&BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->IO_Address = IO_Address;
- ProbeInfo->PCI_Address = PCI_Address;
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;
@@ -978,31 +936,80 @@
then the Primary I/O Address must be probed explicitly before any PCI
host adapters are probed.
*/
- if (PrimaryProbeInfo->IO_Address == 0 &&
- !BusLogic_ProbeOptions.Bits.NoProbeISA)
- {
- PrimaryProbeInfo->IO_Address = BusLogic_ISA_StandardAddresses[0];
- PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
- }
+ 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.Bits.NoProbeISA)
- for (StandardAddressIndex = 1;
- StandardAddressIndex < BusLogic_ISA_StandardAddressesCount;
- StandardAddressIndex++)
- if (!StandardAddressSeen[StandardAddressIndex] &&
- BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
- {
- BusLogic_ProbeInfo_T *ProbeInfo =
- &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->IO_Address =
- BusLogic_ISA_StandardAddresses[StandardAddressIndex];
- ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
- }
+ 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.
+ */
+ Index = 0;
+ while (pcibios_find_device(PCI_VENDOR_ID_BUSLOGIC,
+ PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
+ Index++, &Bus, &DeviceFunction) == 0)
+ if (pcibios_read_config_dword(Bus, DeviceFunction,
+ PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
+ pcibios_read_config_byte(Bus, DeviceFunction,
+ PCI_INTERRUPT_LINE, &IRQ_Channel) == 0)
+ {
+ unsigned char Device = DeviceFunction >> 3;
+ IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
+ if (IO_Address == 0 || IRQ_Channel == 0 || IRQ_Channel >= NR_IRQS)
+ 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;
}
@@ -1014,11 +1021,13 @@
number of FlashPoint Host Adapters found.
*/
-static int BusLogic_InitializeFlashPointProbeInfo(void)
+static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
+ *PrototypeHostAdapter)
{
int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
- unsigned char Bus, DeviceFunction, IRQ_Channel;
+ unsigned char Bus, DeviceFunction;
unsigned int BaseAddress0, BaseAddress1;
+ unsigned char IRQ_Channel;
BusLogic_IO_Address_T IO_Address;
BusLogic_PCI_Address_T PCI_Address;
unsigned short Index = 0;
@@ -1065,7 +1074,7 @@
NULL, Bus, Device, IO_Address);
continue;
}
- if (BusLogic_GlobalOptions.Bits.TraceProbe)
+ if (BusLogic_GlobalOptions.TraceProbe)
{
BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
"detected at\n", NULL);
@@ -1077,10 +1086,10 @@
{
BusLogic_ProbeInfo_T *ProbeInfo =
&BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->IO_Address = IO_Address;
- ProbeInfo->PCI_Address = PCI_Address;
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;
@@ -1116,44 +1125,41 @@
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 Kernel Command Line
- options "MultiMasterFirst" and "FlashPointFirst" can be used to force a
- particular probe order.
+ 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(void)
+static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
+ *PrototypeHostAdapter)
{
/*
- If BusLogic_Setup has provided an I/O Address probe list, do not override
- the Kernel Command Line specifications.
- */
- if (BusLogic_ProbeInfoCount > 0) return;
- /*
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.Bits.NoProbePCI && pcibios_present())
+ if (!BusLogic_ProbeOptions.NoProbePCI && pcibios_present())
{
- if (BusLogic_ProbeOptions.Bits.ProbeMultiMasterFirst)
+ if (BusLogic_ProbeOptions.MultiMasterFirst)
{
- BusLogic_InitializeMultiMasterProbeInfo();
- BusLogic_InitializeFlashPointProbeInfo();
+ BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
+ BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
}
- else if (BusLogic_ProbeOptions.Bits.ProbeFlashPointFirst)
+ else if (BusLogic_ProbeOptions.FlashPointFirst)
{
- BusLogic_InitializeFlashPointProbeInfo();
- BusLogic_InitializeMultiMasterProbeInfo();
+ BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
+ BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
}
else
{
- int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo();
- int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo();
+ 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 HostAdapterPrototype;
- BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
+ BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
BusLogic_FetchHostAdapterLocalRAMRequest_T
FetchHostAdapterLocalRAMRequest;
BusLogic_BIOSDriveMapByte_T Drive0MapByte;
@@ -1195,7 +1201,7 @@
}
}
}
- else BusLogic_InitializeProbeInfoListISA();
+ else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
}
@@ -1211,10 +1217,13 @@
{
BusLogic_AnnounceDriver(HostAdapter);
if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
- BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n"
- "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);
+ {
+ BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
+ 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);
@@ -1240,20 +1249,14 @@
*/
if (BusLogic_FlashPointHostAdapterP(HostAdapter))
{
- FlashPoint_Info_T *FlashPointInfo = (FlashPoint_Info_T *)
- scsi_init_malloc(sizeof(FlashPoint_Info_T), GFP_ATOMIC);
- int Retries = 10;
- if (FlashPointInfo == NULL)
- return BusLogic_Failure(HostAdapter, "ALLOCATING FLASHPOINT INFO");
- FlashPointInfo->BaseAddress = HostAdapter->IO_Address;
+ FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
+ FlashPointInfo->BaseAddress =
+ (BusLogic_Base_Address_T) HostAdapter->IO_Address;
FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
FlashPointInfo->Present = false;
- while (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
- FlashPointInfo->Present) &&
- --Retries >= 0) ;
- if (!FlashPointInfo->Present)
+ if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
+ FlashPointInfo->Present))
{
- scsi_init_free((char *) FlashPointInfo, sizeof(FlashPoint_Info_T));
BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
"PCI Bus %d Device %d\n", HostAdapter,
HostAdapter->Bus, HostAdapter->Device);
@@ -1264,8 +1267,7 @@
HostAdapter);
return false;
}
- HostAdapter->FlashPointInfo = FlashPointInfo;
- if (BusLogic_GlobalOptions.Bits.TraceProbe)
+ if (BusLogic_GlobalOptions.TraceProbe)
BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
HostAdapter, HostAdapter->IO_Address);
/*
@@ -1283,7 +1285,7 @@
StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
- if (BusLogic_GlobalOptions.Bits.TraceProbe)
+ if (BusLogic_GlobalOptions.TraceProbe)
BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
"Geometry 0x%02X\n", HostAdapter,
HostAdapter->IO_Address, StatusRegister.All,
@@ -1318,12 +1320,16 @@
/*
- BusLogic_HardResetHostAdapter issues a Hard Reset to the Host Adapter,
- and waits for Host Adapter Diagnostics to complete.
+ 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_HardResetHostAdapter(BusLogic_HostAdapter_T
- *HostAdapter)
+static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
+ *HostAdapter,
+ boolean HardReset)
{
BusLogic_StatusRegister_T StatusRegister;
int TimeoutCounter;
@@ -1332,9 +1338,11 @@
*/
if (BusLogic_FlashPointHostAdapterP(HostAdapter))
{
- HostAdapter->FlashPointInfo->ReportDataUnderrun = true;
+ FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
+ FlashPointInfo->HostSoftReset = !HardReset;
+ FlashPointInfo->ReportDataUnderrun = true;
HostAdapter->CardHandle =
- FlashPoint_HardResetHostAdapter(HostAdapter->FlashPointInfo);
+ FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
/*
Indicate the Host Adapter Hard Reset completed successfully.
@@ -1342,10 +1350,12 @@
return true;
}
/*
- Issue a Hard Reset Command to the Host Adapter. The Host Adapter should
- respond by setting Diagnostic Active in the Status Register.
+ 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.
*/
- BusLogic_HardReset(HostAdapter);
+ if (HardReset)
+ BusLogic_HardReset(HostAdapter);
+ else BusLogic_SoftReset(HostAdapter);
/*
Wait until Diagnostic Active is set in the Status Register.
*/
@@ -1356,8 +1366,8 @@
if (StatusRegister.Bits.DiagnosticActive) break;
udelay(100);
}
- if (BusLogic_GlobalOptions.Bits.TraceHardReset)
- BusLogic_Notice("BusLogic_HardReset(0x%X): Diagnostic Active, "
+ if (BusLogic_GlobalOptions.TraceHardwareReset)
+ BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
"Status 0x%02X\n", HostAdapter,
HostAdapter->IO_Address, StatusRegister.All);
if (TimeoutCounter < 0) return false;
@@ -1377,8 +1387,8 @@
if (!StatusRegister.Bits.DiagnosticActive) break;
udelay(100);
}
- if (BusLogic_GlobalOptions.Bits.TraceHardReset)
- BusLogic_Notice("BusLogic_HardReset(0x%X): Diagnostic Completed, "
+ if (BusLogic_GlobalOptions.TraceHardwareReset)
+ BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
"Status 0x%02X\n", HostAdapter,
HostAdapter->IO_Address, StatusRegister.All);
if (TimeoutCounter < 0) return false;
@@ -1396,8 +1406,8 @@
break;
udelay(100);
}
- if (BusLogic_GlobalOptions.Bits.TraceHardReset)
- BusLogic_Notice("BusLogic_HardReset(0x%X): Host Adapter Ready, "
+ if (BusLogic_GlobalOptions.TraceHardwareReset)
+ BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
"Status 0x%02X\n", HostAdapter,
HostAdapter->IO_Address, StatusRegister.All);
if (TimeoutCounter < 0) return false;
@@ -1430,12 +1440,11 @@
/*
BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
- Host Adapter. It also determines the IRQ Channel for non-PCI Host Adapters.
+ Host Adapter.
*/
static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
{
- BusLogic_Configuration_T Configuration;
BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
BusLogic_RequestedReplyLength_T RequestedReplyLength;
boolean Result = true;
@@ -1444,29 +1453,6 @@
*/
if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
/*
- Issue the Inquire Configuration command if the IRQ Channel is unknown.
- */
- if (HostAdapter->IRQ_Channel == 0)
- if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration,
- NULL, 0, &Configuration, sizeof(Configuration))
- == sizeof(Configuration))
- {
- 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;
- else Result = false;
- }
- else Result = false;
- /*
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
@@ -1484,7 +1470,7 @@
/*
Provide tracing information if requested and return.
*/
- if (BusLogic_GlobalOptions.Bits.TraceProbe)
+ if (BusLogic_GlobalOptions.TraceProbe)
BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
return Result;
@@ -1512,7 +1498,7 @@
BusLogic_GeometryRegister_T GeometryRegister;
BusLogic_RequestedReplyLength_T RequestedReplyLength;
unsigned char *TargetPointer, Character;
- int i;
+ int TargetID, i;
/*
Configuration Information for FlashPoint Host Adapters is provided in the
FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
@@ -1521,7 +1507,7 @@
*/
if (BusLogic_FlashPointHostAdapterP(HostAdapter))
{
- FlashPoint_Info_T *FlashPointInfo = HostAdapter->FlashPointInfo;
+ FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
TargetPointer = HostAdapter->ModelName;
*TargetPointer++ = 'B';
*TargetPointer++ = 'T';
@@ -1550,8 +1536,8 @@
HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
HostAdapter->MaxLogicalUnits = 32;
- HostAdapter->InitialCCBs = 64;
- HostAdapter->IncrementalCCBs = 16;
+ HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
+ HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
HostAdapter->DriverQueueDepth = 255;
HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
@@ -1692,18 +1678,36 @@
*/
HostAdapter->SCSI_ID = Configuration.HostAdapterID;
/*
- Determine the Bus Type and save it in the Host Adapter structure,
- and determine and save the DMA Channel for ISA Host Adapters.
+ 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;
+ {
+ 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.
@@ -1837,7 +1841,7 @@
HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
/*
- Select appropriate values for the Driver Queue Depth, Mailbox Count,
+ 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
@@ -1868,18 +1872,16 @@
if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
{
HostAdapter->StrictRoundRobinModeSupport = true;
- HostAdapter->MailboxCount = 255;
- HostAdapter->InitialCCBs = 64;
- HostAdapter->IncrementalCCBs = 16;
+ HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
}
else
{
HostAdapter->StrictRoundRobinModeSupport = false;
HostAdapter->MailboxCount = 32;
- HostAdapter->InitialCCBs = 32;
- HostAdapter->IncrementalCCBs = 8;
}
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
@@ -1931,57 +1933,36 @@
*/
Common:
/*
- Initialize the Host Adapter Name and Interrupt Label fields from the
- Model Name.
+ Initialize the Host Adapter Full Model Name from the Model Name.
*/
strcpy(HostAdapter->FullModelName, "BusLogic ");
strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
- strcpy(HostAdapter->InterruptLabel, HostAdapter->FullModelName);
/*
Select an appropriate value for the Tagged Queue Depth either from a
- Command Line Entry, 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. Tagged Queuing is disabled by default when the Tagged Queue Depth
- is 1 since queuing multiple commands is not possible.
- */
- if (HostAdapter->CommandLineEntry != NULL &&
- HostAdapter->CommandLineEntry->TaggedQueueDepth > 0)
- HostAdapter->TaggedQueueDepth =
- HostAdapter->CommandLineEntry->TaggedQueueDepth;
- else if (HostAdapter->BounceBuffersRequired)
- HostAdapter->TaggedQueueDepth = BusLogic_TaggedQueueDepthBounceBuffers;
- else HostAdapter->TaggedQueueDepth = BusLogic_TaggedQueueDepthAutomatic;
- HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
- if (HostAdapter->UntaggedQueueDepth > HostAdapter->TaggedQueueDepth &&
- HostAdapter->TaggedQueueDepth > 0)
- HostAdapter->UntaggedQueueDepth = HostAdapter->TaggedQueueDepth;
- if (HostAdapter->TaggedQueueDepth == 1)
- HostAdapter->TaggedQueuingPermitted = 0;
- /*
- Select an appropriate value for Bus Settle Time either from a Command
- Line Entry, or from BusLogic_DefaultBusSettleTime.
- */
- if (HostAdapter->CommandLineEntry != NULL &&
- HostAdapter->CommandLineEntry->BusSettleTime > 0)
- HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime;
- else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
- /*
- Select an appropriate value for Local Options from a Command Line Entry.
- */
- if (HostAdapter->CommandLineEntry != NULL)
- HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions;
- /*
- Select appropriate values for the Error Recovery Strategy array either from
- a Command Line Entry, or using BusLogic_ErrorRecovery_Default.
- */
- if (HostAdapter->CommandLineEntry != NULL)
- memcpy(HostAdapter->ErrorRecoveryStrategy,
- HostAdapter->CommandLineEntry->ErrorRecoveryStrategy,
- sizeof(HostAdapter->ErrorRecoveryStrategy));
- else memset(HostAdapter->ErrorRecoveryStrategy,
- BusLogic_ErrorRecovery_Default,
- sizeof(HostAdapter->ErrorRecoveryStrategy));
+ 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
@@ -1989,15 +1970,34 @@
*/
HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
/*
- Combine the default Tagged Queuing Permitted bits with any Command
- Line Entry Tagged Queuing specification.
+ Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
+ Options Tagged Queuing specification.
*/
- if (HostAdapter->CommandLineEntry != NULL)
+ if (HostAdapter->DriverOptions != NULL)
HostAdapter->TaggedQueuingPermitted =
- (HostAdapter->CommandLineEntry->TaggedQueuingPermitted &
- HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) |
+ (HostAdapter->DriverOptions->TaggedQueuingPermitted &
+ HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
(HostAdapter->TaggedQueuingPermitted &
- ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask);
+ ~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.
*/
@@ -2017,7 +2017,8 @@
unsigned short SynchronousPermitted, FastPermitted;
unsigned short UltraPermitted, WidePermitted;
unsigned short DisconnectPermitted, TaggedQueuingPermitted;
- boolean CommonSynchronousNegotiation, CommonErrorRecovery;
+ boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
+ boolean CommonErrorRecovery;
char SynchronousString[BusLogic_MaxTargetDevices+1];
char WideString[BusLogic_MaxTargetDevices+1];
char DisconnectString[BusLogic_MaxTargetDevices+1];
@@ -2083,22 +2084,26 @@
CommonSynchronousNegotiation = true;
}
else if (SynchronousPermitted == AllTargetsMask)
- if (FastPermitted == 0)
- {
- SynchronousMessage = "Slow";
- CommonSynchronousNegotiation = true;
- }
- else if (FastPermitted == AllTargetsMask)
- if (UltraPermitted == 0)
+ {
+ if (FastPermitted == 0)
{
- SynchronousMessage = "Fast";
+ SynchronousMessage = "Slow";
CommonSynchronousNegotiation = true;
}
- else if (UltraPermitted == AllTargetsMask)
+ else if (FastPermitted == AllTargetsMask)
{
- SynchronousMessage = "Ultra";
- CommonSynchronousNegotiation = true;
+ if (UltraPermitted == 0)
+ {
+ SynchronousMessage = "Fast";
+ CommonSynchronousNegotiation = true;
+ }
+ else if (UltraPermitted == AllTargetsMask)
+ {
+ SynchronousMessage = "Ultra";
+ CommonSynchronousNegotiation = true;
+ }
}
+ }
if (!CommonSynchronousNegotiation)
{
for (TargetID = 0;
@@ -2175,9 +2180,20 @@
HostAdapter, HostAdapter->DriverQueueDepth,
HostAdapter->DriverScatterGatherLimit);
BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
- if (HostAdapter->TaggedQueueDepth > 0)
- BusLogic_Info("%d", HostAdapter, HostAdapter->TaggedQueueDepth);
- else BusLogic_Info("Automatic", 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: %d\n", HostAdapter,
HostAdapter->UntaggedQueueDepth);
CommonErrorRecovery = true;
@@ -2238,8 +2254,6 @@
static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
{
- BusLogic_HostAdapter_T *FirstHostAdapter =
- BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel];
if (HostAdapter->IRQ_Channel == 0)
{
BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
@@ -2247,24 +2261,15 @@
return false;
}
/*
- Acquire exclusive or shared access to the IRQ Channel if necessary.
+ Acquire shared access to the IRQ Channel.
*/
- if (FirstHostAdapter->Next == NULL)
- {
- if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
- SA_INTERRUPT | SA_SHIRQ,
- HostAdapter->InterruptLabel, NULL) < 0)
- {
- BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
- HostAdapter, HostAdapter->IRQ_Channel);
- return false;
- }
- }
- else if (strlen(FirstHostAdapter->InterruptLabel) + 11
- < sizeof(FirstHostAdapter->InterruptLabel))
+ if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
+ SA_INTERRUPT | SA_SHIRQ,
+ HostAdapter->FullModelName, HostAdapter) < 0)
{
- strcat(FirstHostAdapter->InterruptLabel, " + ");
- strcat(FirstHostAdapter->InterruptLabel, HostAdapter->ModelName);
+ BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
+ HostAdapter, HostAdapter->IRQ_Channel);
+ return false;
}
HostAdapter->IRQ_ChannelAcquired = true;
/*
@@ -2297,14 +2302,11 @@
static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
{
- BusLogic_HostAdapter_T *FirstHostAdapter =
- BusLogic_RegisteredHostAdapters[HostAdapter->IRQ_Channel];
/*
- Release exclusive or shared access to the IRQ Channel.
+ Release shared access to the IRQ Channel.
*/
if (HostAdapter->IRQ_ChannelAcquired)
- if (FirstHostAdapter->Next == NULL)
- free_irq(HostAdapter->IRQ_Channel, NULL);
+ free_irq(HostAdapter->IRQ_Channel, HostAdapter);
/*
Release exclusive access to the DMA Channel.
*/
@@ -2314,50 +2316,6 @@
/*
- BusLogic_TestInterrupts tests for proper functioning of the Host Adapter
- Interrupt Register and that interrupts generated by the Host Adapter are
- getting through to the Interrupt Handler. A large proportion of initial
- problems with installing PCI Host Adapters are due to configuration problems
- where either the Host Adapter or Motherboard is configured incorrectly, and
- interrupts do not get through as a result.
-*/
-
-static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
-{
- unsigned int InitialInterruptCount, FinalInterruptCount;
- int TestCount = 5, i;
- /*
- FlashPoint Host Adapters do not provide for an interrupt test.
- */
- if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
- /*
- Inhibit the Interrupt Test if requested.
- */
- if (HostAdapter->LocalOptions.Bits.InhibitInterruptTest) return true;
- /*
- Issue the Test Command Complete Interrupt commands.
- */
- InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
- for (i = 0; i < TestCount; i++)
- BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
- NULL, 0, NULL, 0);
- FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
- /*
- Verify that BusLogic_InterruptHandler was called at least TestCount
- times. Shared IRQ Channels could cause more than TestCount interrupts to
- occur, but there should never be fewer than TestCount, unless one or more
- interrupts were lost.
- */
- if (FinalInterruptCount < InitialInterruptCount + TestCount)
- return BusLogic_Failure(HostAdapter, "HOST ADAPTER INTERRUPT TEST");
- /*
- Indicate the Host Adapter Interrupt Test completed successfully.
- */
- return true;
-}
-
-
-/*
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.
@@ -2371,25 +2329,42 @@
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;
- memset(HostAdapter->TaggedQueuingActive, false,
- sizeof(HostAdapter->TaggedQueuingActive));
- memset(HostAdapter->CommandSuccessfulFlag, false,
- sizeof(HostAdapter->CommandSuccessfulFlag));
- memset(HostAdapter->ActiveCommands, 0,
- sizeof(HostAdapter->ActiveCommands));
- memset(HostAdapter->CommandsSinceReset, 0,
- sizeof(HostAdapter->CommandsSinceReset));
+ {
+ 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,
@@ -2397,11 +2372,6 @@
memset(HostAdapter->FirstIncomingMailbox, 0,
HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
/*
- Initialize the pointers to the Next Mailboxes.
- */
- HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
- HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
- /*
Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
*/
ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
@@ -2442,11 +2412,14 @@
Announce Successful Initialization.
*/
Done:
- if (HostAdapter->HostAdapterInitialized)
- BusLogic_Warning("*** %s Initialized Successfully ***\n",
- HostAdapter, HostAdapter->FullModelName);
- else BusLogic_Info("*** %s Initialized Successfully ***\n",
- HostAdapter, HostAdapter->FullModelName);
+ 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.
@@ -2457,7 +2430,7 @@
/*
BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
- through Host Adapter and reports on the results.
+ through Host Adapter.
*/
static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
@@ -2468,7 +2441,7 @@
BusLogic_SetupInformation_T SetupInformation;
BusLogic_SynchronousPeriod_T SynchronousPeriod;
BusLogic_RequestedReplyLength_T RequestedReplyLength;
- int TargetDevicesFound = 0, TargetID;
+ 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
@@ -2480,13 +2453,11 @@
*/
if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
/*
- Inhibit the Target Devices Inquiry if requested.
+ Inhibit the Target Device Inquiry if requested.
*/
- if (HostAdapter->LocalOptions.Bits.InhibitTargetInquiry)
- {
- BusLogic_Info(" Target Device Inquiry Inhibited\n", HostAdapter);
- return true;
- }
+ 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
@@ -2502,6 +2473,9 @@
&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
{
@@ -2511,10 +2485,9 @@
!= sizeof(InstalledDevicesID0to7))
return BusLogic_Failure(HostAdapter,
"INQUIRE INSTALLED DEVICES ID 0 TO 7");
- InstalledDevices = 0;
for (TargetID = 0; TargetID < 8; TargetID++)
- if (InstalledDevicesID0to7[TargetID] != 0)
- InstalledDevices |= (1 << TargetID);
+ HostAdapter->TargetFlags[TargetID].TargetExists =
+ (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
}
/*
Issue the Inquire Setup Information command.
@@ -2525,6 +2498,19 @@
&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.
*/
@@ -2536,65 +2522,15 @@
&SynchronousPeriod, sizeof(SynchronousPeriod))
!= sizeof(SynchronousPeriod))
return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
+ for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
+ HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
}
else
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
- SynchronousPeriod[TargetID] =
+ HostAdapter->SynchronousPeriod[TargetID] =
20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
.TransferPeriod;
- else SynchronousPeriod[TargetID] = 0;
- /*
- Save the Installed Devices, Synchronous Values, and Synchronous Period
- information in the Host Adapter structure.
- */
- HostAdapter->InstalledDevices = InstalledDevices;
- memcpy(HostAdapter->SynchronousValues,
- SetupInformation.SynchronousValuesID0to7,
- sizeof(BusLogic_SynchronousValues8_T));
- if (HostAdapter->HostWideSCSI)
- memcpy(&HostAdapter->SynchronousValues[8],
- SetupInformation.SynchronousValuesID8to15,
- sizeof(BusLogic_SynchronousValues8_T));
- memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod,
- sizeof(BusLogic_SynchronousPeriod_T));
- /*
- Report on the Target Devices found.
- */
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (HostAdapter->InstalledDevices & (1 << TargetID))
- {
- int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID];
- if (SynchronousPeriod > 10)
- {
- int SynchronousTransferRate = 100000000 / SynchronousPeriod;
- int RoundedSynchronousTransferRate =
- (SynchronousTransferRate + 5000) / 10000;
- BusLogic_Info(" Target %d: Synchronous at "
- "%d.%02d mega-transfers/second, offset %d\n",
- HostAdapter, TargetID,
- RoundedSynchronousTransferRate / 100,
- RoundedSynchronousTransferRate % 100,
- HostAdapter->SynchronousValues[TargetID].Offset);
- }
- else if (SynchronousPeriod > 0)
- {
- int SynchronousTransferRate = 100000000 / SynchronousPeriod;
- int RoundedSynchronousTransferRate =
- (SynchronousTransferRate + 50000) / 100000;
- BusLogic_Info(" Target %d: Synchronous at "
- "%d.%01d mega-transfers/second, offset %d\n",
- HostAdapter, TargetID,
- RoundedSynchronousTransferRate / 10,
- RoundedSynchronousTransferRate % 10,
- HostAdapter->SynchronousValues[TargetID].Offset);
- }
- else BusLogic_Info(" Target %d: Asynchronous\n",
- HostAdapter, TargetID);
- TargetDevicesFound++;
- }
- if (TargetDevicesFound == 0)
- BusLogic_Info(" No Target Devices Found\n", HostAdapter);
/*
Indicate the Target Device Inquiry completed successfully.
*/
@@ -2603,10 +2539,87 @@
/*
- BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
- structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
- SCSI Host structure are intentionally left uninitialized, as this driver
- handles acquisition and release of these resources explicitly, as well as
+ BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
+ through Host Adapter.
+*/
+
+static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
+ *HostAdapter)
+{
+ int TargetID;
+ /*
+ Inhibit the Target Device Inquiry and Reporting if requested.
+ */
+ if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
+ HostAdapter->DriverOptions != NULL &&
+ HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
+ return;
+ /*
+ Report on the Target Devices found.
+ */
+ for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
+ {
+ BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
+ if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
+ {
+ int SynchronousTransferRate = 0;
+ if (BusLogic_FlashPointHostAdapterP(HostAdapter))
+ {
+ boolean WideTransfersActive;
+ FlashPoint_InquireTargetInfo(
+ HostAdapter->CardHandle, TargetID,
+ &HostAdapter->SynchronousPeriod[TargetID],
+ &HostAdapter->SynchronousOffset[TargetID],
+ &WideTransfersActive);
+ TargetFlags->WideTransfersActive = WideTransfersActive;
+ }
+ else if (TargetFlags->WideTransfersSupported &&
+ (HostAdapter->WidePermitted & (1 << TargetID)) &&
+ strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
+ TargetFlags->WideTransfersActive = true;
+ if (HostAdapter->SynchronousPeriod[TargetID] > 0)
+ SynchronousTransferRate =
+ 100000 / HostAdapter->SynchronousPeriod[TargetID];
+ if (TargetFlags->WideTransfersActive)
+ SynchronousTransferRate <<= 1;
+ if (SynchronousTransferRate >= 9950)
+ {
+ SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
+ BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
+ "%d.%01d MB/sec, offset %d\n",
+ HostAdapter, TargetID,
+ HostAdapter->QueueDepth[TargetID],
+ (TargetFlags->WideTransfersActive ? "Wide " : ""),
+ SynchronousTransferRate / 10,
+ SynchronousTransferRate % 10,
+ HostAdapter->SynchronousOffset[TargetID]);
+ }
+ else if (SynchronousTransferRate > 0)
+ {
+ SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
+ BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
+ "%d.%02d MB/sec, offset %d\n",
+ HostAdapter, TargetID,
+ HostAdapter->QueueDepth[TargetID],
+ (TargetFlags->WideTransfersActive ? "Wide " : ""),
+ SynchronousTransferRate / 100,
+ SynchronousTransferRate % 100,
+ HostAdapter->SynchronousOffset[TargetID]);
+ }
+ else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n",
+ HostAdapter, TargetID,
+ HostAdapter->QueueDepth[TargetID]);
+ TargetFlags->TargetInfoReported = true;
+ }
+ }
+}
+
+
+/*
+ BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
+ structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
+ SCSI Host structure are intentionally left uninitialized, as this driver
+ handles acquisition and release of these resources explicitly, as well as
ensuring exclusive access to the Host Adapter hardware and data structures
through explicit acquisition and release of the Host Adapter's Lock.
*/
@@ -2628,9 +2641,11 @@
/*
- BusLogic_SelectQueueDepths selects Queue Depths for each Target Device
- based on the Host Adapter's Total Queue Depth and the number, type, speed,
- and capabilities of the Target Devices.
+ BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
+ on the Host Adapter's Total Queue Depth and the number, type, speed, and
+ capabilities of the Target Devices. When called for the last Host Adapter,
+ it reports on the Target Device Information for all BusLogic Host Adapters
+ since all the Target Devices have now been probed.
*/
static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
@@ -2638,41 +2653,69 @@
{
BusLogic_HostAdapter_T *HostAdapter =
(BusLogic_HostAdapter_T *) Host->hostdata;
- int TaggedQueueDepth = HostAdapter->TaggedQueueDepth;
- int UntaggedQueueDepth = HostAdapter->UntaggedQueueDepth;
- int TaggedDeviceCount = 0, UntaggedDeviceCount = 0;
- int DesiredCCBs = HostAdapter->MaxTargetDevices - 1;
+ int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
+ int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
+ int AllocatedQueueDepth = 0;
SCSI_Device_T *Device;
- for (Device = DeviceList; Device != NULL; Device = Device->next)
- if (Device->host == Host)
+ int TargetID;
+ for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
+ if (HostAdapter->TargetFlags[TargetID].TargetExists)
{
- if (Device->tagged_supported &&
- (HostAdapter->TaggedQueuingPermitted & (1 << Device->id)))
- TaggedDeviceCount++;
- else UntaggedDeviceCount++;
+ int QueueDepth = HostAdapter->QueueDepth[TargetID];
+ if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
+ (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
+ {
+ TaggedDeviceCount++;
+ if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
+ }
+ else
+ {
+ UntaggedDeviceCount++;
+ if (QueueDepth == 0 ||
+ QueueDepth > HostAdapter->UntaggedQueueDepth)
+ {
+ QueueDepth = HostAdapter->UntaggedQueueDepth;
+ HostAdapter->QueueDepth[TargetID] = QueueDepth;
+ }
+ }
+ AllocatedQueueDepth += QueueDepth;
+ if (QueueDepth == 1)
+ HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
}
- if (TaggedQueueDepth == 0 && TaggedDeviceCount > 0)
+ HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
+ if (AutomaticTaggedDeviceCount > 0)
{
- TaggedQueueDepth =
- 1 + ((HostAdapter->HostAdapterQueueDepth
- - UntaggedDeviceCount * UntaggedQueueDepth)
- / TaggedDeviceCount);
- if (TaggedQueueDepth > BusLogic_PreferredTaggedQueueDepth)
- TaggedQueueDepth = BusLogic_PreferredTaggedQueueDepth;
+ AutomaticTaggedQueueDepth =
+ (HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
+ / AutomaticTaggedDeviceCount;
+ if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
+ AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
+ if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
+ AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
+ for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
+ if (HostAdapter->TargetFlags[TargetID].TargetExists &&
+ HostAdapter->QueueDepth[TargetID] == 0)
+ {
+ AllocatedQueueDepth += AutomaticTaggedQueueDepth;
+ HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
+ }
}
for (Device = DeviceList; Device != NULL; Device = Device->next)
if (Device->host == Host)
- {
- if (Device->tagged_supported &&
- (HostAdapter->TaggedQueuingPermitted & (1 << Device->id)))
- Device->queue_depth = TaggedQueueDepth;
- else Device->queue_depth = UntaggedQueueDepth;
- HostAdapter->QueueDepth[Device->id] = Device->queue_depth;
- DesiredCCBs += Device->queue_depth;
- }
+ Device->queue_depth = HostAdapter->QueueDepth[Device->id];
+ /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
+ AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
+ if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
+ AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
BusLogic_CreateAdditionalCCBs(HostAdapter,
- DesiredCCBs - HostAdapter->AllocatedCCBs,
+ AllocatedQueueDepth
+ - HostAdapter->AllocatedCCBs,
false);
+ if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
+ for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
+ HostAdapter != NULL;
+ HostAdapter = HostAdapter->Next)
+ BusLogic_ReportTargetDeviceInfo(HostAdapter);
}
@@ -2686,50 +2729,48 @@
int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
{
- int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0, ProbeIndex;
- char *MessageBuffer = NULL;
- if (BusLogic_ProbeOptions.Bits.NoProbe) return 0;
- BusLogic_InitializeProbeInfoList();
+ int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
+ BusLogic_HostAdapter_T *PrototypeHostAdapter;
+ if (BusLogic_ProbeOptions.NoProbe) return 0;
+ BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
+ kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
+ GFP_ATOMIC);
+ if (BusLogic_ProbeInfoList == NULL)
+ {
+ BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
+ return 0;
+ }
+ memset(BusLogic_ProbeInfoList, 0,
+ BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
+ PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
+ kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
+ if (PrototypeHostAdapter == NULL)
+ {
+ kfree(BusLogic_ProbeInfoList);
+ BusLogic_Error("BusLogic: Unable to allocate Prototype "
+ "Host Adapter\n", NULL);
+ return 0;
+ }
+ memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
+ if (BusLogic_Options != NULL)
+ BusLogic_ParseDriverOptions(BusLogic_Options);
+ BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
{
BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
- BusLogic_HostAdapter_T HostAdapterPrototype;
- BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
+ BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
SCSI_Host_T *Host;
if (ProbeInfo->IO_Address == 0) continue;
memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
- HostAdapter->IO_Address = ProbeInfo->IO_Address;
- HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
+ HostAdapter->IO_Address = ProbeInfo->IO_Address;
+ HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
HostAdapter->Bus = ProbeInfo->Bus;
HostAdapter->Device = ProbeInfo->Device;
HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
HostAdapter->AddressCount =
- BusLogic_HostAdapter_AddressCount[HostAdapter->HostAdapterType];
- if (MessageBuffer == NULL)
- MessageBuffer =
- scsi_init_malloc(BusLogic_MessageBufferSize, GFP_ATOMIC);
- if (MessageBuffer == NULL)
- {
- BusLogic_Error("BusLogic: Unable to allocate Message Buffer\n",
- HostAdapter);
- return BusLogicHostAdapterCount;
- }
- HostAdapter->MessageBuffer = MessageBuffer;
- /*
- If an explicit I/O Address was specified, Initialize the Command Line
- Entry field and inhibit the check for whether the I/O Address range is
- already in use.
- */
- if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
- BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address ==
- HostAdapter->IO_Address)
- HostAdapter->CommandLineEntry =
- &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
- else if (check_region(HostAdapter->IO_Address,
- HostAdapter->AddressCount) < 0)
- continue;
+ BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
/*
Probe the Host Adapter. If unsuccessful, abort further initialization.
*/
@@ -2738,22 +2779,20 @@
Hard Reset the Host Adapter. If unsuccessful, abort further
initialization.
*/
- if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
+ if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
/*
Check the Host Adapter. If unsuccessful, abort further initialization.
*/
if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
/*
- Initialize the Command Line Entry field if an explicit I/O Address
- was not specified.
+ Initialize the Driver Options field if provided.
*/
- if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
- BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
- HostAdapter->CommandLineEntry =
- &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
+ if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
+ HostAdapter->DriverOptions =
+ &BusLogic_DriverOptions[DriverOptionsIndex++];
/*
Announce the Driver Version and Date, Author's Name, Copyright Notice,
- and Contact Address.
+ and Electronic Mail Address.
*/
BusLogic_AnnounceDriver(HostAdapter);
/*
@@ -2771,32 +2810,25 @@
*/
Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
- memcpy(HostAdapter, &HostAdapterPrototype,
- sizeof(BusLogic_HostAdapter_T));
+ memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
HostAdapter->SCSI_Host = Host;
HostAdapter->HostNumber = Host->host_no;
Host->select_queue_depths = BusLogic_SelectQueueDepths;
/*
Add Host Adapter to the end of the list of registered BusLogic
- Host Adapters. In order for Command Complete Interrupts to be
- properly dismissed by BusLogic_InterruptHandler, the Host Adapter
- must be registered.
+ Host Adapters.
*/
BusLogic_RegisterHostAdapter(HostAdapter);
/*
Read the Host Adapter Configuration, Configure the Host Adapter,
- Acquire the System Resources necessary to use the Host Adapter,
- then Test Interrupts, Create the Mailboxes, Initial CCBs, and
- Target Device Statistics, Initialize the Host Adapter, and
- finally perform Target Device Inquiry.
+ Acquire the System Resources necessary to use the Host Adapter, then
+ Create the Initial CCBs, Initialize the Host Adapter, and finally
+ perform Target Device Inquiry.
*/
if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
BusLogic_AcquireResources(HostAdapter) &&
- BusLogic_TestInterrupts(HostAdapter) &&
- BusLogic_CreateMailboxes(HostAdapter) &&
BusLogic_CreateInitialCCBs(HostAdapter) &&
- BusLogic_CreateTargetDeviceStatistics(HostAdapter) &&
BusLogic_InitializeHostAdapter(HostAdapter) &&
BusLogic_TargetDeviceInquiry(HostAdapter))
{
@@ -2806,7 +2838,6 @@
Name of the Host Adapter will appear, and initialize the SCSI
Host structure.
*/
- MessageBuffer = NULL;
release_region(HostAdapter->IO_Address,
HostAdapter->AddressCount);
request_region(HostAdapter->IO_Address,
@@ -2818,24 +2849,22 @@
else
{
/*
- An error occurred during Host Adapter Configuration Querying,
- Host Adapter Configuration, Resource Acquisition, Interrupt
- Testing, CCB Creation, Host Adapter Initialization, or Target
- Device Inquiry, so remove Host Adapter from the list of
- registered BusLogic Host Adapters, destroy the Target Device
- Statistics, CCBs, and Mailboxes, Release the System Resources,
- and Unregister the SCSI Host.
+ An error occurred during Host Adapter Configuration Querying, Host
+ Adapter Configuration, Resource Acquisition, CCB Creation, Host
+ Adapter Initialization, or Target Device Inquiry, so remove Host
+ Adapter from the list of registered BusLogic Host Adapters, destroy
+ the CCBs, Release the System Resources, and Unregister the SCSI
+ Host.
*/
- BusLogic_DestroyTargetDeviceStatistics(HostAdapter);
BusLogic_DestroyCCBs(HostAdapter);
- BusLogic_DestroyMailboxes(HostAdapter);
BusLogic_ReleaseResources(HostAdapter);
BusLogic_UnregisterHostAdapter(HostAdapter);
scsi_unregister(Host);
}
}
- if (MessageBuffer != NULL)
- scsi_init_free(MessageBuffer, BusLogic_MessageBufferSize);
+ kfree(PrototypeHostAdapter);
+ kfree(BusLogic_ProbeInfoList);
+ BusLogic_ProbeInfoList = NULL;
return BusLogicHostAdapterCount;
}
@@ -2851,21 +2880,16 @@
BusLogic_HostAdapter_T *HostAdapter =
(BusLogic_HostAdapter_T *) Host->hostdata;
/*
- FlashPoint Host Adapters must also be released by the FlashPoint
+ FlashPoint Host Adapters must first be released by the FlashPoint
SCCB Manager.
*/
if (BusLogic_FlashPointHostAdapterP(HostAdapter))
- {
- FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
- scsi_init_free((char *) HostAdapter->FlashPointInfo,
- sizeof(FlashPoint_Info_T));
- }
+ FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
/*
- Destroy the CCBs and Mailboxes, and release any system resources acquired
- to support Host Adapter.
+ Destroy the CCBs and release any system resources acquired to
+ support Host Adapter.
*/
BusLogic_DestroyCCBs(HostAdapter);
- BusLogic_DestroyMailboxes(HostAdapter);
BusLogic_ReleaseResources(HostAdapter);
/*
Release usage of the I/O Address range.
@@ -2885,19 +2909,20 @@
static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
{
+ BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
CCB->Status = BusLogic_CCB_Completed;
CCB->Next = NULL;
- if (BusLogic_FirstCompletedCCB == NULL)
+ if (HostAdapter->FirstCompletedCCB == NULL)
{
- BusLogic_FirstCompletedCCB = CCB;
- BusLogic_LastCompletedCCB = CCB;
+ HostAdapter->FirstCompletedCCB = CCB;
+ HostAdapter->LastCompletedCCB = CCB;
}
else
{
- BusLogic_LastCompletedCCB->Next = CCB;
- BusLogic_LastCompletedCCB = CCB;
+ HostAdapter->LastCompletedCCB->Next = CCB;
+ HostAdapter->LastCompletedCCB = CCB;
}
- CCB->HostAdapter->ActiveCommands[CCB->TargetID]--;
+ HostAdapter->ActiveCommands[CCB->TargetID]--;
}
@@ -2988,27 +3013,29 @@
BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
Bus_to_Virtual(NextIncomingMailbox->CCB);
if (CompletionCode != BusLogic_AbortedCommandNotFound)
- if (CCB->Status == BusLogic_CCB_Active ||
- CCB->Status == BusLogic_CCB_Reset)
- {
- /*
- Save the Completion Code for this CCB and queue the CCB
- for completion processing.
- */
- CCB->CompletionCode = CompletionCode;
- BusLogic_QueueCompletedCCB(CCB);
- }
- else
- {
- /*
- If a CCB ever appears in an Incoming Mailbox and is not marked as
- status Active or Reset, then there is most likely a bug in the
- Host Adapter firmware.
- */
- BusLogic_Warning("Illegal CCB #%ld status %d in "
- "Incoming Mailbox\n", HostAdapter,
- CCB->SerialNumber, CCB->Status);
- }
+ {
+ if (CCB->Status == BusLogic_CCB_Active ||
+ CCB->Status == BusLogic_CCB_Reset)
+ {
+ /*
+ Save the Completion Code for this CCB and queue the CCB
+ for completion processing.
+ */
+ CCB->CompletionCode = CompletionCode;
+ BusLogic_QueueCompletedCCB(CCB);
+ }
+ else
+ {
+ /*
+ If a CCB ever appears in an Incoming Mailbox and is not marked
+ as status Active or Reset, then there is most likely a bug in
+ the Host Adapter firmware.
+ */
+ BusLogic_Warning("Illegal CCB #%ld status %d in "
+ "Incoming Mailbox\n", HostAdapter,
+ CCB->SerialNumber, CCB->Status);
+ }
+ }
NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
@@ -3018,25 +3045,23 @@
/*
- BusLogic_ProcessCompletedCCBs iterates over the completed CCBs setting
- the SCSI Command Result Codes, deallocating the CCBs, and calling the
- SCSI Subsystem Completion Routines. Interrupts should already have been
- disabled by the caller.
+ BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
+ Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
+ calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
+ should already have been acquired by the caller.
*/
-static void BusLogic_ProcessCompletedCCBs(void)
+static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
{
- static boolean ProcessCompletedCCBsActive = false;
- if (ProcessCompletedCCBsActive) return;
- ProcessCompletedCCBsActive = true;
- while (BusLogic_FirstCompletedCCB != NULL)
+ if (HostAdapter->ProcessCompletedCCBsActive) return;
+ HostAdapter->ProcessCompletedCCBsActive = true;
+ while (HostAdapter->FirstCompletedCCB != NULL)
{
- BusLogic_CCB_T *CCB = BusLogic_FirstCompletedCCB;
+ BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
SCSI_Command_T *Command = CCB->Command;
- BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
- BusLogic_FirstCompletedCCB = CCB->Next;
- if (BusLogic_FirstCompletedCCB == NULL)
- BusLogic_LastCompletedCCB = NULL;
+ HostAdapter->FirstCompletedCCB = CCB->Next;
+ if (HostAdapter->FirstCompletedCCB == NULL)
+ HostAdapter->LastCompletedCCB = NULL;
/*
Process the Completed CCB.
*/
@@ -3047,10 +3072,9 @@
"%d Completed\n", HostAdapter,
CCB->SerialNumber, TargetID);
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[TargetID]
- .BusDeviceResetsCompleted);
+ &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
+ HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
HostAdapter->CommandsSinceReset[TargetID] = 0;
- HostAdapter->TaggedQueuingActive[TargetID] = false;
HostAdapter->LastResetCompleted[TargetID] = jiffies;
/*
Place CCB back on the Host Adapter's free list.
@@ -3101,16 +3125,17 @@
HostAdapter, CCB->SerialNumber, CCB->TargetID);
break;
case BusLogic_CommandCompletedWithoutError:
- HostAdapter->TargetDeviceStatistics[CCB->TargetID]
+ HostAdapter->TargetStatistics[CCB->TargetID]
.CommandsCompleted++;
- HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
+ HostAdapter->TargetFlags[CCB->TargetID]
+ .CommandSuccessfulFlag = true;
Command->result = DID_OK << 16;
break;
case BusLogic_CommandAbortedAtHostRequest:
BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
HostAdapter, CCB->SerialNumber, CCB->TargetID);
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[CCB->TargetID]
+ &HostAdapter->TargetStatistics[CCB->TargetID]
.CommandAbortsCompleted);
Command->result = DID_ABORT << 16;
break;
@@ -3121,9 +3146,9 @@
CCB->TargetDeviceStatus);
if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
{
- HostAdapter->TargetDeviceStatistics[CCB->TargetID]
+ HostAdapter->TargetStatistics[CCB->TargetID]
.CommandsCompleted++;
- if (BusLogic_GlobalOptions.Bits.TraceErrors)
+ if (BusLogic_GlobalOptions.TraceErrors)
{
int i;
BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
@@ -3147,6 +3172,22 @@
break;
}
/*
+ When an INQUIRY command completes normally, save the
+ CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
+ Wide Data Transfers Supported) bits.
+ */
+ if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
+ CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
+ {
+ BusLogic_TargetFlags_T *TargetFlags =
+ &HostAdapter->TargetFlags[CCB->TargetID];
+ SCSI_Inquiry_T *InquiryResult =
+ (SCSI_Inquiry_T *) Command->request_buffer;
+ TargetFlags->TargetExists = true;
+ TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
+ TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
+ }
+ /*
Place CCB back on the Host Adapter's free list.
*/
BusLogic_DeallocateCCB(CCB);
@@ -3156,7 +3197,7 @@
Command->scsi_done(Command);
}
}
- ProcessCompletedCCBsActive = false;
+ HostAdapter->ProcessCompletedCCBsActive = false;
}
@@ -3169,96 +3210,84 @@
void *DeviceIdentifier,
Registers_T *InterruptRegisters)
{
- BusLogic_HostAdapter_T *FirstHostAdapter =
- BusLogic_RegisteredHostAdapters[IRQ_Channel];
- boolean HostAdapterResetRequested = false;
- BusLogic_HostAdapter_T *HostAdapter;
- BusLogic_Lock_T Lock;
+ BusLogic_HostAdapter_T *HostAdapter =
+ (BusLogic_HostAdapter_T *) DeviceIdentifier;
+ ProcessorFlags_T ProcessorFlags;
/*
- Iterate over the installed BusLogic Host Adapters accepting any Incoming
- Mailbox entries and saving the completed CCBs for processing. This
- interrupt handler is installed as a fast interrupt, so interrupts are
- disabled when the interrupt handler is entered.
+ Acquire exclusive access to Host Adapter.
*/
- for (HostAdapter = FirstHostAdapter;
- HostAdapter != NULL;
- HostAdapter = HostAdapter->Next)
+ BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
+ /*
+ Handle Interrupts appropriately for each Host Adapter type.
+ */
+ if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
{
+ BusLogic_InterruptRegister_T InterruptRegister;
/*
- Acquire exclusive access to Host Adapter.
+ Read the Host Adapter Interrupt Register.
*/
- BusLogic_AcquireHostAdapterLockID(HostAdapter, &Lock);
- /*
- Handle Interrupts appropriately for each Host Adapter type.
- */
- if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
+ InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
+ if (InterruptRegister.Bits.InterruptValid)
{
- BusLogic_InterruptRegister_T InterruptRegister;
/*
- Read the Host Adapter Interrupt Register.
+ Acknowledge the interrupt and reset the Host Adapter
+ Interrupt Register.
*/
- InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
- if (InterruptRegister.Bits.InterruptValid)
- {
- /*
- Acknowledge the interrupt and reset the Host Adapter
- Interrupt Register.
- */
- BusLogic_InterruptReset(HostAdapter);
- /*
- Process valid External SCSI Bus Reset and Incoming Mailbox
- Loaded Interrupts. Command Complete Interrupts are noted,
- and Outgoing Mailbox Available Interrupts are ignored, as
- they are never enabled.
- */
- if (InterruptRegister.Bits.ExternalBusReset)
- {
- HostAdapter->HostAdapterResetRequested = true;
- HostAdapterResetRequested = true;
- }
- else if (InterruptRegister.Bits.IncomingMailboxLoaded)
- BusLogic_ScanIncomingMailboxes(HostAdapter);
- else if (InterruptRegister.Bits.CommandComplete)
- HostAdapter->HostAdapterCommandCompleted = true;
- }
- }
- else
- {
+ BusLogic_InterruptReset(HostAdapter);
/*
- Check if there is a pending interrupt for this Host Adapter.
+ Process valid External SCSI Bus Reset and Incoming Mailbox
+ Loaded Interrupts. Command Complete Interrupts are noted,
+ and Outgoing Mailbox Available Interrupts are ignored, as
+ they are never enabled.
*/
- if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
- if (FlashPoint_HandleInterrupt(HostAdapter->CardHandle)
- == FlashPoint_ExternalBusReset)
- {
- HostAdapter->HostAdapterResetRequested = true;
- HostAdapterResetRequested = true;
- }
+ if (InterruptRegister.Bits.ExternalBusReset)
+ HostAdapter->HostAdapterExternalReset = true;
+ else if (InterruptRegister.Bits.IncomingMailboxLoaded)
+ BusLogic_ScanIncomingMailboxes(HostAdapter);
+ else if (InterruptRegister.Bits.CommandComplete)
+ HostAdapter->HostAdapterCommandCompleted = true;
}
+ }
+ else
+ {
/*
- Release exclusive access to Host Adapter.
+ Check if there is a pending interrupt for this Host Adapter.
*/
- BusLogic_ReleaseHostAdapterLockID(HostAdapter, &Lock);
+ if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
+ switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
+ {
+ case FlashPoint_NormalInterrupt:
+ break;
+ case FlashPoint_ExternalBusReset:
+ HostAdapter->HostAdapterExternalReset = true;
+ break;
+ case FlashPoint_InternalError:
+ BusLogic_Warning("Internal FlashPoint Error detected"
+ " - Resetting Host Adapter\n", HostAdapter);
+ HostAdapter->HostAdapterInternalError = true;
+ break;
+ }
}
/*
Process any completed CCBs.
*/
- if (BusLogic_FirstCompletedCCB != NULL)
- BusLogic_ProcessCompletedCCBs();
+ if (HostAdapter->FirstCompletedCCB != NULL)
+ BusLogic_ProcessCompletedCCBs(HostAdapter);
/*
- Iterate over the Host Adapters performing any requested
- Host Adapter Resets.
+ Reset the Host Adapter if requested.
*/
- if (HostAdapterResetRequested)
- for (HostAdapter = FirstHostAdapter;
- HostAdapter != NULL;
- HostAdapter = HostAdapter->Next)
- if (HostAdapter->HostAdapterResetRequested)
- {
- BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
- HostAdapter->HostAdapterResetRequested = false;
- scsi_mark_host_reset(HostAdapter->SCSI_Host);
- }
+ if (HostAdapter->HostAdapterExternalReset ||
+ HostAdapter->HostAdapterInternalError)
+ {
+ BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
+ HostAdapter->HostAdapterExternalReset = false;
+ HostAdapter->HostAdapterInternalError = false;
+ scsi_mark_host_reset(HostAdapter->SCSI_Host);
+ }
+ /*
+ Release exclusive access to Host Adapter.
+ */
+ BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
}
@@ -3293,8 +3322,7 @@
{
HostAdapter->ActiveCommands[CCB->TargetID]++;
if (CCB->Opcode != BusLogic_BusDeviceReset)
- HostAdapter->TargetDeviceStatistics[CCB->TargetID]
- .CommandsAttempted++;
+ HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
}
return true;
}
@@ -3312,8 +3340,10 @@
{
BusLogic_HostAdapter_T *HostAdapter =
(BusLogic_HostAdapter_T *) Command->host->hostdata;
- BusLogic_TargetDeviceStatistics_T *TargetDeviceStatistics =
- HostAdapter->TargetDeviceStatistics;
+ BusLogic_TargetFlags_T *TargetFlags =
+ &HostAdapter->TargetFlags[Command->target];
+ BusLogic_TargetStatistics_T *TargetStatistics =
+ HostAdapter->TargetStatistics;
unsigned char *CDB = Command->cmnd;
int CDB_Length = Command->cmd_len;
int TargetID = Command->target;
@@ -3321,7 +3351,7 @@
void *BufferPointer = Command->request_buffer;
int BufferLength = Command->request_bufflen;
int SegmentCount = Command->use_sg;
- BusLogic_Lock_T Lock;
+ ProcessorFlags_T ProcessorFlags;
BusLogic_CCB_T *CCB;
/*
SCSI REQUEST_SENSE commands will be executed automatically by the Host
@@ -3337,7 +3367,7 @@
/*
Acquire exclusive access to Host Adapter.
*/
- BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
/*
Allocate a CCB from the Host Adapter's free list. In the unlikely event
that there are none available and memory allocation fails, wait 1 second
@@ -3371,13 +3401,9 @@
int Segment;
CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
-#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
- else CCB->DataPointer = (BusLogic_BusAddress_T) CCB->ScatterGatherList;
-#else
- CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
-#endif
+ else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
for (Segment = 0; Segment < SegmentCount; Segment++)
{
CCB->ScatterGatherList[Segment].SegmentByteCount =
@@ -3391,22 +3417,20 @@
case READ_6:
case READ_10:
CCB->DataDirection = BusLogic_DataInLengthChecked;
- TargetDeviceStatistics[TargetID].ReadCommands++;
+ TargetStatistics[TargetID].ReadCommands++;
BusLogic_IncrementByteCounter(
- &TargetDeviceStatistics[TargetID].TotalBytesRead, BufferLength);
+ &TargetStatistics[TargetID].TotalBytesRead, BufferLength);
BusLogic_IncrementSizeBucket(
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets,
- BufferLength);
+ TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
break;
case WRITE_6:
case WRITE_10:
CCB->DataDirection = BusLogic_DataOutLengthChecked;
- TargetDeviceStatistics[TargetID].WriteCommands++;
+ TargetStatistics[TargetID].WriteCommands++;
BusLogic_IncrementByteCounter(
- &TargetDeviceStatistics[TargetID].TotalBytesWritten, BufferLength);
+ &TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
BusLogic_IncrementSizeBucket(
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets,
- BufferLength);
+ TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
break;
default:
CCB->DataDirection = BusLogic_UncheckedDataTransfer;
@@ -3434,20 +3458,18 @@
necessary to wait until there are no pending commands for a target device
before queuing tagged commands.
*/
- HostAdapter->TaggedQueuingSupported[TargetID] =
- Command->device->tagged_supported;
if (HostAdapter->CommandsSinceReset[TargetID]++ >=
BusLogic_MaxTaggedQueueDepth &&
- !HostAdapter->TaggedQueuingActive[TargetID] &&
+ !TargetFlags->TaggedQueuingActive &&
HostAdapter->ActiveCommands[TargetID] == 0 &&
- HostAdapter->TaggedQueuingSupported[TargetID] &&
+ TargetFlags->TaggedQueuingSupported &&
(HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
{
- HostAdapter->TaggedQueuingActive[TargetID] = true;
+ TargetFlags->TaggedQueuingActive = true;
BusLogic_Notice("Tagged Queuing now active for Target %d\n",
HostAdapter, TargetID);
}
- if (HostAdapter->TaggedQueuingActive[TargetID])
+ if (TargetFlags->TaggedQueuingActive)
{
BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
/*
@@ -3457,7 +3479,7 @@
write nearer the head position continue to arrive without interruption.
Therefore, for each Target Device this driver keeps track of the last
time either the queue was empty or an Ordered Queue Tag was issued. If
- more than 3 seconds (one fifth of the 15 second disk timeout) have
+ more than 4 seconds (one fifth of the 20 second disk timeout) have
elapsed since this last sequence point, this command will be issued
with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
the Target Device to complete all previously queued commands before
@@ -3465,7 +3487,7 @@
*/
if (HostAdapter->ActiveCommands[TargetID] == 0)
HostAdapter->LastSequencePoint[TargetID] = jiffies;
- else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 3*HZ)
+ else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
{
HostAdapter->LastSequencePoint[TargetID] = jiffies;
QueueTag = BusLogic_OrderedQueueTag;
@@ -3519,20 +3541,20 @@
*/
CCB->Status = BusLogic_CCB_Active;
HostAdapter->ActiveCommands[TargetID]++;
- TargetDeviceStatistics[TargetID].CommandsAttempted++;
+ TargetStatistics[TargetID].CommandsAttempted++;
FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
/*
The Command may have already completed and BusLogic_QueueCompletedCCB
been called, or it may still be pending.
*/
if (CCB->Status == BusLogic_CCB_Completed)
- BusLogic_ProcessCompletedCCBs();
+ BusLogic_ProcessCompletedCCBs(HostAdapter);
}
/*
Release exclusive access to Host Adapter.
*/
Done:
- BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
return 0;
}
@@ -3546,15 +3568,15 @@
BusLogic_HostAdapter_T *HostAdapter =
(BusLogic_HostAdapter_T *) Command->host->hostdata;
int TargetID = Command->target;
- BusLogic_Lock_T Lock;
+ ProcessorFlags_T ProcessorFlags;
BusLogic_CCB_T *CCB;
int Result;
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[TargetID].CommandAbortsRequested);
+ &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
/*
Acquire exclusive access to Host Adapter.
*/
- BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
/*
If this Command has already completed, then no Abort is necessary.
*/
@@ -3604,7 +3626,7 @@
Firmware version 5.xx does generate Abort Tag messages, so it is
possible to abort commands when Tagged Queuing is active.
*/
- if (HostAdapter->TaggedQueuingActive[TargetID] &&
+ if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
HostAdapter->FirmwareVersion[0] < '5')
{
BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
@@ -3618,8 +3640,7 @@
BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
HostAdapter, CCB->SerialNumber, TargetID);
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[TargetID]
- .CommandAbortsAttempted);
+ &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
Result = SCSI_ABORT_PENDING;
}
else
@@ -3638,7 +3659,7 @@
BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
HostAdapter, CCB->SerialNumber, TargetID);
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[TargetID].CommandAbortsAttempted);
+ &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
/*
The Abort may have already been completed and
@@ -3648,7 +3669,7 @@
Result = SCSI_ABORT_PENDING;
if (CCB->Status == BusLogic_CCB_Completed)
{
- BusLogic_ProcessCompletedCCBs();
+ BusLogic_ProcessCompletedCCBs(HostAdapter);
Result = SCSI_ABORT_SUCCESS;
}
}
@@ -3656,7 +3677,7 @@
Release exclusive access to Host Adapter.
*/
Done:
- BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
return Result;
}
@@ -3670,18 +3691,31 @@
SCSI_Command_T *Command,
unsigned int ResetFlags)
{
- BusLogic_Lock_T Lock;
+ ProcessorFlags_T ProcessorFlags;
BusLogic_CCB_T *CCB;
int TargetID, Result;
- if (Command == NULL)
- BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
- else BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[Command->target]
- .HostAdapterResetsRequested);
+ boolean HardReset;
+ if (HostAdapter->HostAdapterExternalReset)
+ {
+ BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
+ HardReset = false;
+ }
+ else if (HostAdapter->HostAdapterInternalError)
+ {
+ BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
+ HardReset = true;
+ }
+ else
+ {
+ BusLogic_IncrementErrorCounter(
+ &HostAdapter->TargetStatistics[Command->target]
+ .HostAdapterResetsRequested);
+ HardReset = true;
+ }
/*
Acquire exclusive access to Host Adapter.
*/
- BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
/*
If this is an Asynchronous Reset and this Command has already completed,
then no Reset is necessary.
@@ -3723,20 +3757,25 @@
}
}
if (Command == NULL)
- BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
- HostAdapter, HostAdapter->FullModelName);
+ {
+ if (HostAdapter->HostAdapterInternalError)
+ BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
+ HostAdapter, HostAdapter->FullModelName);
+ else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
+ HostAdapter, HostAdapter->FullModelName);
+ }
else
{
BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
HostAdapter->FullModelName, Command->target);
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[Command->target]
+ &HostAdapter->TargetStatistics[Command->target]
.HostAdapterResetsAttempted);
}
/*
Attempt to Reset and Reinitialize the Host Adapter.
*/
- if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
+ if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
BusLogic_InitializeHostAdapter(HostAdapter)))
{
BusLogic_Error("Resetting %s Failed\n", HostAdapter,
@@ -3746,7 +3785,7 @@
}
if (Command != NULL)
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[Command->target]
+ &HostAdapter->TargetStatistics[Command->target]
.HostAdapterResetsCompleted);
/*
Mark all currently executing CCBs as having been Reset.
@@ -3761,7 +3800,8 @@
Note that a timer interrupt may occur here, but all active CCBs have
already been marked Reset and so a reentrant call will return Pending.
*/
- BusLogic_Delay(HostAdapter->BusSettleTime);
+ if (HardReset)
+ BusLogic_Delay(HostAdapter->BusSettleTime);
/*
If this is a Synchronous Reset, perform completion processing for
the Command being Reset.
@@ -3798,7 +3838,7 @@
Release exclusive access to Host Adapter.
*/
Done:
- BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
return Result;
}
@@ -3814,14 +3854,14 @@
{
int TargetID = Command->target;
BusLogic_CCB_T *CCB, *XCCB;
- BusLogic_Lock_T Lock;
+ ProcessorFlags_T ProcessorFlags;
int Result = -1;
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[TargetID].BusDeviceResetsRequested);
+ &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
/*
Acquire exclusive access to Host Adapter.
*/
- BusLogic_AcquireHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
/*
If this is an Asynchronous Reset and this Command has already completed,
then no Reset is necessary.
@@ -3891,7 +3931,7 @@
while there are tagged commands outstanding. Therefore, in that case a
full Host Adapter Hard Reset and SCSI Bus Reset must be done.
*/
- if (HostAdapter->TaggedQueuingActive[TargetID] &&
+ if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
HostAdapter->ActiveCommands[TargetID] > 0 &&
HostAdapter->FirmwareVersion[0] < '5')
goto Done;
@@ -3958,7 +3998,7 @@
processing performed.
*/
BusLogic_IncrementErrorCounter(
- &HostAdapter->TargetDeviceStatistics[TargetID].BusDeviceResetsAttempted);
+ &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
HostAdapter->LastResetAttempted[TargetID] = jiffies;
for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
@@ -3973,7 +4013,7 @@
if (BusLogic_FlashPointHostAdapterP(HostAdapter))
if (CCB->Status == BusLogic_CCB_Completed)
{
- BusLogic_ProcessCompletedCCBs();
+ BusLogic_ProcessCompletedCCBs(HostAdapter);
Result = SCSI_RESET_SUCCESS;
}
/*
@@ -3986,7 +4026,7 @@
/*
Release exclusive access to Host Adapter.
*/
- BusLogic_ReleaseHostAdapterLock(HostAdapter, &Lock);
+ BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
return Result;
}
@@ -4007,11 +4047,11 @@
it has been less than 10 minutes since the last reset occurred, or since
the system was initialized if no prior resets have occurred.
*/
- if (HostAdapter->TaggedQueuingActive[TargetID] &&
+ if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
{
HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
- HostAdapter->TaggedQueuingActive[TargetID] = false;
+ HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
BusLogic_Warning("Tagged Queuing now disabled for Target %d\n",
HostAdapter, TargetID);
}
@@ -4032,10 +4072,10 @@
forcing a Hard Reset before the Bus Device Reset has had a chance to
clear the error condition.
*/
- if (HostAdapter->CommandSuccessfulFlag[TargetID] ||
+ if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
{
- HostAdapter->CommandSuccessfulFlag[TargetID] = false;
+ HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
}
/* Fall through to Hard Reset case. */
@@ -4076,16 +4116,18 @@
struct buffer_head *BufferHead;
if (HostAdapter->ExtendedTranslationEnabled &&
Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
- if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
- {
- DiskParameters->Heads = 255;
- DiskParameters->Sectors = 63;
- }
- else
- {
- DiskParameters->Heads = 128;
- DiskParameters->Sectors = 32;
- }
+ {
+ if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
+ {
+ DiskParameters->Heads = 255;
+ DiskParameters->Sectors = 63;
+ }
+ else
+ {
+ DiskParameters->Heads = 128;
+ DiskParameters->Sectors = 32;
+ }
+ }
else
{
DiskParameters->Heads = 64;
@@ -4105,24 +4147,28 @@
*/
if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
{
- struct partition *PartitionEntry =
- (struct partition *) (BufferHead->b_data + 0x1BE);
+ PartitionTable_T *FirstPartitionEntry =
+ (PartitionTable_T *) (BufferHead->b_data + 0x1BE);
+ PartitionTable_T *PartitionEntry = FirstPartitionEntry;
int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
+ unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
{
- if (PartitionEntry->end_head == 64-1)
+ PartitionEntryEndHead = PartitionEntry->end_head;
+ PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
+ if (PartitionEntryEndHead == 64-1)
{
DiskParameters->Heads = 64;
DiskParameters->Sectors = 32;
break;
}
- else if (PartitionEntry->end_head == 128-1)
+ else if (PartitionEntryEndHead == 128-1)
{
DiskParameters->Heads = 128;
DiskParameters->Sectors = 32;
break;
}
- else if (PartitionEntry->end_head == 255-1)
+ else if (PartitionEntryEndHead == 255-1)
{
DiskParameters->Heads = 255;
DiskParameters->Sectors = 63;
@@ -4130,14 +4176,29 @@
}
PartitionEntry++;
}
+ if (PartitionNumber == 4)
+ {
+ PartitionEntryEndHead = FirstPartitionEntry->end_head;
+ PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
+ }
DiskParameters->Cylinders =
Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
- if (SavedCylinders != DiskParameters->Cylinders)
+ if (PartitionNumber < 4 &&
+ PartitionEntryEndSector == DiskParameters->Sectors)
{
- BusLogic_Warning("Warning: Extended Translation Setting "
- "(> 1GB Switch) does not match\n", HostAdapter);
- BusLogic_Warning("Partition Table - Adopting %d/%d Geometry "
- "from Partition Table\n", HostAdapter,
+ if (DiskParameters->Cylinders != SavedCylinders)
+ BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
+ HostAdapter,
+ DiskParameters->Heads, DiskParameters->Sectors);
+ }
+ else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
+ {
+ BusLogic_Warning("Warning: Partition Table appears to "
+ "have Geometry %d/%d which is\n", HostAdapter,
+ PartitionEntryEndHead + 1,
+ PartitionEntryEndSector);
+ BusLogic_Warning("not compatible with current BusLogic "
+ "Host Adapter Geometry %d/%d\n", HostAdapter,
DiskParameters->Heads, DiskParameters->Sectors);
}
}
@@ -4155,22 +4216,21 @@
int HostNumber, int WriteFlag)
{
BusLogic_HostAdapter_T *HostAdapter;
- BusLogic_TargetDeviceStatistics_T *TargetDeviceStatistics;
- int IRQ_Channel, TargetID, Length;
+ BusLogic_TargetStatistics_T *TargetStatistics;
+ int TargetID, Length;
char *Buffer;
if (WriteFlag) return 0;
- for (IRQ_Channel = 0; IRQ_Channel < NR_IRQS; IRQ_Channel++)
+ for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
+ HostAdapter != NULL;
+ HostAdapter = HostAdapter->Next)
+ if (HostAdapter->HostNumber == HostNumber) break;
+ if (HostAdapter == NULL)
{
- HostAdapter = BusLogic_RegisteredHostAdapters[IRQ_Channel];
- while (HostAdapter != NULL)
- {
- if (HostAdapter->HostNumber == HostNumber) break;
- HostAdapter = HostAdapter->Next;
- }
- if (HostAdapter != NULL) break;
+ BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
+ NULL, HostNumber);
+ return 0;
}
- if (HostAdapter == NULL) return -1;
- TargetDeviceStatistics = HostAdapter->TargetDeviceStatistics;
+ TargetStatistics = HostAdapter->TargetStatistics;
Buffer = HostAdapter->MessageBuffer;
Length = HostAdapter->MessageBufferLength;
Length += sprintf(&Buffer[Length], "\n\
@@ -4181,100 +4241,105 @@
Length += sprintf(&Buffer[Length], "\n\n\
DATA TRANSFER STATISTICS\n\
\n\
-Target Tagged Queuing Queue Depth Commands Attempted Commands Completed\n\
-====== ============== =========== ================== ==================\n");
+Target Tagged Queuing Queue Depth Active Attempted Completed\n\
+====== ============== =========== ====== ========= =========\n");
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0)
- {
- Length +=
- sprintf(&Buffer[Length], " %2d %s", TargetID,
- (HostAdapter->TaggedQueuingSupported[TargetID]
- ? (HostAdapter->TaggedQueuingActive[TargetID]
- ? " Active"
- : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
- ? " Permitted" : " Disabled"))
- : "Not Supported"));
- Length += sprintf(&Buffer[Length],
- " %3d %9u %9u\n",
- HostAdapter->QueueDepth[TargetID],
- TargetDeviceStatistics[TargetID].CommandsAttempted,
- TargetDeviceStatistics[TargetID].CommandsCompleted);
- }
+ {
+ BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
+ if (!TargetFlags->TargetExists) continue;
+ Length +=
+ sprintf(&Buffer[Length], " %2d %s", TargetID,
+ (TargetFlags->TaggedQueuingSupported
+ ? (TargetFlags->TaggedQueuingActive
+ ? " Active"
+ : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
+ ? " Permitted" : " Disabled"))
+ : "Not Supported"));
+ Length += sprintf(&Buffer[Length],
+ " %3d %3u %9u %9u\n",
+ HostAdapter->QueueDepth[TargetID],
+ HostAdapter->ActiveCommands[TargetID],
+ TargetStatistics[TargetID].CommandsAttempted,
+ TargetStatistics[TargetID].CommandsCompleted);
+ }
Length += sprintf(&Buffer[Length], "\n\
Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
====== ============= ============== =================== ===================\n");
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0)
- {
+ {
+ BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
+ if (!TargetFlags->TargetExists) continue;
+ Length +=
+ sprintf(&Buffer[Length], " %2d %9u %9u", TargetID,
+ TargetStatistics[TargetID].ReadCommands,
+ TargetStatistics[TargetID].WriteCommands);
+ if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
Length +=
- sprintf(&Buffer[Length], " %2d %9u %9u", TargetID,
- TargetDeviceStatistics[TargetID].ReadCommands,
- TargetDeviceStatistics[TargetID].WriteCommands);
- if (TargetDeviceStatistics[TargetID].TotalBytesRead.Billions > 0)
- Length +=
- sprintf(&Buffer[Length], " %9u%09u",
- TargetDeviceStatistics[TargetID].TotalBytesRead.Billions,
- TargetDeviceStatistics[TargetID].TotalBytesRead.Units);
- else
- Length +=
- sprintf(&Buffer[Length], " %9u",
- TargetDeviceStatistics[TargetID].TotalBytesRead.Units);
- if (TargetDeviceStatistics[TargetID].TotalBytesWritten.Billions > 0)
- Length +=
- sprintf(&Buffer[Length], " %9u%09u\n",
- TargetDeviceStatistics[TargetID].TotalBytesWritten.Billions,
- TargetDeviceStatistics[TargetID].TotalBytesWritten.Units);
- else
- Length +=
- sprintf(&Buffer[Length], " %9u\n",
- TargetDeviceStatistics[TargetID].TotalBytesWritten.Units);
- }
+ sprintf(&Buffer[Length], " %9u%09u",
+ TargetStatistics[TargetID].TotalBytesRead.Billions,
+ TargetStatistics[TargetID].TotalBytesRead.Units);
+ else
+ Length +=
+ sprintf(&Buffer[Length], " %9u",
+ TargetStatistics[TargetID].TotalBytesRead.Units);
+ if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
+ Length +=
+ sprintf(&Buffer[Length], " %9u%09u\n",
+ TargetStatistics[TargetID].TotalBytesWritten.Billions,
+ TargetStatistics[TargetID].TotalBytesWritten.Units);
+ else
+ Length +=
+ sprintf(&Buffer[Length], " %9u\n",
+ TargetStatistics[TargetID].TotalBytesWritten.Units);
+ }
Length += sprintf(&Buffer[Length], "\n\
Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
====== ======= ========= ========= ========= ========= =========\n");
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0)
- {
- Length +=
- sprintf(&Buffer[Length],
- " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[0],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[1],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[2],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[3],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[4]);
- Length +=
- sprintf(&Buffer[Length],
- " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[0],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[1],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[2],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[3],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[4]);
- }
+ {
+ BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
+ if (!TargetFlags->TargetExists) continue;
+ Length +=
+ sprintf(&Buffer[Length],
+ " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
+ Length +=
+ sprintf(&Buffer[Length],
+ " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
+ }
Length += sprintf(&Buffer[Length], "\n\
Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
====== ======= ========= ========= ========= ========= =========\n");
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0)
- {
- Length +=
- sprintf(&Buffer[Length],
- " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[5],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[6],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[7],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[8],
- TargetDeviceStatistics[TargetID].ReadCommandSizeBuckets[9]);
- Length +=
- sprintf(&Buffer[Length],
- " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[5],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[6],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[7],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[8],
- TargetDeviceStatistics[TargetID].WriteCommandSizeBuckets[9]);
- }
+ {
+ BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
+ if (!TargetFlags->TargetExists) continue;
+ Length +=
+ sprintf(&Buffer[Length],
+ " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
+ TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
+ Length +=
+ sprintf(&Buffer[Length],
+ " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
+ TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
+ }
Length += sprintf(&Buffer[Length], "\n\n\
ERROR RECOVERY STATISTICS\n\
\n\
@@ -4283,21 +4348,26 @@
ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
- if (TargetDeviceStatistics[TargetID].CommandsCompleted > 0)
+ {
+ BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
+ if (!TargetFlags->TargetExists) continue;
Length +=
sprintf(&Buffer[Length], "\
%2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID,
- TargetDeviceStatistics[TargetID].CommandAbortsRequested,
- TargetDeviceStatistics[TargetID].CommandAbortsAttempted,
- TargetDeviceStatistics[TargetID].CommandAbortsCompleted,
- TargetDeviceStatistics[TargetID].BusDeviceResetsRequested,
- TargetDeviceStatistics[TargetID].BusDeviceResetsAttempted,
- TargetDeviceStatistics[TargetID].BusDeviceResetsCompleted,
- TargetDeviceStatistics[TargetID].HostAdapterResetsRequested,
- TargetDeviceStatistics[TargetID].HostAdapterResetsAttempted,
- TargetDeviceStatistics[TargetID].HostAdapterResetsCompleted);
+ TargetStatistics[TargetID].CommandAbortsRequested,
+ TargetStatistics[TargetID].CommandAbortsAttempted,
+ TargetStatistics[TargetID].CommandAbortsCompleted,
+ TargetStatistics[TargetID].BusDeviceResetsRequested,
+ TargetStatistics[TargetID].BusDeviceResetsAttempted,
+ TargetStatistics[TargetID].BusDeviceResetsCompleted,
+ TargetStatistics[TargetID].HostAdapterResetsRequested,
+ TargetStatistics[TargetID].HostAdapterResetsAttempted,
+ TargetStatistics[TargetID].HostAdapterResetsCompleted);
+ }
Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
HostAdapter->ExternalHostAdapterResets);
+ Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
+ HostAdapter->HostAdapterInternalErrors);
if (Length >= BusLogic_MessageBufferSize)
BusLogic_Error("Message Buffer length %d exceeds size %d\n",
HostAdapter, Length, BusLogic_MessageBufferSize);
@@ -4339,17 +4409,22 @@
Buffer);
HostAdapter->MessageBufferLength += Length;
if (BeginningOfLine)
- printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
- HostAdapter->HostNumber, Buffer);
+ {
+ if (Buffer[0] != '\n' || Length > 1)
+ printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
+ HostAdapter->HostNumber, Buffer);
+ }
else printk("%s", Buffer);
}
else
{
if (BeginningOfLine)
- if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
- printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
- HostAdapter->HostNumber, Buffer);
- else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
+ {
+ if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
+ printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
+ HostAdapter->HostNumber, Buffer);
+ else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
+ }
else printk("%s", Buffer);
}
BeginningOfLine = (Buffer[Length-1] == '\n');
@@ -4357,364 +4432,553 @@
/*
- BusLogic_Setup handles processing of Kernel Command Line Arguments.
+ BusLogic_ParseKeyword parses an individual option keyword. It returns true
+ and updates the pointer if the keyword is recognized and false otherwise.
+*/
- For the BusLogic driver, a Kernel Command Line Entry comprises the driver
- identifier "BusLogic=" optionally followed by a comma-separated sequence of
- integers and then optionally followed by a comma-separated sequence of
- strings. Each command line entry applies to one BusLogic Host Adapter.
- Multiple command line entries may be used in systems which contain multiple
- BusLogic Host Adapters.
+static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
+{
+ char *Pointer = *StringPointer;
+ while (*Keyword != '\0')
+ {
+ char StringChar = *Pointer++;
+ char KeywordChar = *Keyword++;
+ if (StringChar >= 'A' && StringChar <= 'Z')
+ StringChar += 'a' - 'Z';
+ if (KeywordChar >= 'A' && KeywordChar <= 'Z')
+ KeywordChar += 'a' - 'Z';
+ if (StringChar != KeywordChar) return false;
+ }
+ *StringPointer = Pointer;
+ return true;
+}
- The first integer specified is the I/O Address at which the Host Adapter is
- located. If unspecified, it defaults to 0 which means to apply this entry to
- the first BusLogic Host Adapter found during the default probe sequence. If
- any I/O Address parameters are provided on the command line, then the default
- probe sequence is omitted.
-
- The second integer specified is the Tagged Queue Depth to use for Target
- Devices that support Tagged Queuing. The Queue Depth is the number of SCSI
- commands that are allowed to be concurrently presented for execution. If
- unspecified, it defaults to 0 which means to use a value determined
- automatically based on the Host Adapter's Total Queue Depth and the number,
- type, speed, and capabilities of the detected Target Devices. For Host
- Adapters that require ISA Bounce Buffers, the Tagged Queue Depth is
- automatically set to BusLogic_TaggedQueueDepthBounceBuffers to avoid
- excessive preallocation of DMA Bounce Buffer memory. Target Devices that do
- not support Tagged Queuing use a Queue Depth of BusLogic_UntaggedQueueDepth.
-
- The third integer specified is the Bus Settle Time in seconds. This is
- the amount of time to wait between a Host Adapter Hard Reset which initiates
- a SCSI Bus Reset and issuing any SCSI Commands. If unspecified, it defaults
- to 0 which means to use the value of BusLogic_DefaultBusSettleTime.
-
- The fourth integer specified is the Local Options. If unspecified, it
- defaults to 0. Note that Local Options are only applied to a specific Host
- Adapter.
- The fifth integer specified is the Global Options. If unspecified, it
- defaults to 0. Note that Global Options are applied across all Host
- Adapters.
+/*
+ BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
+ specifications.
- The string options are used to provide control over Tagged Queuing, Error
- Recovery, and Host Adapter Probing.
+ BusLogic Driver Options may be specified either via the Linux Kernel Command
+ Line or via the Loadable Kernel Module Installation Facility. Driver Options
+ for multiple host adapters may be specified either by separating the option
+ strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
+ command line. Individual option specifications for a single host adapter are
+ separated by commas. The Probing and Debugging Options apply to all host
+ adapters whereas the remaining options apply individually only to the
+ selected host adapter.
- The Tagged Queuing specification begins with "TQ:" and allows for explicitly
- specifying whether Tagged Queuing is permitted on Target Devices that support
- it. The following specification options are available:
-
- TQ:Default Tagged Queuing will be permitted based on the firmware
- version of the BusLogic Host Adapter and based on
- whether the Tagged Queue Depth value allows queuing
- multiple commands.
-
- TQ:Enable Tagged Queuing will be enabled for all Target Devices
- on this Host Adapter overriding any limitation that
- would otherwise be imposed based on the Host Adapter
- firmware version.
-
- TQ:Disable Tagged Queuing will be disabled for all Target Devices
- on this Host Adapter.
-
- TQ:<Per-Target-Spec> Tagged Queuing will be controlled individually for each
- Target Device. <Per-Target-Spec> is a sequence of "Y",
- "N", and "X" characters. "Y" enabled Tagged Queuing,
- "N" disables Tagged Queuing, and "X" accepts the
- default based on the firmware version. The first
- character refers to Target Device 0, the second to
- Target Device 1, and so on; if the sequence of "Y",
- "N", and "X" characters does not cover all the Target
- Devices, unspecified characters are assumed to be "X".
-
- Note that explicitly requesting Tagged Queuing may lead to problems; this
- facility is provided primarily to allow disabling Tagged Queuing on Target
- Devices that do not implement it correctly.
-
- The Error Recovery Strategy specification begins with "ER:" and allows for
- explicitly specifying the Error Recovery action to be performed when
- ResetCommand is called due to a SCSI Command failing to complete
- successfully. The following specification options are available:
-
- ER:Default Error Recovery will select between the Hard Reset and
- Bus Device Reset options based on the recommendation
- of the SCSI Subsystem.
-
- ER:HardReset Error Recovery will initiate a Host Adapter Hard Reset
- which also causes a SCSI Bus Reset.
-
- ER:BusDeviceReset Error Recovery will send a Bus Device Reset message to
- the individual Target Device causing the error. If
- Error Recovery is again initiated for this Target
- Device and no SCSI Command to this Target Device has
- completed successfully since the Bus Device Reset
- message was sent, then a Hard Reset will be attempted.
-
- ER:None Error Recovery will be suppressed. This option should
- only be selected if a SCSI Bus Reset or Bus Device
- Reset will cause the Target Device to fail completely
- and unrecoverably.
-
- ER:<Per-Target-Spec> Error Recovery will be controlled individually for each
- Target Device. <Per-Target-Spec> is a sequence of "D",
- "H", "B", and "N" characters. "D" selects Default, "H"
- selects Hard Reset, "B" selects Bus Device Reset, and
- "N" selects None. The first character refers to Target
- Device 0, the second to Target Device 1, and so on; if
- the sequence of "D", "H", "B", and "N" characters does
- not cover all the possible Target Devices, unspecified
- characters are assumed to be "D".
-
- The Host Adapter Probing specification comprises the following strings:
-
- NoProbe No probing of any kind is to be performed, and hence
- no BusLogic Host Adapters will be detected.
-
- NoProbeISA No probing of the standard ISA I/O Addresses will
- be done, and hence only PCI MultiMaster and FlashPoint
- Host Adapters will be detected.
-
- NoProbePCI No interrogation of PCI Configuration Space will be
- made, and hence only ISA Multimaster Host Adapters
- will be detected, as well as PCI Multimaster Host
- Adapters that have their ISA Compatible I/O Port
- set to "Primary" or "Alternate".
-
- NoSortPCI PCI MultiMaster Host Adapters will be enumerated in
- the order provided by the PCI BIOS, ignoring any
- setting of the AutoSCSI "Use Bus And Device # For PCI
- Scanning Seq." option.
-
- MultiMasterFirst 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. This option forces MultiMaster Host
- Adapters to be probed first.
-
- FlashPointFirst 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. This option forces FlashPoint Host
- Adapters to be probed first.
-
- Debug Sets all the tracing bits in BusLogic_GlobalOptions.
-
-*/
-
-void BusLogic_Setup(char *Strings, int *Integers)
-{
- BusLogic_CommandLineEntry_T *CommandLineEntry =
- &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
- int IntegerCount = Integers[0];
- int TargetID, i;
- CommandLineEntry->IO_Address = 0;
- CommandLineEntry->TaggedQueueDepth = 0;
- CommandLineEntry->BusSettleTime = 0;
- CommandLineEntry->TaggedQueuingPermitted = 0;
- CommandLineEntry->TaggedQueuingPermittedMask = 0;
- CommandLineEntry->LocalOptions.All = 0;
- memset(CommandLineEntry->ErrorRecoveryStrategy,
- BusLogic_ErrorRecovery_Default,
- sizeof(CommandLineEntry->ErrorRecoveryStrategy));
- if (IntegerCount > 5)
- BusLogic_Error("BusLogic: Unexpected Command Line Integers "
- "ignored\n", NULL);
- if (IntegerCount >= 1)
- {
- BusLogic_IO_Address_T IO_Address = Integers[1];
- if (IO_Address > 0)
- {
- BusLogic_ProbeInfo_T *ProbeInfo;
- for (i = 0; ; i++)
- if (BusLogic_ISA_StandardAddresses[i] == 0)
- {
- BusLogic_Error("BusLogic: Invalid Command Line Entry "
- "(illegal I/O Address 0x%X)\n",
- NULL, IO_Address);
- return;
- }
- else if (i < BusLogic_ProbeInfoCount &&
- IO_Address == BusLogic_ProbeInfoList[i].IO_Address)
- {
- BusLogic_Error("BusLogic: Invalid Command Line Entry "
- "(duplicate I/O Address 0x%X)\n",
- NULL, IO_Address);
- return;
- }
- else if (IO_Address >= 0x400 ||
- IO_Address == BusLogic_ISA_StandardAddresses[i]) break;
- ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
- ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
- ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
- }
- CommandLineEntry->IO_Address = IO_Address;
- }
- if (IntegerCount >= 2)
- {
- unsigned short TaggedQueueDepth = Integers[2];
- if (TaggedQueueDepth > BusLogic_MaxTaggedQueueDepth)
- {
- BusLogic_Error("BusLogic: Invalid Command Line Entry "
- "(illegal Tagged Queue Depth %d)\n",
- NULL, TaggedQueueDepth);
+ The BusLogic Driver Probing Options comprise the following:
+
+ IO:<integer>
+
+ The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
+ MultiMaster Host Adapter. If neither "IO:" nor "NoProbeISA" options are
+ specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
+ will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134). Multiple
+ "IO:" options may be specified to precisely determine the I/O Addresses to
+ be probed, but the probe order will always follow the standard list.
+
+ NoProbe
+
+ The "NoProbe" option disables all probing and therefore no BusLogic Host
+ Adapters will be detected.
+
+ NoProbeISA
+
+ The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
+ Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
+ will be detected.
+
+ NoProbePCI
+
+ The "NoProbePCI" options disables the interrogation of PCI Configuration
+ Space and therefore only ISA Multimaster Host Adapters will be detected, as
+ well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
+ Port set to "Primary" or "Alternate".
+
+ NoSortPCI
+
+ The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
+ enumerated in the order provided by the PCI BIOS, ignoring any setting of
+ the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
+
+ MultiMasterFirst
+
+ The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
+ before FlashPoint Host Adapters. 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.
+
+ FlashPointFirst
+
+ The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
+ before MultiMaster Host Adapters.
+
+ The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
+ the Queue Depth and whether Tagged Queuing is permitted for each Target
+ Device (assuming that the Target Device supports Tagged Queuing). The Queue
+ Depth is the number of SCSI Commands that are allowed to be concurrently
+ presented for execution (either to the Host Adapter or Target Device). Note
+ that explicitly enabling Tagged Queuing may lead to problems; the option to
+ enable or disable Tagged Queuing is provided primarily to allow disabling
+ Tagged Queuing on Target Devices that do not implement it correctly. The
+ following options are available:
+
+ QueueDepth:<integer>
+
+ The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
+ Target Devices that support Tagged Queuing, as well as the maximum Queue
+ Depth for devices that do not support Tagged Queuing. If no Queue Depth
+ option is provided, the Queue Depth will be determined automatically based
+ on the Host Adapter's Total Queue Depth and the number, type, speed, and
+ capabilities of the detected Target Devices. For Host Adapters that
+ require ISA Bounce Buffers, the Queue Depth is automatically set by default
+ to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
+ excessive preallocation of DMA Bounce Buffer memory. Target Devices that
+ do not support Tagged Queuing always have their Queue Depth set to
+ BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
+ lower Queue Depth option is provided. A Queue Depth of 1 automatically
+ disables Tagged Queuing.
+
+ QueueDepth:[<integer>,<integer>...]
+
+ The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
+ individually for each Target Device. If an <integer> is omitted, the
+ associated Target Device will have its Queue Depth selected automatically.
+
+ TaggedQueuing:Default
+
+ The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
+ based on the firmware version of the BusLogic Host Adapter and based on
+ whether the Queue Depth allows queuing multiple commands.
+
+ TaggedQueuing:Enable
+
+ The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
+ all Target Devices on this Host Adapter, overriding any limitation that
+ would otherwise be imposed based on the Host Adapter firmware version.
+
+ TaggedQueuing:Disable
+
+ The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
+ for all Target Devices on this Host Adapter.
+
+ TaggedQueuing:<Target-Spec>
+
+ The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
+ Tagged Queuing individually for each Target Device. <Target-Spec> is a
+ sequence of "Y", "N", and "X" characters. "Y" enables Tagged Queuing, "N"
+ disables Tagged Queuing, and "X" accepts the default based on the firmware
+ version. The first character refers to Target Device 0, the second to
+ Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
+ does not cover all the Target Devices, unspecified characters are assumed
+ to be "X".
+
+ The BusLogic Driver Error Recovery Option allows for explicitly specifying
+ the Error Recovery action to be performed when BusLogic_ResetCommand is
+ called due to a SCSI Command failing to complete successfully. The following
+ options are available:
+
+ ErrorRecovery:Default
+
+ The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
+ Reset and Bus Device Reset options based on the recommendation of the SCSI
+ Subsystem.
+
+ ErrorRecovery:HardReset
+
+ The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
+ Adapter Hard Reset which also causes a SCSI Bus Reset.
+
+ ErrorRecovery:BusDeviceReset
+
+ The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
+ a Bus Device Reset message to the individual Target Device causing the
+ error. If Error Recovery is again initiated for this Target Device and no
+ SCSI Command to this Target Device has completed successfully since the Bus
+ Device Reset message was sent, then a Hard Reset will be attempted.
+
+ ErrorRecovery:None
+
+ The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
+ This option should only be selected if a SCSI Bus Reset or Bus Device Reset
+ will cause the Target Device or a critical operation to suffer a complete
+ and unrecoverable failure.
+
+ ErrorRecovery:<Target-Spec>
+
+ The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
+ Error Recovery individually for each Target Device. <Target-Spec> is a
+ sequence of "D", "H", "B", and "N" characters. "D" selects Default, "H"
+ selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
+ The first character refers to Target Device 0, the second to Target Device
+ 1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
+ cover all the possible Target Devices, unspecified characters are assumed
+ to be "D".
+
+ The BusLogic Driver Miscellaneous Options comprise the following:
+
+ BusSettleTime:<seconds>
+
+ The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
+ seconds. The Bus Settle Time is the amount of time to wait between a Host
+ Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
+ Commands. If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
+
+ InhibitTargetInquiry
+
+ The "InhibitTargetInquiry" option inhibits the execution of an Inquire
+ Target Devices or Inquire Installed Devices command on MultiMaster Host
+ Adapters. This may be necessary with some older Target Devices that do not
+ respond correctly when Logical Units above 0 are addressed.
+
+ The BusLogic Driver Debugging Options comprise the following:
+
+ TraceProbe
+
+ The "TraceProbe" option enables tracing of Host Adapter Probing.
+
+ TraceHardwareReset
+
+ The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
+ Reset.
+
+ TraceConfiguration
+
+ The "TraceConfiguration" option enables tracing of Host Adapter
+ Configuration.
+
+ TraceErrors
+
+ The "TraceErrors" option enables tracing of SCSI Commands that return an
+ error from the Target Device. The CDB and Sense Data will be printed for
+ each SCSI Command that fails.
+
+ Debug
+
+ The "Debug" option enables all debugging options.
+
+ The following examples demonstrate setting the Queue Depth for Target Devices
+ 1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
+ Devices on the second host adapter to 31, and the Bus Settle Time on the
+ second host adapter to 30 seconds.
+
+ Linux Kernel Command Line:
+
+ linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
+
+ LILO Linux Boot Loader (in /etc/lilo.conf):
+
+ append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
+
+ INSMOD Loadable Kernel Module Installation Facility:
+
+ insmod BusLogic.o \
+ 'BusLogic_Options="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
+
+ NOTE: Module Utilities 2.1.71 or later is required for correct parsing
+ of driver options containing commas.
+
+*/
+
+static void BusLogic_ParseDriverOptions(char *OptionsString)
+{
+ while (true)
+ {
+ BusLogic_DriverOptions_T *DriverOptions =
+ &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
+ int TargetID;
+ memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
+ for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_Default;
+ while (*OptionsString != '\0' && *OptionsString != ';')
+ {
+ /* Probing Options. */
+ if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
+ {
+ BusLogic_IO_Address_T IO_Address =
+ simple_strtoul(OptionsString, &OptionsString, 0);
+ BusLogic_ProbeOptions.LimitedProbeISA = true;
+ switch (IO_Address)
+ {
+ case 0x330:
+ BusLogic_ProbeOptions.Probe330 = true;
+ break;
+ case 0x334:
+ BusLogic_ProbeOptions.Probe334 = true;
+ break;
+ case 0x230:
+ BusLogic_ProbeOptions.Probe230 = true;
+ break;
+ case 0x234:
+ BusLogic_ProbeOptions.Probe234 = true;
+ break;
+ case 0x130:
+ BusLogic_ProbeOptions.Probe130 = true;
+ break;
+ case 0x134:
+ BusLogic_ProbeOptions.Probe134 = true;
+ break;
+ default:
+ BusLogic_Error("BusLogic: Invalid Driver Options "
+ "(illegal I/O Address 0x%X)\n",
+ NULL, IO_Address);
+ return;
+ }
+ }
+ else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
+ BusLogic_ProbeOptions.NoProbeISA = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
+ BusLogic_ProbeOptions.NoProbePCI = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
+ BusLogic_ProbeOptions.NoProbe = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
+ BusLogic_ProbeOptions.NoSortPCI = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
+ BusLogic_ProbeOptions.MultiMasterFirst = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
+ BusLogic_ProbeOptions.FlashPointFirst = true;
+ /* Tagged Queuing Options. */
+ else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
+ BusLogic_ParseKeyword(&OptionsString, "QD:["))
+ {
+ for (TargetID = 0;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++)
+ {
+ unsigned short QueueDepth =
+ simple_strtoul(OptionsString, &OptionsString, 0);
+ if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
+ {
+ BusLogic_Error("BusLogic: Invalid Driver Options "
+ "(illegal Queue Depth %d)\n",
+ NULL, QueueDepth);
+ return;
+ }
+ DriverOptions->QueueDepth[TargetID] = QueueDepth;
+ if (*OptionsString == ',')
+ OptionsString++;
+ else if (*OptionsString == ']')
+ break;
+ else
+ {
+ BusLogic_Error("BusLogic: Invalid Driver Options "
+ "(',' or ']' expected at '%s')\n",
+ NULL, OptionsString);
+ return;
+ }
+ }
+ if (*OptionsString != ']')
+ {
+ BusLogic_Error("BusLogic: Invalid Driver Options "
+ "(']' expected at '%s')\n",
+ NULL, OptionsString);
+ return;
+ }
+ else OptionsString++;
+ }
+ else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
+ BusLogic_ParseKeyword(&OptionsString, "QD:"))
+ {
+ unsigned short QueueDepth =
+ simple_strtoul(OptionsString, &OptionsString, 0);
+ if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
+ {
+ BusLogic_Error("BusLogic: Invalid Driver Options "
+ "(illegal Queue Depth %d)\n",
+ NULL, QueueDepth);
+ return;
+ }
+ DriverOptions->CommonQueueDepth = QueueDepth;
+ for (TargetID = 0;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++)
+ DriverOptions->QueueDepth[TargetID] = QueueDepth;
+ }
+ else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
+ BusLogic_ParseKeyword(&OptionsString, "TQ:"))
+ {
+ if (BusLogic_ParseKeyword(&OptionsString, "Default"))
+ {
+ DriverOptions->TaggedQueuingPermitted = 0x0000;
+ DriverOptions->TaggedQueuingPermittedMask = 0x0000;
+ }
+ else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
+ {
+ DriverOptions->TaggedQueuingPermitted = 0xFFFF;
+ DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
+ }
+ else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
+ {
+ DriverOptions->TaggedQueuingPermitted = 0x0000;
+ DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
+ }
+ else
+ {
+ unsigned short TargetBit;
+ for (TargetID = 0, TargetBit = 1;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++, TargetBit <<= 1)
+ switch (*OptionsString++)
+ {
+ case 'Y':
+ DriverOptions->TaggedQueuingPermitted |= TargetBit;
+ DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
+ break;
+ case 'N':
+ DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
+ DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
+ break;
+ case 'X':
+ break;
+ default:
+ OptionsString--;
+ TargetID = BusLogic_MaxTargetDevices;
+ break;
+ }
+ }
+ }
+ /* Error Recovery Option. */
+ else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
+ BusLogic_ParseKeyword(&OptionsString, "ER:"))
+ {
+ if (BusLogic_ParseKeyword(&OptionsString, "Default"))
+ for (TargetID = 0;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++)
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_Default;
+ else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
+ for (TargetID = 0;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++)
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_HardReset;
+ else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
+ for (TargetID = 0;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++)
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_BusDeviceReset;
+ else if (BusLogic_ParseKeyword(&OptionsString, "None"))
+ for (TargetID = 0;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++)
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_None;
+ else
+ for (TargetID = 0;
+ TargetID < BusLogic_MaxTargetDevices;
+ TargetID++)
+ switch (*OptionsString++)
+ {
+ case 'D':
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_Default;
+ break;
+ case 'H':
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_HardReset;
+ break;
+ case 'B':
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_BusDeviceReset;
+ break;
+ case 'N':
+ DriverOptions->ErrorRecoveryStrategy[TargetID] =
+ BusLogic_ErrorRecovery_None;
+ break;
+ default:
+ OptionsString--;
+ TargetID = BusLogic_MaxTargetDevices;
+ break;
+ }
+ }
+ /* Miscellaneous Options. */
+ else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
+ BusLogic_ParseKeyword(&OptionsString, "BST:"))
+ {
+ unsigned short BusSettleTime =
+ simple_strtoul(OptionsString, &OptionsString, 0);
+ if (BusSettleTime > 5 * 60)
+ {
+ BusLogic_Error("BusLogic: Invalid Driver Options "
+ "(illegal Bus Settle Time %d)\n",
+ NULL, BusSettleTime);
+ return;
+ }
+ DriverOptions->BusSettleTime = BusSettleTime;
+ }
+ else if (BusLogic_ParseKeyword(&OptionsString,
+ "InhibitTargetInquiry"))
+ DriverOptions->LocalOptions.InhibitTargetInquiry = true;
+ /* Debugging Options. */
+ else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
+ BusLogic_GlobalOptions.TraceProbe = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
+ BusLogic_GlobalOptions.TraceHardwareReset = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
+ BusLogic_GlobalOptions.TraceConfiguration = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
+ BusLogic_GlobalOptions.TraceErrors = true;
+ else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
+ {
+ BusLogic_GlobalOptions.TraceProbe = true;
+ BusLogic_GlobalOptions.TraceHardwareReset = true;
+ BusLogic_GlobalOptions.TraceConfiguration = true;
+ BusLogic_GlobalOptions.TraceErrors = true;
+ }
+ if (*OptionsString == ',')
+ OptionsString++;
+ else if (*OptionsString != ';' && *OptionsString != '\0')
+ {
+ BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
+ "ignored\n", NULL, OptionsString);
+ *OptionsString = '\0';
+ }
+ }
+ if (!(BusLogic_DriverOptionsCount == 0 ||
+ BusLogic_ProbeInfoCount == 0 ||
+ BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
+ {
+ BusLogic_Error("BusLogic: Invalid Driver Options "
+ "(all or no I/O Addresses must be specified)\n", NULL);
return;
}
- CommandLineEntry->TaggedQueueDepth = TaggedQueueDepth;
+ /*
+ Tagged Queuing is disabled when the Queue Depth is 1 since queuing
+ multiple commands is not possible.
+ */
+ for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
+ if (DriverOptions->QueueDepth[TargetID] == 1)
+ {
+ unsigned short TargetBit = 1 << TargetID;
+ DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
+ DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
+ }
+ if (*OptionsString == ';') OptionsString++;
+ if (*OptionsString == '\0') return;
}
- if (IntegerCount >= 3)
- CommandLineEntry->BusSettleTime = Integers[3];
- if (IntegerCount >= 4)
- CommandLineEntry->LocalOptions.All = Integers[4];
- if (IntegerCount >= 5)
- BusLogic_GlobalOptions.All |= Integers[5];
- if (!(BusLogic_CommandLineEntryCount == 0 ||
- BusLogic_ProbeInfoCount == 0 ||
- BusLogic_CommandLineEntryCount == BusLogic_ProbeInfoCount))
+}
+
+
+/*
+ BusLogic_Setup handles processing of Kernel Command Line Arguments.
+*/
+
+void BusLogic_Setup(char *CommandLineString, int *CommandLineIntegers)
+{
+ if (CommandLineIntegers[0] != 0)
{
- BusLogic_Error("BusLogic: Invalid Command Line Entry "
- "(all or no I/O Addresses must be specified)\n", NULL);
+ BusLogic_Error("BusLogic: Obsolete Command Line Entry "
+ "Format Ignored\n", NULL);
return;
}
- if (Strings == NULL) return;
- while (*Strings != '\0')
- if (strncmp(Strings, "TQ:", 3) == 0)
- {
- Strings += 3;
- if (strncmp(Strings, "Default", 7) == 0)
- Strings += 7;
- else if (strncmp(Strings, "Enable", 6) == 0)
- {
- Strings += 6;
- CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
- CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
- }
- else if (strncmp(Strings, "Disable", 7) == 0)
- {
- Strings += 7;
- CommandLineEntry->TaggedQueuingPermitted = 0x0000;
- CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
- }
- else
- for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
- switch (*Strings++)
- {
- case 'Y':
- CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
- CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
- break;
- case 'N':
- CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
- break;
- case 'X':
- break;
- default:
- Strings--;
- TargetID = BusLogic_MaxTargetDevices;
- break;
- }
- }
- else if (strncmp(Strings, "ER:", 3) == 0)
- {
- Strings += 3;
- if (strncmp(Strings, "Default", 7) == 0)
- Strings += 7;
- else if (strncmp(Strings, "HardReset", 9) == 0)
- {
- Strings += 9;
- memset(CommandLineEntry->ErrorRecoveryStrategy,
- BusLogic_ErrorRecovery_HardReset,
- sizeof(CommandLineEntry->ErrorRecoveryStrategy));
- }
- else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
- {
- Strings += 14;
- memset(CommandLineEntry->ErrorRecoveryStrategy,
- BusLogic_ErrorRecovery_BusDeviceReset,
- sizeof(CommandLineEntry->ErrorRecoveryStrategy));
- }
- else if (strncmp(Strings, "None", 4) == 0)
- {
- Strings += 4;
- memset(CommandLineEntry->ErrorRecoveryStrategy,
- BusLogic_ErrorRecovery_None,
- sizeof(CommandLineEntry->ErrorRecoveryStrategy));
- }
- else
- for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
- switch (*Strings++)
- {
- case 'D':
- CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
- BusLogic_ErrorRecovery_Default;
- break;
- case 'H':
- CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
- BusLogic_ErrorRecovery_HardReset;
- break;
- case 'B':
- CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
- BusLogic_ErrorRecovery_BusDeviceReset;
- break;
- case 'N':
- CommandLineEntry->ErrorRecoveryStrategy[TargetID] =
- BusLogic_ErrorRecovery_None;
- break;
- default:
- Strings--;
- TargetID = BusLogic_MaxTargetDevices;
- break;
- }
- }
- else if (strcmp(Strings, "NoProbe") == 0 ||
- strcmp(Strings, "noprobe") == 0)
- {
- Strings += 7;
- BusLogic_ProbeOptions.Bits.NoProbe = true;
- }
- else if (strncmp(Strings, "NoProbeISA", 10) == 0)
- {
- Strings += 10;
- BusLogic_ProbeOptions.Bits.NoProbeISA = true;
- }
- else if (strncmp(Strings, "NoProbePCI", 10) == 0)
- {
- Strings += 10;
- BusLogic_ProbeOptions.Bits.NoProbePCI = true;
- }
- else if (strncmp(Strings, "NoSortPCI", 9) == 0)
- {
- Strings += 9;
- BusLogic_ProbeOptions.Bits.NoSortPCI = true;
- }
- else if (strncmp(Strings, "MultiMasterFirst", 16) == 0)
- {
- Strings += 16;
- BusLogic_ProbeOptions.Bits.ProbeMultiMasterFirst = true;
- }
- else if (strncmp(Strings, "FlashPointFirst", 15) == 0)
- {
- Strings += 15;
- BusLogic_ProbeOptions.Bits.ProbeFlashPointFirst = true;
- }
- else if (strncmp(Strings, "Debug", 5) == 0)
- {
- Strings += 5;
- BusLogic_GlobalOptions.Bits.TraceProbe = true;
- BusLogic_GlobalOptions.Bits.TraceHardReset = true;
- BusLogic_GlobalOptions.Bits.TraceConfiguration = true;
- BusLogic_GlobalOptions.Bits.TraceErrors = true;
- }
- else if (*Strings == ',')
- Strings++;
- else
- {
- BusLogic_Error("BusLogic: Unexpected Command Line String '%s' "
- "ignored\n", NULL, Strings);
- break;
- }
+ if (CommandLineString == NULL || *CommandLineString == '\0') return;
+ BusLogic_ParseDriverOptions(CommandLineString);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov