X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2FBusLogic.c;h=06faeb228887e5be4c5a41d0cc50365be5f45b79;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=e4d60d1d1ade3de63d7a901eb3c8c828044f3b0b;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index e4d60d1d1..06faeb228 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -142,11 +142,8 @@ static char *BusLogic_CommandFailureReason; static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter) { - BusLogic_Announce("***** BusLogic SCSI Driver Version " - BusLogic_DriverVersion " of " - BusLogic_DriverDate " *****\n", HostAdapter); - BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff " - "\n", HostAdapter); + BusLogic_Announce("***** BusLogic SCSI Driver Version " BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n", HostAdapter); + BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff " "\n", HostAdapter); } @@ -157,9 +154,8 @@ static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter) static const char *BusLogic_DriverInfo(struct Scsi_Host *Host) { - struct BusLogic_HostAdapter *HostAdapter = - (struct BusLogic_HostAdapter *) Host->hostdata; - return HostAdapter->FullModelName; + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata; + return HostAdapter->FullModelName; } @@ -170,17 +166,14 @@ static const char *BusLogic_DriverInfo(struct Scsi_Host *Host) static void __init BusLogic_RegisterHostAdapter(struct BusLogic_HostAdapter *HostAdapter) { - HostAdapter->Next = NULL; - if (BusLogic_FirstRegisteredHostAdapter == NULL) - { - BusLogic_FirstRegisteredHostAdapter = HostAdapter; - BusLogic_LastRegisteredHostAdapter = HostAdapter; - } - else - { - BusLogic_LastRegisteredHostAdapter->Next = HostAdapter; - BusLogic_LastRegisteredHostAdapter = HostAdapter; - } + HostAdapter->Next = NULL; + if (BusLogic_FirstRegisteredHostAdapter == NULL) { + BusLogic_FirstRegisteredHostAdapter = HostAdapter; + BusLogic_LastRegisteredHostAdapter = HostAdapter; + } else { + BusLogic_LastRegisteredHostAdapter->Next = HostAdapter; + BusLogic_LastRegisteredHostAdapter = HostAdapter; + } } @@ -191,24 +184,18 @@ static void __init BusLogic_RegisterHostAdapter(struct BusLogic_HostAdapter *Hos static void BusLogic_UnregisterHostAdapter(struct BusLogic_HostAdapter *HostAdapter) { - if (HostAdapter == BusLogic_FirstRegisteredHostAdapter) - { - BusLogic_FirstRegisteredHostAdapter = - BusLogic_FirstRegisteredHostAdapter->Next; - if (HostAdapter == BusLogic_LastRegisteredHostAdapter) - BusLogic_LastRegisteredHostAdapter = NULL; - } - else - { - struct BusLogic_HostAdapter *PreviousHostAdapter = - BusLogic_FirstRegisteredHostAdapter; - while (PreviousHostAdapter != NULL && - PreviousHostAdapter->Next != HostAdapter) - PreviousHostAdapter = PreviousHostAdapter->Next; - if (PreviousHostAdapter != NULL) - PreviousHostAdapter->Next = HostAdapter->Next; - } - HostAdapter->Next = NULL; + if (HostAdapter == BusLogic_FirstRegisteredHostAdapter) { + BusLogic_FirstRegisteredHostAdapter = BusLogic_FirstRegisteredHostAdapter->Next; + if (HostAdapter == BusLogic_LastRegisteredHostAdapter) + BusLogic_LastRegisteredHostAdapter = NULL; + } else { + struct BusLogic_HostAdapter *PreviousHostAdapter = BusLogic_FirstRegisteredHostAdapter; + while (PreviousHostAdapter != NULL && PreviousHostAdapter->Next != HostAdapter) + PreviousHostAdapter = PreviousHostAdapter->Next; + if (PreviousHostAdapter != NULL) + PreviousHostAdapter->Next = HostAdapter->Next; + } + HostAdapter->Next = NULL; } @@ -218,33 +205,29 @@ static void BusLogic_UnregisterHostAdapter(struct BusLogic_HostAdapter *HostAdap created CCBs are added to Host Adapter's free list. */ -static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, - void *BlockPointer, int BlockSize, - dma_addr_t BlockPointerHandle) +static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, void *BlockPointer, int BlockSize, dma_addr_t BlockPointerHandle) { - struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer; - unsigned int offset = 0; - memset(BlockPointer, 0, BlockSize); - CCB->AllocationGroupHead = BlockPointerHandle; - CCB->AllocationGroupSize = BlockSize; - while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0) - { - CCB->Status = BusLogic_CCB_Free; - CCB->HostAdapter = HostAdapter; - CCB->DMA_Handle = (u32)BlockPointerHandle + offset; - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - { - CCB->CallbackFunction = BusLogic_QueueCompletedCCB; - CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress; + struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer; + unsigned int offset = 0; + memset(BlockPointer, 0, BlockSize); + CCB->AllocationGroupHead = BlockPointerHandle; + CCB->AllocationGroupSize = BlockSize; + while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0) { + CCB->Status = BusLogic_CCB_Free; + CCB->HostAdapter = HostAdapter; + CCB->DMA_Handle = (u32) BlockPointerHandle + offset; + 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++; + offset += sizeof(struct BusLogic_CCB); } - CCB->Next = HostAdapter->Free_CCBs; - CCB->NextAll = HostAdapter->All_CCBs; - HostAdapter->Free_CCBs = CCB; - HostAdapter->All_CCBs = CCB; - HostAdapter->AllocatedCCBs++; - CCB++; - offset += sizeof(struct BusLogic_CCB); - } } @@ -254,23 +237,18 @@ static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, static boolean __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter) { - int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); - void *BlockPointer; - dma_addr_t BlockPointerHandle; - while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) - { - BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, - &BlockPointerHandle); - if (BlockPointer == NULL) - { - BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", - HostAdapter); - return false; + int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); + void *BlockPointer; + dma_addr_t BlockPointerHandle; + while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs) { + BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle); + if (BlockPointer == NULL) { + BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n", HostAdapter); + return false; + } + BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle); } - BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, - BlockPointerHandle); - } - return true; + return true; } @@ -280,25 +258,19 @@ static boolean __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *Ho static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter) { - struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL; - HostAdapter->All_CCBs = NULL; - HostAdapter->Free_CCBs = NULL; - while ((CCB = NextCCB) != NULL) - { - NextCCB = CCB->NextAll; - if (CCB->AllocationGroupHead) - { - if (Last_CCB) - pci_free_consistent(HostAdapter->PCI_Device, - Last_CCB->AllocationGroupSize, Last_CCB, - Last_CCB->AllocationGroupHead); - Last_CCB = CCB; + struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL; + HostAdapter->All_CCBs = NULL; + HostAdapter->Free_CCBs = NULL; + while ((CCB = NextCCB) != NULL) { + NextCCB = CCB->NextAll; + if (CCB->AllocationGroupHead) { + if (Last_CCB) + pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead); + Last_CCB = CCB; + } } - } - if (Last_CCB) - pci_free_consistent(HostAdapter->PCI_Device, - Last_CCB->AllocationGroupSize, Last_CCB, - Last_CCB->AllocationGroupHead); + if (Last_CCB) + pci_free_consistent(HostAdapter->PCI_Device, Last_CCB->AllocationGroupSize, Last_CCB, Last_CCB->AllocationGroupHead); } @@ -309,40 +281,30 @@ static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter) multiple host adapters share the same IRQ Channel. */ -static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, - int AdditionalCCBs, - boolean SuccessMessageP) +static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, boolean SuccessMessageP) { - int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); - int PreviouslyAllocated = HostAdapter->AllocatedCCBs; - void *BlockPointer; - dma_addr_t BlockPointerHandle; - if (AdditionalCCBs <= 0) return; - while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) - { - BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, - &BlockPointerHandle); - if (BlockPointer == NULL) break; - BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, - BlockPointerHandle); - } - 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); - if (HostAdapter->DriverQueueDepth > - HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) - { - HostAdapter->DriverQueueDepth = - HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount; - HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth; - } + int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB); + int PreviouslyAllocated = HostAdapter->AllocatedCCBs; + void *BlockPointer; + dma_addr_t BlockPointerHandle; + if (AdditionalCCBs <= 0) + return; + while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs) { + BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize, &BlockPointerHandle); + if (BlockPointer == NULL) + break; + BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize, BlockPointerHandle); + } + 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); + if (HostAdapter->DriverQueueDepth > HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount) { + HostAdapter->DriverQueueDepth = HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount; + HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth; + } } /* @@ -352,31 +314,27 @@ static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapt */ static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter - *HostAdapter) + *HostAdapter) { - static unsigned long SerialNumber = 0; - struct BusLogic_CCB *CCB; - CCB = HostAdapter->Free_CCBs; - if (CCB != NULL) - { - CCB->SerialNumber = ++SerialNumber; - HostAdapter->Free_CCBs = CCB->Next; - CCB->Next = NULL; - if (HostAdapter->Free_CCBs == NULL) - BusLogic_CreateAdditionalCCBs(HostAdapter, - HostAdapter->IncrementalCCBs, - true); - return CCB; - } - BusLogic_CreateAdditionalCCBs(HostAdapter, - HostAdapter->IncrementalCCBs, - true); - CCB = HostAdapter->Free_CCBs; - if (CCB == NULL) return NULL; - CCB->SerialNumber = ++SerialNumber; - HostAdapter->Free_CCBs = CCB->Next; - CCB->Next = NULL; - return CCB; + static unsigned long SerialNumber = 0; + struct BusLogic_CCB *CCB; + CCB = HostAdapter->Free_CCBs; + if (CCB != NULL) { + CCB->SerialNumber = ++SerialNumber; + HostAdapter->Free_CCBs = CCB->Next; + CCB->Next = NULL; + if (HostAdapter->Free_CCBs == NULL) + BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true); + return CCB; + } + BusLogic_CreateAdditionalCCBs(HostAdapter, HostAdapter->IncrementalCCBs, true); + CCB = HostAdapter->Free_CCBs; + if (CCB == NULL) + return NULL; + CCB->SerialNumber = ++SerialNumber; + HostAdapter->Free_CCBs = CCB->Next; + CCB->Next = NULL; + return CCB; } @@ -388,26 +346,17 @@ static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB) { - struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter; - if (CCB->Command->use_sg != 0) - { - pci_unmap_sg(HostAdapter->PCI_Device, - (struct scatterlist *)CCB->Command->request_buffer, - CCB->Command->use_sg, - scsi_to_pci_dma_dir(CCB->Command->sc_data_direction)); - } - else if (CCB->Command->request_bufflen != 0) - { - pci_unmap_single(HostAdapter->PCI_Device, CCB->DataPointer, - CCB->DataLength, - scsi_to_pci_dma_dir(CCB->Command->sc_data_direction)); - } - pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer, - CCB->SenseDataLength, PCI_DMA_FROMDEVICE); - CCB->Command = NULL; - CCB->Status = BusLogic_CCB_Free; - CCB->Next = HostAdapter->Free_CCBs; - HostAdapter->Free_CCBs = CCB; + struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter; + if (CCB->Command->use_sg != 0) { + pci_unmap_sg(HostAdapter->PCI_Device, (struct scatterlist *) CCB->Command->request_buffer, CCB->Command->use_sg, scsi_to_pci_dma_dir(CCB->Command->sc_data_direction)); + } else if (CCB->Command->request_bufflen != 0) { + pci_unmap_single(HostAdapter->PCI_Device, CCB->DataPointer, CCB->DataLength, scsi_to_pci_dma_dir(CCB->Command->sc_data_direction)); + } + pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE); + CCB->Command = NULL; + CCB->Status = BusLogic_CCB_Free; + CCB->Next = HostAdapter->Free_CCBs; + HostAdapter->Free_CCBs = CCB; } @@ -429,228 +378,205 @@ static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB) waiting for the Host Adapter Ready bit to be set in the Status Register. */ -static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, - enum BusLogic_OperationCode OperationCode, - void *ParameterData, - int ParameterLength, - void *ReplyData, - int ReplyLength) +static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_OperationCode OperationCode, void *ParameterData, int ParameterLength, void *ReplyData, int ReplyLength) { - unsigned char *ParameterPointer = (unsigned char *) ParameterData; - unsigned char *ReplyPointer = (unsigned char *) ReplyData; - union BusLogic_StatusRegister StatusRegister; - union BusLogic_InterruptRegister InterruptRegister; - unsigned long ProcessorFlags = 0; - int ReplyBytes = 0, Result; - long TimeoutCounter; - /* - Clear out the Reply Data if provided. - */ - if (ReplyLength > 0) - memset(ReplyData, 0, ReplyLength); - /* - If the IRQ Channel has not yet been acquired, then interrupts must be - disabled while issuing host adapter commands since a Command Complete - interrupt could occur if the IRQ Channel was previously enabled by another - BusLogic Host Adapter or another driver sharing the same IRQ Channel. - */ - if (!HostAdapter->IRQ_ChannelAcquired) - { - local_irq_save(ProcessorFlags); - local_irq_disable(); - } - /* - Wait for the Host Adapter Ready bit to be set and the Command/Parameter - Register Busy bit to be reset in the Status Register. - */ - TimeoutCounter = 10000; - while (--TimeoutCounter >= 0) - { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.HostAdapterReady && - !StatusRegister.sr.CommandParameterRegisterBusy) - break; - udelay(100); - } - if (TimeoutCounter < 0) - { - BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready"; - Result = -2; - goto Done; - } - /* - Write the OperationCode to the Command/Parameter Register. - */ - HostAdapter->HostAdapterCommandCompleted = false; - BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode); - /* - Write any additional Parameter Bytes. - */ - TimeoutCounter = 10000; - while (ParameterLength > 0 && --TimeoutCounter >= 0) - { - /* - Wait 100 microseconds to give the Host Adapter enough time to determine - whether the last value written to the Command/Parameter Register was - valid or not. If the Command Complete bit is set in the Interrupt - Register, then the Command Invalid bit in the Status Register will be - reset if the Operation Code or Parameter was valid and the command - has completed, or set if the Operation Code or Parameter was invalid. - If the Data In Register Ready bit is set in the Status Register, then - the Operation Code was valid, and data is waiting to be read back - from the Host Adapter. Otherwise, wait for the Command/Parameter - Register Busy bit in the Status Register to be reset. - */ - udelay(100); - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (InterruptRegister.ir.CommandComplete) break; - if (HostAdapter->HostAdapterCommandCompleted) break; - if (StatusRegister.sr.DataInRegisterReady) break; - if (StatusRegister.sr.CommandParameterRegisterBusy) continue; - BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++); - ParameterLength--; - } - if (TimeoutCounter < 0) - { - BusLogic_CommandFailureReason = - "Timeout waiting for Parameter Acceptance"; - Result = -2; - goto Done; - } - /* - The Modify I/O Address command does not cause a Command Complete Interrupt. - */ - if (OperationCode == BusLogic_ModifyIOAddress) - { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.CommandInvalid) - { - BusLogic_CommandFailureReason = "Modify I/O Address Invalid"; - Result = -1; - goto Done; + unsigned char *ParameterPointer = (unsigned char *) ParameterData; + unsigned char *ReplyPointer = (unsigned char *) ReplyData; + union BusLogic_StatusRegister StatusRegister; + union BusLogic_InterruptRegister InterruptRegister; + unsigned long ProcessorFlags = 0; + int ReplyBytes = 0, Result; + long TimeoutCounter; + /* + Clear out the Reply Data if provided. + */ + if (ReplyLength > 0) + memset(ReplyData, 0, ReplyLength); + /* + If the IRQ Channel has not yet been acquired, then interrupts must be + disabled while issuing host adapter commands since a Command Complete + interrupt could occur if the IRQ Channel was previously enabled by another + BusLogic Host Adapter or another driver sharing the same IRQ Channel. + */ + if (!HostAdapter->IRQ_ChannelAcquired) { + local_irq_save(ProcessorFlags); + local_irq_disable(); + } + /* + Wait for the Host Adapter Ready bit to be set and the Command/Parameter + Register Busy bit to be reset in the Status Register. + */ + TimeoutCounter = 10000; + while (--TimeoutCounter >= 0) { + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (StatusRegister.sr.HostAdapterReady && !StatusRegister.sr.CommandParameterRegisterBusy) + break; + udelay(100); + } + if (TimeoutCounter < 0) { + BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready"; + Result = -2; + goto Done; + } + /* + Write the OperationCode to the Command/Parameter Register. + */ + HostAdapter->HostAdapterCommandCompleted = false; + BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode); + /* + Write any additional Parameter Bytes. + */ + TimeoutCounter = 10000; + while (ParameterLength > 0 && --TimeoutCounter >= 0) { + /* + Wait 100 microseconds to give the Host Adapter enough time to determine + whether the last value written to the Command/Parameter Register was + valid or not. If the Command Complete bit is set in the Interrupt + Register, then the Command Invalid bit in the Status Register will be + reset if the Operation Code or Parameter was valid and the command + has completed, or set if the Operation Code or Parameter was invalid. + If the Data In Register Ready bit is set in the Status Register, then + the Operation Code was valid, and data is waiting to be read back + from the Host Adapter. Otherwise, wait for the Command/Parameter + Register Busy bit in the Status Register to be reset. + */ + udelay(100); + InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (InterruptRegister.ir.CommandComplete) + break; + if (HostAdapter->HostAdapterCommandCompleted) + break; + if (StatusRegister.sr.DataInRegisterReady) + break; + if (StatusRegister.sr.CommandParameterRegisterBusy) + continue; + BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++); + ParameterLength--; } - if (BusLogic_GlobalOptions.TraceConfiguration) - BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " - "(Modify I/O Address)\n", HostAdapter, - OperationCode, StatusRegister.All); - Result = 0; - goto Done; - } - /* - Select an appropriate timeout value for awaiting command completion. - */ - switch (OperationCode) - { - case BusLogic_InquireInstalledDevicesID0to7: - case BusLogic_InquireInstalledDevicesID8to15: - case BusLogic_InquireTargetDevices: - /* Approximately 60 seconds. */ - TimeoutCounter = 60*10000; - break; - default: - /* Approximately 1 second. */ - TimeoutCounter = 10000; - break; - } - /* - Receive any Reply Bytes, waiting for either the Command Complete bit to - be set in the Interrupt Register, or for the Interrupt Handler to set the - Host Adapter Command Completed bit in the Host Adapter structure. - */ - while (--TimeoutCounter >= 0) - { - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (InterruptRegister.ir.CommandComplete) break; - if (HostAdapter->HostAdapterCommandCompleted) break; - if (StatusRegister.sr.DataInRegisterReady) - { - if (++ReplyBytes <= ReplyLength) - *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter); - else BusLogic_ReadDataInRegister(HostAdapter); + if (TimeoutCounter < 0) { + BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance"; + Result = -2; + goto Done; } - if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && - StatusRegister.sr.HostAdapterReady) break; - udelay(100); - } - if (TimeoutCounter < 0) - { - BusLogic_CommandFailureReason = "Timeout waiting for Command Complete"; - Result = -2; - goto Done; - } - /* - Clear any pending Command Complete Interrupt. - */ - BusLogic_InterruptReset(HostAdapter); - /* - Provide tracing information if requested. - */ - if (BusLogic_GlobalOptions.TraceConfiguration) - { - int i; - BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", - HostAdapter, OperationCode, - StatusRegister.All, ReplyLength, ReplyBytes); - if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes; - for (i = 0; i < ReplyLength; i++) - BusLogic_Notice(" %02X", HostAdapter, - ((unsigned char *) ReplyData)[i]); - BusLogic_Notice("\n", HostAdapter); - } - /* - Process Command Invalid conditions. - */ - if (StatusRegister.sr.CommandInvalid) - { - /* - Some early BusLogic Host Adapters may not recover properly from - a Command Invalid condition, so if this appears to be the case, - a Soft Reset is issued to the Host Adapter. Potentially invalid - commands are never attempted after Mailbox Initialization is - performed, so there should be no Host Adapter state lost by a - Soft Reset in response to a Command Invalid condition. - */ - udelay(1000); - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.CommandInvalid || - StatusRegister.sr.Reserved || - StatusRegister.sr.DataInRegisterReady || - StatusRegister.sr.CommandParameterRegisterBusy || - !StatusRegister.sr.HostAdapterReady || - !StatusRegister.sr.InitializationRequired || - StatusRegister.sr.DiagnosticActive || - StatusRegister.sr.DiagnosticFailure) - { - BusLogic_SoftReset(HostAdapter); - udelay(1000); + /* + The Modify I/O Address command does not cause a Command Complete Interrupt. + */ + if (OperationCode == BusLogic_ModifyIOAddress) { + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (StatusRegister.sr.CommandInvalid) { + BusLogic_CommandFailureReason = "Modify I/O Address Invalid"; + Result = -1; + goto Done; + } + if (BusLogic_GlobalOptions.TraceConfiguration) + BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: " "(Modify I/O Address)\n", HostAdapter, OperationCode, StatusRegister.All); + Result = 0; + goto Done; + } + /* + Select an appropriate timeout value for awaiting command completion. + */ + switch (OperationCode) { + case BusLogic_InquireInstalledDevicesID0to7: + case BusLogic_InquireInstalledDevicesID8to15: + case BusLogic_InquireTargetDevices: + /* Approximately 60 seconds. */ + TimeoutCounter = 60 * 10000; + break; + default: + /* Approximately 1 second. */ + TimeoutCounter = 10000; + break; } - BusLogic_CommandFailureReason = "Command Invalid"; - Result = -1; - goto Done; - } - /* - Handle Excess Parameters Supplied conditions. - */ - if (ParameterLength > 0) - { - BusLogic_CommandFailureReason = "Excess Parameters Supplied"; - Result = -1; - goto Done; - } - /* - Indicate the command completed successfully. - */ - BusLogic_CommandFailureReason = NULL; - Result = ReplyBytes; - /* - Restore the interrupt status if necessary and return. - */ -Done: - if (!HostAdapter->IRQ_ChannelAcquired) - local_irq_restore(ProcessorFlags); - return Result; + /* + Receive any Reply Bytes, waiting for either the Command Complete bit to + be set in the Interrupt Register, or for the Interrupt Handler to set the + Host Adapter Command Completed bit in the Host Adapter structure. + */ + while (--TimeoutCounter >= 0) { + InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (InterruptRegister.ir.CommandComplete) + break; + if (HostAdapter->HostAdapterCommandCompleted) + break; + if (StatusRegister.sr.DataInRegisterReady) { + if (++ReplyBytes <= ReplyLength) + *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter); + else + BusLogic_ReadDataInRegister(HostAdapter); + } + if (OperationCode == BusLogic_FetchHostAdapterLocalRAM && StatusRegister.sr.HostAdapterReady) + break; + udelay(100); + } + if (TimeoutCounter < 0) { + BusLogic_CommandFailureReason = "Timeout waiting for Command Complete"; + Result = -2; + goto Done; + } + /* + Clear any pending Command Complete Interrupt. + */ + BusLogic_InterruptReset(HostAdapter); + /* + Provide tracing information if requested. + */ + if (BusLogic_GlobalOptions.TraceConfiguration) { + int i; + BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:", HostAdapter, OperationCode, StatusRegister.All, ReplyLength, ReplyBytes); + if (ReplyLength > ReplyBytes) + ReplyLength = ReplyBytes; + for (i = 0; i < ReplyLength; i++) + BusLogic_Notice(" %02X", HostAdapter, ((unsigned char *) ReplyData)[i]); + BusLogic_Notice("\n", HostAdapter); + } + /* + Process Command Invalid conditions. + */ + if (StatusRegister.sr.CommandInvalid) { + /* + Some early BusLogic Host Adapters may not recover properly from + a Command Invalid condition, so if this appears to be the case, + a Soft Reset is issued to the Host Adapter. Potentially invalid + commands are never attempted after Mailbox Initialization is + performed, so there should be no Host Adapter state lost by a + Soft Reset in response to a Command Invalid condition. + */ + udelay(1000); + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (StatusRegister.sr.CommandInvalid || + StatusRegister.sr.Reserved || + StatusRegister.sr.DataInRegisterReady || + StatusRegister.sr.CommandParameterRegisterBusy || !StatusRegister.sr.HostAdapterReady || !StatusRegister.sr.InitializationRequired || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.DiagnosticFailure) { + BusLogic_SoftReset(HostAdapter); + udelay(1000); + } + BusLogic_CommandFailureReason = "Command Invalid"; + Result = -1; + goto Done; + } + /* + Handle Excess Parameters Supplied conditions. + */ + if (ParameterLength > 0) { + BusLogic_CommandFailureReason = "Excess Parameters Supplied"; + Result = -1; + goto Done; + } + /* + Indicate the command completed successfully. + */ + BusLogic_CommandFailureReason = NULL; + Result = ReplyBytes; + /* + Restore the interrupt status if necessary and return. + */ + Done: + if (!HostAdapter->IRQ_ChannelAcquired) + local_irq_restore(ProcessorFlags); + return Result; } @@ -662,13 +588,14 @@ Done: static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address) { - struct BusLogic_ProbeInfo *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; - ProbeInfo->PCI_Device = NULL; + struct BusLogic_ProbeInfo *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; + ProbeInfo->PCI_Device = NULL; } @@ -681,38 +608,27 @@ static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address) static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapter *PrototypeHostAdapter) { - /* - If BusLogic Driver Options specifications requested that ISA Bus Probes - be inhibited, do not proceed further. - */ - if (BusLogic_ProbeOptions.NoProbeISA) return; - /* - Append the list of standard BusLogic MultiMaster ISA I/O Addresses. - */ - if (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe330 - : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0) - BusLogic_AppendProbeAddressISA(0x330); - if (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe334 - : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0) - BusLogic_AppendProbeAddressISA(0x334); - if (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe230 - : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0) - BusLogic_AppendProbeAddressISA(0x230); - if (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe234 - : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0) - BusLogic_AppendProbeAddressISA(0x234); - if (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe130 - : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0) - BusLogic_AppendProbeAddressISA(0x130); - if (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe134 - : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0) - BusLogic_AppendProbeAddressISA(0x134); + /* + If BusLogic Driver Options specifications requested that ISA Bus Probes + be inhibited, do not proceed further. + */ + if (BusLogic_ProbeOptions.NoProbeISA) + return; + /* + Append the list of standard BusLogic MultiMaster ISA I/O Addresses. + */ + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x330); + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x334); + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x230); + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x234); + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x130); + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0) + BusLogic_AppendProbeAddressISA(0x134); } @@ -724,30 +640,24 @@ static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapt of increasing PCI Bus and Device Number. */ -static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList, - int ProbeInfoCount) +static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList, int ProbeInfoCount) { - int LastInterchange = ProbeInfoCount-1, Bound, j; - while (LastInterchange > 0) - { - Bound = LastInterchange; - LastInterchange = 0; - for (j = 0; j < Bound; j++) - { - struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j]; - struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j+1]; - if (ProbeInfo1->Bus > ProbeInfo2->Bus || - (ProbeInfo1->Bus == ProbeInfo2->Bus && - (ProbeInfo1->Device > ProbeInfo2->Device))) - { - struct BusLogic_ProbeInfo TempProbeInfo; - memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo)); - memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo)); - memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo)); - LastInterchange = j; - } + int LastInterchange = ProbeInfoCount - 1, Bound, j; + while (LastInterchange > 0) { + Bound = LastInterchange; + LastInterchange = 0; + for (j = 0; j < Bound; j++) { + struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j]; + struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j + 1]; + if (ProbeInfo1->Bus > ProbeInfo2->Bus || (ProbeInfo1->Bus == ProbeInfo2->Bus && (ProbeInfo1->Device > ProbeInfo2->Device))) { + struct BusLogic_ProbeInfo TempProbeInfo; + memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo)); + memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo)); + memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo)); + LastInterchange = j; + } + } } - } } @@ -762,292 +672,226 @@ static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoLi static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAdapter *PrototypeHostAdapter) { - struct BusLogic_ProbeInfo *PrimaryProbeInfo = - &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount]; - int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1; - int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0; - boolean ForceBusDeviceScanningOrder = false; - boolean ForceBusDeviceScanningOrderChecked = false; - boolean StandardAddressSeen[6]; - struct pci_dev *PCI_Device = NULL; - int i; - if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0; - BusLogic_ProbeInfoCount++; - for (i = 0; i < 6; i++) - StandardAddressSeen[i] = false; - /* - Iterate over the MultiMaster PCI Host Adapters. For each enumerated host - adapter, determine whether its ISA Compatible I/O Port is enabled and if - so, whether it is assigned the Primary I/O Address. A host adapter that is - assigned the Primary I/O Address will always be the preferred boot device. - The MultiMaster BIOS will first recognize a host adapter at the Primary I/O - Address, then any other PCI host adapters, and finally any host adapters - located at the remaining standard ISA I/O Addresses. When a PCI host - adapter is found with its ISA Compatible I/O Port enabled, a command is - issued to disable the ISA Compatible I/O Port, and it is noted that the - particular standard ISA I/O Address need not be probed. - */ - PrimaryProbeInfo->IO_Address = 0; - while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, - PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, - PCI_Device)) != NULL) - { - struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; - struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation; - enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest; - unsigned char Bus; - unsigned char Device; - unsigned int IRQ_Channel; - unsigned long BaseAddress0; - unsigned long BaseAddress1; - unsigned long IO_Address; - unsigned long PCI_Address; - - if (pci_enable_device(PCI_Device)) - continue; - - if (pci_set_dma_mask(PCI_Device, (u64)0xffffffff)) - continue; - - Bus = PCI_Device->bus->number; - Device = PCI_Device->devfn >> 3; - IRQ_Channel = PCI_Device->irq; - IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); - PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); - - if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) - { - BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " - "MultiMaster Host Adapter\n", NULL, BaseAddress0); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", - NULL, Bus, Device, IO_Address); - continue; - } - if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO) - { - BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " - "MultiMaster Host Adapter\n", NULL, BaseAddress1); - BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", - NULL, Bus, Device, PCI_Address); - continue; - } - if (IRQ_Channel == 0) - { - BusLogic_Error("BusLogic: IRQ Channel %d invalid for " - "MultiMaster Host Adapter\n", NULL, IRQ_Channel); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", - NULL, Bus, Device, IO_Address); - continue; - } - if (BusLogic_GlobalOptions.TraceProbe) - { - BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " - "detected at\n", NULL); - BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " - "0x%X PCI Address 0x%X\n", NULL, - Bus, Device, IO_Address, PCI_Address); - } - /* - Issue the Inquire PCI Host Adapter Information command to determine - the ISA Compatible I/O Port. If the ISA Compatible I/O Port is - known and enabled, note that the particular Standard ISA I/O - Address should not be probed. - */ - HostAdapter->IO_Address = IO_Address; - BusLogic_InterruptReset(HostAdapter); - if (BusLogic_Command(HostAdapter, - BusLogic_InquirePCIHostAdapterInformation, - NULL, 0, &PCIHostAdapterInformation, - sizeof(PCIHostAdapterInformation)) - == sizeof(PCIHostAdapterInformation)) - { - if (PCIHostAdapterInformation.ISACompatibleIOPort < 6) - StandardAddressSeen[PCIHostAdapterInformation - .ISACompatibleIOPort] = true; - } - else PCIHostAdapterInformation.ISACompatibleIOPort = - BusLogic_IO_Disable; - /* - * Issue the Modify I/O Address command to disable the ISA Compatible - * I/O Port. On PCI Host Adapters, the Modify I/O Address command - * allows modification of the ISA compatible I/O Address that the Host - * Adapter responds to; it does not affect the PCI compliant I/O Address - * assigned at system initialization. - */ - ModifyIOAddressRequest = BusLogic_IO_Disable; - BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress, - &ModifyIOAddressRequest, - sizeof(ModifyIOAddressRequest), NULL, 0); - /* - For the first MultiMaster Host Adapter enumerated, issue the Fetch - Host Adapter Local RAM command to read byte 45 of the AutoSCSI area, - for the setting of the "Use Bus And Device # For PCI Scanning Seq." - option. Issue the Inquire Board ID command since this option is - only valid for the BT-948/958/958D. - */ - if (!ForceBusDeviceScanningOrderChecked) - { - struct BusLogic_FetchHostAdapterLocalRAMRequest - FetchHostAdapterLocalRAMRequest; - struct BusLogic_AutoSCSIByte45 AutoSCSIByte45; - struct BusLogic_BoardID BoardID; - FetchHostAdapterLocalRAMRequest.ByteOffset = - BusLogic_AutoSCSI_BaseOffset + 45; - FetchHostAdapterLocalRAMRequest.ByteCount = - sizeof(AutoSCSIByte45); - BusLogic_Command(HostAdapter, - BusLogic_FetchHostAdapterLocalRAM, - &FetchHostAdapterLocalRAMRequest, - sizeof(FetchHostAdapterLocalRAMRequest), - &AutoSCSIByte45, sizeof(AutoSCSIByte45)); - BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, - NULL, 0, &BoardID, sizeof(BoardID)); - if (BoardID.FirmwareVersion1stDigit == '5') - ForceBusDeviceScanningOrder = - AutoSCSIByte45.ForceBusDeviceScanningOrder; - ForceBusDeviceScanningOrderChecked = true; - } - /* - Determine whether this MultiMaster Host Adapter has its ISA - Compatible I/O Port enabled and is assigned the Primary I/O Address. - If it does, then it is the Primary MultiMaster Host Adapter and must - be recognized first. If it does not, then it is added to the list - for probing after any Primary MultiMaster Host Adapter is probed. - */ - if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) - { - PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; - PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; - PrimaryProbeInfo->IO_Address = IO_Address; - PrimaryProbeInfo->PCI_Address = PCI_Address; - PrimaryProbeInfo->Bus = Bus; - PrimaryProbeInfo->Device = Device; - PrimaryProbeInfo->IRQ_Channel = IRQ_Channel; - PrimaryProbeInfo->PCI_Device = PCI_Device; - PCIMultiMasterCount++; + struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount]; + int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1; + int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0; + boolean ForceBusDeviceScanningOrder = false; + boolean ForceBusDeviceScanningOrderChecked = false; + boolean StandardAddressSeen[6]; + struct pci_dev *PCI_Device = NULL; + int i; + if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) + return 0; + BusLogic_ProbeInfoCount++; + for (i = 0; i < 6; i++) + StandardAddressSeen[i] = false; + /* + Iterate over the MultiMaster PCI Host Adapters. For each enumerated host + adapter, determine whether its ISA Compatible I/O Port is enabled and if + so, whether it is assigned the Primary I/O Address. A host adapter that is + assigned the Primary I/O Address will always be the preferred boot device. + The MultiMaster BIOS will first recognize a host adapter at the Primary I/O + Address, then any other PCI host adapters, and finally any host adapters + located at the remaining standard ISA I/O Addresses. When a PCI host + adapter is found with its ISA Compatible I/O Port enabled, a command is + issued to disable the ISA Compatible I/O Port, and it is noted that the + particular standard ISA I/O Address need not be probed. + */ + PrimaryProbeInfo->IO_Address = 0; + while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_Device)) != NULL) { + struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; + struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation; + enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest; + unsigned char Bus; + unsigned char Device; + unsigned int IRQ_Channel; + unsigned long BaseAddress0; + unsigned long BaseAddress1; + unsigned long IO_Address; + unsigned long PCI_Address; + + if (pci_enable_device(PCI_Device)) + continue; + + if (pci_set_dma_mask(PCI_Device, (u64) 0xffffffff)) + continue; + + Bus = PCI_Device->bus->number; + Device = PCI_Device->devfn >> 3; + IRQ_Channel = PCI_Device->irq; + IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); + PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); + + if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { + BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "MultiMaster Host Adapter\n", NULL, BaseAddress0); + BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + continue; + } + if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) { + BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "MultiMaster Host Adapter\n", NULL, BaseAddress1); + BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address); + continue; + } + if (IRQ_Channel == 0) { + BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "MultiMaster Host Adapter\n", NULL, IRQ_Channel); + BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + continue; + } + if (BusLogic_GlobalOptions.TraceProbe) { + BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter " "detected at\n", NULL); + BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address); + } + /* + Issue the Inquire PCI Host Adapter Information command to determine + the ISA Compatible I/O Port. If the ISA Compatible I/O Port is + known and enabled, note that the particular Standard ISA I/O + Address should not be probed. + */ + HostAdapter->IO_Address = IO_Address; + BusLogic_InterruptReset(HostAdapter); + if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation)) + == sizeof(PCIHostAdapterInformation)) { + if (PCIHostAdapterInformation.ISACompatibleIOPort < 6) + StandardAddressSeen[PCIHostAdapterInformation.ISACompatibleIOPort] = true; + } else + PCIHostAdapterInformation.ISACompatibleIOPort = BusLogic_IO_Disable; + /* + * Issue the Modify I/O Address command to disable the ISA Compatible + * I/O Port. On PCI Host Adapters, the Modify I/O Address command + * allows modification of the ISA compatible I/O Address that the Host + * Adapter responds to; it does not affect the PCI compliant I/O Address + * assigned at system initialization. + */ + ModifyIOAddressRequest = BusLogic_IO_Disable; + BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress, &ModifyIOAddressRequest, sizeof(ModifyIOAddressRequest), NULL, 0); + /* + For the first MultiMaster Host Adapter enumerated, issue the Fetch + Host Adapter Local RAM command to read byte 45 of the AutoSCSI area, + for the setting of the "Use Bus And Device # For PCI Scanning Seq." + option. Issue the Inquire Board ID command since this option is + only valid for the BT-948/958/958D. + */ + if (!ForceBusDeviceScanningOrderChecked) { + struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest; + struct BusLogic_AutoSCSIByte45 AutoSCSIByte45; + struct BusLogic_BoardID BoardID; + FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset + 45; + FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIByte45); + BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIByte45, sizeof(AutoSCSIByte45)); + BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)); + if (BoardID.FirmwareVersion1stDigit == '5') + ForceBusDeviceScanningOrder = AutoSCSIByte45.ForceBusDeviceScanningOrder; + ForceBusDeviceScanningOrderChecked = true; + } + /* + Determine whether this MultiMaster Host Adapter has its ISA + Compatible I/O Port enabled and is assigned the Primary I/O Address. + If it does, then it is the Primary MultiMaster Host Adapter and must + be recognized first. If it does not, then it is added to the list + for probing after any Primary MultiMaster Host Adapter is probed. + */ + if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330) { + PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; + PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; + PrimaryProbeInfo->IO_Address = IO_Address; + PrimaryProbeInfo->PCI_Address = PCI_Address; + PrimaryProbeInfo->Bus = Bus; + PrimaryProbeInfo->Device = Device; + PrimaryProbeInfo->IRQ_Channel = IRQ_Channel; + PrimaryProbeInfo->PCI_Device = PCI_Device; + PCIMultiMasterCount++; + } else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) { + struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; + ProbeInfo->HostAdapterType = BusLogic_MultiMaster; + ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; + ProbeInfo->IO_Address = IO_Address; + ProbeInfo->PCI_Address = PCI_Address; + ProbeInfo->Bus = Bus; + ProbeInfo->Device = Device; + ProbeInfo->IRQ_Channel = IRQ_Channel; + ProbeInfo->PCI_Device = PCI_Device; + NonPrimaryPCIMultiMasterCount++; + PCIMultiMasterCount++; + } else + BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL); } - else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) - { - struct BusLogic_ProbeInfo *ProbeInfo = - &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->HostAdapterType = BusLogic_MultiMaster; - ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; - ProbeInfo->IO_Address = IO_Address; - ProbeInfo->PCI_Address = PCI_Address; - ProbeInfo->Bus = Bus; - ProbeInfo->Device = Device; - ProbeInfo->IRQ_Channel = IRQ_Channel; - ProbeInfo->PCI_Device = PCI_Device; - NonPrimaryPCIMultiMasterCount++; - PCIMultiMasterCount++; + /* + If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON + for the first enumerated MultiMaster Host Adapter, and if that host adapter + is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster + Host Adapters in the order of increasing PCI Bus and Device Number. In + that case, sort the probe information into the same order the BIOS uses. + If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster + Host Adapters in the order they are enumerated by the PCI BIOS, and hence + no sorting is necessary. + */ + if (ForceBusDeviceScanningOrder) + BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[NonPrimaryPCIMultiMasterIndex], NonPrimaryPCIMultiMasterCount); + /* + If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address, + then the Primary I/O Address must be probed explicitly before any PCI + host adapters are probed. + */ + if (!BusLogic_ProbeOptions.NoProbeISA) + if (PrimaryProbeInfo->IO_Address == 0 && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) { + PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; + PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; + PrimaryProbeInfo->IO_Address = 0x330; + } + /* + Append the list of standard BusLogic MultiMaster ISA I/O Addresses, + omitting the Primary I/O Address which has already been handled. + */ + if (!BusLogic_ProbeOptions.NoProbeISA) { + if (!StandardAddressSeen[1] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x334); + if (!StandardAddressSeen[2] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x230); + if (!StandardAddressSeen[3] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x234); + if (!StandardAddressSeen[4] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x130); + if (!StandardAddressSeen[5] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)) + BusLogic_AppendProbeAddressISA(0x134); } - else BusLogic_Warning("BusLogic: Too many Host Adapters " - "detected\n", NULL); - } - /* - If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON - for the first enumerated MultiMaster Host Adapter, and if that host adapter - is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster - Host Adapters in the order of increasing PCI Bus and Device Number. In - that case, sort the probe information into the same order the BIOS uses. - If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster - Host Adapters in the order they are enumerated by the PCI BIOS, and hence - no sorting is necessary. - */ - if (ForceBusDeviceScanningOrder) - BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[ - NonPrimaryPCIMultiMasterIndex], - NonPrimaryPCIMultiMasterCount); - /* - If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address, - then the Primary I/O Address must be probed explicitly before any PCI - host adapters are probed. - */ - if (!BusLogic_ProbeOptions.NoProbeISA) - if (PrimaryProbeInfo->IO_Address == 0 && - (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe330 - : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) - { - PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; - PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; - PrimaryProbeInfo->IO_Address = 0x330; - } - /* - Append the list of standard BusLogic MultiMaster ISA I/O Addresses, - omitting the Primary I/O Address which has already been handled. - */ - if (!BusLogic_ProbeOptions.NoProbeISA) - { - if (!StandardAddressSeen[1] && - (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe334 - : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)) - BusLogic_AppendProbeAddressISA(0x334); - if (!StandardAddressSeen[2] && - (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe230 - : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)) - BusLogic_AppendProbeAddressISA(0x230); - if (!StandardAddressSeen[3] && - (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe234 - : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)) - BusLogic_AppendProbeAddressISA(0x234); - if (!StandardAddressSeen[4] && - (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe130 - : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)) - BusLogic_AppendProbeAddressISA(0x130); - if (!StandardAddressSeen[5] && - (BusLogic_ProbeOptions.LimitedProbeISA - ? BusLogic_ProbeOptions.Probe134 - : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)) - BusLogic_AppendProbeAddressISA(0x134); - } - /* - Iterate over the older non-compliant MultiMaster PCI Host Adapters, - noting the PCI bus location and assigned IRQ Channel. - */ - PCI_Device = NULL; - while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, - PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, - PCI_Device)) != NULL) - { - unsigned char Bus; - unsigned char Device; - unsigned int IRQ_Channel; - unsigned long IO_Address; - - if (pci_enable_device(PCI_Device)) - continue; - - if (pci_set_dma_mask(PCI_Device, (u64)0xffffffff)) - continue; - - Bus = PCI_Device->bus->number; - Device = PCI_Device->devfn >> 3; - IRQ_Channel = PCI_Device->irq; - IO_Address = pci_resource_start(PCI_Device, 0); - - if (IO_Address == 0 || IRQ_Channel == 0) continue; - for (i = 0; i < BusLogic_ProbeInfoCount; i++) - { - struct BusLogic_ProbeInfo *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; - ProbeInfo->PCI_Device = PCI_Device; - break; - } + /* + Iterate over the older non-compliant MultiMaster PCI Host Adapters, + noting the PCI bus location and assigned IRQ Channel. + */ + PCI_Device = NULL; + while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC, PCI_Device)) != NULL) { + unsigned char Bus; + unsigned char Device; + unsigned int IRQ_Channel; + unsigned long IO_Address; + + if (pci_enable_device(PCI_Device)) + continue; + + if (pci_set_dma_mask(PCI_Device, (u64) 0xffffffff)) + continue; + + Bus = PCI_Device->bus->number; + Device = PCI_Device->devfn >> 3; + IRQ_Channel = PCI_Device->irq; + IO_Address = pci_resource_start(PCI_Device, 0); + + if (IO_Address == 0 || IRQ_Channel == 0) + continue; + for (i = 0; i < BusLogic_ProbeInfoCount; i++) { + struct BusLogic_ProbeInfo *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; + ProbeInfo->PCI_Device = PCI_Device; + break; + } + } } - } - return PCIMultiMasterCount; + return PCIMultiMasterCount; } @@ -1061,100 +905,77 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter *PrototypeHostAdapter) { - int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0; - struct pci_dev *PCI_Device = NULL; - /* - Interrogate PCI Configuration Space for any FlashPoint Host Adapters. - */ - while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, - PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, - PCI_Device)) != NULL) - { - unsigned char Bus; - unsigned char Device; - unsigned int IRQ_Channel; - unsigned long BaseAddress0; - unsigned long BaseAddress1; - unsigned long IO_Address; - unsigned long PCI_Address; - - if (pci_enable_device(PCI_Device)) - continue; - - if (pci_set_dma_mask(PCI_Device, (u64)0xffffffff)) - continue; - - Bus = PCI_Device->bus->number; - Device = PCI_Device->devfn >> 3; - IRQ_Channel = PCI_Device->irq; - IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); - PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); + int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0; + struct pci_dev *PCI_Device = NULL; + /* + Interrogate PCI Configuration Space for any FlashPoint Host Adapters. + */ + while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT, PCI_Device)) != NULL) { + unsigned char Bus; + unsigned char Device; + unsigned int IRQ_Channel; + unsigned long BaseAddress0; + unsigned long BaseAddress1; + unsigned long IO_Address; + unsigned long PCI_Address; + + if (pci_enable_device(PCI_Device)) + continue; + + if (pci_set_dma_mask(PCI_Device, (u64) 0xffffffff)) + continue; + + Bus = PCI_Device->bus->number; + Device = PCI_Device->devfn >> 3; + IRQ_Channel = PCI_Device->irq; + IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); + PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); #ifndef CONFIG_SCSI_OMIT_FLASHPOINT - if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) - { - BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " - "FlashPoint Host Adapter\n", NULL, BaseAddress0); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", - NULL, Bus, Device, IO_Address); - continue; - } - if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) - { - BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " - "FlashPoint Host Adapter\n", NULL, BaseAddress1); - BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", - NULL, Bus, Device, PCI_Address); - continue; - } - if (IRQ_Channel == 0) - { - BusLogic_Error("BusLogic: IRQ Channel %d invalid for " - "FlashPoint Host Adapter\n", NULL, IRQ_Channel); - BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", - NULL, Bus, Device, IO_Address); - continue; - } - if (BusLogic_GlobalOptions.TraceProbe) - { - BusLogic_Notice("BusLogic: FlashPoint Host Adapter " - "detected at\n", NULL); - BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " - "0x%X PCI Address 0x%X\n", NULL, - Bus, Device, IO_Address, PCI_Address); - } - if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) - { - struct BusLogic_ProbeInfo *ProbeInfo = - &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; - ProbeInfo->HostAdapterType = BusLogic_FlashPoint; - ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; - ProbeInfo->IO_Address = IO_Address; - ProbeInfo->PCI_Address = PCI_Address; - ProbeInfo->Bus = Bus; - ProbeInfo->Device = Device; - ProbeInfo->IRQ_Channel = IRQ_Channel; - ProbeInfo->PCI_Device = PCI_Device; - FlashPointCount++; - } - else BusLogic_Warning("BusLogic: Too many Host Adapters " - "detected\n", NULL); + if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { + BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); + BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + continue; + } + if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO) { + BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for " "FlashPoint Host Adapter\n", NULL, BaseAddress1); + BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n", NULL, Bus, Device, PCI_Address); + continue; + } + if (IRQ_Channel == 0) { + BusLogic_Error("BusLogic: IRQ Channel %d invalid for " "FlashPoint Host Adapter\n", NULL, IRQ_Channel); + BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); + continue; + } + if (BusLogic_GlobalOptions.TraceProbe) { + BusLogic_Notice("BusLogic: FlashPoint Host Adapter " "detected at\n", NULL); + BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address " "0x%X PCI Address 0x%X\n", NULL, Bus, Device, IO_Address, PCI_Address); + } + if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters) { + struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++]; + ProbeInfo->HostAdapterType = BusLogic_FlashPoint; + ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus; + ProbeInfo->IO_Address = IO_Address; + ProbeInfo->PCI_Address = PCI_Address; + ProbeInfo->Bus = Bus; + ProbeInfo->Device = Device; + ProbeInfo->IRQ_Channel = IRQ_Channel; + ProbeInfo->PCI_Device = PCI_Device; + FlashPointCount++; + } else + BusLogic_Warning("BusLogic: Too many Host Adapters " "detected\n", NULL); #else - BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " - "PCI Bus %d Device %d\n", NULL, Bus, Device); - BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " - "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel); - BusLogic_Error("BusLogic: support was omitted in this kernel " - "configuration.\n", NULL); + BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", NULL, Bus, Device); + BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, " "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel); + BusLogic_Error("BusLogic: support was omitted in this kernel " "configuration.\n", NULL); #endif - } - /* - The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of - increasing PCI Bus and Device Number, so sort the probe information into - the same order the BIOS uses. - */ - BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], - FlashPointCount); - return FlashPointCount; + } + /* + The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of + increasing PCI Bus and Device Number, so sort the probe information into + the same order the BIOS uses. + */ + BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex], FlashPointCount); + return FlashPointCount; } @@ -1174,106 +995,70 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter *PrototypeHostAdapter) { - /* - If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint - Host Adapters; otherwise, default to the standard ISA MultiMaster probe. - */ - if (!BusLogic_ProbeOptions.NoProbePCI) - { - if (BusLogic_ProbeOptions.MultiMasterFirst) - { - BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); - BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); - } - else if (BusLogic_ProbeOptions.FlashPointFirst) - { - BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); - BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); - } - else - { - int FlashPointCount = - BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); - int PCIMultiMasterCount = - BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); - if (FlashPointCount > 0 && PCIMultiMasterCount > 0) - { - struct BusLogic_ProbeInfo *ProbeInfo = - &BusLogic_ProbeInfoList[FlashPointCount]; - struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; - struct BusLogic_FetchHostAdapterLocalRAMRequest - FetchHostAdapterLocalRAMRequest; - struct BusLogic_BIOSDriveMapByte Drive0MapByte; - while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus) - ProbeInfo++; - HostAdapter->IO_Address = ProbeInfo->IO_Address; - FetchHostAdapterLocalRAMRequest.ByteOffset = - BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0; - FetchHostAdapterLocalRAMRequest.ByteCount = - sizeof(Drive0MapByte); - BusLogic_Command(HostAdapter, - BusLogic_FetchHostAdapterLocalRAM, - &FetchHostAdapterLocalRAMRequest, - sizeof(FetchHostAdapterLocalRAMRequest), - &Drive0MapByte, sizeof(Drive0MapByte)); - /* - If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0 - is controlled by this PCI MultiMaster Host Adapter, then - reverse the probe order so that MultiMaster Host Adapters are - probed before FlashPoint Host Adapters. - */ - if (Drive0MapByte.DiskGeometry != - BusLogic_BIOS_Disk_Not_Installed) - { - struct BusLogic_ProbeInfo - SavedProbeInfo[BusLogic_MaxHostAdapters]; - int MultiMasterCount = - BusLogic_ProbeInfoCount - FlashPointCount; - memcpy(SavedProbeInfo, - BusLogic_ProbeInfoList, - BusLogic_ProbeInfoCount - * sizeof(struct BusLogic_ProbeInfo)); - memcpy(&BusLogic_ProbeInfoList[0], - &SavedProbeInfo[FlashPointCount], - MultiMasterCount * sizeof(struct BusLogic_ProbeInfo)); - memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], - &SavedProbeInfo[0], - FlashPointCount * sizeof(struct BusLogic_ProbeInfo)); + /* + If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint + Host Adapters; otherwise, default to the standard ISA MultiMaster probe. + */ + if (!BusLogic_ProbeOptions.NoProbePCI) { + if (BusLogic_ProbeOptions.MultiMasterFirst) { + BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); + BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); + } else if (BusLogic_ProbeOptions.FlashPointFirst) { + BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); + BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); + } else { + int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); + int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); + if (FlashPointCount > 0 && PCIMultiMasterCount > 0) { + struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount]; + struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; + struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest; + struct BusLogic_BIOSDriveMapByte Drive0MapByte; + while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus) + ProbeInfo++; + HostAdapter->IO_Address = ProbeInfo->IO_Address; + FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0; + FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte); + BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte)); + /* + If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0 + is controlled by this PCI MultiMaster Host Adapter, then + reverse the probe order so that MultiMaster Host Adapters are + probed before FlashPoint Host Adapters. + */ + if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) { + struct BusLogic_ProbeInfo SavedProbeInfo[BusLogic_MaxHostAdapters]; + int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount; + memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(struct BusLogic_ProbeInfo)); + memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(struct BusLogic_ProbeInfo)); + memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(struct BusLogic_ProbeInfo)); + } + } } - } - } - } - else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter); + } else + BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter); } -#endif /* CONFIG_PCI */ +#endif /* CONFIG_PCI */ /* BusLogic_Failure prints a standardized error message, and then returns false. */ -static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, - char *ErrorMessage) +static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage) { - BusLogic_AnnounceDriver(HostAdapter); - if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) - { - 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); - BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage); - if (BusLogic_CommandFailureReason != NULL) - BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, - BusLogic_CommandFailureReason); - return false; + BusLogic_AnnounceDriver(HostAdapter); + if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) { + 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); + BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage); + if (BusLogic_CommandFailureReason != NULL) + BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter, BusLogic_CommandFailureReason); + return false; } @@ -1283,81 +1068,64 @@ static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter) { - union BusLogic_StatusRegister StatusRegister; - union BusLogic_InterruptRegister InterruptRegister; - union BusLogic_GeometryRegister GeometryRegister; - /* - FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - { - struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; - FlashPointInfo->BaseAddress = - (u32) HostAdapter->IO_Address; - FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel; - FlashPointInfo->Present = false; - if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && - FlashPointInfo->Present)) - { - BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " - "PCI Bus %d Device %d\n", HostAdapter, - HostAdapter->Bus, HostAdapter->Device); - BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " - "but FlashPoint\n", HostAdapter, - HostAdapter->IO_Address, HostAdapter->PCI_Address); - BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", - HostAdapter); - return false; + union BusLogic_StatusRegister StatusRegister; + union BusLogic_InterruptRegister InterruptRegister; + union BusLogic_GeometryRegister GeometryRegister; + /* + FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager. + */ + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { + struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; + FlashPointInfo->BaseAddress = (u32) HostAdapter->IO_Address; + FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel; + FlashPointInfo->Present = false; + if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) { + BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %d\n", HostAdapter, HostAdapter->Bus, HostAdapter->Device); + BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, " "but FlashPoint\n", HostAdapter, HostAdapter->IO_Address, HostAdapter->PCI_Address); + BusLogic_Error("BusLogic: Probe Function failed to validate it.\n", HostAdapter); + return false; + } + if (BusLogic_GlobalOptions.TraceProbe) + BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", HostAdapter, HostAdapter->IO_Address); + /* + Indicate the Host Adapter Probe completed successfully. + */ + return true; } - if (BusLogic_GlobalOptions.TraceProbe) - BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n", - HostAdapter, HostAdapter->IO_Address); - /* - Indicate the Host Adapter Probe completed successfully. - */ - return true; - } - /* - Read the Status, Interrupt, and Geometry Registers to test if there are I/O - ports that respond, and to check the values to determine if they are from a - BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which - case there is definitely no BusLogic Host Adapter at this base I/O Address. - The test here is a subset of that used by the BusLogic Host Adapter BIOS. - */ - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter); - if (BusLogic_GlobalOptions.TraceProbe) - BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " - "Geometry 0x%02X\n", HostAdapter, - HostAdapter->IO_Address, StatusRegister.All, - InterruptRegister.All, GeometryRegister.All); - if (StatusRegister.All == 0 || - StatusRegister.sr.DiagnosticActive || - StatusRegister.sr.CommandParameterRegisterBusy || - StatusRegister.sr.Reserved || - StatusRegister.sr.CommandInvalid || - InterruptRegister.ir.Reserved != 0) - return false; - /* - Check the undocumented Geometry Register to test if there is an I/O port - that responded. Adaptec Host Adapters do not implement the Geometry - Register, so this test helps serve to avoid incorrectly recognizing an - Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C - series does respond to the Geometry Register I/O port, but it will be - rejected later when the Inquire Extended Setup Information command is - issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a - BusLogic clone that implements the same interface as earlier BusLogic - Host Adapters, including the undocumented commands, and is therefore - supported by this driver. However, the AMI FastDisk always returns 0x00 - upon reading the Geometry Register, so the extended translation option - should always be left disabled on the AMI FastDisk. - */ - if (GeometryRegister.All == 0xFF) return false; - /* - Indicate the Host Adapter Probe completed successfully. - */ - return true; + /* + Read the Status, Interrupt, and Geometry Registers to test if there are I/O + ports that respond, and to check the values to determine if they are from a + BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which + case there is definitely no BusLogic Host Adapter at this base I/O Address. + The test here is a subset of that used by the BusLogic Host Adapter BIOS. + */ + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); + GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter); + if (BusLogic_GlobalOptions.TraceProbe) + BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, " "Geometry 0x%02X\n", HostAdapter, HostAdapter->IO_Address, StatusRegister.All, InterruptRegister.All, GeometryRegister.All); + if (StatusRegister.All == 0 || StatusRegister.sr.DiagnosticActive || StatusRegister.sr.CommandParameterRegisterBusy || StatusRegister.sr.Reserved || StatusRegister.sr.CommandInvalid || InterruptRegister.ir.Reserved != 0) + return false; + /* + Check the undocumented Geometry Register to test if there is an I/O port + that responded. Adaptec Host Adapters do not implement the Geometry + Register, so this test helps serve to avoid incorrectly recognizing an + Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C + series does respond to the Geometry Register I/O port, but it will be + rejected later when the Inquire Extended Setup Information command is + issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a + BusLogic clone that implements the same interface as earlier BusLogic + Host Adapters, including the undocumented commands, and is therefore + supported by this driver. However, the AMI FastDisk always returns 0x00 + upon reading the Geometry Register, so the extended translation option + should always be left disabled on the AMI FastDisk. + */ + if (GeometryRegister.All == 0xFF) + return false; + /* + Indicate the Host Adapter Probe completed successfully. + */ + return true; } @@ -1370,113 +1138,101 @@ static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *Hos */ static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter - *HostAdapter, - boolean HardReset) + *HostAdapter, boolean HardReset) { - union BusLogic_StatusRegister StatusRegister; - int TimeoutCounter; - /* - FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - { - struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; - FlashPointInfo->HostSoftReset = !HardReset; - FlashPointInfo->ReportDataUnderrun = true; - HostAdapter->CardHandle = - FlashPoint_HardwareResetHostAdapter(FlashPointInfo); - if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false; - /* - Indicate the Host Adapter Hard Reset completed successfully. - */ - return true; - } - /* - Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host - Adapter should respond by setting Diagnostic Active in the Status Register. - */ - if (HardReset) - BusLogic_HardReset(HostAdapter); - else BusLogic_SoftReset(HostAdapter); - /* - Wait until Diagnostic Active is set in the Status Register. - */ - TimeoutCounter = 5*10000; - while (--TimeoutCounter >= 0) - { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.DiagnosticActive) break; - udelay(100); - } - 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; - /* - Wait 100 microseconds to allow completion of any initial diagnostic - activity which might leave the contents of the Status Register - unpredictable. - */ - udelay(100); - /* - Wait until Diagnostic Active is reset in the Status Register. - */ - TimeoutCounter = 10*10000; - while (--TimeoutCounter >= 0) - { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (!StatusRegister.sr.DiagnosticActive) break; - udelay(100); - } - 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; - /* - Wait until at least one of the Diagnostic Failure, Host Adapter Ready, - or Data In Register Ready bits is set in the Status Register. - */ - TimeoutCounter = 10000; - while (--TimeoutCounter >= 0) - { - StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); - if (StatusRegister.sr.DiagnosticFailure || - StatusRegister.sr.HostAdapterReady || - StatusRegister.sr.DataInRegisterReady) - break; - udelay(100); - } - 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; - /* - If Diagnostic Failure is set or Host Adapter Ready is reset, then an - error occurred during the Host Adapter diagnostics. If Data In Register - Ready is set, then there is an Error Code available. - */ - if (StatusRegister.sr.DiagnosticFailure || - !StatusRegister.sr.HostAdapterReady) - { - BusLogic_CommandFailureReason = NULL; - BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS"); - BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", - HostAdapter, StatusRegister.All); - if (StatusRegister.sr.DataInRegisterReady) - { - unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter); - BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", - HostAdapter, ErrorCode); + union BusLogic_StatusRegister StatusRegister; + int TimeoutCounter; + /* + FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager. + */ + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { + struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; + FlashPointInfo->HostSoftReset = !HardReset; + FlashPointInfo->ReportDataUnderrun = true; + HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo); + if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) + return false; + /* + Indicate the Host Adapter Hard Reset completed successfully. + */ + return true; + } + /* + Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host + Adapter should respond by setting Diagnostic Active in the Status Register. + */ + if (HardReset) + BusLogic_HardReset(HostAdapter); + else + BusLogic_SoftReset(HostAdapter); + /* + Wait until Diagnostic Active is set in the Status Register. + */ + TimeoutCounter = 5 * 10000; + while (--TimeoutCounter >= 0) { + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (StatusRegister.sr.DiagnosticActive) + break; + udelay(100); } - return false; - } - /* - Indicate the Host Adapter Hard Reset completed successfully. - */ - return true; + 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; + /* + Wait 100 microseconds to allow completion of any initial diagnostic + activity which might leave the contents of the Status Register + unpredictable. + */ + udelay(100); + /* + Wait until Diagnostic Active is reset in the Status Register. + */ + TimeoutCounter = 10 * 10000; + while (--TimeoutCounter >= 0) { + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (!StatusRegister.sr.DiagnosticActive) + break; + udelay(100); + } + 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; + /* + Wait until at least one of the Diagnostic Failure, Host Adapter Ready, + or Data In Register Ready bits is set in the Status Register. + */ + TimeoutCounter = 10000; + while (--TimeoutCounter >= 0) { + StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); + if (StatusRegister.sr.DiagnosticFailure || StatusRegister.sr.HostAdapterReady || StatusRegister.sr.DataInRegisterReady) + break; + udelay(100); + } + 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; + /* + If Diagnostic Failure is set or Host Adapter Ready is reset, then an + error occurred during the Host Adapter diagnostics. If Data In Register + Ready is set, then there is an Error Code available. + */ + if (StatusRegister.sr.DiagnosticFailure || !StatusRegister.sr.HostAdapterReady) { + BusLogic_CommandFailureReason = NULL; + BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS"); + BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All); + if (StatusRegister.sr.DataInRegisterReady) { + unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter); + BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n", HostAdapter, ErrorCode); + } + return false; + } + /* + Indicate the Host Adapter Hard Reset completed successfully. + */ + return true; } @@ -1487,35 +1243,30 @@ static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter) { - struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; - unsigned char RequestedReplyLength; - boolean Result = true; - /* - FlashPoint Host Adapters do not require this protection. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true; - /* - Issue the Inquire Extended Setup Information command. Only genuine - BusLogic Host Adapters and true clones support this command. Adaptec 1542C - series Host Adapters that respond to the Geometry Register I/O port will - fail this command. - */ - RequestedReplyLength = sizeof(ExtendedSetupInformation); - if (BusLogic_Command(HostAdapter, - BusLogic_InquireExtendedSetupInformation, - &RequestedReplyLength, - sizeof(RequestedReplyLength), - &ExtendedSetupInformation, - sizeof(ExtendedSetupInformation)) - != sizeof(ExtendedSetupInformation)) - Result = false; - /* - Provide tracing information if requested and return. - */ - if (BusLogic_GlobalOptions.TraceProbe) - BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, - HostAdapter->IO_Address, (Result ? "Found" : "Not Found")); - return Result; + struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; + unsigned char RequestedReplyLength; + boolean Result = true; + /* + FlashPoint Host Adapters do not require this protection. + */ + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + return true; + /* + Issue the Inquire Extended Setup Information command. Only genuine + BusLogic Host Adapters and true clones support this command. Adaptec 1542C + series Host Adapters that respond to the Geometry Register I/O port will + fail this command. + */ + RequestedReplyLength = sizeof(ExtendedSetupInformation); + if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation)) + != sizeof(ExtendedSetupInformation)) + Result = false; + /* + Provide tracing information if requested and return. + */ + if (BusLogic_GlobalOptions.TraceProbe) + BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter, HostAdapter->IO_Address, (Result ? "Found" : "Not Found")); + return Result; } @@ -1527,513 +1278,442 @@ static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *Hos static boolean __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter *HostAdapter) { - struct BusLogic_BoardID BoardID; - struct BusLogic_Configuration Configuration; - struct BusLogic_SetupInformation SetupInformation; - struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; - unsigned char HostAdapterModelNumber[5]; - unsigned char FirmwareVersion3rdDigit; - unsigned char FirmwareVersionLetter; - struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation; - struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest; - struct BusLogic_AutoSCSIData AutoSCSIData; - union BusLogic_GeometryRegister GeometryRegister; - unsigned char RequestedReplyLength; - unsigned char *TargetPointer, Character; - int TargetID, i; - /* - Configuration Information for FlashPoint Host Adapters is provided in the - FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function. - Initialize fields in the Host Adapter structure from the FlashPoint_Info - structure. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - { - struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; - TargetPointer = HostAdapter->ModelName; - *TargetPointer++ = 'B'; - *TargetPointer++ = 'T'; - *TargetPointer++ = '-'; - for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++) - *TargetPointer++ = FlashPointInfo->ModelNumber[i]; - *TargetPointer++ = '\0'; - strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion); - HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID; - HostAdapter->ExtendedTranslationEnabled = - FlashPointInfo->ExtendedTranslationEnabled; - HostAdapter->ParityCheckingEnabled = - FlashPointInfo->ParityCheckingEnabled; - HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset; - HostAdapter->LevelSensitiveInterrupt = true; - HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI; - HostAdapter->HostDifferentialSCSI = false; - HostAdapter->HostSupportsSCAM = true; - HostAdapter->HostUltraSCSI = true; - HostAdapter->ExtendedLUNSupport = true; - HostAdapter->TerminationInfoValid = true; - HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated; - HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated; - HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled; - HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2; - HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit; - HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); - HostAdapter->MaxLogicalUnits = 32; - HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; - HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; - HostAdapter->DriverQueueDepth = 255; - HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth; - HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted; - HostAdapter->FastPermitted = FlashPointInfo->FastPermitted; - HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted; - HostAdapter->WidePermitted = FlashPointInfo->WidePermitted; - HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted; - HostAdapter->TaggedQueuingPermitted = 0xFFFF; - goto Common; - } - /* - Issue the Inquire Board ID command. - */ - if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, - &BoardID, sizeof(BoardID)) != sizeof(BoardID)) - return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID"); - /* - Issue the Inquire Configuration command. - */ - if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, - &Configuration, sizeof(Configuration)) - != sizeof(Configuration)) - return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION"); - /* - Issue the Inquire Setup Information command. - */ - RequestedReplyLength = sizeof(SetupInformation); - if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, - &RequestedReplyLength, sizeof(RequestedReplyLength), - &SetupInformation, sizeof(SetupInformation)) - != sizeof(SetupInformation)) - return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION"); - /* - Issue the Inquire Extended Setup Information command. - */ - RequestedReplyLength = sizeof(ExtendedSetupInformation); - if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, - &RequestedReplyLength, sizeof(RequestedReplyLength), - &ExtendedSetupInformation, - sizeof(ExtendedSetupInformation)) - != sizeof(ExtendedSetupInformation)) - return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION"); - /* - Issue the Inquire Firmware Version 3rd Digit command. - */ - FirmwareVersion3rdDigit = '\0'; - if (BoardID.FirmwareVersion1stDigit > '0') - if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, - NULL, 0, &FirmwareVersion3rdDigit, - sizeof(FirmwareVersion3rdDigit)) - != sizeof(FirmwareVersion3rdDigit)) - return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT"); - /* - Issue the Inquire Host Adapter Model Number command. - */ - if (ExtendedSetupInformation.BusType == 'A' && - BoardID.FirmwareVersion1stDigit == '2') - /* BusLogic BT-542B ISA 2.xx */ - strcpy(HostAdapterModelNumber, "542B"); - else if (ExtendedSetupInformation.BusType == 'E' && - BoardID.FirmwareVersion1stDigit == '2' && - (BoardID.FirmwareVersion2ndDigit <= '1' || - (BoardID.FirmwareVersion2ndDigit == '2' && - FirmwareVersion3rdDigit == '0'))) - /* BusLogic BT-742A EISA 2.1x or 2.20 */ - strcpy(HostAdapterModelNumber, "742A"); - else if (ExtendedSetupInformation.BusType == 'E' && - BoardID.FirmwareVersion1stDigit == '0') - /* AMI FastDisk EISA Series 441 0.x */ - strcpy(HostAdapterModelNumber, "747A"); - else - { - RequestedReplyLength = sizeof(HostAdapterModelNumber); - if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, - &RequestedReplyLength, sizeof(RequestedReplyLength), - &HostAdapterModelNumber, - sizeof(HostAdapterModelNumber)) - != sizeof(HostAdapterModelNumber)) - return BusLogic_Failure(HostAdapter, - "INQUIRE HOST ADAPTER MODEL NUMBER"); - } - /* - BusLogic MultiMaster Host Adapters can be identified by their model number - and the major version number of their firmware as follows: - - 5.xx BusLogic "W" Series Host Adapters: - BT-948/958/958D - 4.xx BusLogic "C" Series Host Adapters: - BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF - 3.xx BusLogic "S" Series Host Adapters: - BT-747S/747D/757S/757D/445S/545S/542D - BT-542B/742A (revision H) - 2.xx BusLogic "A" Series Host Adapters: - BT-542B/742A (revision G and below) - 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter - */ - /* - Save the Model Name and Host Adapter Name in the Host Adapter structure. - */ - TargetPointer = HostAdapter->ModelName; - *TargetPointer++ = 'B'; - *TargetPointer++ = 'T'; - *TargetPointer++ = '-'; - for (i = 0; i < sizeof(HostAdapterModelNumber); i++) - { - Character = HostAdapterModelNumber[i]; - if (Character == ' ' || Character == '\0') break; - *TargetPointer++ = Character; - } - *TargetPointer++ = '\0'; - /* - Save the Firmware Version in the Host Adapter structure. - */ - TargetPointer = HostAdapter->FirmwareVersion; - *TargetPointer++ = BoardID.FirmwareVersion1stDigit; - *TargetPointer++ = '.'; - *TargetPointer++ = BoardID.FirmwareVersion2ndDigit; - if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0') - *TargetPointer++ = FirmwareVersion3rdDigit; - *TargetPointer = '\0'; - /* - Issue the Inquire Firmware Version Letter command. - */ - if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) - { - if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, - NULL, 0, &FirmwareVersionLetter, - sizeof(FirmwareVersionLetter)) - != sizeof(FirmwareVersionLetter)) - return BusLogic_Failure(HostAdapter, - "INQUIRE FIRMWARE VERSION LETTER"); - if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0') - *TargetPointer++ = FirmwareVersionLetter; - *TargetPointer = '\0'; - } - /* - Save the Host Adapter SCSI ID in the Host Adapter structure. - */ - HostAdapter->SCSI_ID = Configuration.HostAdapterID; - /* - Determine the Bus Type and save it in the Host Adapter structure, determine - and save the IRQ Channel if necessary, and determine and save the DMA - Channel for ISA Host Adapters. - */ - HostAdapter->HostAdapterBusType = - BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4']; - if (HostAdapter->IRQ_Channel == 0) - { - if (Configuration.IRQ_Channel9) - HostAdapter->IRQ_Channel = 9; - else if (Configuration.IRQ_Channel10) - HostAdapter->IRQ_Channel = 10; - else if (Configuration.IRQ_Channel11) - HostAdapter->IRQ_Channel = 11; - else if (Configuration.IRQ_Channel12) - HostAdapter->IRQ_Channel = 12; - else if (Configuration.IRQ_Channel14) - HostAdapter->IRQ_Channel = 14; - else if (Configuration.IRQ_Channel15) - HostAdapter->IRQ_Channel = 15; - } - if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) - { - if (Configuration.DMA_Channel5) - HostAdapter->DMA_Channel = 5; - else if (Configuration.DMA_Channel6) - HostAdapter->DMA_Channel = 6; - else if (Configuration.DMA_Channel7) - HostAdapter->DMA_Channel = 7; - } - /* - Determine whether Extended Translation is enabled and save it in - the Host Adapter structure. - */ - GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter); - HostAdapter->ExtendedTranslationEnabled = - GeometryRegister.gr.ExtendedTranslationEnabled; - /* - Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide - SCSI flag, Differential SCSI flag, SCAM Supported flag, and - Ultra SCSI flag in the Host Adapter structure. - */ - HostAdapter->HostAdapterScatterGatherLimit = - ExtendedSetupInformation.ScatterGatherLimit; - HostAdapter->DriverScatterGatherLimit = - HostAdapter->HostAdapterScatterGatherLimit; - if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit) - HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit; - if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt) - HostAdapter->LevelSensitiveInterrupt = true; - HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI; - HostAdapter->HostDifferentialSCSI = - ExtendedSetupInformation.HostDifferentialSCSI; - HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM; - HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI; - /* - Determine whether Extended LUN Format CCBs are supported and save the - information in the Host Adapter structure. - */ - if (HostAdapter->FirmwareVersion[0] == '5' || - (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI)) - HostAdapter->ExtendedLUNSupport = true; - /* - Issue the Inquire PCI Host Adapter Information command to read the - Termination Information from "W" series MultiMaster Host Adapters. - */ - if (HostAdapter->FirmwareVersion[0] == '5') - { - if (BusLogic_Command(HostAdapter, - BusLogic_InquirePCIHostAdapterInformation, - NULL, 0, &PCIHostAdapterInformation, - sizeof(PCIHostAdapterInformation)) - != sizeof(PCIHostAdapterInformation)) - return BusLogic_Failure(HostAdapter, - "INQUIRE PCI HOST ADAPTER INFORMATION"); - /* - Save the Termination Information in the Host Adapter structure. - */ - if (PCIHostAdapterInformation.GenericInfoValid) - { - HostAdapter->TerminationInfoValid = true; - HostAdapter->LowByteTerminated = - PCIHostAdapterInformation.LowByteTerminated; - HostAdapter->HighByteTerminated = - PCIHostAdapterInformation.HighByteTerminated; + struct BusLogic_BoardID BoardID; + struct BusLogic_Configuration Configuration; + struct BusLogic_SetupInformation SetupInformation; + struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; + unsigned char HostAdapterModelNumber[5]; + unsigned char FirmwareVersion3rdDigit; + unsigned char FirmwareVersionLetter; + struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation; + struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest; + struct BusLogic_AutoSCSIData AutoSCSIData; + union BusLogic_GeometryRegister GeometryRegister; + unsigned char RequestedReplyLength; + unsigned char *TargetPointer, Character; + int TargetID, i; + /* + Configuration Information for FlashPoint Host Adapters is provided in the + FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function. + Initialize fields in the Host Adapter structure from the FlashPoint_Info + structure. + */ + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { + struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo; + TargetPointer = HostAdapter->ModelName; + *TargetPointer++ = 'B'; + *TargetPointer++ = 'T'; + *TargetPointer++ = '-'; + for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++) + *TargetPointer++ = FlashPointInfo->ModelNumber[i]; + *TargetPointer++ = '\0'; + strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion); + HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID; + HostAdapter->ExtendedTranslationEnabled = FlashPointInfo->ExtendedTranslationEnabled; + HostAdapter->ParityCheckingEnabled = FlashPointInfo->ParityCheckingEnabled; + HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset; + HostAdapter->LevelSensitiveInterrupt = true; + HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI; + HostAdapter->HostDifferentialSCSI = false; + HostAdapter->HostSupportsSCAM = true; + HostAdapter->HostUltraSCSI = true; + HostAdapter->ExtendedLUNSupport = true; + HostAdapter->TerminationInfoValid = true; + HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated; + HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated; + HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled; + HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2; + HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit; + HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); + HostAdapter->MaxLogicalUnits = 32; + HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; + HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; + HostAdapter->DriverQueueDepth = 255; + HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth; + HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted; + HostAdapter->FastPermitted = FlashPointInfo->FastPermitted; + HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted; + HostAdapter->WidePermitted = FlashPointInfo->WidePermitted; + HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted; + HostAdapter->TaggedQueuingPermitted = 0xFFFF; + goto Common; + } + /* + Issue the Inquire Board ID command. + */ + if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0, &BoardID, sizeof(BoardID)) != sizeof(BoardID)) + return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID"); + /* + Issue the Inquire Configuration command. + */ + if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0, &Configuration, sizeof(Configuration)) + != sizeof(Configuration)) + return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION"); + /* + Issue the Inquire Setup Information command. + */ + RequestedReplyLength = sizeof(SetupInformation); + if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation)) + != sizeof(SetupInformation)) + return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION"); + /* + Issue the Inquire Extended Setup Information command. + */ + RequestedReplyLength = sizeof(ExtendedSetupInformation); + if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &ExtendedSetupInformation, sizeof(ExtendedSetupInformation)) + != sizeof(ExtendedSetupInformation)) + return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION"); + /* + Issue the Inquire Firmware Version 3rd Digit command. + */ + FirmwareVersion3rdDigit = '\0'; + if (BoardID.FirmwareVersion1stDigit > '0') + if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, NULL, 0, &FirmwareVersion3rdDigit, sizeof(FirmwareVersion3rdDigit)) + != sizeof(FirmwareVersion3rdDigit)) + return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT"); + /* + Issue the Inquire Host Adapter Model Number command. + */ + if (ExtendedSetupInformation.BusType == 'A' && BoardID.FirmwareVersion1stDigit == '2') + /* BusLogic BT-542B ISA 2.xx */ + strcpy(HostAdapterModelNumber, "542B"); + else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '2' && (BoardID.FirmwareVersion2ndDigit <= '1' || (BoardID.FirmwareVersion2ndDigit == '2' && FirmwareVersion3rdDigit == '0'))) + /* BusLogic BT-742A EISA 2.1x or 2.20 */ + strcpy(HostAdapterModelNumber, "742A"); + else if (ExtendedSetupInformation.BusType == 'E' && BoardID.FirmwareVersion1stDigit == '0') + /* AMI FastDisk EISA Series 441 0.x */ + strcpy(HostAdapterModelNumber, "747A"); + else { + RequestedReplyLength = sizeof(HostAdapterModelNumber); + if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber, &RequestedReplyLength, sizeof(RequestedReplyLength), &HostAdapterModelNumber, sizeof(HostAdapterModelNumber)) + != sizeof(HostAdapterModelNumber)) + return BusLogic_Failure(HostAdapter, "INQUIRE HOST ADAPTER MODEL NUMBER"); } - } - /* - Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data - from "W" and "C" series MultiMaster Host Adapters. - */ - if (HostAdapter->FirmwareVersion[0] >= '4') - { - FetchHostAdapterLocalRAMRequest.ByteOffset = - BusLogic_AutoSCSI_BaseOffset; - FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData); - if (BusLogic_Command(HostAdapter, - BusLogic_FetchHostAdapterLocalRAM, - &FetchHostAdapterLocalRAMRequest, - sizeof(FetchHostAdapterLocalRAMRequest), - &AutoSCSIData, sizeof(AutoSCSIData)) - != sizeof(AutoSCSIData)) - return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM"); - /* - Save the Parity Checking Enabled, Bus Reset Enabled, and Termination - Information in the Host Adapter structure. - */ - HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled; - HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled; - if (HostAdapter->FirmwareVersion[0] == '4') - { - HostAdapter->TerminationInfoValid = true; - HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated; - HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated; + /* + BusLogic MultiMaster Host Adapters can be identified by their model number + and the major version number of their firmware as follows: + + 5.xx BusLogic "W" Series Host Adapters: + BT-948/958/958D + 4.xx BusLogic "C" Series Host Adapters: + BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF + 3.xx BusLogic "S" Series Host Adapters: + BT-747S/747D/757S/757D/445S/545S/542D + BT-542B/742A (revision H) + 2.xx BusLogic "A" Series Host Adapters: + BT-542B/742A (revision G and below) + 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter + */ + /* + Save the Model Name and Host Adapter Name in the Host Adapter structure. + */ + TargetPointer = HostAdapter->ModelName; + *TargetPointer++ = 'B'; + *TargetPointer++ = 'T'; + *TargetPointer++ = '-'; + for (i = 0; i < sizeof(HostAdapterModelNumber); i++) { + Character = HostAdapterModelNumber[i]; + if (Character == ' ' || Character == '\0') + break; + *TargetPointer++ = Character; + } + *TargetPointer++ = '\0'; + /* + Save the Firmware Version in the Host Adapter structure. + */ + TargetPointer = HostAdapter->FirmwareVersion; + *TargetPointer++ = BoardID.FirmwareVersion1stDigit; + *TargetPointer++ = '.'; + *TargetPointer++ = BoardID.FirmwareVersion2ndDigit; + if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0') + *TargetPointer++ = FirmwareVersion3rdDigit; + *TargetPointer = '\0'; + /* + Issue the Inquire Firmware Version Letter command. + */ + if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0) { + if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter, NULL, 0, &FirmwareVersionLetter, sizeof(FirmwareVersionLetter)) + != sizeof(FirmwareVersionLetter)) + return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER"); + if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0') + *TargetPointer++ = FirmwareVersionLetter; + *TargetPointer = '\0'; } - /* - Save the Wide Permitted, Fast Permitted, Synchronous Permitted, - Disconnect Permitted, Ultra Permitted, and SCAM Information in the - Host Adapter structure. - */ - HostAdapter->WidePermitted = AutoSCSIData.WidePermitted; - HostAdapter->FastPermitted = AutoSCSIData.FastPermitted; - HostAdapter->SynchronousPermitted = - AutoSCSIData.SynchronousPermitted; - HostAdapter->DisconnectPermitted = - AutoSCSIData.DisconnectPermitted; - if (HostAdapter->HostUltraSCSI) - HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted; - if (HostAdapter->HostSupportsSCAM) - { - HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled; - HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2; + /* + Save the Host Adapter SCSI ID in the Host Adapter structure. + */ + HostAdapter->SCSI_ID = Configuration.HostAdapterID; + /* + Determine the Bus Type and save it in the Host Adapter structure, determine + and save the IRQ Channel if necessary, and determine and save the DMA + Channel for ISA Host Adapters. + */ + HostAdapter->HostAdapterBusType = BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4']; + if (HostAdapter->IRQ_Channel == 0) { + if (Configuration.IRQ_Channel9) + HostAdapter->IRQ_Channel = 9; + else if (Configuration.IRQ_Channel10) + HostAdapter->IRQ_Channel = 10; + else if (Configuration.IRQ_Channel11) + HostAdapter->IRQ_Channel = 11; + else if (Configuration.IRQ_Channel12) + HostAdapter->IRQ_Channel = 12; + else if (Configuration.IRQ_Channel14) + HostAdapter->IRQ_Channel = 14; + else if (Configuration.IRQ_Channel15) + HostAdapter->IRQ_Channel = 15; + } + if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus) { + if (Configuration.DMA_Channel5) + HostAdapter->DMA_Channel = 5; + else if (Configuration.DMA_Channel6) + HostAdapter->DMA_Channel = 6; + else if (Configuration.DMA_Channel7) + HostAdapter->DMA_Channel = 7; } - } - /* - Initialize fields in the Host Adapter structure for "S" and "A" series - MultiMaster Host Adapters. - */ - if (HostAdapter->FirmwareVersion[0] < '4') - { - if (SetupInformation.SynchronousInitiationEnabled) - { - HostAdapter->SynchronousPermitted = 0xFF; - if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) - { - if (ExtendedSetupInformation.Misc.FastOnEISA) - HostAdapter->FastPermitted = 0xFF; - if (strcmp(HostAdapter->ModelName, "BT-757") == 0) - HostAdapter->WidePermitted = 0xFF; - } + /* + Determine whether Extended Translation is enabled and save it in + the Host Adapter structure. + */ + GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter); + HostAdapter->ExtendedTranslationEnabled = GeometryRegister.gr.ExtendedTranslationEnabled; + /* + Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide + SCSI flag, Differential SCSI flag, SCAM Supported flag, and + Ultra SCSI flag in the Host Adapter structure. + */ + HostAdapter->HostAdapterScatterGatherLimit = ExtendedSetupInformation.ScatterGatherLimit; + HostAdapter->DriverScatterGatherLimit = HostAdapter->HostAdapterScatterGatherLimit; + if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit) + HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit; + if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt) + HostAdapter->LevelSensitiveInterrupt = true; + HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI; + HostAdapter->HostDifferentialSCSI = ExtendedSetupInformation.HostDifferentialSCSI; + HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM; + HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI; + /* + Determine whether Extended LUN Format CCBs are supported and save the + information in the Host Adapter structure. + */ + if (HostAdapter->FirmwareVersion[0] == '5' || (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI)) + HostAdapter->ExtendedLUNSupport = true; + /* + Issue the Inquire PCI Host Adapter Information command to read the + Termination Information from "W" series MultiMaster Host Adapters. + */ + if (HostAdapter->FirmwareVersion[0] == '5') { + if (BusLogic_Command(HostAdapter, BusLogic_InquirePCIHostAdapterInformation, NULL, 0, &PCIHostAdapterInformation, sizeof(PCIHostAdapterInformation)) + != sizeof(PCIHostAdapterInformation)) + return BusLogic_Failure(HostAdapter, "INQUIRE PCI HOST ADAPTER INFORMATION"); + /* + Save the Termination Information in the Host Adapter structure. + */ + if (PCIHostAdapterInformation.GenericInfoValid) { + HostAdapter->TerminationInfoValid = true; + HostAdapter->LowByteTerminated = PCIHostAdapterInformation.LowByteTerminated; + HostAdapter->HighByteTerminated = PCIHostAdapterInformation.HighByteTerminated; + } + } + /* + Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data + from "W" and "C" series MultiMaster Host Adapters. + */ + if (HostAdapter->FirmwareVersion[0] >= '4') { + FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_AutoSCSI_BaseOffset; + FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData); + if (BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &AutoSCSIData, sizeof(AutoSCSIData)) + != sizeof(AutoSCSIData)) + return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM"); + /* + Save the Parity Checking Enabled, Bus Reset Enabled, and Termination + Information in the Host Adapter structure. + */ + HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled; + HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled; + if (HostAdapter->FirmwareVersion[0] == '4') { + HostAdapter->TerminationInfoValid = true; + HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated; + HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated; + } + /* + Save the Wide Permitted, Fast Permitted, Synchronous Permitted, + Disconnect Permitted, Ultra Permitted, and SCAM Information in the + Host Adapter structure. + */ + HostAdapter->WidePermitted = AutoSCSIData.WidePermitted; + HostAdapter->FastPermitted = AutoSCSIData.FastPermitted; + HostAdapter->SynchronousPermitted = AutoSCSIData.SynchronousPermitted; + HostAdapter->DisconnectPermitted = AutoSCSIData.DisconnectPermitted; + if (HostAdapter->HostUltraSCSI) + HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted; + if (HostAdapter->HostSupportsSCAM) { + HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled; + HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2; + } + } + /* + Initialize fields in the Host Adapter structure for "S" and "A" series + MultiMaster Host Adapters. + */ + if (HostAdapter->FirmwareVersion[0] < '4') { + if (SetupInformation.SynchronousInitiationEnabled) { + HostAdapter->SynchronousPermitted = 0xFF; + if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus) { + if (ExtendedSetupInformation.Misc.FastOnEISA) + HostAdapter->FastPermitted = 0xFF; + if (strcmp(HostAdapter->ModelName, "BT-757") == 0) + HostAdapter->WidePermitted = 0xFF; + } + } + HostAdapter->DisconnectPermitted = 0xFF; + HostAdapter->ParityCheckingEnabled = SetupInformation.ParityCheckingEnabled; + HostAdapter->BusResetEnabled = true; + } + /* + Determine the maximum number of Target IDs and Logical Units supported by + this driver for Wide and Narrow Host Adapters. + */ + HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); + HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8); + /* + Select appropriate values for the Mailbox Count, Driver Queue Depth, + Initial CCBs, and Incremental CCBs variables based on whether or not Strict + Round Robin Mode is supported. If Strict Round Robin Mode is supported, + then there is no performance degradation in using the maximum possible + number of Outgoing and Incoming Mailboxes and allowing the Tagged and + Untagged Queue Depths to determine the actual utilization. If Strict Round + Robin Mode is not supported, then the Host Adapter must scan all the + Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can + cause a substantial performance penalty. The host adapters actually have + room to store the following number of CCBs internally; that is, they can + internally queue and manage this many active commands on the SCSI bus + simultaneously. Performance measurements demonstrate that the Driver Queue + Depth should be set to the Mailbox Count, rather than the Host Adapter + Queue Depth (internal CCB capacity), as it is more efficient to have the + queued commands waiting in Outgoing Mailboxes if necessary than to block + the process in the higher levels of the SCSI Subsystem. + + 192 BT-948/958/958D + 100 BT-946C/956C/956CD/747C/757C/757CD/445C + 50 BT-545C/540CF + 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A + */ + if (HostAdapter->FirmwareVersion[0] == '5') + HostAdapter->HostAdapterQueueDepth = 192; + else if (HostAdapter->FirmwareVersion[0] == '4') + HostAdapter->HostAdapterQueueDepth = (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50); + else + HostAdapter->HostAdapterQueueDepth = 30; + if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) { + HostAdapter->StrictRoundRobinModeSupport = true; + HostAdapter->MailboxCount = BusLogic_MaxMailboxes; + } else { + HostAdapter->StrictRoundRobinModeSupport = false; + HostAdapter->MailboxCount = 32; + } + HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount; + HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; + HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; + /* + Tagged Queuing support is available and operates properly on all "W" series + MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with + firmware version 4.22 and above, and on "S" series MultiMaster Host + Adapters with firmware version 3.35 and above. + */ + HostAdapter->TaggedQueuingPermitted = 0; + switch (HostAdapter->FirmwareVersion[0]) { + case '5': + HostAdapter->TaggedQueuingPermitted = 0xFFFF; + break; + case '4': + if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0) + HostAdapter->TaggedQueuingPermitted = 0xFFFF; + break; + case '3': + if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0) + HostAdapter->TaggedQueuingPermitted = 0xFFFF; + break; } - HostAdapter->DisconnectPermitted = 0xFF; - HostAdapter->ParityCheckingEnabled = - SetupInformation.ParityCheckingEnabled; - HostAdapter->BusResetEnabled = true; - } - /* - Determine the maximum number of Target IDs and Logical Units supported by - this driver for Wide and Narrow Host Adapters. - */ - HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8); - HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8); - /* - Select appropriate values for the Mailbox Count, Driver Queue Depth, - Initial CCBs, and Incremental CCBs variables based on whether or not Strict - Round Robin Mode is supported. If Strict Round Robin Mode is supported, - then there is no performance degradation in using the maximum possible - number of Outgoing and Incoming Mailboxes and allowing the Tagged and - Untagged Queue Depths to determine the actual utilization. If Strict Round - Robin Mode is not supported, then the Host Adapter must scan all the - Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can - cause a substantial performance penalty. The host adapters actually have - room to store the following number of CCBs internally; that is, they can - internally queue and manage this many active commands on the SCSI bus - simultaneously. Performance measurements demonstrate that the Driver Queue - Depth should be set to the Mailbox Count, rather than the Host Adapter - Queue Depth (internal CCB capacity), as it is more efficient to have the - queued commands waiting in Outgoing Mailboxes if necessary than to block - the process in the higher levels of the SCSI Subsystem. - - 192 BT-948/958/958D - 100 BT-946C/956C/956CD/747C/757C/757CD/445C - 50 BT-545C/540CF - 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A - */ - if (HostAdapter->FirmwareVersion[0] == '5') - HostAdapter->HostAdapterQueueDepth = 192; - else if (HostAdapter->FirmwareVersion[0] == '4') - HostAdapter->HostAdapterQueueDepth = - (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50); - else HostAdapter->HostAdapterQueueDepth = 30; - if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0) - { - HostAdapter->StrictRoundRobinModeSupport = true; - HostAdapter->MailboxCount = BusLogic_MaxMailboxes; - } - else - { - HostAdapter->StrictRoundRobinModeSupport = false; - HostAdapter->MailboxCount = 32; - } - HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount; - HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize; - HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize; - /* - Tagged Queuing support is available and operates properly on all "W" series - MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with - firmware version 4.22 and above, and on "S" series MultiMaster Host - Adapters with firmware version 3.35 and above. - */ - HostAdapter->TaggedQueuingPermitted = 0; - switch (HostAdapter->FirmwareVersion[0]) - { - case '5': - HostAdapter->TaggedQueuingPermitted = 0xFFFF; - break; - case '4': - if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0) - HostAdapter->TaggedQueuingPermitted = 0xFFFF; - break; - case '3': - if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0) - HostAdapter->TaggedQueuingPermitted = 0xFFFF; - break; - } - /* - Determine the Host Adapter BIOS Address if the BIOS is enabled and - save it in the Host Adapter structure. The BIOS is disabled if the - BIOS_Address is 0. - */ - HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12; - /* - ISA Host Adapters require Bounce Buffers if there is more than 16MB memory. - */ - if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && - (void *) high_memory > (void *) MAX_DMA_ADDRESS) - HostAdapter->BounceBuffersRequired = true; - /* - BusLogic BT-445S Host Adapters prior to board revision E have a hardware - bug whereby when the BIOS is enabled, transfers to/from the same address - range the BIOS occupies modulo 16MB are handled incorrectly. Only properly - functioning BT-445S Host Adapters have firmware version 3.37, so require - that ISA Bounce Buffers be used for the buggy BT-445S models if there is - more than 16MB memory. - */ - if (HostAdapter->BIOS_Address > 0 && - strcmp(HostAdapter->ModelName, "BT-445S") == 0 && - strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && - (void *) high_memory > (void *) MAX_DMA_ADDRESS) - HostAdapter->BounceBuffersRequired = true; - /* - Initialize parameters common to MultiMaster and FlashPoint Host Adapters. - */ -Common: - /* - Initialize the Host Adapter Full Model Name from the Model Name. - */ - strcpy(HostAdapter->FullModelName, "BusLogic "); - strcat(HostAdapter->FullModelName, HostAdapter->ModelName); - /* - Select an appropriate value for the Tagged Queue Depth either from a - BusLogic Driver Options specification, or based on whether this Host - Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth - is left at 0 for automatic determination in BusLogic_SelectQueueDepths. - Initialize the Untagged Queue Depth. - */ - for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) - { - unsigned char QueueDepth = 0; - if (HostAdapter->DriverOptions != NULL && - HostAdapter->DriverOptions->QueueDepth[TargetID] > 0) - QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID]; - else if (HostAdapter->BounceBuffersRequired) - QueueDepth = BusLogic_TaggedQueueDepthBB; - HostAdapter->QueueDepth[TargetID] = QueueDepth; - } - if (HostAdapter->BounceBuffersRequired) - HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB; - else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth; - if (HostAdapter->DriverOptions != NULL) - HostAdapter->CommonQueueDepth = - HostAdapter->DriverOptions->CommonQueueDepth; - if (HostAdapter->CommonQueueDepth > 0 && - HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth) - HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth; - /* - Tagged Queuing is only allowed if Disconnect/Reconnect is permitted. - Therefore, mask the Tagged Queuing Permitted Default bits with the - Disconnect/Reconnect Permitted bits. - */ - HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted; - /* - Combine the default Tagged Queuing Permitted bits with any BusLogic Driver - Options Tagged Queuing specification. - */ - if (HostAdapter->DriverOptions != NULL) - HostAdapter->TaggedQueuingPermitted = - (HostAdapter->DriverOptions->TaggedQueuingPermitted & - HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | - (HostAdapter->TaggedQueuingPermitted & - ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask); - - /* - Select an appropriate value for Bus Settle Time either from a BusLogic - Driver Options specification, or from BusLogic_DefaultBusSettleTime. - */ - if (HostAdapter->DriverOptions != NULL && - HostAdapter->DriverOptions->BusSettleTime > 0) - HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime; - else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime; - /* - Indicate reading the Host Adapter Configuration completed successfully. - */ - return true; + /* + Determine the Host Adapter BIOS Address if the BIOS is enabled and + save it in the Host Adapter structure. The BIOS is disabled if the + BIOS_Address is 0. + */ + HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12; + /* + ISA Host Adapters require Bounce Buffers if there is more than 16MB memory. + */ + if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus && (void *) high_memory > (void *) MAX_DMA_ADDRESS) + HostAdapter->BounceBuffersRequired = true; + /* + BusLogic BT-445S Host Adapters prior to board revision E have a hardware + bug whereby when the BIOS is enabled, transfers to/from the same address + range the BIOS occupies modulo 16MB are handled incorrectly. Only properly + functioning BT-445S Host Adapters have firmware version 3.37, so require + that ISA Bounce Buffers be used for the buggy BT-445S models if there is + more than 16MB memory. + */ + if (HostAdapter->BIOS_Address > 0 && strcmp(HostAdapter->ModelName, "BT-445S") == 0 && strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 && (void *) high_memory > (void *) MAX_DMA_ADDRESS) + HostAdapter->BounceBuffersRequired = true; + /* + Initialize parameters common to MultiMaster and FlashPoint Host Adapters. + */ + Common: + /* + Initialize the Host Adapter Full Model Name from the Model Name. + */ + strcpy(HostAdapter->FullModelName, "BusLogic "); + strcat(HostAdapter->FullModelName, HostAdapter->ModelName); + /* + Select an appropriate value for the Tagged Queue Depth either from a + BusLogic Driver Options specification, or based on whether this Host + Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth + is left at 0 for automatic determination in BusLogic_SelectQueueDepths. + Initialize the Untagged Queue Depth. + */ + for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++) { + unsigned char QueueDepth = 0; + if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->QueueDepth[TargetID] > 0) + QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID]; + else if (HostAdapter->BounceBuffersRequired) + QueueDepth = BusLogic_TaggedQueueDepthBB; + HostAdapter->QueueDepth[TargetID] = QueueDepth; + } + if (HostAdapter->BounceBuffersRequired) + HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB; + else + HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth; + if (HostAdapter->DriverOptions != NULL) + HostAdapter->CommonQueueDepth = HostAdapter->DriverOptions->CommonQueueDepth; + if (HostAdapter->CommonQueueDepth > 0 && HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth) + HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth; + /* + Tagged Queuing is only allowed if Disconnect/Reconnect is permitted. + Therefore, mask the Tagged Queuing Permitted Default bits with the + Disconnect/Reconnect Permitted bits. + */ + HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted; + /* + Combine the default Tagged Queuing Permitted bits with any BusLogic Driver + Options Tagged Queuing specification. + */ + if (HostAdapter->DriverOptions != NULL) + HostAdapter->TaggedQueuingPermitted = + (HostAdapter->DriverOptions->TaggedQueuingPermitted & HostAdapter->DriverOptions->TaggedQueuingPermittedMask) | (HostAdapter->TaggedQueuingPermitted & ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask); + + /* + Select an appropriate value for Bus Settle Time either from a BusLogic + Driver Options specification, or from BusLogic_DefaultBusSettleTime. + */ + if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->BusSettleTime > 0) + HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime; + else + HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime; + /* + Indicate reading the Host Adapter Configuration completed successfully. + */ + return true; } @@ -2045,210 +1725,144 @@ Common: static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter *HostAdapter) { - unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1; - unsigned short SynchronousPermitted, FastPermitted; - unsigned short UltraPermitted, WidePermitted; - unsigned short DisconnectPermitted, TaggedQueuingPermitted; - boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth; - char SynchronousString[BusLogic_MaxTargetDevices+1]; - char WideString[BusLogic_MaxTargetDevices+1]; - char DisconnectString[BusLogic_MaxTargetDevices+1]; - char TaggedQueuingString[BusLogic_MaxTargetDevices+1]; - char *SynchronousMessage = SynchronousString; - char *WideMessage = WideString; - char *DisconnectMessage = DisconnectString; - char *TaggedQueuingMessage = TaggedQueuingString; - int TargetID; - BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", - HostAdapter, HostAdapter->ModelName, - BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], - (HostAdapter->HostWideSCSI ? " Wide" : ""), - (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), - (HostAdapter->HostUltraSCSI ? " Ultra" : "")); - BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, " - "IRQ Channel: %d/%s\n", HostAdapter, - HostAdapter->FirmwareVersion, - HostAdapter->IO_Address, HostAdapter->IRQ_Channel, - (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge")); - if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) - { - BusLogic_Info(" DMA Channel: ", HostAdapter); - if (HostAdapter->DMA_Channel > 0) - BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel); - else BusLogic_Info("None, ", HostAdapter); - if (HostAdapter->BIOS_Address > 0) - BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, - HostAdapter->BIOS_Address); - else BusLogic_Info("BIOS Address: None, ", HostAdapter); - } - else - { - BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", - HostAdapter, HostAdapter->Bus, HostAdapter->Device); - if (HostAdapter->PCI_Address > 0) - BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address); - else BusLogic_Info("Unassigned, ", HostAdapter); - } - BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, - HostAdapter->SCSI_ID); - BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", - HostAdapter, - (HostAdapter->ParityCheckingEnabled - ? "Enabled" : "Disabled"), - (HostAdapter->ExtendedTranslationEnabled - ? "Enabled" : "Disabled")); - AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID); - SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask; - FastPermitted = HostAdapter->FastPermitted & AllTargetsMask; - UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask; - if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && - (HostAdapter->FirmwareVersion[0] >= '4' || - HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || - BusLogic_FlashPointHostAdapterP(HostAdapter)) - { - CommonSynchronousNegotiation = false; - if (SynchronousPermitted == 0) - { - SynchronousMessage = "Disabled"; - CommonSynchronousNegotiation = true; - } - else if (SynchronousPermitted == AllTargetsMask) - { - if (FastPermitted == 0) - { - SynchronousMessage = "Slow"; - CommonSynchronousNegotiation = true; - } - else if (FastPermitted == AllTargetsMask) - { - if (UltraPermitted == 0) - { - SynchronousMessage = "Fast"; - CommonSynchronousNegotiation = true; + unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1; + unsigned short SynchronousPermitted, FastPermitted; + unsigned short UltraPermitted, WidePermitted; + unsigned short DisconnectPermitted, TaggedQueuingPermitted; + boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth; + char SynchronousString[BusLogic_MaxTargetDevices + 1]; + char WideString[BusLogic_MaxTargetDevices + 1]; + char DisconnectString[BusLogic_MaxTargetDevices + 1]; + char TaggedQueuingString[BusLogic_MaxTargetDevices + 1]; + char *SynchronousMessage = SynchronousString; + char *WideMessage = WideString; + char *DisconnectMessage = DisconnectString; + char *TaggedQueuingMessage = TaggedQueuingString; + int TargetID; + BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n", + HostAdapter, HostAdapter->ModelName, + BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType], (HostAdapter->HostWideSCSI ? " Wide" : ""), (HostAdapter->HostDifferentialSCSI ? " Differential" : ""), (HostAdapter->HostUltraSCSI ? " Ultra" : "")); + BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, " "IRQ Channel: %d/%s\n", HostAdapter, HostAdapter->FirmwareVersion, HostAdapter->IO_Address, HostAdapter->IRQ_Channel, (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge")); + if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus) { + BusLogic_Info(" DMA Channel: ", HostAdapter); + if (HostAdapter->DMA_Channel > 0) + BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel); + else + BusLogic_Info("None, ", HostAdapter); + if (HostAdapter->BIOS_Address > 0) + BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter, HostAdapter->BIOS_Address); + else + BusLogic_Info("BIOS Address: None, ", HostAdapter); + } else { + BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ", HostAdapter, HostAdapter->Bus, HostAdapter->Device); + if (HostAdapter->PCI_Address > 0) + BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address); + else + BusLogic_Info("Unassigned, ", HostAdapter); + } + BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter, HostAdapter->SCSI_ID); + BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n", HostAdapter, (HostAdapter->ParityCheckingEnabled ? "Enabled" : "Disabled"), (HostAdapter->ExtendedTranslationEnabled ? "Enabled" : "Disabled")); + AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID); + SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask; + FastPermitted = HostAdapter->FastPermitted & AllTargetsMask; + UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask; + if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) && (HostAdapter->FirmwareVersion[0] >= '4' || HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) || BusLogic_FlashPointHostAdapterP(HostAdapter)) { + CommonSynchronousNegotiation = false; + if (SynchronousPermitted == 0) { + SynchronousMessage = "Disabled"; + CommonSynchronousNegotiation = true; + } else if (SynchronousPermitted == AllTargetsMask) { + if (FastPermitted == 0) { + SynchronousMessage = "Slow"; + CommonSynchronousNegotiation = true; + } else if (FastPermitted == AllTargetsMask) { + if (UltraPermitted == 0) { + SynchronousMessage = "Fast"; + CommonSynchronousNegotiation = true; + } else if (UltraPermitted == AllTargetsMask) { + SynchronousMessage = "Ultra"; + CommonSynchronousNegotiation = true; + } + } } - else if (UltraPermitted == AllTargetsMask) - { - SynchronousMessage = "Ultra"; - CommonSynchronousNegotiation = true; + if (!CommonSynchronousNegotiation) { + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + SynchronousString[TargetID] = ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : (!(FastPermitted & (1 << TargetID)) ? 'S' : (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U'))); + SynchronousString[HostAdapter->SCSI_ID] = '#'; + SynchronousString[HostAdapter->MaxTargetDevices] = '\0'; } - } - } - if (!CommonSynchronousNegotiation) - { - for (TargetID = 0; - TargetID < HostAdapter->MaxTargetDevices; - TargetID++) - SynchronousString[TargetID] = - ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' : - (!(FastPermitted & (1 << TargetID)) ? 'S' : - (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U'))); - SynchronousString[HostAdapter->SCSI_ID] = '#'; - SynchronousString[HostAdapter->MaxTargetDevices] = '\0'; + } else + SynchronousMessage = (SynchronousPermitted == 0 ? "Disabled" : "Enabled"); + WidePermitted = HostAdapter->WidePermitted & AllTargetsMask; + if (WidePermitted == 0) + WideMessage = "Disabled"; + else if (WidePermitted == AllTargetsMask) + WideMessage = "Enabled"; + else { + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + WideString[TargetID] = ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N'); + WideString[HostAdapter->SCSI_ID] = '#'; + WideString[HostAdapter->MaxTargetDevices] = '\0'; + } + DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask; + if (DisconnectPermitted == 0) + DisconnectMessage = "Disabled"; + else if (DisconnectPermitted == AllTargetsMask) + DisconnectMessage = "Enabled"; + else { + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + DisconnectString[TargetID] = ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N'); + DisconnectString[HostAdapter->SCSI_ID] = '#'; + DisconnectString[HostAdapter->MaxTargetDevices] = '\0'; + } + TaggedQueuingPermitted = HostAdapter->TaggedQueuingPermitted & AllTargetsMask; + if (TaggedQueuingPermitted == 0) + TaggedQueuingMessage = "Disabled"; + else if (TaggedQueuingPermitted == AllTargetsMask) + TaggedQueuingMessage = "Enabled"; + else { + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + TaggedQueuingString[TargetID] = ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N'); + TaggedQueuingString[HostAdapter->SCSI_ID] = '#'; + TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0'; + } + BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", HostAdapter, SynchronousMessage, WideMessage); + BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", HostAdapter, DisconnectMessage, TaggedQueuingMessage); + if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { + BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " "Mailboxes: %d\n", HostAdapter, HostAdapter->DriverScatterGatherLimit, HostAdapter->HostAdapterScatterGatherLimit, HostAdapter->MailboxCount); + BusLogic_Info(" Driver Queue Depth: %d, " "Host Adapter Queue Depth: %d\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->HostAdapterQueueDepth); + } else + BusLogic_Info(" Driver Queue Depth: %d, " "Scatter/Gather Limit: %d segments\n", HostAdapter, HostAdapter->DriverQueueDepth, HostAdapter->DriverScatterGatherLimit); + BusLogic_Info(" Tagged Queue Depth: ", HostAdapter); + CommonTaggedQueueDepth = true; + for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) { + CommonTaggedQueueDepth = false; + break; + } + if (CommonTaggedQueueDepth) { + if (HostAdapter->QueueDepth[0] > 0) + BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]); + else + BusLogic_Info("Automatic", HostAdapter); + } else + BusLogic_Info("Individual", HostAdapter); + BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, HostAdapter->UntaggedQueueDepth); + if (HostAdapter->TerminationInfoValid) { + if (HostAdapter->HostWideSCSI) + BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? (HostAdapter->HighByteTerminated ? "Both Enabled" : "Low Enabled") + : (HostAdapter->HighByteTerminated ? "High Enabled" : "Both Disabled"))); + else + BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, (HostAdapter->LowByteTerminated ? "Enabled" : "Disabled")); + if (HostAdapter->HostSupportsSCAM) + BusLogic_Info(", SCAM: %s", HostAdapter, (HostAdapter->SCAM_Enabled ? (HostAdapter->SCAM_Level2 ? "Enabled, Level 2" : "Enabled, Level 1") + : "Disabled")); + BusLogic_Info("\n", HostAdapter); } - } - else SynchronousMessage = - (SynchronousPermitted == 0 ? "Disabled" : "Enabled"); - WidePermitted = HostAdapter->WidePermitted & AllTargetsMask; - if (WidePermitted == 0) - WideMessage = "Disabled"; - else if (WidePermitted == AllTargetsMask) - WideMessage = "Enabled"; - else - { - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - WideString[TargetID] = - ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N'); - WideString[HostAdapter->SCSI_ID] = '#'; - WideString[HostAdapter->MaxTargetDevices] = '\0'; - } - DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask; - if (DisconnectPermitted == 0) - DisconnectMessage = "Disabled"; - else if (DisconnectPermitted == AllTargetsMask) - DisconnectMessage = "Enabled"; - else - { - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - DisconnectString[TargetID] = - ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N'); - DisconnectString[HostAdapter->SCSI_ID] = '#'; - DisconnectString[HostAdapter->MaxTargetDevices] = '\0'; - } - TaggedQueuingPermitted = - HostAdapter->TaggedQueuingPermitted & AllTargetsMask; - if (TaggedQueuingPermitted == 0) - TaggedQueuingMessage = "Disabled"; - else if (TaggedQueuingPermitted == AllTargetsMask) - TaggedQueuingMessage = "Enabled"; - else - { - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - TaggedQueuingString[TargetID] = - ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N'); - TaggedQueuingString[HostAdapter->SCSI_ID] = '#'; - TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0'; - } - BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n", - HostAdapter, SynchronousMessage, WideMessage); - BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n", - HostAdapter, DisconnectMessage, TaggedQueuingMessage); - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) - { - BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, " - "Mailboxes: %d\n", HostAdapter, - HostAdapter->DriverScatterGatherLimit, - HostAdapter->HostAdapterScatterGatherLimit, - HostAdapter->MailboxCount); - BusLogic_Info(" Driver Queue Depth: %d, " - "Host Adapter Queue Depth: %d\n", - HostAdapter, HostAdapter->DriverQueueDepth, - HostAdapter->HostAdapterQueueDepth); - } - else BusLogic_Info(" Driver Queue Depth: %d, " - "Scatter/Gather Limit: %d segments\n", - HostAdapter, HostAdapter->DriverQueueDepth, - HostAdapter->DriverScatterGatherLimit); - BusLogic_Info(" Tagged Queue Depth: ", HostAdapter); - CommonTaggedQueueDepth = true; - for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0]) - { - CommonTaggedQueueDepth = false; - break; - } - if (CommonTaggedQueueDepth) - { - if (HostAdapter->QueueDepth[0] > 0) - BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]); - else BusLogic_Info("Automatic", HostAdapter); - } - else BusLogic_Info("Individual", HostAdapter); - BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter, - HostAdapter->UntaggedQueueDepth); - if (HostAdapter->TerminationInfoValid) - { - if (HostAdapter->HostWideSCSI) - BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, - (HostAdapter->LowByteTerminated - ? (HostAdapter->HighByteTerminated - ? "Both Enabled" : "Low Enabled") - : (HostAdapter->HighByteTerminated - ? "High Enabled" : "Both Disabled"))); - else BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter, - (HostAdapter->LowByteTerminated ? - "Enabled" : "Disabled")); - if (HostAdapter->HostSupportsSCAM) - BusLogic_Info(", SCAM: %s", HostAdapter, - (HostAdapter->SCAM_Enabled - ? (HostAdapter->SCAM_Level2 - ? "Enabled, Level 2" : "Enabled, Level 1") - : "Disabled")); - BusLogic_Info("\n", HostAdapter); - } - /* - Indicate reporting the Host Adapter configuration completed successfully. - */ - return true; + /* + Indicate reporting the Host Adapter configuration completed successfully. + */ + return true; } @@ -2259,43 +1873,34 @@ static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_Ho static boolean __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter) { - if (HostAdapter->IRQ_Channel == 0) - { - BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", - HostAdapter); - return false; - } - /* - Acquire shared access to the IRQ Channel. - */ - if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, - SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0) - { - BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", - HostAdapter, HostAdapter->IRQ_Channel); - return false; - } - HostAdapter->IRQ_ChannelAcquired = true; - /* - Acquire exclusive access to the DMA Channel. - */ - if (HostAdapter->DMA_Channel > 0) - { - if (request_dma(HostAdapter->DMA_Channel, - HostAdapter->FullModelName) < 0) - { - BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", - HostAdapter, HostAdapter->DMA_Channel); - return false; + if (HostAdapter->IRQ_Channel == 0) { + BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter); + return false; } - set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE); - enable_dma(HostAdapter->DMA_Channel); - HostAdapter->DMA_ChannelAcquired = true; - } - /* - Indicate the System Resource Acquisition completed successfully, - */ - return true; + /* + Acquire shared access to the IRQ Channel. + */ + if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0) { + BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->IRQ_Channel); + return false; + } + HostAdapter->IRQ_ChannelAcquired = true; + /* + Acquire exclusive access to the DMA Channel. + */ + if (HostAdapter->DMA_Channel > 0) { + if (request_dma(HostAdapter->DMA_Channel, HostAdapter->FullModelName) < 0) { + BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n", HostAdapter, HostAdapter->DMA_Channel); + return false; + } + set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE); + enable_dma(HostAdapter->DMA_Channel); + HostAdapter->DMA_ChannelAcquired = true; + } + /* + Indicate the System Resource Acquisition completed successfully, + */ + return true; } @@ -2306,26 +1911,24 @@ static boolean __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *Hos static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter) { - /* - Release shared access to the IRQ Channel. - */ - if (HostAdapter->IRQ_ChannelAcquired) - free_irq(HostAdapter->IRQ_Channel, HostAdapter); - /* - Release exclusive access to the DMA Channel. - */ - if (HostAdapter->DMA_ChannelAcquired) - free_dma(HostAdapter->DMA_Channel); - /* - Release any allocated memory structs not released elsewhere - */ - if (HostAdapter->MailboxSpace) - pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, - HostAdapter->MailboxSpace, - HostAdapter->MailboxSpaceHandle); - HostAdapter->MailboxSpace = NULL; - HostAdapter->MailboxSpaceHandle = 0; - HostAdapter->MailboxSize = 0; + /* + Release shared access to the IRQ Channel. + */ + if (HostAdapter->IRQ_ChannelAcquired) + free_irq(HostAdapter->IRQ_Channel, HostAdapter); + /* + Release exclusive access to the DMA Channel. + */ + if (HostAdapter->DMA_ChannelAcquired) + free_dma(HostAdapter->DMA_Channel); + /* + Release any allocated memory structs not released elsewhere + */ + if (HostAdapter->MailboxSpace) + pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, HostAdapter->MailboxSpace, HostAdapter->MailboxSpaceHandle); + HostAdapter->MailboxSpace = NULL; + HostAdapter->MailboxSpaceHandle = 0; + HostAdapter->MailboxSize = 0; } @@ -2338,114 +1941,94 @@ static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter) static boolean BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter *HostAdapter) { - struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest; - enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest; - enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest; - int TargetID; - /* - Initialize the pointers to the first and last CCBs that are queued for - completion processing. - */ - HostAdapter->FirstCompletedCCB = NULL; - HostAdapter->LastCompletedCCB = NULL; - /* - Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active, - Command Successful Flag, Active Commands, and Commands Since Reset - for each Target Device. - */ - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - { - HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; - HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; - HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false; - HostAdapter->ActiveCommands[TargetID] = 0; - HostAdapter->CommandsSinceReset[TargetID] = 0; - } - /* - FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done; - /* - Initialize the Outgoing and Incoming Mailbox pointers. - */ - HostAdapter->MailboxSize = HostAdapter->MailboxCount * - (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox)); - HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, - HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle); - if (HostAdapter->MailboxSpace == NULL) - return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION"); - HostAdapter->FirstOutgoingMailbox = - (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace; - HostAdapter->LastOutgoingMailbox = - HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1; - HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; - HostAdapter->FirstIncomingMailbox = - (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1); - HostAdapter->LastIncomingMailbox = - HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1; - HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; - - /* - Initialize the Outgoing and Incoming Mailbox structures. - */ - memset(HostAdapter->FirstOutgoingMailbox, 0, - HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox)); - memset(HostAdapter->FirstIncomingMailbox, 0, - HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox)); - /* - Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes. - */ - ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount; - ExtendedMailboxRequest.BaseMailboxAddress = - (u32) HostAdapter->MailboxSpaceHandle; - if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, - &ExtendedMailboxRequest, - sizeof(ExtendedMailboxRequest), NULL, 0) < 0) - return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION"); - /* - Enable Strict Round Robin Mode if supported by the Host Adapter. In - Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing - Mailbox for each new command, rather than scanning through all the - Outgoing Mailboxes to find any that have new commands in them. Strict - Round Robin Mode is significantly more efficient. - */ - if (HostAdapter->StrictRoundRobinModeSupport) - { - RoundRobinModeRequest = BusLogic_StrictRoundRobinMode; - if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, - &RoundRobinModeRequest, - sizeof(RoundRobinModeRequest), NULL, 0) < 0) - return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE"); - } - /* - For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB - Format command to allow 32 Logical Units per Target Device. - */ - if (HostAdapter->ExtendedLUNSupport) - { - SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB; - if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, - &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), - NULL, 0) < 0) - return BusLogic_Failure(HostAdapter, "SET CCB FORMAT"); - } - /* - Announce Successful Initialization. - */ -Done: - if (!HostAdapter->HostAdapterInitialized) - { - BusLogic_Info("*** %s Initialized Successfully ***\n", - HostAdapter, HostAdapter->FullModelName); - BusLogic_Info("\n", HostAdapter); - } - else BusLogic_Warning("*** %s Initialized Successfully ***\n", - HostAdapter, HostAdapter->FullModelName); - HostAdapter->HostAdapterInitialized = true; - /* - Indicate the Host Adapter Initialization completed successfully. - */ - return true; + struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest; + enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest; + enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest; + int TargetID; + /* + Initialize the pointers to the first and last CCBs that are queued for + completion processing. + */ + HostAdapter->FirstCompletedCCB = NULL; + HostAdapter->LastCompletedCCB = NULL; + /* + Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active, + Command Successful Flag, Active Commands, and Commands Since Reset + for each Target Device. + */ + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { + HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; + HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; + HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false; + HostAdapter->ActiveCommands[TargetID] = 0; + HostAdapter->CommandsSinceReset[TargetID] = 0; + } + /* + FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes. + */ + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + goto Done; + /* + Initialize the Outgoing and Incoming Mailbox pointers. + */ + HostAdapter->MailboxSize = HostAdapter->MailboxCount * (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox)); + HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle); + if (HostAdapter->MailboxSpace == NULL) + return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION"); + HostAdapter->FirstOutgoingMailbox = (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace; + HostAdapter->LastOutgoingMailbox = HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1; + HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; + HostAdapter->FirstIncomingMailbox = (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1); + HostAdapter->LastIncomingMailbox = HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1; + HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; + + /* + Initialize the Outgoing and Incoming Mailbox structures. + */ + memset(HostAdapter->FirstOutgoingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox)); + memset(HostAdapter->FirstIncomingMailbox, 0, HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox)); + /* + Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes. + */ + ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount; + ExtendedMailboxRequest.BaseMailboxAddress = (u32) HostAdapter->MailboxSpaceHandle; + if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox, &ExtendedMailboxRequest, sizeof(ExtendedMailboxRequest), NULL, 0) < 0) + return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION"); + /* + Enable Strict Round Robin Mode if supported by the Host Adapter. In + Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing + Mailbox for each new command, rather than scanning through all the + Outgoing Mailboxes to find any that have new commands in them. Strict + Round Robin Mode is significantly more efficient. + */ + if (HostAdapter->StrictRoundRobinModeSupport) { + RoundRobinModeRequest = BusLogic_StrictRoundRobinMode; + if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode, &RoundRobinModeRequest, sizeof(RoundRobinModeRequest), NULL, 0) < 0) + return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE"); + } + /* + For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB + Format command to allow 32 Logical Units per Target Device. + */ + if (HostAdapter->ExtendedLUNSupport) { + SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB; + if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat, &SetCCBFormatRequest, sizeof(SetCCBFormatRequest), NULL, 0) < 0) + return BusLogic_Failure(HostAdapter, "SET CCB FORMAT"); + } + /* + Announce Successful Initialization. + */ + Done: + if (!HostAdapter->HostAdapterInitialized) { + BusLogic_Info("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName); + BusLogic_Info("\n", HostAdapter); + } else + BusLogic_Warning("*** %s Initialized Successfully ***\n", HostAdapter, HostAdapter->FullModelName); + HostAdapter->HostAdapterInitialized = true; + /* + Indicate the Host Adapter Initialization completed successfully. + */ + return true; } @@ -2457,127 +2040,106 @@ Done: static boolean __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter *HostAdapter) { - u16 InstalledDevices; - u8 InstalledDevicesID0to7[8]; - struct BusLogic_SetupInformation SetupInformation; - u8 SynchronousPeriod[BusLogic_MaxTargetDevices]; - unsigned char RequestedReplyLength; - int TargetID; - /* - Wait a few seconds between the Host Adapter Hard Reset which initiates - a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get - confused if they receive SCSI Commands too soon after a SCSI Bus Reset. - */ - BusLogic_Delay(HostAdapter->BusSettleTime); - /* - FlashPoint Host Adapters do not provide for Target Device Inquiry. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true; - /* - Inhibit the Target Device Inquiry if requested. - */ - if (HostAdapter->DriverOptions != NULL && - HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry) - return true; - /* - Issue the Inquire Target Devices command for host adapters with firmware - version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command - for older host adapters. This is necessary to force Synchronous Transfer - Negotiation so that the Inquire Setup Information and Inquire Synchronous - Period commands will return valid data. The Inquire Target Devices command - is preferable to Inquire Installed Devices ID 0 to 7 since it only probes - Logical Unit 0 of each Target Device. - */ - if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) - { - - /* - * Issue a Inquire Target Devices command. Inquire Target Devices only - * tests Logical Unit 0 of each Target Device unlike the Inquire Installed - * Devices commands which test Logical Units 0 - 7. Two bytes are - * returned, where byte 0 bit 0 set indicates that Target Device 0 exists, - * and so on. - */ - - if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, - &InstalledDevices, sizeof(InstalledDevices)) - != sizeof(InstalledDevices)) - return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->TargetFlags[TargetID].TargetExists = - (InstalledDevices & (1 << TargetID) ? true : false); - } - else - { - - /* - * Issue an Inquire Installed Devices command. For each Target Device, - * a byte is returned where bit 0 set indicates that Logical Unit 0 - * exists, bit 1 set indicates that Logical Unit 1 exists, and so on. - */ - - if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, - NULL, 0, &InstalledDevicesID0to7, - sizeof(InstalledDevicesID0to7)) - != sizeof(InstalledDevicesID0to7)) - return BusLogic_Failure(HostAdapter, - "INQUIRE INSTALLED DEVICES ID 0 TO 7"); - for (TargetID = 0; TargetID < 8; TargetID++) - HostAdapter->TargetFlags[TargetID].TargetExists = - (InstalledDevicesID0to7[TargetID] != 0 ? true : false); - } - /* - Issue the Inquire Setup Information command. - */ - RequestedReplyLength = sizeof(SetupInformation); - if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, - &RequestedReplyLength, sizeof(RequestedReplyLength), - &SetupInformation, sizeof(SetupInformation)) - != sizeof(SetupInformation)) - return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->SynchronousOffset[TargetID] = - (TargetID < 8 - ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset - : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset); - if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0) - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - HostAdapter->TargetFlags[TargetID].WideTransfersActive = - (TargetID < 8 - ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID) - ? true : false) - : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8)) - ? true : false)); - /* - Issue the Inquire Synchronous Period command. - */ - if (HostAdapter->FirmwareVersion[0] >= '3') - { - - /* Issue a Inquire Synchronous Period command. For each Target Device, - * a byte is returned which represents the Synchronous Transfer Period - * in units of 10 nanoseconds. - */ - - RequestedReplyLength = sizeof(SynchronousPeriod); - if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, - &RequestedReplyLength, sizeof(RequestedReplyLength), - &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) - HostAdapter->SynchronousPeriod[TargetID] = - 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID] - .TransferPeriod; - /* - Indicate the Target Device Inquiry completed successfully. - */ - return true; + u16 InstalledDevices; + u8 InstalledDevicesID0to7[8]; + struct BusLogic_SetupInformation SetupInformation; + u8 SynchronousPeriod[BusLogic_MaxTargetDevices]; + unsigned char RequestedReplyLength; + int TargetID; + /* + Wait a few seconds between the Host Adapter Hard Reset which initiates + a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get + confused if they receive SCSI Commands too soon after a SCSI Bus Reset. + */ + BusLogic_Delay(HostAdapter->BusSettleTime); + /* + FlashPoint Host Adapters do not provide for Target Device Inquiry. + */ + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + return true; + /* + Inhibit the Target Device Inquiry if requested. + */ + if (HostAdapter->DriverOptions != NULL && HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry) + return true; + /* + Issue the Inquire Target Devices command for host adapters with firmware + version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command + for older host adapters. This is necessary to force Synchronous Transfer + Negotiation so that the Inquire Setup Information and Inquire Synchronous + Period commands will return valid data. The Inquire Target Devices command + is preferable to Inquire Installed Devices ID 0 to 7 since it only probes + Logical Unit 0 of each Target Device. + */ + if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0) { + + /* + * Issue a Inquire Target Devices command. Inquire Target Devices only + * tests Logical Unit 0 of each Target Device unlike the Inquire Installed + * Devices commands which test Logical Units 0 - 7. Two bytes are + * returned, where byte 0 bit 0 set indicates that Target Device 0 exists, + * and so on. + */ + + if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0, &InstalledDevices, sizeof(InstalledDevices)) + != sizeof(InstalledDevices)) + return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES"); + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevices & (1 << TargetID) ? true : false); + } else { + + /* + * Issue an Inquire Installed Devices command. For each Target Device, + * a byte is returned where bit 0 set indicates that Logical Unit 0 + * exists, bit 1 set indicates that Logical Unit 1 exists, and so on. + */ + + if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7, NULL, 0, &InstalledDevicesID0to7, sizeof(InstalledDevicesID0to7)) + != sizeof(InstalledDevicesID0to7)) + return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7"); + for (TargetID = 0; TargetID < 8; TargetID++) + HostAdapter->TargetFlags[TargetID].TargetExists = (InstalledDevicesID0to7[TargetID] != 0 ? true : false); + } + /* + Issue the Inquire Setup Information command. + */ + RequestedReplyLength = sizeof(SetupInformation); + if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation, &RequestedReplyLength, sizeof(RequestedReplyLength), &SetupInformation, sizeof(SetupInformation)) + != sizeof(SetupInformation)) + return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION"); + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + HostAdapter->SynchronousOffset[TargetID] = (TargetID < 8 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset : SetupInformation.SynchronousValuesID8to15[TargetID - 8].Offset); + if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0) + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + HostAdapter->TargetFlags[TargetID].WideTransfersActive = (TargetID < 8 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID) + ? true : false) + : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID - 8)) + ? true : false)); + /* + Issue the Inquire Synchronous Period command. + */ + if (HostAdapter->FirmwareVersion[0] >= '3') { + + /* Issue a Inquire Synchronous Period command. For each Target Device, + * a byte is returned which represents the Synchronous Transfer Period + * in units of 10 nanoseconds. + */ + + RequestedReplyLength = sizeof(SynchronousPeriod); + if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod, &RequestedReplyLength, sizeof(RequestedReplyLength), &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) + HostAdapter->SynchronousPeriod[TargetID] = 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID] + .TransferPeriod; + /* + Indicate the Target Device Inquiry completed successfully. + */ + return true; } /* @@ -2590,18 +2152,17 @@ static boolean __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter */ static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter - *HostAdapter, - struct Scsi_Host *Host) + *HostAdapter, struct Scsi_Host *Host) { - Host->max_id = HostAdapter->MaxTargetDevices; - Host->max_lun = HostAdapter->MaxLogicalUnits; - Host->max_channel = 0; - Host->unique_id = HostAdapter->IO_Address; - Host->this_id = HostAdapter->SCSI_ID; - Host->can_queue = HostAdapter->DriverQueueDepth; - Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit; - Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired; - Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth; + Host->max_id = HostAdapter->MaxTargetDevices; + Host->max_lun = HostAdapter->MaxLogicalUnits; + Host->max_channel = 0; + Host->unique_id = HostAdapter->IO_Address; + Host->this_id = HostAdapter->SCSI_ID; + Host->can_queue = HostAdapter->DriverQueueDepth; + Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit; + Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired; + Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth; } /* @@ -2614,38 +2175,29 @@ static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter */ static int BusLogic_SlaveConfigure(struct scsi_device *Device) { - struct BusLogic_HostAdapter *HostAdapter = - (struct BusLogic_HostAdapter *) Device->host->hostdata; - int TargetID = Device->id; - int QueueDepth = HostAdapter->QueueDepth[TargetID]; - - if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && - (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) - { - if (QueueDepth == 0) - QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth; - HostAdapter->QueueDepth[TargetID] = QueueDepth; - scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth); - } - else - { - HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID); - QueueDepth = HostAdapter->UntaggedQueueDepth; - HostAdapter->QueueDepth[TargetID] = QueueDepth; - scsi_adjust_queue_depth(Device, 0, QueueDepth); - } - QueueDepth = 0; - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - if (HostAdapter->TargetFlags[TargetID].TargetExists) - { - QueueDepth += HostAdapter->QueueDepth[TargetID]; - } - if (QueueDepth > HostAdapter->AllocatedCCBs) - BusLogic_CreateAdditionalCCBs(HostAdapter, - QueueDepth - - HostAdapter->AllocatedCCBs, - false); - return 0; + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Device->host->hostdata; + int TargetID = Device->id; + int QueueDepth = HostAdapter->QueueDepth[TargetID]; + + if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) { + if (QueueDepth == 0) + QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth; + HostAdapter->QueueDepth[TargetID] = QueueDepth; + scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth); + } else { + HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID); + QueueDepth = HostAdapter->UntaggedQueueDepth; + HostAdapter->QueueDepth[TargetID] = QueueDepth; + scsi_adjust_queue_depth(Device, 0, QueueDepth); + } + QueueDepth = 0; + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) + if (HostAdapter->TargetFlags[TargetID].TargetExists) { + QueueDepth += HostAdapter->QueueDepth[TargetID]; + } + if (QueueDepth > HostAdapter->AllocatedCCBs) + BusLogic_CreateAdditionalCCBs(HostAdapter, QueueDepth - HostAdapter->AllocatedCCBs, false); + return 0; } /* @@ -2658,162 +2210,145 @@ static int BusLogic_SlaveConfigure(struct scsi_device *Device) static int __init BusLogic_DetectHostAdapter(struct scsi_host_template *HostTemplate) { - int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex; - struct BusLogic_HostAdapter *PrototypeHostAdapter; - if (BusLogic_ProbeOptions.NoProbe) return 0; - BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *) - kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), - 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(struct BusLogic_ProbeInfo)); - PrototypeHostAdapter = (struct BusLogic_HostAdapter *) - kmalloc(sizeof(struct BusLogic_HostAdapter), 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(struct BusLogic_HostAdapter)); + int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex; + struct BusLogic_HostAdapter *PrototypeHostAdapter; + if (BusLogic_ProbeOptions.NoProbe) + return 0; + BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *) + kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), 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(struct BusLogic_ProbeInfo)); + PrototypeHostAdapter = (struct BusLogic_HostAdapter *) + kmalloc(sizeof(struct BusLogic_HostAdapter), 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(struct BusLogic_HostAdapter)); #ifdef MODULE - if (BusLogic != NULL) - BusLogic_Setup(BusLogic); + if (BusLogic != NULL) + BusLogic_Setup(BusLogic); #endif - BusLogic_InitializeProbeInfoList(PrototypeHostAdapter); - for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) - { - struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex]; - struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; - struct Scsi_Host *Host; - if (ProbeInfo->IO_Address == 0) continue; - memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter)); - 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_HostAdapterAddressCount[HostAdapter->HostAdapterType]; - /* - Probe the Host Adapter. If unsuccessful, abort further initialization. - */ - if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue; - /* - Hard Reset the Host Adapter. If unsuccessful, abort further - initialization. - */ - if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue; - /* - Check the Host Adapter. If unsuccessful, abort further initialization. - */ - if (!BusLogic_CheckHostAdapter(HostAdapter)) continue; - /* - Initialize the Driver Options field if provided. - */ - if (DriverOptionsIndex < BusLogic_DriverOptionsCount) - HostAdapter->DriverOptions = - &BusLogic_DriverOptions[DriverOptionsIndex++]; - /* - Announce the Driver Version and Date, Author's Name, Copyright Notice, - and Electronic Mail Address. - */ - BusLogic_AnnounceDriver(HostAdapter); - /* - Register usage of the I/O Address range. From this point onward, any - failure will be assumed to be due to a problem with the Host Adapter, - rather than due to having mistakenly identified this port as belonging - to a BusLogic Host Adapter. The I/O Address range will not be - released, thereby preventing it from being incorrectly identified as - any other type of Host Adapter. - */ - if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, - "BusLogic")) continue; - /* - Register the SCSI Host structure. - */ - - Host = scsi_host_alloc(HostTemplate, sizeof(struct BusLogic_HostAdapter)); - if(Host==NULL) - { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); - continue; - } - HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata; - memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter)); - HostAdapter->SCSI_Host = Host; - HostAdapter->HostNumber = Host->host_no; - /* - Add Host Adapter to the end of the list of registered BusLogic - 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 - 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_CreateInitialCCBs(HostAdapter) && - BusLogic_InitializeHostAdapter(HostAdapter) && - BusLogic_TargetDeviceInquiry(HostAdapter)) - { - /* - Initialization has been completed successfully. Release and - re-register usage of the I/O Address range so that the Model - Name of the Host Adapter will appear, and initialize the SCSI - Host structure. - */ - release_region(HostAdapter->IO_Address, - HostAdapter->AddressCount); - if(!request_region(HostAdapter->IO_Address, - HostAdapter->AddressCount, - HostAdapter->FullModelName)) { - printk(KERN_WARNING "BusLogic: Release and re-register of " - "port 0x%04lx failed \n", - (unsigned long)HostAdapter->IO_Address); - BusLogic_DestroyCCBs(HostAdapter); - BusLogic_ReleaseResources(HostAdapter); - BusLogic_UnregisterHostAdapter(HostAdapter); - scsi_host_put(Host); - } - else { - BusLogic_InitializeHostStructure(HostAdapter, Host); - scsi_add_host(Host, NULL); - scsi_scan_host(Host); - BusLogicHostAdapterCount++; - } - } - else - { - /* - 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_DestroyCCBs(HostAdapter); - BusLogic_ReleaseResources(HostAdapter); - BusLogic_UnregisterHostAdapter(HostAdapter); - scsi_host_put(Host); + BusLogic_InitializeProbeInfoList(PrototypeHostAdapter); + for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++) { + struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex]; + struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter; + struct Scsi_Host *Host; + if (ProbeInfo->IO_Address == 0) + continue; + memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter)); + 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_HostAdapterAddressCount[HostAdapter->HostAdapterType]; + /* + Probe the Host Adapter. If unsuccessful, abort further initialization. + */ + if (!BusLogic_ProbeHostAdapter(HostAdapter)) + continue; + /* + Hard Reset the Host Adapter. If unsuccessful, abort further + initialization. + */ + if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) + continue; + /* + Check the Host Adapter. If unsuccessful, abort further initialization. + */ + if (!BusLogic_CheckHostAdapter(HostAdapter)) + continue; + /* + Initialize the Driver Options field if provided. + */ + if (DriverOptionsIndex < BusLogic_DriverOptionsCount) + HostAdapter->DriverOptions = &BusLogic_DriverOptions[DriverOptionsIndex++]; + /* + Announce the Driver Version and Date, Author's Name, Copyright Notice, + and Electronic Mail Address. + */ + BusLogic_AnnounceDriver(HostAdapter); + /* + Register usage of the I/O Address range. From this point onward, any + failure will be assumed to be due to a problem with the Host Adapter, + rather than due to having mistakenly identified this port as belonging + to a BusLogic Host Adapter. The I/O Address range will not be + released, thereby preventing it from being incorrectly identified as + any other type of Host Adapter. + */ + if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, "BusLogic")) + continue; + /* + Register the SCSI Host structure. + */ + + Host = scsi_host_alloc(HostTemplate, sizeof(struct BusLogic_HostAdapter)); + if (Host == NULL) { + release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + continue; + } + HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata; + memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter)); + HostAdapter->SCSI_Host = Host; + HostAdapter->HostNumber = Host->host_no; + /* + Add Host Adapter to the end of the list of registered BusLogic + 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 + 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_CreateInitialCCBs(HostAdapter) && BusLogic_InitializeHostAdapter(HostAdapter) && BusLogic_TargetDeviceInquiry(HostAdapter)) { + /* + Initialization has been completed successfully. Release and + re-register usage of the I/O Address range so that the Model + Name of the Host Adapter will appear, and initialize the SCSI + Host structure. + */ + release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, HostAdapter->FullModelName)) { + printk(KERN_WARNING "BusLogic: Release and re-register of " "port 0x%04lx failed \n", (unsigned long) HostAdapter->IO_Address); + BusLogic_DestroyCCBs(HostAdapter); + BusLogic_ReleaseResources(HostAdapter); + BusLogic_UnregisterHostAdapter(HostAdapter); + scsi_host_put(Host); + } else { + BusLogic_InitializeHostStructure(HostAdapter, Host); + scsi_add_host(Host, NULL); + scsi_scan_host(Host); + BusLogicHostAdapterCount++; + } + } else { + /* + 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_DestroyCCBs(HostAdapter); + BusLogic_ReleaseResources(HostAdapter); + BusLogic_UnregisterHostAdapter(HostAdapter); + scsi_host_put(Host); + } } - } - kfree(PrototypeHostAdapter); - kfree(BusLogic_ProbeInfoList); - BusLogic_ProbeInfoList = NULL; - return BusLogicHostAdapterCount; + kfree(PrototypeHostAdapter); + kfree(BusLogic_ProbeInfoList); + BusLogic_ProbeInfoList = NULL; + return BusLogicHostAdapterCount; } @@ -2825,29 +2360,28 @@ static int __init BusLogic_DetectHostAdapter(struct scsi_host_template *HostTemp static int __exit BusLogic_ReleaseHostAdapter(struct Scsi_Host *Host) { - struct BusLogic_HostAdapter *HostAdapter = - (struct BusLogic_HostAdapter *) Host->hostdata; - /* - FlashPoint Host Adapters must first be released by the FlashPoint - SCCB Manager. - */ - if (BusLogic_FlashPointHostAdapterP(HostAdapter)) - FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle); - /* - Destroy the CCBs and release any system resources acquired to - support Host Adapter. - */ - BusLogic_DestroyCCBs(HostAdapter); - BusLogic_ReleaseResources(HostAdapter); - /* - Release usage of the I/O Address range. - */ - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); - /* - Remove Host Adapter from the list of registered BusLogic Host Adapters. - */ - BusLogic_UnregisterHostAdapter(HostAdapter); - return 0; + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata; + /* + FlashPoint Host Adapters must first be released by the FlashPoint + SCCB Manager. + */ + if (BusLogic_FlashPointHostAdapterP(HostAdapter)) + FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle); + /* + Destroy the CCBs and release any system resources acquired to + support Host Adapter. + */ + BusLogic_DestroyCCBs(HostAdapter); + BusLogic_ReleaseResources(HostAdapter); + /* + Release usage of the I/O Address range. + */ + release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + /* + Remove Host Adapter from the list of registered BusLogic Host Adapters. + */ + BusLogic_UnregisterHostAdapter(HostAdapter); + return 0; } @@ -2857,20 +2391,17 @@ static int __exit BusLogic_ReleaseHostAdapter(struct Scsi_Host *Host) static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB) { - struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter; - CCB->Status = BusLogic_CCB_Completed; - CCB->Next = NULL; - if (HostAdapter->FirstCompletedCCB == NULL) - { - HostAdapter->FirstCompletedCCB = CCB; - HostAdapter->LastCompletedCCB = CCB; - } - else - { - HostAdapter->LastCompletedCCB->Next = CCB; - HostAdapter->LastCompletedCCB = CCB; - } - HostAdapter->ActiveCommands[CCB->TargetID]--; + struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter; + CCB->Status = BusLogic_CCB_Completed; + CCB->Next = NULL; + if (HostAdapter->FirstCompletedCCB == NULL) { + HostAdapter->FirstCompletedCCB = CCB; + HostAdapter->LastCompletedCCB = CCB; + } else { + HostAdapter->LastCompletedCCB->Next = CCB; + HostAdapter->LastCompletedCCB = CCB; + } + HostAdapter->ActiveCommands[CCB->TargetID]--; } @@ -2879,57 +2410,50 @@ static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB) the Host Adapter Status and Target Device Status. */ -static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, - enum BusLogic_HostAdapterStatus - HostAdapterStatus, - enum BusLogic_TargetDeviceStatus - TargetDeviceStatus) +static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, enum BusLogic_HostAdapterStatus HostAdapterStatus, enum BusLogic_TargetDeviceStatus TargetDeviceStatus) { - int HostStatus; - switch (HostAdapterStatus) - { - case BusLogic_CommandCompletedNormally: - case BusLogic_LinkedCommandCompleted: - case BusLogic_LinkedCommandCompletedWithFlag: - HostStatus = DID_OK; - break; - case BusLogic_SCSISelectionTimeout: - HostStatus = DID_TIME_OUT; - break; - case BusLogic_InvalidOutgoingMailboxActionCode: - case BusLogic_InvalidCommandOperationCode: - case BusLogic_InvalidCommandParameter: - BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", - HostAdapter, HostAdapterStatus); - case BusLogic_DataUnderRun: - case BusLogic_DataOverRun: - case BusLogic_UnexpectedBusFree: - case BusLogic_LinkedCCBhasInvalidLUN: - case BusLogic_AutoRequestSenseFailed: - case BusLogic_TaggedQueuingMessageRejected: - case BusLogic_UnsupportedMessageReceived: - case BusLogic_HostAdapterHardwareFailed: - case BusLogic_TargetDeviceReconnectedImproperly: - case BusLogic_AbortQueueGenerated: - case BusLogic_HostAdapterSoftwareError: - case BusLogic_HostAdapterHardwareTimeoutError: - case BusLogic_SCSIParityErrorDetected: - HostStatus = DID_ERROR; - break; - case BusLogic_InvalidBusPhaseRequested: - case BusLogic_TargetFailedResponseToATN: - case BusLogic_HostAdapterAssertedRST: - case BusLogic_OtherDeviceAssertedRST: - case BusLogic_HostAdapterAssertedBusDeviceReset: - HostStatus = DID_RESET; - break; - default: - BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", - HostAdapter, HostAdapterStatus); - HostStatus = DID_ERROR; - break; - } - return (HostStatus << 16) | TargetDeviceStatus; + int HostStatus; + switch (HostAdapterStatus) { + case BusLogic_CommandCompletedNormally: + case BusLogic_LinkedCommandCompleted: + case BusLogic_LinkedCommandCompletedWithFlag: + HostStatus = DID_OK; + break; + case BusLogic_SCSISelectionTimeout: + HostStatus = DID_TIME_OUT; + break; + case BusLogic_InvalidOutgoingMailboxActionCode: + case BusLogic_InvalidCommandOperationCode: + case BusLogic_InvalidCommandParameter: + BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n", HostAdapter, HostAdapterStatus); + case BusLogic_DataUnderRun: + case BusLogic_DataOverRun: + case BusLogic_UnexpectedBusFree: + case BusLogic_LinkedCCBhasInvalidLUN: + case BusLogic_AutoRequestSenseFailed: + case BusLogic_TaggedQueuingMessageRejected: + case BusLogic_UnsupportedMessageReceived: + case BusLogic_HostAdapterHardwareFailed: + case BusLogic_TargetDeviceReconnectedImproperly: + case BusLogic_AbortQueueGenerated: + case BusLogic_HostAdapterSoftwareError: + case BusLogic_HostAdapterHardwareTimeoutError: + case BusLogic_SCSIParityErrorDetected: + HostStatus = DID_ERROR; + break; + case BusLogic_InvalidBusPhaseRequested: + case BusLogic_TargetFailedResponseToATN: + case BusLogic_HostAdapterAssertedRST: + case BusLogic_OtherDeviceAssertedRST: + case BusLogic_HostAdapterAssertedBusDeviceReset: + HostStatus = DID_RESET; + break; + default: + BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n", HostAdapter, HostAdapterStatus); + HostStatus = DID_ERROR; + break; + } + return (HostStatus << 16) | TargetDeviceStatus; } @@ -2940,62 +2464,51 @@ static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter, static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter) { - /* - Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving - any completed CCBs for further processing. It is essential that for each - CCB and SCSI Command issued, command completion processing is performed - exactly once. Therefore, only Incoming Mailboxes with completion code - Command Completed Without Error, Command Completed With Error, or Command - Aborted At Host Request are saved for completion processing. When an - Incoming Mailbox has a completion code of Aborted Command Not Found, the - CCB had already completed or been aborted before the current Abort request - was processed, and so completion processing has already occurred and no - further action should be taken. - */ - struct BusLogic_IncomingMailbox *NextIncomingMailbox = - HostAdapter->NextIncomingMailbox; - enum BusLogic_CompletionCode CompletionCode; - while ((CompletionCode = NextIncomingMailbox->CompletionCode) != - BusLogic_IncomingMailboxFree) - { - /* - We are only allowed to do this because we limit our architectures we - run on to machines where bus_to_virt() actually works. There *needs* - to be a dma_addr_to_virt() in the new PCI DMA mapping interface to - replace bus_to_virt() or else this code is going to become very - innefficient. - */ - struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) - 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); - } + /* + Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving + any completed CCBs for further processing. It is essential that for each + CCB and SCSI Command issued, command completion processing is performed + exactly once. Therefore, only Incoming Mailboxes with completion code + Command Completed Without Error, Command Completed With Error, or Command + Aborted At Host Request are saved for completion processing. When an + Incoming Mailbox has a completion code of Aborted Command Not Found, the + CCB had already completed or been aborted before the current Abort request + was processed, and so completion processing has already occurred and no + further action should be taken. + */ + struct BusLogic_IncomingMailbox *NextIncomingMailbox = HostAdapter->NextIncomingMailbox; + enum BusLogic_CompletionCode CompletionCode; + while ((CompletionCode = NextIncomingMailbox->CompletionCode) != BusLogic_IncomingMailboxFree) { + /* + We are only allowed to do this because we limit our architectures we + run on to machines where bus_to_virt() actually works. There *needs* + to be a dma_addr_to_virt() in the new PCI DMA mapping interface to + replace bus_to_virt() or else this code is going to become very + innefficient. + */ + struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) 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); + } + } + NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree; + if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox) + NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; } - NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree; - if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox) - NextIncomingMailbox = HostAdapter->FirstIncomingMailbox; - } - HostAdapter->NextIncomingMailbox = NextIncomingMailbox; + HostAdapter->NextIncomingMailbox = NextIncomingMailbox; } @@ -3008,153 +2521,126 @@ static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdap static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter) { - if (HostAdapter->ProcessCompletedCCBsActive) return; - HostAdapter->ProcessCompletedCCBsActive = true; - while (HostAdapter->FirstCompletedCCB != NULL) - { - struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB; - struct scsi_cmnd *Command = CCB->Command; - HostAdapter->FirstCompletedCCB = CCB->Next; - if (HostAdapter->FirstCompletedCCB == NULL) - HostAdapter->LastCompletedCCB = NULL; - /* - Process the Completed CCB. - */ - if (CCB->Opcode == BusLogic_BusDeviceReset) - { - int TargetID = CCB->TargetID; - BusLogic_Warning("Bus Device Reset CCB #%ld to Target " - "%d Completed\n", HostAdapter, - CCB->SerialNumber, TargetID); - BusLogic_IncrementErrorCounter( - &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted); - HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; - HostAdapter->CommandsSinceReset[TargetID] = 0; - HostAdapter->LastResetCompleted[TargetID] = jiffies; - /* - Place CCB back on the Host Adapter's free list. - */ - BusLogic_DeallocateCCB(CCB); -#if 0 /* this needs to be redone different for new EH */ - /* - Bus Device Reset CCBs have the Command field non-NULL only when a - Bus Device Reset was requested for a Command that did not have a - currently active CCB in the Host Adapter (i.e., a Synchronous - Bus Device Reset), and hence would not have its Completion Routine - called otherwise. - */ - while (Command != NULL) - { - struct scsi_cmnd *NextCommand = Command->reset_chain; - Command->reset_chain = NULL; - Command->result = DID_RESET << 16; - Command->scsi_done(Command); - Command = NextCommand; - } + if (HostAdapter->ProcessCompletedCCBsActive) + return; + HostAdapter->ProcessCompletedCCBsActive = true; + while (HostAdapter->FirstCompletedCCB != NULL) { + struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB; + struct scsi_cmnd *Command = CCB->Command; + HostAdapter->FirstCompletedCCB = CCB->Next; + if (HostAdapter->FirstCompletedCCB == NULL) + HostAdapter->LastCompletedCCB = NULL; + /* + Process the Completed CCB. + */ + if (CCB->Opcode == BusLogic_BusDeviceReset) { + int TargetID = CCB->TargetID; + BusLogic_Warning("Bus Device Reset CCB #%ld to Target " "%d Completed\n", HostAdapter, CCB->SerialNumber, TargetID); + BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted); + HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false; + HostAdapter->CommandsSinceReset[TargetID] = 0; + HostAdapter->LastResetCompleted[TargetID] = jiffies; + /* + Place CCB back on the Host Adapter's free list. + */ + BusLogic_DeallocateCCB(CCB); +#if 0 /* this needs to be redone different for new EH */ + /* + Bus Device Reset CCBs have the Command field non-NULL only when a + Bus Device Reset was requested for a Command that did not have a + currently active CCB in the Host Adapter (i.e., a Synchronous + Bus Device Reset), and hence would not have its Completion Routine + called otherwise. + */ + while (Command != NULL) { + struct scsi_cmnd *NextCommand = Command->reset_chain; + Command->reset_chain = NULL; + Command->result = DID_RESET << 16; + Command->scsi_done(Command); + Command = NextCommand; + } #endif - /* - Iterate over the CCBs for this Host Adapter performing completion - processing for any CCBs marked as Reset for this Target. - */ - for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll) - if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) - { - Command = CCB->Command; - BusLogic_DeallocateCCB(CCB); - HostAdapter->ActiveCommands[TargetID]--; - Command->result = DID_RESET << 16; - Command->scsi_done(Command); - } - HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; - } - else - { - /* - Translate the Completion Code, Host Adapter Status, and Target - Device Status into a SCSI Subsystem Result Code. - */ - switch (CCB->CompletionCode) - { - case BusLogic_IncomingMailboxFree: - case BusLogic_AbortedCommandNotFound: - case BusLogic_InvalidCCB: - BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", - HostAdapter, CCB->SerialNumber, CCB->TargetID); - break; - case BusLogic_CommandCompletedWithoutError: - HostAdapter->TargetStatistics[CCB->TargetID] - .CommandsCompleted++; - 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->TargetStatistics[CCB->TargetID] - .CommandAbortsCompleted); - Command->result = DID_ABORT << 16; - break; - case BusLogic_CommandCompletedWithError: - Command->result = - BusLogic_ComputeResultCode(HostAdapter, - CCB->HostAdapterStatus, - CCB->TargetDeviceStatus); - if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) - { - HostAdapter->TargetStatistics[CCB->TargetID] - .CommandsCompleted++; - if (BusLogic_GlobalOptions.TraceErrors) - { - int i; - BusLogic_Notice("CCB #%ld Target %d: Result %X Host " - "Adapter Status %02X " - "Target Status %02X\n", - HostAdapter, CCB->SerialNumber, - CCB->TargetID, Command->result, - CCB->HostAdapterStatus, - CCB->TargetDeviceStatus); - BusLogic_Notice("CDB ", HostAdapter); - for (i = 0; i < CCB->CDB_Length; i++) - BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]); - BusLogic_Notice("\n", HostAdapter); - BusLogic_Notice("Sense ", HostAdapter); - for (i = 0; i < CCB->SenseDataLength; i++) - BusLogic_Notice(" %02X", HostAdapter, - Command->sense_buffer[i]); - BusLogic_Notice("\n", HostAdapter); - } + /* + Iterate over the CCBs for this Host Adapter performing completion + processing for any CCBs marked as Reset for this Target. + */ + for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll) + if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID) { + Command = CCB->Command; + BusLogic_DeallocateCCB(CCB); + HostAdapter->ActiveCommands[TargetID]--; + Command->result = DID_RESET << 16; + Command->scsi_done(Command); + } + HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL; + } else { + /* + Translate the Completion Code, Host Adapter Status, and Target + Device Status into a SCSI Subsystem Result Code. + */ + switch (CCB->CompletionCode) { + case BusLogic_IncomingMailboxFree: + case BusLogic_AbortedCommandNotFound: + case BusLogic_InvalidCCB: + BusLogic_Warning("CCB #%ld to Target %d Impossible State\n", HostAdapter, CCB->SerialNumber, CCB->TargetID); + break; + case BusLogic_CommandCompletedWithoutError: + HostAdapter->TargetStatistics[CCB->TargetID] + .CommandsCompleted++; + 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->TargetStatistics[CCB->TargetID] + .CommandAbortsCompleted); + Command->result = DID_ABORT << 16; + break; + case BusLogic_CommandCompletedWithError: + Command->result = BusLogic_ComputeResultCode(HostAdapter, CCB->HostAdapterStatus, CCB->TargetDeviceStatus); + if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout) { + HostAdapter->TargetStatistics[CCB->TargetID] + .CommandsCompleted++; + if (BusLogic_GlobalOptions.TraceErrors) { + int i; + BusLogic_Notice("CCB #%ld Target %d: Result %X Host " + "Adapter Status %02X " "Target Status %02X\n", HostAdapter, CCB->SerialNumber, CCB->TargetID, Command->result, CCB->HostAdapterStatus, CCB->TargetDeviceStatus); + BusLogic_Notice("CDB ", HostAdapter); + for (i = 0; i < CCB->CDB_Length; i++) + BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]); + BusLogic_Notice("\n", HostAdapter); + BusLogic_Notice("Sense ", HostAdapter); + for (i = 0; i < CCB->SenseDataLength; i++) + BusLogic_Notice(" %02X", HostAdapter, Command->sense_buffer[i]); + BusLogic_Notice("\n", HostAdapter); + } + } + 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) { + struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID]; + struct SCSI_Inquiry *InquiryResult = (struct SCSI_Inquiry *) 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); + /* + Call the SCSI Command Completion Routine. + */ + Command->scsi_done(Command); } - 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) - { - struct BusLogic_TargetFlags *TargetFlags = - &HostAdapter->TargetFlags[CCB->TargetID]; - struct SCSI_Inquiry *InquiryResult = - (struct SCSI_Inquiry *) 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); - /* - Call the SCSI Command Completion Routine. - */ - Command->scsi_done(Command); } - } - HostAdapter->ProcessCompletedCCBsActive = false; + HostAdapter->ProcessCompletedCCBsActive = false; } @@ -3163,97 +2649,83 @@ static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapt Adapters. */ -static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, - void *DeviceIdentifier, - struct pt_regs *InterruptRegisters) +static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdentifier, struct pt_regs *InterruptRegisters) { - struct BusLogic_HostAdapter *HostAdapter = - (struct BusLogic_HostAdapter *) DeviceIdentifier; - unsigned long ProcessorFlags; - /* - Acquire exclusive access to Host Adapter. - */ - BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags); - /* - Handle Interrupts appropriately for each Host Adapter type. - */ - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) - { - union BusLogic_InterruptRegister InterruptRegister; - /* - Read the Host Adapter Interrupt Register. - */ - InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); - if (InterruptRegister.ir.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.ir.ExternalBusReset) - HostAdapter->HostAdapterExternalReset = true; - else if (InterruptRegister.ir.IncomingMailboxLoaded) - BusLogic_ScanIncomingMailboxes(HostAdapter); - else if (InterruptRegister.ir.CommandComplete) - HostAdapter->HostAdapterCommandCompleted = true; + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) DeviceIdentifier; + unsigned long ProcessorFlags; + /* + Acquire exclusive access to Host Adapter. + */ + BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags); + /* + Handle Interrupts appropriately for each Host Adapter type. + */ + if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { + union BusLogic_InterruptRegister InterruptRegister; + /* + Read the Host Adapter Interrupt Register. + */ + InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter); + if (InterruptRegister.ir.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.ir.ExternalBusReset) + HostAdapter->HostAdapterExternalReset = true; + else if (InterruptRegister.ir.IncomingMailboxLoaded) + BusLogic_ScanIncomingMailboxes(HostAdapter); + else if (InterruptRegister.ir.CommandComplete) + HostAdapter->HostAdapterCommandCompleted = true; + } + } else { + /* + Check if there is a pending interrupt for this Host Adapter. + */ + 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 (HostAdapter->FirstCompletedCCB != NULL) + BusLogic_ProcessCompletedCCBs(HostAdapter); + /* + Reset the Host Adapter if requested. + */ + if (HostAdapter->HostAdapterExternalReset) { + BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", HostAdapter, HostAdapter->FullModelName); + BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets); + BusLogic_ResetHostAdapter(HostAdapter, false); + HostAdapter->HostAdapterExternalReset = false; + } else if (HostAdapter->HostAdapterInternalError) { + BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", HostAdapter, HostAdapter->FullModelName); + BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors); + BusLogic_ResetHostAdapter(HostAdapter, true); + HostAdapter->HostAdapterInternalError = false; } - } - else - { - /* - Check if there is a pending interrupt for this Host Adapter. - */ - 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 (HostAdapter->FirstCompletedCCB != NULL) - BusLogic_ProcessCompletedCCBs(HostAdapter); - /* - Reset the Host Adapter if requested. - */ - if (HostAdapter->HostAdapterExternalReset) - { - BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n", - HostAdapter, HostAdapter->FullModelName); - BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets); - BusLogic_ResetHostAdapter(HostAdapter, false); - HostAdapter->HostAdapterExternalReset = false; - } - else if (HostAdapter->HostAdapterInternalError) - { - BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n", - HostAdapter, HostAdapter->FullModelName); - BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors); - BusLogic_ResetHostAdapter(HostAdapter, true); - HostAdapter->HostAdapterInternalError = false; - } - /* - Release exclusive access to Host Adapter. - */ - BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags); - return IRQ_HANDLED; + /* + Release exclusive access to Host Adapter. + */ + BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags); + return IRQ_HANDLED; } @@ -3264,43 +2736,38 @@ static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, */ static boolean BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter - *HostAdapter, - enum BusLogic_ActionCode ActionCode, - struct BusLogic_CCB *CCB) + *HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB) { - struct BusLogic_OutgoingMailbox *NextOutgoingMailbox; - NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox; - if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) - { - CCB->Status = BusLogic_CCB_Active; - /* - The CCB field must be written before the Action Code field since - the Host Adapter is operating asynchronously and the locking code - does not protect against simultaneous access by the Host Adapter. - */ - NextOutgoingMailbox->CCB = CCB->DMA_Handle; - NextOutgoingMailbox->ActionCode = ActionCode; - BusLogic_StartMailboxCommand(HostAdapter); - if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox) - NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; - HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox; - if (ActionCode == BusLogic_MailboxStartCommand) - { - HostAdapter->ActiveCommands[CCB->TargetID]++; - if (CCB->Opcode != BusLogic_BusDeviceReset) - HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++; + struct BusLogic_OutgoingMailbox *NextOutgoingMailbox; + NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox; + if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree) { + CCB->Status = BusLogic_CCB_Active; + /* + The CCB field must be written before the Action Code field since + the Host Adapter is operating asynchronously and the locking code + does not protect against simultaneous access by the Host Adapter. + */ + NextOutgoingMailbox->CCB = CCB->DMA_Handle; + NextOutgoingMailbox->ActionCode = ActionCode; + BusLogic_StartMailboxCommand(HostAdapter); + if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox) + NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox; + HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox; + if (ActionCode == BusLogic_MailboxStartCommand) { + HostAdapter->ActiveCommands[CCB->TargetID]++; + if (CCB->Opcode != BusLogic_BusDeviceReset) + HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++; + } + return true; } - return true; - } - return false; + return false; } /* Error Handling (EH) support */ -static int BusLogic_host_reset(Scsi_Cmnd *SCpnt) +static int BusLogic_host_reset(Scsi_Cmnd * SCpnt) { - struct BusLogic_HostAdapter *HostAdapter = - (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata; + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata; unsigned int id = SCpnt->device->id; struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id]; @@ -3314,237 +2781,190 @@ static int BusLogic_host_reset(Scsi_Cmnd *SCpnt) Outgoing Mailbox for execution by the associated Host Adapter. */ -static int BusLogic_QueueCommand(struct scsi_cmnd *Command, - void (*CompletionRoutine)(struct scsi_cmnd *)) +static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRoutine) (struct scsi_cmnd *)) { - struct BusLogic_HostAdapter *HostAdapter = - (struct BusLogic_HostAdapter *) Command->device->host->hostdata; - struct BusLogic_TargetFlags *TargetFlags = - &HostAdapter->TargetFlags[Command->device->id]; - struct BusLogic_TargetStatistics *TargetStatistics = - HostAdapter->TargetStatistics; - unsigned char *CDB = Command->cmnd; - int CDB_Length = Command->cmd_len; - int TargetID = Command->device->id; - int LogicalUnit = Command->device->lun; - void *BufferPointer = Command->request_buffer; - int BufferLength = Command->request_bufflen; - int SegmentCount = Command->use_sg; - struct BusLogic_CCB *CCB; - /* - SCSI REQUEST_SENSE commands will be executed automatically by the Host - Adapter for any errors, so they should not be executed explicitly unless - the Sense Data is zero indicating that no error occurred. - */ - if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) - { - Command->result = DID_OK << 16; - CompletionRoutine(Command); - return 0; - } - /* - 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 - and try again. If that fails, the Host Adapter is probably hung so signal - an error as a Host Adapter Hard Reset should be initiated soon. - */ - CCB = BusLogic_AllocateCCB(HostAdapter); - if (CCB == NULL) - { - BusLogic_ReleaseHostAdapterLock(HostAdapter); - BusLogic_Delay(1); - BusLogic_AcquireHostAdapterLock(HostAdapter); - CCB = BusLogic_AllocateCCB(HostAdapter); - if (CCB == NULL) - { - Command->result = DID_ERROR << 16; - CompletionRoutine(Command); - return 0; - } - } - /* - Initialize the fields in the BusLogic Command Control Block (CCB). - */ - if (SegmentCount == 0 && BufferLength != 0) - { - CCB->Opcode = BusLogic_InitiatorCCB; - CCB->DataLength = BufferLength; - CCB->DataPointer = - pci_map_single(HostAdapter->PCI_Device, BufferPointer, BufferLength, - scsi_to_pci_dma_dir(Command->sc_data_direction)); - } - else if (SegmentCount != 0) - { - struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer; - int Segment, Count; - - Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount, - scsi_to_pci_dma_dir(Command->sc_data_direction)); - CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather; - CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment); - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) - CCB->DataPointer = (unsigned int)CCB->DMA_Handle + - ((unsigned long)&CCB->ScatterGatherList - - (unsigned long)CCB); - else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList); - for (Segment = 0; Segment < Count; Segment++) - { - CCB->ScatterGatherList[Segment].SegmentByteCount = - sg_dma_len(ScatterList+Segment); - CCB->ScatterGatherList[Segment].SegmentDataPointer = - sg_dma_address(ScatterList+Segment); - } - } - else - { - CCB->Opcode = BusLogic_InitiatorCCB; - CCB->DataLength = BufferLength; - CCB->DataPointer = 0; - } - switch (CDB[0]) - { - case READ_6: - case READ_10: - CCB->DataDirection = BusLogic_DataInLengthChecked; - TargetStatistics[TargetID].ReadCommands++; - BusLogic_IncrementByteCounter( - &TargetStatistics[TargetID].TotalBytesRead, BufferLength); - BusLogic_IncrementSizeBucket( - TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength); - break; - case WRITE_6: - case WRITE_10: - CCB->DataDirection = BusLogic_DataOutLengthChecked; - TargetStatistics[TargetID].WriteCommands++; - BusLogic_IncrementByteCounter( - &TargetStatistics[TargetID].TotalBytesWritten, BufferLength); - BusLogic_IncrementSizeBucket( - TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength); - break; - default: - CCB->DataDirection = BusLogic_UncheckedDataTransfer; - break; - } - CCB->CDB_Length = CDB_Length; - CCB->HostAdapterStatus = 0; - CCB->TargetDeviceStatus = 0; - CCB->TargetID = TargetID; - CCB->LogicalUnit = LogicalUnit; - CCB->TagEnable = false; - CCB->LegacyTagEnable = false; - /* - BusLogic recommends that after a Reset the first couple of commands that - are sent to a Target Device be sent in a non Tagged Queue fashion so that - the Host Adapter and Target Device can establish Synchronous and Wide - Transfer before Queue Tag messages can interfere with the Synchronous and - Wide Negotiation messages. By waiting to enable Tagged Queuing until after - the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is - assured that after a Reset any pending commands are requeued before Tagged - Queuing is enabled and that the Tagged Queuing message will not occur while - the partition table is being printed. In addition, some devices do not - properly handle the transition from non-tagged to tagged commands, so it is - necessary to wait until there are no pending commands for a target device - before queuing tagged commands. - */ - if (HostAdapter->CommandsSinceReset[TargetID]++ >= - BusLogic_MaxTaggedQueueDepth && - !TargetFlags->TaggedQueuingActive && - HostAdapter->ActiveCommands[TargetID] == 0 && - TargetFlags->TaggedQueuingSupported && - (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) - { - TargetFlags->TaggedQueuingActive = true; - BusLogic_Notice("Tagged Queuing now active for Target %d\n", - HostAdapter, TargetID); - } - if (TargetFlags->TaggedQueuingActive) - { - enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag; - /* - When using Tagged Queuing with Simple Queue Tags, it appears that disk - drive controllers do not guarantee that a queued command will not - remain in a disconnected state indefinitely if commands that read or - 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 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 - this command may be executed. - */ - if (HostAdapter->ActiveCommands[TargetID] == 0) - HostAdapter->LastSequencePoint[TargetID] = jiffies; - else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ) - { - HostAdapter->LastSequencePoint[TargetID] = jiffies; - QueueTag = BusLogic_OrderedQueueTag; - } - if (HostAdapter->ExtendedLUNSupport) - { - CCB->TagEnable = true; - CCB->QueueTag = QueueTag; + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata; + struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[Command->device->id]; + struct BusLogic_TargetStatistics *TargetStatistics = HostAdapter->TargetStatistics; + unsigned char *CDB = Command->cmnd; + int CDB_Length = Command->cmd_len; + int TargetID = Command->device->id; + int LogicalUnit = Command->device->lun; + void *BufferPointer = Command->request_buffer; + int BufferLength = Command->request_bufflen; + int SegmentCount = Command->use_sg; + struct BusLogic_CCB *CCB; + /* + SCSI REQUEST_SENSE commands will be executed automatically by the Host + Adapter for any errors, so they should not be executed explicitly unless + the Sense Data is zero indicating that no error occurred. + */ + if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) { + Command->result = DID_OK << 16; + CompletionRoutine(Command); + return 0; } - else - { - CCB->LegacyTagEnable = true; - CCB->LegacyQueueTag = QueueTag; + /* + 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 + and try again. If that fails, the Host Adapter is probably hung so signal + an error as a Host Adapter Hard Reset should be initiated soon. + */ + CCB = BusLogic_AllocateCCB(HostAdapter); + if (CCB == NULL) { + BusLogic_ReleaseHostAdapterLock(HostAdapter); + BusLogic_Delay(1); + BusLogic_AcquireHostAdapterLock(HostAdapter); + CCB = BusLogic_AllocateCCB(HostAdapter); + if (CCB == NULL) { + Command->result = DID_ERROR << 16; + CompletionRoutine(Command); + return 0; + } } - } - memcpy(CCB->CDB, CDB, CDB_Length); - CCB->SenseDataLength = sizeof(Command->sense_buffer); - CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, - Command->sense_buffer, - CCB->SenseDataLength, - PCI_DMA_FROMDEVICE); - CCB->Command = Command; - Command->scsi_done = CompletionRoutine; - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) - { - /* - Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI - Subsystem should not attempt to queue more commands than can be placed - in Outgoing Mailboxes, so there should always be one free. In the - unlikely event that there are none available, wait 1 second and try - again. If that fails, the Host Adapter is probably hung so signal an - error as a Host Adapter Hard Reset should be initiated soon. - */ - if (!BusLogic_WriteOutgoingMailbox( - HostAdapter, BusLogic_MailboxStartCommand, CCB)) - { - BusLogic_ReleaseHostAdapterLock(HostAdapter); - BusLogic_Warning("Unable to write Outgoing Mailbox - " - "Pausing for 1 second\n", HostAdapter); - BusLogic_Delay(1); - BusLogic_AcquireHostAdapterLock(HostAdapter); - if (!BusLogic_WriteOutgoingMailbox( - HostAdapter, BusLogic_MailboxStartCommand, CCB)) - { - BusLogic_Warning("Still unable to write Outgoing Mailbox - " - "Host Adapter Dead?\n", HostAdapter); - BusLogic_DeallocateCCB(CCB); - Command->result = DID_ERROR << 16; - Command->scsi_done(Command); - } + /* + Initialize the fields in the BusLogic Command Control Block (CCB). + */ + if (SegmentCount == 0 && BufferLength != 0) { + CCB->Opcode = BusLogic_InitiatorCCB; + CCB->DataLength = BufferLength; + CCB->DataPointer = pci_map_single(HostAdapter->PCI_Device, BufferPointer, BufferLength, scsi_to_pci_dma_dir(Command->sc_data_direction)); + } else if (SegmentCount != 0) { + struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer; + int Segment, Count; + + Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount, scsi_to_pci_dma_dir(Command->sc_data_direction)); + CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather; + CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment); + if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) + CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB); + else + CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList); + for (Segment = 0; Segment < Count; Segment++) { + CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(ScatterList + Segment); + CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(ScatterList + Segment); + } + } else { + CCB->Opcode = BusLogic_InitiatorCCB; + CCB->DataLength = BufferLength; + CCB->DataPointer = 0; + } + switch (CDB[0]) { + case READ_6: + case READ_10: + CCB->DataDirection = BusLogic_DataInLengthChecked; + TargetStatistics[TargetID].ReadCommands++; + BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesRead, BufferLength); + BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength); + break; + case WRITE_6: + case WRITE_10: + CCB->DataDirection = BusLogic_DataOutLengthChecked; + TargetStatistics[TargetID].WriteCommands++; + BusLogic_IncrementByteCounter(&TargetStatistics[TargetID].TotalBytesWritten, BufferLength); + BusLogic_IncrementSizeBucket(TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength); + break; + default: + CCB->DataDirection = BusLogic_UncheckedDataTransfer; + break; + } + CCB->CDB_Length = CDB_Length; + CCB->HostAdapterStatus = 0; + CCB->TargetDeviceStatus = 0; + CCB->TargetID = TargetID; + CCB->LogicalUnit = LogicalUnit; + CCB->TagEnable = false; + CCB->LegacyTagEnable = false; + /* + BusLogic recommends that after a Reset the first couple of commands that + are sent to a Target Device be sent in a non Tagged Queue fashion so that + the Host Adapter and Target Device can establish Synchronous and Wide + Transfer before Queue Tag messages can interfere with the Synchronous and + Wide Negotiation messages. By waiting to enable Tagged Queuing until after + the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is + assured that after a Reset any pending commands are requeued before Tagged + Queuing is enabled and that the Tagged Queuing message will not occur while + the partition table is being printed. In addition, some devices do not + properly handle the transition from non-tagged to tagged commands, so it is + necessary to wait until there are no pending commands for a target device + before queuing tagged commands. + */ + if (HostAdapter->CommandsSinceReset[TargetID]++ >= + BusLogic_MaxTaggedQueueDepth && !TargetFlags->TaggedQueuingActive && HostAdapter->ActiveCommands[TargetID] == 0 && TargetFlags->TaggedQueuingSupported && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID))) { + TargetFlags->TaggedQueuingActive = true; + BusLogic_Notice("Tagged Queuing now active for Target %d\n", HostAdapter, TargetID); + } + if (TargetFlags->TaggedQueuingActive) { + enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag; + /* + When using Tagged Queuing with Simple Queue Tags, it appears that disk + drive controllers do not guarantee that a queued command will not + remain in a disconnected state indefinitely if commands that read or + 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 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 + this command may be executed. + */ + if (HostAdapter->ActiveCommands[TargetID] == 0) + HostAdapter->LastSequencePoint[TargetID] = jiffies; + else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4 * HZ) { + HostAdapter->LastSequencePoint[TargetID] = jiffies; + QueueTag = BusLogic_OrderedQueueTag; + } + if (HostAdapter->ExtendedLUNSupport) { + CCB->TagEnable = true; + CCB->QueueTag = QueueTag; + } else { + CCB->LegacyTagEnable = true; + CCB->LegacyQueueTag = QueueTag; + } } - } - else - { - /* - Call the FlashPoint SCCB Manager to start execution of the CCB. - */ - CCB->Status = BusLogic_CCB_Active; - HostAdapter->ActiveCommands[TargetID]++; - 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(HostAdapter); - } - return 0; + memcpy(CCB->CDB, CDB, CDB_Length); + CCB->SenseDataLength = sizeof(Command->sense_buffer); + CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE); + CCB->Command = Command; + Command->scsi_done = CompletionRoutine; + if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { + /* + Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI + Subsystem should not attempt to queue more commands than can be placed + in Outgoing Mailboxes, so there should always be one free. In the + unlikely event that there are none available, wait 1 second and try + again. If that fails, the Host Adapter is probably hung so signal an + error as a Host Adapter Hard Reset should be initiated soon. + */ + if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) { + BusLogic_ReleaseHostAdapterLock(HostAdapter); + BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter); + BusLogic_Delay(1); + BusLogic_AcquireHostAdapterLock(HostAdapter); + if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) { + BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter); + BusLogic_DeallocateCCB(CCB); + Command->result = DID_ERROR << 16; + Command->scsi_done(Command); + } + } + } else { + /* + Call the FlashPoint SCCB Manager to start execution of the CCB. + */ + CCB->Status = BusLogic_CCB_Active; + HostAdapter->ActiveCommands[TargetID]++; + 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(HostAdapter); + } + return 0; } @@ -3554,105 +2974,75 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, static int BusLogic_AbortCommand(struct scsi_cmnd *Command) { - struct BusLogic_HostAdapter *HostAdapter = - (struct BusLogic_HostAdapter *) Command->device->host->hostdata; - - int TargetID = Command->device->id; - struct BusLogic_CCB *CCB; - BusLogic_IncrementErrorCounter( - &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested); - /* - If this Command has already completed, then no Abort is necessary. - */ - if (Command->serial_number != Command->serial_number_at_timeout) - { - BusLogic_Warning("Unable to Abort Command to Target %d - " - "Already Completed\n", HostAdapter, TargetID); - return SUCCESS; - } - /* - Attempt to find an Active CCB for this Command. If no Active CCB for this - Command is found, then no Abort is necessary. - */ - for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll) - if (CCB->Command == Command) break; - if (CCB == NULL) - { - BusLogic_Warning("Unable to Abort Command to Target %d - " - "No CCB Found\n", HostAdapter, TargetID); - return SUCCESS; - } - else if (CCB->Status == BusLogic_CCB_Completed) - { - BusLogic_Warning("Unable to Abort Command to Target %d - " - "CCB Completed\n", HostAdapter, TargetID); - return SUCCESS; - } - else if (CCB->Status == BusLogic_CCB_Reset) - { - BusLogic_Warning("Unable to Abort Command to Target %d - " - "CCB Reset\n", HostAdapter, TargetID); - return SUCCESS; - } - if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) - { - /* - Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx - do not generate Abort Tag messages, but only generate the non-tagged - Abort message. Since non-tagged commands are not sent by the Host - Adapter until the queue of outstanding tagged commands has completed, - and the Abort message is treated as a non-tagged command, it is - effectively impossible to abort commands when Tagged Queuing is active. - Firmware version 5.xx does generate Abort Tag messages, so it is - possible to abort commands when Tagged Queuing is active. - */ - if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && - HostAdapter->FirmwareVersion[0] < '5') - { - BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " - "Abort Tag Not Supported\n", - HostAdapter, CCB->SerialNumber, TargetID); - return FAILURE; - } - else if (BusLogic_WriteOutgoingMailbox( - HostAdapter, BusLogic_MailboxAbortCommand, CCB)) - { - BusLogic_Warning("Aborting CCB #%ld to Target %d\n", - HostAdapter, CCB->SerialNumber, TargetID); - BusLogic_IncrementErrorCounter( - &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); - return SUCCESS; - } - else - { - BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " - "No Outgoing Mailboxes\n", - HostAdapter, CCB->SerialNumber, TargetID); - return FAILURE; + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) Command->device->host->hostdata; + + int TargetID = Command->device->id; + struct BusLogic_CCB *CCB; + BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested); + /* + If this Command has already completed, then no Abort is necessary. + */ + if (Command->serial_number != Command->serial_number_at_timeout) { + BusLogic_Warning("Unable to Abort Command to Target %d - " "Already Completed\n", HostAdapter, TargetID); + return SUCCESS; } - } - else - { - /* - Call the FlashPoint SCCB Manager to abort execution of the CCB. - */ - BusLogic_Warning("Aborting CCB #%ld to Target %d\n", - HostAdapter, CCB->SerialNumber, TargetID); - BusLogic_IncrementErrorCounter( - &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); - FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB); - /* - The Abort may have already been completed and - BusLogic_QueueCompletedCCB been called, or it - may still be pending. - */ - if (CCB->Status == BusLogic_CCB_Completed) - { - BusLogic_ProcessCompletedCCBs(HostAdapter); + /* + Attempt to find an Active CCB for this Command. If no Active CCB for this + Command is found, then no Abort is necessary. + */ + for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll) + if (CCB->Command == Command) + break; + if (CCB == NULL) { + BusLogic_Warning("Unable to Abort Command to Target %d - " "No CCB Found\n", HostAdapter, TargetID); + return SUCCESS; + } else if (CCB->Status == BusLogic_CCB_Completed) { + BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Completed\n", HostAdapter, TargetID); + return SUCCESS; + } else if (CCB->Status == BusLogic_CCB_Reset) { + BusLogic_Warning("Unable to Abort Command to Target %d - " "CCB Reset\n", HostAdapter, TargetID); + return SUCCESS; + } + if (BusLogic_MultiMasterHostAdapterP(HostAdapter)) { + /* + Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx + do not generate Abort Tag messages, but only generate the non-tagged + Abort message. Since non-tagged commands are not sent by the Host + Adapter until the queue of outstanding tagged commands has completed, + and the Abort message is treated as a non-tagged command, it is + effectively impossible to abort commands when Tagged Queuing is active. + Firmware version 5.xx does generate Abort Tag messages, so it is + possible to abort commands when Tagged Queuing is active. + */ + if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive && HostAdapter->FirmwareVersion[0] < '5') { + BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "Abort Tag Not Supported\n", HostAdapter, CCB->SerialNumber, TargetID); + return FAILURE; + } else if (BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxAbortCommand, CCB)) { + BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID); + BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); + return SUCCESS; + } else { + BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - " "No Outgoing Mailboxes\n", HostAdapter, CCB->SerialNumber, TargetID); + return FAILURE; + } + } else { + /* + Call the FlashPoint SCCB Manager to abort execution of the CCB. + */ + BusLogic_Warning("Aborting CCB #%ld to Target %d\n", HostAdapter, CCB->SerialNumber, TargetID); + BusLogic_IncrementErrorCounter(&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted); + FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB); + /* + The Abort may have already been completed and + BusLogic_QueueCompletedCCB been called, or it + may still be pending. + */ + if (CCB->Status == BusLogic_CCB_Completed) { + BusLogic_ProcessCompletedCCBs(HostAdapter); + } + return SUCCESS; } - return SUCCESS; - } - return SUCCESS; + return SUCCESS; } /* @@ -3660,8 +3050,7 @@ static int BusLogic_AbortCommand(struct scsi_cmnd *Command) currently executing SCSI Commands as having been Reset. */ -static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, - boolean HardReset) +static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, boolean HardReset) { struct BusLogic_CCB *CCB; int TargetID; @@ -3670,10 +3059,8 @@ static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, * Attempt to Reset and Reinitialize the Host Adapter. */ - if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && - BusLogic_InitializeHostAdapter(HostAdapter))) { - BusLogic_Error("Resetting %s Failed\n", HostAdapter, - HostAdapter->FullModelName); + if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) && BusLogic_InitializeHostAdapter(HostAdapter))) { + BusLogic_Error("Resetting %s Failed\n", HostAdapter, HostAdapter->FullModelName); return FAILURE; } @@ -3721,98 +3108,70 @@ static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, the BIOS, and a warning may be displayed. */ -static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, - sector_t capacity, int *Parameters) +static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device, sector_t capacity, int *Parameters) { - struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata; - struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters; - unsigned char *buf; - if (HostAdapter->ExtendedTranslationEnabled && - capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */) - { - if (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; - DiskParameters->Sectors = 32; - } - DiskParameters->Cylinders = - (unsigned long)capacity / (DiskParameters->Heads * DiskParameters->Sectors); - buf = scsi_bios_ptable(Device); - if (buf == NULL) return 0; - /* - If the boot sector partition table flag is valid, search for a partition - table entry whose end_head matches one of the standard BusLogic geometry - translations (64/32, 128/32, or 255/63). - */ - if (*(unsigned short *) (buf+64) == 0xAA55) - { - struct partition *FirstPartitionEntry = (struct partition *) buf; - struct partition *PartitionEntry = FirstPartitionEntry; - int SavedCylinders = DiskParameters->Cylinders, PartitionNumber; - unsigned char PartitionEntryEndHead=0, PartitionEntryEndSector=0; - for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) - { - PartitionEntryEndHead = PartitionEntry->end_head; - PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F; - if (PartitionEntryEndHead == 64-1) - { - DiskParameters->Heads = 64; - DiskParameters->Sectors = 32; - break; - } - else if (PartitionEntryEndHead == 128-1) - { - DiskParameters->Heads = 128; - DiskParameters->Sectors = 32; - break; - } - else if (PartitionEntryEndHead == 255-1) - { - DiskParameters->Heads = 255; - DiskParameters->Sectors = 63; - break; - } - PartitionEntry++; - } - if (PartitionNumber == 4) - { - PartitionEntryEndHead = FirstPartitionEntry->end_head; - PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F; - } - DiskParameters->Cylinders = - (unsigned long)capacity / (DiskParameters->Heads * DiskParameters->Sectors); - if (PartitionNumber < 4 && - PartitionEntryEndSector == DiskParameters->Sectors) - { - if (DiskParameters->Cylinders != SavedCylinders) - BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n", - HostAdapter, - DiskParameters->Heads, DiskParameters->Sectors); + struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata; + struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters; + unsigned char *buf; + if (HostAdapter->ExtendedTranslationEnabled && capacity >= 2 * 1024 * 1024 /* 1 GB in 512 byte sectors */ ) { + if (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; + DiskParameters->Sectors = 32; } - 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); + DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors); + buf = scsi_bios_ptable(Device); + if (buf == NULL) + return 0; + /* + If the boot sector partition table flag is valid, search for a partition + table entry whose end_head matches one of the standard BusLogic geometry + translations (64/32, 128/32, or 255/63). + */ + if (*(unsigned short *) (buf + 64) == 0xAA55) { + struct partition *FirstPartitionEntry = (struct partition *) buf; + struct partition *PartitionEntry = FirstPartitionEntry; + int SavedCylinders = DiskParameters->Cylinders, PartitionNumber; + unsigned char PartitionEntryEndHead = 0, PartitionEntryEndSector = 0; + for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++) { + PartitionEntryEndHead = PartitionEntry->end_head; + PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F; + if (PartitionEntryEndHead == 64 - 1) { + DiskParameters->Heads = 64; + DiskParameters->Sectors = 32; + break; + } else if (PartitionEntryEndHead == 128 - 1) { + DiskParameters->Heads = 128; + DiskParameters->Sectors = 32; + break; + } else if (PartitionEntryEndHead == 255 - 1) { + DiskParameters->Heads = 255; + DiskParameters->Sectors = 63; + break; + } + PartitionEntry++; + } + if (PartitionNumber == 4) { + PartitionEntryEndHead = FirstPartitionEntry->end_head; + PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F; + } + DiskParameters->Cylinders = (unsigned long) capacity / (DiskParameters->Heads * DiskParameters->Sectors); + if (PartitionNumber < 4 && PartitionEntryEndSector == DiskParameters->Sectors) { + 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); + } } - } - kfree(buf); - return 0; + kfree(buf); + return 0; } @@ -3820,178 +3179,124 @@ static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_de BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/. */ -static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, - char **StartPointer, off_t Offset, - int BytesAvailable, int WriteFlag) +static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer, char **StartPointer, off_t Offset, int BytesAvailable, int WriteFlag) { - struct BusLogic_HostAdapter *HostAdapter; - struct BusLogic_TargetStatistics *TargetStatistics; - int TargetID, Length; - char *Buffer; - for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; - HostAdapter != NULL; - HostAdapter = HostAdapter->Next) - if (HostAdapter->HostNumber == shost->host_no) break; - if (HostAdapter == NULL) - { - BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n", - NULL, shost->host_no); - return 0; - } - TargetStatistics = HostAdapter->TargetStatistics; - if (WriteFlag) - { - HostAdapter->ExternalHostAdapterResets = 0; - HostAdapter->HostAdapterInternalErrors = 0; - memset(TargetStatistics, 0, - BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics)); - return 0; - } - Buffer = HostAdapter->MessageBuffer; - Length = HostAdapter->MessageBufferLength; - Length += sprintf(&Buffer[Length], "\n\ + struct BusLogic_HostAdapter *HostAdapter; + struct BusLogic_TargetStatistics *TargetStatistics; + int TargetID, Length; + char *Buffer; + for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next) + if (HostAdapter->HostNumber == shost->host_no) + break; + if (HostAdapter == NULL) { + BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n", NULL, shost->host_no); + return 0; + } + TargetStatistics = HostAdapter->TargetStatistics; + if (WriteFlag) { + HostAdapter->ExternalHostAdapterResets = 0; + HostAdapter->HostAdapterInternalErrors = 0; + memset(TargetStatistics, 0, BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics)); + return 0; + } + Buffer = HostAdapter->MessageBuffer; + Length = HostAdapter->MessageBufferLength; + Length += sprintf(&Buffer[Length], "\n\ Current Driver Queue Depth: %d\n\ -Currently Allocated CCBs: %d\n", - HostAdapter->DriverQueueDepth, - HostAdapter->AllocatedCCBs); - Length += sprintf(&Buffer[Length], "\n\n\ +Currently Allocated CCBs: %d\n", HostAdapter->DriverQueueDepth, HostAdapter->AllocatedCCBs); + Length += sprintf(&Buffer[Length], "\n\n\ DATA TRANSFER STATISTICS\n\ \n\ Target Tagged Queuing Queue Depth Active Attempted Completed\n\ ====== ============== =========== ====== ========= =========\n"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - { - struct BusLogic_TargetFlags *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\ + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { + struct BusLogic_TargetFlags *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++) - { - struct BusLogic_TargetFlags *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], " %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\ + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { + struct BusLogic_TargetFlags *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], " %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++) - { - struct BusLogic_TargetFlags *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\ + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { + struct BusLogic_TargetFlags *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++) - { - struct BusLogic_TargetFlags *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\ + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { + struct BusLogic_TargetFlags *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\ Command Aborts Bus Device Resets Host Adapter Resets\n\ Target Requested Completed Requested Completed Requested Completed\n\ ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\ ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n"); - for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) - { - struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; - if (!TargetFlags->TargetExists) continue; - Length += - sprintf(&Buffer[Length], "\ - %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, - 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); - if ((Length -= Offset) <= 0) return 0; - if (Length >= BytesAvailable) Length = BytesAvailable; - memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length); - *StartPointer = ProcBuffer; - return Length; + for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { + struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID]; + if (!TargetFlags->TargetExists) + continue; + Length += sprintf(&Buffer[Length], "\ + %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID, 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); + if ((Length -= Offset) <= 0) + return 0; + if (Length >= BytesAvailable) + Length = BytesAvailable; + memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length); + *StartPointer = ProcBuffer; + return Length; } @@ -3999,52 +3304,39 @@ Target Requested Completed Requested Completed Requested Completed\n\ BusLogic_Message prints Driver Messages. */ -static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, - char *Format, - struct BusLogic_HostAdapter *HostAdapter, - ...) +static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...) { - static char Buffer[BusLogic_LineBufferSize]; - static boolean BeginningOfLine = true; - va_list Arguments; - int Length = 0; - va_start(Arguments, HostAdapter); - Length = vsprintf(Buffer, Format, Arguments); - va_end(Arguments); - if (MessageLevel == BusLogic_AnnounceLevel) - { - static int AnnouncementLines = 0; - strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], - Buffer); - HostAdapter->MessageBufferLength += Length; - if (++AnnouncementLines <= 2) - printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer); - } - else if (MessageLevel == BusLogic_InfoLevel) - { - strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], - Buffer); - HostAdapter->MessageBufferLength += Length; - if (BeginningOfLine) - { - 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); - } - else printk("%s", Buffer); - } - BeginningOfLine = (Buffer[Length-1] == '\n'); + static char Buffer[BusLogic_LineBufferSize]; + static boolean BeginningOfLine = true; + va_list Arguments; + int Length = 0; + va_start(Arguments, HostAdapter); + Length = vsprintf(Buffer, Format, Arguments); + va_end(Arguments); + if (MessageLevel == BusLogic_AnnounceLevel) { + static int AnnouncementLines = 0; + strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer); + HostAdapter->MessageBufferLength += Length; + if (++AnnouncementLines <= 2) + printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer); + } else if (MessageLevel == BusLogic_InfoLevel) { + strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength], Buffer); + HostAdapter->MessageBufferLength += Length; + if (BeginningOfLine) { + 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); + } else + printk("%s", Buffer); + } + BeginningOfLine = (Buffer[Length - 1] == '\n'); } @@ -4055,19 +3347,19 @@ static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, static boolean __init 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; + 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; } @@ -4090,225 +3382,165 @@ static boolean __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword) static int __init BusLogic_ParseDriverOptions(char *OptionsString) { - while (true) - { - struct BusLogic_DriverOptions *DriverOptions = - &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++]; - int TargetID; - memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions)); - while (*OptionsString != '\0' && *OptionsString != ';') - { - /* Probing Options. */ - if (BusLogic_ParseKeyword(&OptionsString, "IO:")) - { - unsigned long 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 " - "(invalid I/O Address 0x%X)\n", - NULL, IO_Address); - return 0; - } - } - 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 " - "(invalid Queue Depth %d)\n", - NULL, QueueDepth); - return 0; - } - 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 0; - } - } - if (*OptionsString != ']') - { - BusLogic_Error("BusLogic: Invalid Driver Options " - "(']' expected at '%s')\n", - NULL, OptionsString); - return 0; - } - 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 " - "(invalid Queue Depth %d)\n", - NULL, QueueDepth); - return 0; + while (true) { + struct BusLogic_DriverOptions *DriverOptions = &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++]; + int TargetID; + memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions)); + while (*OptionsString != '\0' && *OptionsString != ';') { + /* Probing Options. */ + if (BusLogic_ParseKeyword(&OptionsString, "IO:")) { + unsigned long 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 " "(invalid I/O Address 0x%X)\n", NULL, IO_Address); + return 0; + } + } 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 " "(invalid Queue Depth %d)\n", NULL, QueueDepth); + return 0; + } + 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 0; + } + } + if (*OptionsString != ']') { + BusLogic_Error("BusLogic: Invalid Driver Options " "(']' expected at '%s')\n", NULL, OptionsString); + return 0; + } 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 " "(invalid Queue Depth %d)\n", NULL, QueueDepth); + return 0; + } + 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; + } + } + } + /* 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 " "(invalid Bus Settle Time %d)\n", NULL, BusSettleTime); + return 0; + } + 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'; + } } - 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; + 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 0; } - 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; - } - } - } - /* 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 " - "(invalid Bus Settle Time %d)\n", - NULL, BusSettleTime); - return 0; - } - 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 0; - } - /* - 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 0; - } - return 1; + /* + 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 0; + } + return 1; } /* @@ -4316,21 +3548,21 @@ static int __init BusLogic_ParseDriverOptions(char *OptionsString) */ static struct scsi_host_template driver_template = { - .module = THIS_MODULE, - .proc_name = "BusLogic", - .proc_info = BusLogic_ProcDirectoryInfo, - .name = "BusLogic", - .info = BusLogic_DriverInfo, - .queuecommand = BusLogic_QueueCommand, - .slave_configure = BusLogic_SlaveConfigure, - .bios_param = BusLogic_BIOSDiskParameters, - .eh_host_reset_handler = BusLogic_host_reset, + .module = THIS_MODULE, + .proc_name = "BusLogic", + .proc_info = BusLogic_ProcDirectoryInfo, + .name = "BusLogic", + .info = BusLogic_DriverInfo, + .queuecommand = BusLogic_QueueCommand, + .slave_configure = BusLogic_SlaveConfigure, + .bios_param = BusLogic_BIOSDiskParameters, + .eh_host_reset_handler = BusLogic_host_reset, #if 0 - .eh_abort_handler = BusLogic_AbortCommand, + .eh_abort_handler = BusLogic_AbortCommand, #endif - .unchecked_isa_dma = 1, - .max_sectors = 128, - .use_clustering = ENABLE_CLUSTERING, + .unchecked_isa_dma = 1, + .max_sectors = 128, + .use_clustering = ENABLE_CLUSTERING, }; /* @@ -4341,11 +3573,10 @@ static int __init BusLogic_Setup(char *str) { int ints[3]; - (void)get_options(str, ARRAY_SIZE(ints), ints); + (void) get_options(str, ARRAY_SIZE(ints), ints); if (ints[0] != 0) { - BusLogic_Error("BusLogic: Obsolete Command Line Entry " - "Format Ignored\n", NULL); + BusLogic_Error("BusLogic: Obsolete Command Line Entry " "Format Ignored\n", NULL); return 0; } if (str == NULL || *str == '\0') @@ -4357,13 +3588,14 @@ static int __init BusLogic_Setup(char *str) * Initialization function */ -static int __init BusLogic_init(void) { +static int __init BusLogic_init(void) +{ #ifdef MODULE if (BusLogic) BusLogic_Setup(BusLogic); #endif - + return BusLogic_DetectHostAdapter(&driver_template) ? 0 : -ENODEV; } @@ -4374,14 +3606,12 @@ static int __init BusLogic_init(void) { static void __exit BusLogic_exit(void) { struct BusLogic_HostAdapter *HostAdapter; - for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; - HostAdapter != NULL; HostAdapter = HostAdapter->Next) { + for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next) { struct Scsi_Host *host = HostAdapter->SCSI_Host; scsi_remove_host(host); } - for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; - HostAdapter != NULL; HostAdapter = HostAdapter->Next) { + for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next) { struct Scsi_Host *host = HostAdapter->SCSI_Host; BusLogic_ReleaseHostAdapter(host); }