BOOLEAN OslIsPciDevicePresent(ULONG BusNumber, ULONG SlotNumber) { UINT32 ReadLength; PCI_COMMON_CONFIG PciConfig; /* Detect device presence by reading the PCI configuration space */ ReadLength = HalGetBusDataByOffset(PCIConfiguration, BusNumber, SlotNumber, &PciConfig, 0, sizeof(PciConfig)); if (ReadLength == 0) { DPRINT("PCI device is not present\n"); return FALSE; } ASSERT(ReadLength >= 2); if (PciConfig.VendorID == PCI_INVALID_VENDORID) { DPRINT("Invalid vendor ID in PCI configuration space\n"); return FALSE; } DPRINT("PCI device is present\n"); return TRUE; }
ULONG NdisImmediateReadPciSlotInformation( IN NDIS_HANDLE WrapperConfigurationContext, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG Length ) /*++ Routine Description: This routine reads from the PCI configuration space a specified length of bytes at a certain offset. Arguments: WrapperConfigurationContext - Context passed to MacAddAdapter. SlotNumber - The slot number of the device. Offset - Offset to read from Buffer - Place to store the bytes Length - Number of bytes to read Return Value: Returns the number of bytes read. --*/ { ULONG DataLength = 0; ULONG BusNumber; PRTL_QUERY_REGISTRY_TABLE KeyQueryTable; KeyQueryTable = (PRTL_QUERY_REGISTRY_TABLE)WrapperConfigurationContext; BusNumber = KeyQueryTable[3].DefaultLength; ASSERT((NDIS_INTERFACE_TYPE)(KeyQueryTable[3].DefaultType) == NdisInterfacePci); DataLength = HalGetBusDataByOffset(PCIConfiguration, BusNumber, SlotNumber, Buffer, Offset, Length); return DataLength; }
/* * @implemented */ ULONG NTAPI HalGetBusData(IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length) { /* Call the extended function */ return HalGetBusDataByOffset(BusDataType, BusNumber, SlotNumber, Buffer, 0, Length); }
NTSTATUS SlReadPciConfig( READ_PCI_CONFIG_INPUT *ReadPciConfigInput, UINT32 InputBufferSize, VOID *OutputBuffer, UINT32 OutputBufferSize, UINT32 *BytesReturned ) { PCI_SLOT_NUMBER slot; UINT32 bus, error; if (InputBufferSize != sizeof(READ_PCI_CONFIG_INPUT)) return STATUS_INVALID_PARAMETER; bus = PciGetBus(ReadPciConfigInput->PciAddress); slot.u.AsULONG = 0; slot.u.bits.DeviceNumber = PciGetDev(ReadPciConfigInput->PciAddress); slot.u.bits.FunctionNumber = PciGetFunc(ReadPciConfigInput->PciAddress); error = HalGetBusDataByOffset( PCIConfiguration, bus, slot.u.AsULONG, OutputBuffer, ReadPciConfigInput->PciOffset, OutputBufferSize ); *BytesReturned = 0; if (error == 0) return STATUS_UNSUCCESSFUL; else if (OutputBufferSize != 2 && error == 2) return STATUS_UNSUCCESSFUL; else if (OutputBufferSize != OutputBufferSize) return STATUS_UNSUCCESSFUL; *BytesReturned = OutputBufferSize; return STATUS_SUCCESS; }
UCHAR NTAPI PciGetAdjustedInterruptLine(IN PPCI_PDO_EXTENSION PdoExtension) { UCHAR InterruptLine = 0, PciInterruptLine; ULONG Length; /* Does the device have an interrupt pin? */ if (PdoExtension->InterruptPin) { /* Find the associated line on the parent bus */ Length = HalGetBusDataByOffset(PCIConfiguration, PdoExtension->ParentFdoExtension->BaseBus, PdoExtension->Slot.u.AsULONG, &PciInterruptLine, FIELD_OFFSET(PCI_COMMON_HEADER, u.type0.InterruptLine), sizeof(UCHAR)); if (Length) InterruptLine = PciInterruptLine; } /* Either keep the original interrupt line, or the one on the master bus */ return InterruptLine ? PdoExtension->RawInterruptLine : InterruptLine; }
BOOL CSDHCBase::InitializeHardware( ) { SETFNAME(_T("InitializeHardware")); DEBUGCHK(m_hBusAccess); DEBUGCHK(m_regDevice.IsOK()); PREFAST_DEBUGCHK(m_pSlotInfos); RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware\n"))); ValidateSlotCount(); BOOL fRet = FALSE; PHYSICAL_ADDRESS PortAddress; DWORD inIoSpace = 0; // Read window information DDKWINDOWINFO wini; wini.cbSize = sizeof(wini); DWORD dwStatus = DDKReg_GetWindowInfo(m_regDevice, &wini); if (dwStatus != ERROR_SUCCESS) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting window information\r\n"), pszFname)); goto EXIT; } // Read ISR information DDKISRINFO isri; isri.cbSize = sizeof(isri); dwStatus = DDKReg_GetIsrInfo(m_regDevice, &isri); if (dwStatus != ERROR_SUCCESS) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting ISR information\r\n"), pszFname)); goto EXIT; } #ifdef SET_TI_BOARD_PCI_REG { DDKPCIINFO dpi; dpi.cbSize = sizeof(dpi); DDKReg_GetPciInfo(m_regDevice, &dpi); DWORD RetVal; PCI_SLOT_NUMBER SlotNumber; SlotNumber.u.AsULONG = 0; SlotNumber.u.bits.DeviceNumber = dpi.dwDeviceNumber; SlotNumber.u.bits.FunctionNumber = 1; HalGetBusDataByOffset( PCIConfiguration, wini.dwBusNumber, SlotNumber.u.AsULONG, &RetVal, 0x84, sizeof( RetVal ) ); if (!(RetVal & 0x00200000)) { RetVal |= 0x00200000; HalSetBusDataByOffset( PCIConfiguration, wini.dwBusNumber, SlotNumber.u.AsULONG, &RetVal, 0x84, sizeof( RetVal ) ); } } #endif // Sanity check ISR if (isri.dwSysintr == SYSINTR_NOP) { RETAILMSG(0,(TEXT("%s No sysintr specified in registry\r\n"),pszFname)); DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s No sysintr specified in registry\r\n"), pszFname)); goto EXIT; } if (isri.szIsrDll[0] != 0) { if ( (isri.szIsrHandler[0] == 0) || (isri.dwIrq == IRQ_UNSPECIFIED) ) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Invalid installable ISR information in registry\r\n"), pszFname)); goto EXIT; } } m_interfaceType = (INTERFACE_TYPE) wini.dwInterfaceType; m_dwBusNumber = wini.dwBusNumber; DWORD dwSlotZeroWindow; dwSlotZeroWindow = DetermineFirstSlotWindow(&wini); DEBUGCHK(dwSlotZeroWindow < wini.dwNumMemWindows); DEBUGCHK( (dwSlotZeroWindow + m_cSlots) <= wini.dwNumMemWindows ); // Use the slot zero window for the ISR PDEVICEWINDOW pWindowSlotZero = &wini.memWindows[dwSlotZeroWindow]; PortAddress.LowPart = pWindowSlotZero->dwBase; PortAddress.HighPart = 0; RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware go on...\n"))); // Install an ISR, if present if (isri.szIsrDll[0] != 0) { m_hISRHandler = LoadIntChainHandler(isri.szIsrDll, isri.szIsrHandler, (BYTE) isri.dwIrq); if (m_hISRHandler == NULL) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error installing ISR\r\n"), pszFname)); goto EXIT; } else { GIISR_INFO Info; DWORD dwPhysAddr; fRet = BusTransBusAddrToStatic(m_hBusAccess, (INTERFACE_TYPE) wini.dwInterfaceType, wini.dwBusNumber, PortAddress, pWindowSlotZero->dwLen, &inIoSpace, (PVOID *) &dwPhysAddr); if (fRet == FALSE) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error translating bus address to static address\r\n"), pszFname)); goto EXIT; } // Initialize ISR Info.SysIntr = isri.dwSysintr; Info.CheckPort = TRUE; Info.PortIsIO = (inIoSpace != 0); Info.UseMaskReg = FALSE; Info.PortAddr = dwPhysAddr + SDHC_SLOT_INT_STATUS; Info.PortSize = sizeof(USHORT); Info.Mask = 0xFF; fRet = KernelLibIoControl(m_hISRHandler, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL); if (fRet == FALSE) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error setting up ISR\r\n"), pszFname)); goto EXIT; } } } m_dwSysIntr = isri.dwSysintr; DEBUGMSG(SDCARD_ZONE_INIT, (_T("%s IRQ 0x%X mapped to SYS_INTR 0x%X\r\n"), pszFname, isri.dwIrq, m_dwSysIntr)); const DWORD dwEndWindow = dwSlotZeroWindow + m_cSlots; for (DWORD dwWindow = dwSlotZeroWindow; dwWindow < dwEndWindow; ++dwWindow) { DEBUGCHK(dwWindow < wini.dwNumMemWindows); PDEVICEWINDOW pWindowSD = &wini.memWindows[dwWindow]; DEBUGMSG(SDCARD_ZONE_INIT, (_T("%s Base address -> 0x%x; length -> 0x%x \r\n"), pszFname, pWindowSD->dwBase, pWindowSD->dwLen)); PortAddress.LowPart = pWindowSD->dwBase; PortAddress.HighPart = 0; inIoSpace = 0; PVOID pvRegisters; DEBUGCHK(pWindowSlotZero->dwLen >= sizeof(SSDHC_REGISTERS)); RETAILMSG(0,(TEXT("BusTransBusAddrToVirtual. 0x%X\n"),PortAddress)); fRet = BusTransBusAddrToVirtual(m_hBusAccess, (INTERFACE_TYPE) wini.dwInterfaceType, wini.dwBusNumber, PortAddress, pWindowSD->dwLen, &inIoSpace, &pvRegisters); if (fRet == FALSE) { RETAILMSG(0,(TEXT("%s error translating SD address \r\n"),pszFname)); DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s error translating SD address \r\n"), pszFname)); goto EXIT; } DEBUGCHK(inIoSpace == 0); // Will not work for I/O mappings. DWORD dwSlot = dwWindow - dwSlotZeroWindow; DEBUGCHK(dwSlot < m_cSlots); m_pSlotInfos[dwSlot].pucRegisters = (volatile UCHAR*) pvRegisters; m_pSlotInfos[dwSlot].dwExtraInfo = pWindowSD->dwLen; } m_fHardwareInitialized = TRUE; fRet = TRUE; RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware finished.\n"))); EXIT: return fRet; }
ULONG x86BiosReadIoSpace ( IN XM_OPERATION_DATATYPE DataType, IN USHORT PortNumber ) /*++ Routine Description: This function reads from emulated I/O space. Arguments: DataType - Supplies the datatype for the read operation. PortNumber - Supplies the port number in I/O space to read from. Return Value: The value read from I/O space is returned as the function value. N.B. If an aligned operation is specified, then the individual bytes are read from the specified port one at a time and assembled into the specified datatype. --*/ { ULONG Result; ULONG PciBusNumber; PCI_SLOT_NUMBER SlotNumber; union { PUCHAR Byte; PUSHORT Word; PULONG Long; } u; // // Compute port address and read port. // // // If PortNumber is in ISA Motherboard space, then overide the base address of // the IO space with ISA space, otherwise, use the base address passed in on // initialization. // if (PortNumber < 0x1000 && ((PortNumber & 0x3ff) < 0x100)) { u.Long = (PULONG)((ULONG)HalpEisaControlBase[0] + PortNumber); } else { u.Long = (PULONG)(x86BiosIoSpace + PortNumber); } if (DataType == BYTE_DATA) { Result = READ_REGISTER_UCHAR(u.Byte); } else if (DataType == LONG_DATA) { // // If PortNumber is attempting to access the PCI config registers defined for X86 systems, // intercept them, and make the appropriate HAL call to get the PCI confoguration data. // if (PortNumber == 0xcf8) { Result = HalpPciConfigAddress; } else if (PortNumber == 0xcfc && (HalpPciConfigAddress & 0x80000000)) { PciBusNumber = (HalpPciConfigAddress >> 16) & 0xff; SlotNumber.u.AsULONG = 0; SlotNumber.u.bits.DeviceNumber = (HalpPciConfigAddress >> 11) & 0x1f; SlotNumber.u.bits.FunctionNumber = (HalpPciConfigAddress >> 8) & 0x07; HalGetBusDataByOffset (PCIConfiguration, PciBusNumber, SlotNumber.u.AsULONG, &Result, HalpPciConfigAddress & 0xfc, 4 ); } else { if (((ULONG)u.Long & 0x3) != 0) {
VOID KdpGetBusData ( IN PDBGKD_MANIPULATE_STATE64 m, IN PSTRING AdditionalData, IN PCONTEXT Context ) /*++ Routine Description: This function is called in response to a get bus data state manipulation message. Its function is to read I/O configuration space. Arguments: m - Supplies the state manipulation message. AdditionalData - Supplies any additional data for the message. Context - Supplies the current context. Return Value: None. --*/ { PDBGKD_GET_SET_BUS_DATA a = &m->u.GetSetBusData; ULONG Length; STRING MessageHeader; MessageHeader.Length = sizeof(*m); MessageHeader.Buffer = (PCHAR)m; ASSERT(AdditionalData->Length == 0); m->ReturnStatus = STATUS_SUCCESS; // // Trim length to fit in a single message // if (a->Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64))) { Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64); } else { Length = a->Length; } // // Get the bus data. // Length = HalGetBusDataByOffset( a->BusDataType, a->BusNumber, a->SlotNumber, AdditionalData->Buffer, a->Offset, Length ); // // Update the data length. // a->Length = Length; AdditionalData->Length = (USHORT)Length; KdpSendPacket( PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, AdditionalData ); }
VOID NdisReadEisaSlotInformationEx( OUT PNDIS_STATUS Status, IN NDIS_HANDLE WrapperConfigurationContext, OUT PUINT SlotNumber, OUT PNDIS_EISA_FUNCTION_INFORMATION *EisaData, OUT PUINT NumberOfFunctions ) /*++ Routine Description: This routine reads the EISA data from the slot given. Arguments: Status - Status of request to be returned to the user. WrapperConfigurationContext - Context passed to MacAddAdapter. SlotNumber - the EISA Slot where the card is at. EisaData - pointer to a buffer where the EISA configuration is to be returned. NumberOfFunctions - Returns the number of function structures in the EisaData. Return Value: None. --*/ { PNDIS_EISA_FUNCTION_INFORMATION EisaBlockPointer; PNDIS_EISA_SLOT_INFORMATION SlotInformation; NTSTATUS NtStatus; ULONG BusNumber; ULONG DataLength; NDIS_INTERFACE_TYPE BusType; NDIS_CONFIGURATION_HANDLE NdisConfiguration; // // Get the BusNumber and the BusType from the Context here!! // NdisConfiguration.KeyQueryTable = (PRTL_QUERY_REGISTRY_TABLE)WrapperConfigurationContext; BusType = (NDIS_INTERFACE_TYPE)(NdisConfiguration.KeyQueryTable[3].DefaultType); BusNumber = NdisConfiguration.KeyQueryTable[3].DefaultLength; *Status = NDIS_STATUS_FAILURE; // Assume failure do { // // First check if any bus access is allowed // if (BusType != Eisa) { break; } SlotInformation = NdisConfiguration.KeyQueryTable[3].DefaultData; *NumberOfFunctions = 2; // // Was there already a buffer allocated? // if (SlotInformation == NULL) { // // No, allocate a buffer // SlotInformation = (PNDIS_EISA_SLOT_INFORMATION) ALLOC_FROM_POOL(sizeof(NDIS_EISA_SLOT_INFORMATION) + (*NumberOfFunctions * sizeof(NDIS_EISA_FUNCTION_INFORMATION)), NDIS_TAG_SLOT_INFO); if (SlotInformation == NULL) { *Status = NDIS_STATUS_RESOURCES; break; } // // Free any old buffer // if (NdisConfiguration.KeyQueryTable[3].DefaultData != NULL) { FREE_POOL(NdisConfiguration.KeyQueryTable[3].DefaultData); } NdisConfiguration.KeyQueryTable[3].DefaultData = SlotInformation; } // // Now get the slot number that we read in earlier // *SlotNumber = NdisConfiguration.KeyQueryTable[4].DefaultLength; DataLength = HalGetBusDataByOffset(EisaConfiguration, BusNumber, *SlotNumber, (PVOID)SlotInformation, 0, sizeof(NDIS_EISA_SLOT_INFORMATION) + (*NumberOfFunctions * sizeof(NDIS_EISA_FUNCTION_INFORMATION))); // // Check for multiple functions in the Eisa data. // while (DataLength == (*NumberOfFunctions * sizeof(NDIS_EISA_FUNCTION_INFORMATION))) { *NumberOfFunctions++; // // Now allocate a new buffer // SlotInformation = (PNDIS_EISA_SLOT_INFORMATION) ALLOC_FROM_POOL(sizeof(NDIS_EISA_SLOT_INFORMATION) + (*NumberOfFunctions *sizeof(NDIS_EISA_FUNCTION_INFORMATION)), NDIS_TAG_SLOT_INFO); if (SlotInformation == NULL) { break; } // // Free any old buffer // if (NdisConfiguration.KeyQueryTable[3].DefaultData != NULL) { FREE_POOL(NdisConfiguration.KeyQueryTable[3].DefaultData); } NdisConfiguration.KeyQueryTable[3].DefaultData = SlotInformation; // // Get new information // DataLength = HalGetBusDataByOffset(EisaConfiguration, BusNumber, *SlotNumber, (PVOID)SlotInformation, sizeof(NDIS_EISA_SLOT_INFORMATION) + 0, (*NumberOfFunctions * sizeof(NDIS_EISA_FUNCTION_INFORMATION))); } if (SlotInformation == NULL) { *Status = NDIS_STATUS_RESOURCES; break; } EisaBlockPointer = (PNDIS_EISA_FUNCTION_INFORMATION) ((PUCHAR)SlotInformation + sizeof(CM_EISA_SLOT_INFORMATION)); *EisaData = EisaBlockPointer; *NumberOfFunctions--; // We overshoot by 1 to verify last one found. *Status = NDIS_STATUS_SUCCESS; } while (FALSE); }
VOID ndisAddBusInformation( IN PNDIS_CONFIGURATION_HANDLE ConfigHandle, IN PBUS_SLOT_DB pDb ) /*++ For OEM adapters that do not have their bus-id in the registry, do them a favor and add it. --*/ { ULONGLONG Buffer[(sizeof(NDIS_EISA_SLOT_INFORMATION)+sizeof(NDIS_EISA_FUNCTION_INFORMATION))/sizeof(ULONGLONG) + 1]; PNDIS_STRING BusIdStr; NDIS_STRING PciIdStr = NDIS_STRING_CONST("AdapterCFID"); NDIS_STRING EisaIdStr = NDIS_STRING_CONST("EisaCompressedId"); NDIS_STRING McaIdStr = NDIS_STRING_CONST("McaPosId"); PNDIS_EISA_SLOT_INFORMATION SlotInformation; NDIS_CONFIGURATION_PARAMETER ParmValue; PNDIS_MCA_POS_DATA McaData; NDIS_STATUS Status; ULONG BusId, DataLength = 0; // // Read the bus-id by politely asking the HAL // switch (pDb->BusType) { case NdisInterfaceEisa: SlotInformation = (PNDIS_EISA_SLOT_INFORMATION)Buffer; DataLength = HalGetBusDataByOffset(EisaConfiguration, pDb->BusNumber, pDb->SlotNumber, SlotInformation, 0, sizeof(NDIS_EISA_SLOT_INFORMATION) + sizeof(NDIS_EISA_FUNCTION_INFORMATION)); BusId = SlotInformation->CompressedId; break; case NdisInterfaceMca: McaData = (PNDIS_MCA_POS_DATA)Buffer; DataLength = HalGetBusDataByOffset(Pos, pDb->BusNumber, pDb->SlotNumber - 1, McaData, 0, sizeof(NDIS_MCA_POS_DATA)); BusId = McaData->AdapterId; break; case NdisInterfacePci: DataLength = HalGetBusDataByOffset(PCIConfiguration, pDb->BusNumber, pDb->SlotNumber, &BusId, 0, sizeof(ULONG)); } if (DataLength != 0) { ParmValue.ParameterType = NdisParameterInteger; ParmValue.ParameterData.IntegerData = BusId; switch (pDb->BusType) { case NdisInterfaceEisa: BusIdStr = &EisaIdStr; break; case NdisInterfaceMca: BusIdStr = &McaIdStr; break; case NdisInterfacePci: BusIdStr = &PciIdStr; break; } if (pDb->BusType != NdisInterfacePci) { // // Do not do it for Pci buses just yet. Some OEM cards do bogus things. // NdisWriteConfiguration(&Status, ConfigHandle, BusIdStr, &ParmValue); // // Finally create a data-base entry for this // ndisAddGlobalDb(pDb->BusType, pDb->BusId, pDb->BusNumber, pDb->SlotNumber); } } }
NDIS_STATUS ndisFixBusInformation( IN PNDIS_CONFIGURATION_HANDLE ConfigHandle, IN PBUS_SLOT_DB pDb ) /*++ Make sure that the card is in the slot that the registry says it is. If it is not, scan the bus to see if we find the card. If we do, then fix up the registry so that next time we do not have to do this. Also keep track of the cards so that we handle multiple instances. --*/ { NDIS_STATUS Status = NDIS_STATUS_FAILURE; ULONGLONG Buffer[(sizeof(NDIS_EISA_SLOT_INFORMATION)+sizeof(NDIS_EISA_FUNCTION_INFORMATION))/sizeof(ULONGLONG) + 1]; PNDIS_EISA_SLOT_INFORMATION SlotInformation; PNDIS_MCA_POS_DATA McaData; NDIS_CONFIGURATION_PARAMETER ParmValue; ULONG BusId, Mask = 0xFFFFFFFF; ULONG DataLength; ULONG Bus, Slot, MaxSlot = 0xFF; SlotInformation = (PNDIS_EISA_SLOT_INFORMATION)Buffer; McaData = (PNDIS_MCA_POS_DATA)Buffer; // // Read the slot information for the slot specified in the registry // switch (pDb->BusType) { case NdisInterfaceEisa: Mask = 0xFFFFFF; DataLength = HalGetBusDataByOffset(EisaConfiguration, pDb->BusNumber, pDb->SlotNumber, SlotInformation, 0, sizeof(NDIS_EISA_SLOT_INFORMATION) + sizeof(NDIS_EISA_FUNCTION_INFORMATION)); BusId = SlotInformation->CompressedId; break; case NdisInterfaceMca: MaxSlot = 7; DataLength = 0; if ((pDb->SlotNumber <= MaxSlot) && (pDb->SlotNumber > 0)) { DataLength = HalGetBusDataByOffset(Pos, pDb->BusNumber, pDb->SlotNumber - 1, McaData, 0, sizeof(NDIS_MCA_POS_DATA)); BusId = McaData->AdapterId; } break; case NdisInterfacePci: DataLength = HalGetBusDataByOffset(PCIConfiguration, pDb->BusNumber, pDb->SlotNumber, &BusId, 0, sizeof(ULONG)); } if ((DataLength != 0) && ((BusId & Mask) == (pDb->BusId & Mask))) { // // The card seems to be where it is supposed to be. Make sure that is the // case by searching our db to see if this is already installed. Use BusId // and not the masked busid for search and in our database. // // If we found an EISA card where the registry says it should be but found another // loaded instance, allow it - for multifunction EISA cards, we can have two cards // with the same bus#/slot#. // if (!ndisSearchGlobalDb(pDb->BusType, BusId, pDb->BusNumber, pDb->SlotNumber) || (pDb->BusType == NdisInterfaceEisa)) { if (ndisAddGlobalDb(pDb->BusType, BusId, pDb->BusNumber, pDb->SlotNumber)) { return NDIS_STATUS_SUCCESS; } // // We could not add to global list. Unlikely we can proceed anyway. // return NDIS_STATUS_RESOURCES; } } // // The card is not where it ought to be. Scan the bus and find out where it is. // for (Bus = 0; NOTHING; Bus ++) { for (Slot = 0; Slot < MaxSlot; Slot ++) { switch (pDb->BusType) { case NdisInterfaceEisa: DataLength = HalGetBusDataByOffset(EisaConfiguration, Bus, Slot, SlotInformation, 0, sizeof(NDIS_EISA_SLOT_INFORMATION) + sizeof(NDIS_EISA_FUNCTION_INFORMATION)); BusId = SlotInformation->CompressedId; break; case NdisInterfaceMca: DataLength = HalGetBusDataByOffset(Pos, Bus, Slot, McaData, 0, sizeof(NDIS_MCA_POS_DATA)); BusId = McaData->AdapterId; break; case NdisInterfacePci: DataLength = HalGetBusDataByOffset(PCIConfiguration, Bus, Slot, &BusId, 0, sizeof(ULONG)); break; } if (DataLength == 0) { // // No more buses, we failed // return NDIS_STATUS_FAILURE; } if ((BusId & Mask) == (pDb->BusId & Mask)) { if (pDb->BusType == NdisInterfaceMca) { // // MCA Slot #s are 0 based for HAL and 1 based for registry // Slot ++; } // // Found one, make sure we do not already know about it // if (!ndisSearchGlobalDb(pDb->BusType, pDb->BusId, Bus, Slot)) { NDIS_STRING BusNumStr = NDIS_STRING_CONST("BusNumber"); NDIS_STRING SlotNumStr = NDIS_STRING_CONST("SlotNumber"); // // This is it. First write it back to the registry. Then // to the global db. // ParmValue.ParameterType = NdisParameterInteger; ParmValue.ParameterData.IntegerData = Bus; NdisWriteConfiguration(&Status, ConfigHandle, &BusNumStr, &ParmValue); ParmValue.ParameterData.IntegerData = Slot; NdisWriteConfiguration(&Status, ConfigHandle, &SlotNumStr, &ParmValue); if (ndisAddGlobalDb(pDb->BusType, pDb->BusId, Bus, Slot)) { pDb->BusNumber = Bus; pDb->SlotNumber = Slot; return NDIS_STATUS_SUCCESS; } // // We could not add to global list. Unlikely we can proceed anyway. // return NDIS_STATUS_RESOURCES; } } } } return Status; }
ULONG NdisReadPciSlotInformation( IN NDIS_HANDLE NdisAdapterHandle, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG Length ) /*++ Routine Description: This routine reads from the PCI configuration space a specified length of bytes at a certain offset. Arguments: NdisAdapterHandle - Adapter we are talking about. SlotNumber - The slot number of the device. Offset - Offset to read from Buffer - Place to store the bytes Length - Number of bytes to read Return Value: Returns the number of bytes read. --*/ { ULONG DataLength = 0; PNDIS_ADAPTER_BLOCK Adapter = (PNDIS_ADAPTER_BLOCK)NdisAdapterHandle; PNDIS_MINIPORT_BLOCK Miniport = (PNDIS_MINIPORT_BLOCK)NdisAdapterHandle; if (Adapter->DeviceObject == NULL) { // // This is a mini-port // ASSERT(Miniport->BusType == NdisInterfacePci); DataLength = HalGetBusDataByOffset(PCIConfiguration, Miniport->BusNumber, SlotNumber, Buffer, Offset, Length); } else { ASSERT(Adapter->BusType == NdisInterfacePci); DataLength = HalGetBusDataByOffset(PCIConfiguration, Adapter->BusNumber, SlotNumber, Buffer, Offset, Length); } return DataLength; }
VOID NdisReadMcaPosInformation( OUT PNDIS_STATUS Status, IN NDIS_HANDLE WrapperConfigurationContext, OUT PUINT ChannelNumber, OUT PNDIS_MCA_POS_DATA McaData ) /*++ Routine Description: This routine reads the MCA data from the POS corresponding to the channel specified. Arguments: WrapperConfigurationContext - Context passed to MacAddAdapter. ChannelNumber - the MCA channel number. McaData - pointer to a buffer where the channel information is to be returned. Return Value: None. --*/ { NDIS_INTERFACE_TYPE BusType; ULONG BusNumber; NDIS_CONFIGURATION_HANDLE NdisConfiguration; ULONG DataLength; // // Get the BusNumber and the BusType from the Context here!! // NdisConfiguration.KeyQueryTable = (PRTL_QUERY_REGISTRY_TABLE)WrapperConfigurationContext; BusType = (NDIS_INTERFACE_TYPE)(NdisConfiguration.KeyQueryTable[3].DefaultType); BusNumber = NdisConfiguration.KeyQueryTable[3].DefaultLength; *Status = NDIS_STATUS_FAILURE; *ChannelNumber = 0; do { // // First check if any bus access is allowed // if (BusType != MicroChannel) { break; } // // Get the channel number that we read in earlier. Note that the HAL // apis expect the channel to be zero based. // *ChannelNumber = NdisConfiguration.KeyQueryTable[4].DefaultLength; DataLength = HalGetBusDataByOffset(Pos, BusNumber, *ChannelNumber - 1, (PVOID)McaData, 0, sizeof(NDIS_MCA_POS_DATA)); *Status = NDIS_STATUS_SUCCESS; } while (FALSE); }