📄 buslogic.c
字号:
"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;}/* BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters by interrogating the PCI Configuration Space on PCI machines as well as from the list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both FlashPoint and PCI MultiMaster Host Adapters are present, this driver will probe for FlashPoint Host Adapters first unless the BIOS primary disk is controlled by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host Adapters will be probed first. The BusLogic Driver Options specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force a particular probe order.*/static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T *PrototypeHostAdapter){ /* If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint Host Adapters; otherwise, default to the standard ISA MultiMaster probe. */ if (!BusLogic_ProbeOptions.NoProbePCI && pci_present()) { if (BusLogic_ProbeOptions.MultiMasterFirst) { BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); } else if (BusLogic_ProbeOptions.FlashPointFirst) { BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); } else { int FlashPointCount = BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter); int PCIMultiMasterCount = BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter); if (FlashPointCount > 0 && PCIMultiMasterCount > 0) { BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[FlashPointCount]; BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter; BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest; BusLogic_BIOSDriveMapByte_T Drive0MapByte; while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus) ProbeInfo++; HostAdapter->IO_Address = ProbeInfo->IO_Address; FetchHostAdapterLocalRAMRequest.ByteOffset = BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0; FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(Drive0MapByte); BusLogic_Command(HostAdapter, BusLogic_FetchHostAdapterLocalRAM, &FetchHostAdapterLocalRAMRequest, sizeof(FetchHostAdapterLocalRAMRequest), &Drive0MapByte, sizeof(Drive0MapByte)); /* If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0 is controlled by this PCI MultiMaster Host Adapter, then reverse the probe order so that MultiMaster Host Adapters are probed before FlashPoint Host Adapters. */ if (Drive0MapByte.DiskGeometry != BusLogic_BIOS_Disk_Not_Installed) { BusLogic_ProbeInfo_T SavedProbeInfo[BusLogic_MaxHostAdapters]; int MultiMasterCount = BusLogic_ProbeInfoCount - FlashPointCount; memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, BusLogic_ProbeInfoCount * sizeof(BusLogic_ProbeInfo_T)); memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(BusLogic_ProbeInfo_T)); memcpy(&BusLogic_ProbeInfoList[MultiMasterCount], &SavedProbeInfo[0], FlashPointCount * sizeof(BusLogic_ProbeInfo_T)); } } } } else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);}#endif /* CONFIG_PCI *//* BusLogic_Failure prints a standardized error message, and then returns false.*/static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter, char *ErrorMessage){ BusLogic_AnnounceDriver(HostAdapter); if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) { BusLogic_Error("While configuring BusLogic PCI Host Adapter 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_ProbeHostAdapter probes for a BusLogic Host Adapter.*/static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter){ BusLogic_StatusRegister_T StatusRegister; BusLogic_InterruptRegister_T InterruptRegister; BusLogic_GeometryRegister_T GeometryRegister; /* FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager. */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo; FlashPointInfo->BaseAddress = (BusLogic_Base_Address_T) HostAdapter->IO_Address; FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel; FlashPointInfo->Present = false; if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 && FlashPointInfo->Present)) { BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at " "PCI Bus %d Device %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; } /* 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.Bits.DiagnosticActive || StatusRegister.Bits.CommandParameterRegisterBusy || StatusRegister.Bits.Reserved || StatusRegister.Bits.CommandInvalid || InterruptRegister.Bits.Reserved != 0) return false; /* Check the undocumented Geometry Register to test if there is an I/O port that responded. Adaptec Host Adapters do not implement the Geometry Register, so this test helps serve to avoid incorrectly recognizing an Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C series does respond to the Geometry Register I/O port, but it will be rejected later when the Inquire Extended Setup Information command is issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a BusLogic clone that implements the same interface as earlier BusLogic Host Adapters, including the undocumented commands, and is therefore supported by this driver. However, the AMI FastDisk always returns 0x00 upon reading the Geometry Register, so the extended translation option should always be left disabled on the AMI FastDisk. */ if (GeometryRegister.All == 0xFF) return false; /* Indicate the Host Adapter Probe completed successfully. */ return true;}/* BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter and waits for Host Adapter Diagnostics to complete. If HardReset is true, a Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a Soft Reset is performed which only resets the Host Adapter without forcing a SCSI Bus Reset.*/static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter, boolean HardReset){ BusLogic_StatusRegister_T StatusRegister; int TimeoutCounter; /* FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager. */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) { FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo; FlashPointInfo->HostSoftReset = !HardReset; FlashPointInfo->ReportDataUnderrun = true; HostAdapter->CardHandle = FlashPoint_HardwareResetHostAdapter(FlashPointInfo); if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false; /* Indicate the Host Adapter Hard Reset completed successfully. */ return true; } /* Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host Adapter should respond by setting Diagnostic Active in the Status Register. */ if (HardReset) BusLogic_HardReset(HostAdapter); else BusLogic_SoftReset(HostAdapter); /* Wait until Diagnostic Active is set in the Status Register. */ TimeoutCounter = 5*10000; while (--TimeoutCounter >= 0) { StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter); if (StatusRegister.Bits.DiagnosticActive) break; udelay(100); } if (BusLogic_GlobalOptions.TraceHardwareReset) BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, " "Status 0x%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.Bits.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.Bits.DiagnosticFailure || StatusRegister.Bits.HostAdapterReady || StatusRegister.Bits.DataInRegisterReady) break; udelay(100); } if (BusLogic_GlobalOptions.TraceHardwareReset) BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, " "Status 0x%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.Bits.DiagnosticFailure || !StatusRegister.Bits.HostAdapterReady) { BusLogic_CommandFailureReason = NULL; BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS"); BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n", HostAdapter, StatusRegister.All); if (StatusRegister.Bits.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;}/* BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic Host Adapter.*/static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter){ BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation; BusLogic_RequestedReplyLength_T RequestedReplyLength; boolean Result = true; /* FlashPoint Host Adapters do not require this protection. */ if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true; /* Issue the Inquire Extended Setup Information command. Only genuine BusLogic Host Adapters and true clones support this command. Adaptec 1542C series Host Adapters that respond to the Geometry Register I/O port will fail this command. */ RequestedReplyLength = sizeof(ExtendedSetupInformation);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -