📄 buslogic.c
字号:
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 __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)); } } } } else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);}#endif /* CONFIG_PCI *//* BusLogic_Failure prints a standardized error message, and then returns false.*/static bool 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_ProbeHostAdapter probes for a BusLogic Host Adapter.*/static bool __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; } 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;}/* 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 bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool 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); } 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 bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter){ struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation; unsigned char RequestedReplyLength; bool 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;}/* BusLogic_ReadHostAdapterConfiguration reads the Configuration Information from Host Adapter and initializes the Host Adapter structure.*/static bool __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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -