📄 buslogic.c
字号:
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_get_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, DMA_32BIT_MASK )) 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_dev_get(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_dev_get(PCI_Device); NonPrimaryPCIMultiMasterCount++; PCIMultiMasterCount++; } 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)) { 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)) BusLogic_AppendProbeAddressISA(0x334); if (!StandardAddressSeen[2] && (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230)) BusLogic_AppendProbeAddressISA(0x230); if (!StandardAddressSeen[3] && (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234)) BusLogic_AppendProbeAddressISA(0x234); if (!StandardAddressSeen[4] && (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130)) BusLogic_AppendProbeAddressISA(0x130); if (!StandardAddressSeen[5] && (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134)) 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_get_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, DMA_32BIT_MASK)) 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_dev_get(PCI_Device); break; } } } return PCIMultiMasterCount;}/* BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address and Bus Probe Information to be checked for potential BusLogic FlashPoint Host Adapters by interrogating the PCI Configuration Space. It returns the number of FlashPoint Host Adapters found.*/static int __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_get_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, DMA_32BIT_MASK)) 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_dev_get(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);#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -