Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbussupp.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS HAL 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: hal/halx86/generic/legacy/bussupp.c 00005 * PURPOSE: HAL Legacy Bus Support Code 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <hal.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS ********************************************************************/ 00016 00017 extern KSPIN_LOCK HalpPCIConfigLock; 00018 ULONG HalpPciIrqMask; 00019 00020 /* PRIVATE FUNCTIONS **********************************************************/ 00021 00022 PBUS_HANDLER 00023 NTAPI 00024 HalpAllocateBusHandler(IN INTERFACE_TYPE InterfaceType, 00025 IN BUS_DATA_TYPE BusDataType, 00026 IN ULONG BusNumber, 00027 IN INTERFACE_TYPE ParentBusInterfaceType, 00028 IN ULONG ParentBusNumber, 00029 IN ULONG BusSpecificData) 00030 { 00031 PBUS_HANDLER Bus; 00032 00033 /* Register the bus handler */ 00034 HalRegisterBusHandler(InterfaceType, 00035 BusDataType, 00036 BusNumber, 00037 ParentBusInterfaceType, 00038 ParentBusNumber, 00039 BusSpecificData, 00040 NULL, 00041 &Bus); 00042 if (!Bus) return NULL; 00043 00044 /* Check for a valid interface */ 00045 if (InterfaceType != InterfaceTypeUndefined) 00046 { 00047 /* Allocate address ranges and zero them out */ 00048 Bus->BusAddresses = ExAllocatePoolWithTag(NonPagedPool, 00049 sizeof(SUPPORTED_RANGES), 00050 ' laH'); 00051 RtlZeroMemory(Bus->BusAddresses, sizeof(SUPPORTED_RANGES)); 00052 00053 /* Build the data structure */ 00054 Bus->BusAddresses->Version = HAL_SUPPORTED_RANGE_VERSION; 00055 Bus->BusAddresses->Dma.Limit = 7; 00056 Bus->BusAddresses->Memory.Limit = 0xFFFFFFFF; 00057 Bus->BusAddresses->IO.Limit = 0xFFFF; 00058 Bus->BusAddresses->IO.SystemAddressSpace = 1; 00059 Bus->BusAddresses->PrefetchMemory.Base = 1; 00060 } 00061 00062 /* Return the bus address */ 00063 return Bus; 00064 } 00065 00066 VOID 00067 NTAPI 00068 INIT_FUNCTION 00069 HalpRegisterInternalBusHandlers(VOID) 00070 { 00071 PBUS_HANDLER Bus; 00072 00073 /* Only do processor 1 */ 00074 if (KeGetCurrentPrcb()->Number) return; 00075 00076 /* Register root support */ 00077 HalpInitBusHandler(); 00078 00079 /* Allocate the system bus */ 00080 Bus = HalpAllocateBusHandler(Internal, 00081 ConfigurationSpaceUndefined, 00082 0, 00083 InterfaceTypeUndefined, 00084 0, 00085 0); 00086 if (Bus) 00087 { 00088 /* Set it up */ 00089 Bus->GetInterruptVector = HalpGetSystemInterruptVector; 00090 Bus->TranslateBusAddress = HalpTranslateSystemBusAddress; 00091 } 00092 00093 /* Allocate the CMOS bus */ 00094 Bus = HalpAllocateBusHandler(InterfaceTypeUndefined, 00095 Cmos, 00096 0, 00097 InterfaceTypeUndefined, 00098 0, 00099 0); 00100 if (Bus) 00101 { 00102 /* Set it up */ 00103 Bus->GetBusData = HalpcGetCmosData; 00104 Bus->SetBusData = HalpcSetCmosData; 00105 } 00106 00107 /* Allocate the CMOS bus */ 00108 Bus = HalpAllocateBusHandler(InterfaceTypeUndefined, 00109 Cmos, 00110 1, 00111 InterfaceTypeUndefined, 00112 0, 00113 0); 00114 if (Bus) 00115 { 00116 /* Set it up */ 00117 Bus->GetBusData = HalpcGetCmosData; 00118 Bus->SetBusData = HalpcSetCmosData; 00119 } 00120 00121 /* Allocate ISA bus */ 00122 Bus = HalpAllocateBusHandler(Isa, 00123 ConfigurationSpaceUndefined, 00124 0, 00125 Internal, 00126 0, 00127 0); 00128 if (Bus) 00129 { 00130 /* Set it up */ 00131 Bus->GetBusData = HalpNoBusData; 00132 Bus->BusAddresses->Memory.Limit = 0xFFFFFF; 00133 Bus->TranslateBusAddress = HalpTranslateIsaBusAddress; 00134 } 00135 00136 /* No support for EISA or MCA */ 00137 ASSERT(HalpBusType == MACHINE_TYPE_ISA); 00138 } 00139 00140 #ifndef _MINIHAL_ 00141 NTSTATUS 00142 NTAPI 00143 INIT_FUNCTION 00144 HalpMarkChipsetDecode(BOOLEAN OverrideEnable) 00145 { 00146 NTSTATUS Status; 00147 UNICODE_STRING KeyString; 00148 ULONG Data = OverrideEnable; 00149 HANDLE KeyHandle, Handle; 00150 00151 /* Open CCS key */ 00152 RtlInitUnicodeString(&KeyString, 00153 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET"); 00154 Status = HalpOpenRegistryKey(&Handle, 0, &KeyString, KEY_ALL_ACCESS, FALSE); 00155 if (NT_SUCCESS(Status)) 00156 { 00157 /* Open PNP Bios key */ 00158 RtlInitUnicodeString(&KeyString, L"Control\\Biosinfo\\PNPBios"); 00159 Status = HalpOpenRegistryKey(&KeyHandle, 00160 Handle, 00161 &KeyString, 00162 KEY_ALL_ACCESS, 00163 TRUE); 00164 00165 /* Close root key */ 00166 ZwClose(Handle); 00167 00168 /* Check if PNP BIOS key exists */ 00169 if (NT_SUCCESS(Status)) 00170 { 00171 /* Set the override value */ 00172 RtlInitUnicodeString(&KeyString, L"FullDecodeChipsetOverride"); 00173 Status = ZwSetValueKey(KeyHandle, 00174 &KeyString, 00175 0, 00176 REG_DWORD, 00177 &Data, 00178 sizeof(Data)); 00179 00180 /* Close subkey */ 00181 ZwClose(KeyHandle); 00182 } 00183 } 00184 00185 /* Return status */ 00186 return Status; 00187 } 00188 00189 PBUS_HANDLER 00190 NTAPI 00191 INIT_FUNCTION 00192 HalpAllocateAndInitPciBusHandler(IN ULONG PciType, 00193 IN ULONG BusNo, 00194 IN BOOLEAN TestAllocation) 00195 { 00196 PBUS_HANDLER Bus; 00197 PPCIPBUSDATA BusData; 00198 00199 /* Allocate the bus handler */ 00200 Bus = HalpAllocateBusHandler(PCIBus, 00201 PCIConfiguration, 00202 BusNo, 00203 Internal, 00204 0, 00205 sizeof(PCIPBUSDATA)); 00206 00207 /* Set it up */ 00208 Bus->GetBusData = (PGETSETBUSDATA)HalpGetPCIData; 00209 Bus->SetBusData = (PGETSETBUSDATA)HalpSetPCIData; 00210 Bus->GetInterruptVector = (PGETINTERRUPTVECTOR)HalpGetPCIIntOnISABus; 00211 Bus->AdjustResourceList = (PADJUSTRESOURCELIST)HalpAdjustPCIResourceList; 00212 Bus->AssignSlotResources = (PASSIGNSLOTRESOURCES)HalpAssignPCISlotResources; 00213 Bus->BusAddresses->Dma.Limit = 0; 00214 00215 /* Get our custom bus data */ 00216 BusData = (PPCIPBUSDATA)Bus->BusData; 00217 00218 /* Setup custom bus data */ 00219 BusData->CommonData.Tag = PCI_DATA_TAG; 00220 BusData->CommonData.Version = PCI_DATA_VERSION; 00221 BusData->CommonData.ReadConfig = (PciReadWriteConfig)HalpReadPCIConfig; 00222 BusData->CommonData.WriteConfig = (PciReadWriteConfig)HalpWritePCIConfig; 00223 BusData->CommonData.Pin2Line = (PciPin2Line)HalpPCIPin2ISALine; 00224 BusData->CommonData.Line2Pin = (PciLine2Pin)HalpPCIISALine2Pin; 00225 BusData->MaxDevice = PCI_MAX_DEVICES; 00226 BusData->GetIrqRange = (PciIrqRange)HalpGetISAFixedPCIIrq; 00227 00228 /* Initialize the bitmap */ 00229 RtlInitializeBitMap(&BusData->DeviceConfigured, BusData->ConfiguredBits, 256); 00230 00231 /* Check the type of PCI bus */ 00232 switch (PciType) 00233 { 00234 /* Type 1 PCI Bus */ 00235 case 1: 00236 00237 /* Copy the Type 1 handler data */ 00238 RtlCopyMemory(&PCIConfigHandler, 00239 &PCIConfigHandlerType1, 00240 sizeof(PCIConfigHandler)); 00241 00242 /* Set correct I/O Ports */ 00243 BusData->Config.Type1.Address = PCI_TYPE1_ADDRESS_PORT; 00244 BusData->Config.Type1.Data = PCI_TYPE1_DATA_PORT; 00245 break; 00246 00247 /* Type 2 PCI Bus */ 00248 case 2: 00249 00250 /* Copy the Type 1 handler data */ 00251 RtlCopyMemory(&PCIConfigHandler, 00252 &PCIConfigHandlerType2, 00253 sizeof (PCIConfigHandler)); 00254 00255 /* Set correct I/O Ports */ 00256 BusData->Config.Type2.CSE = PCI_TYPE2_CSE_PORT; 00257 BusData->Config.Type2.Forward = PCI_TYPE2_FORWARD_PORT; 00258 BusData->Config.Type2.Base = PCI_TYPE2_ADDRESS_BASE; 00259 00260 /* Only 16 devices supported, not 32 */ 00261 BusData->MaxDevice = 16; 00262 break; 00263 00264 default: 00265 00266 /* Invalid type */ 00267 DbgPrint("HAL: Unnkown PCI type\n"); 00268 } 00269 00270 /* Return the bus handler */ 00271 return Bus; 00272 } 00273 00274 BOOLEAN 00275 NTAPI 00276 INIT_FUNCTION 00277 HalpIsValidPCIDevice(IN PBUS_HANDLER BusHandler, 00278 IN PCI_SLOT_NUMBER Slot) 00279 { 00280 UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH]; 00281 PPCI_COMMON_CONFIG PciHeader = (PVOID)DataBuffer; 00282 ULONG i; 00283 ULONG_PTR Address; 00284 00285 /* Read the PCI header */ 00286 HalpReadPCIConfig(BusHandler, Slot, PciHeader, 0, PCI_COMMON_HDR_LENGTH); 00287 00288 /* Make sure it's a valid device */ 00289 if ((PciHeader->VendorID == PCI_INVALID_VENDORID) || 00290 (PCI_CONFIGURATION_TYPE(PciHeader) != PCI_DEVICE_TYPE)) 00291 { 00292 /* Bail out */ 00293 return FALSE; 00294 } 00295 00296 /* Make sure interrupt numbers make sense */ 00297 if (((PciHeader->u.type0.InterruptPin) && 00298 (PciHeader->u.type0.InterruptPin > 4)) || 00299 (PciHeader->u.type0.InterruptLine & 0x70)) 00300 { 00301 /* Bail out */ 00302 return FALSE; 00303 } 00304 00305 /* Now scan PCI BARs */ 00306 for (i = 0; i < PCI_TYPE0_ADDRESSES; i++) 00307 { 00308 /* Check what kind of address it is */ 00309 Address = PciHeader->u.type0.BaseAddresses[i]; 00310 if (Address & PCI_ADDRESS_IO_SPACE) 00311 { 00312 /* Highest I/O port is 65535 */ 00313 if (Address > 0xFFFF) return FALSE; 00314 } 00315 else 00316 { 00317 /* MMIO should be higher than 0x80000 */ 00318 if ((Address > 0xF) && (Address < 0x80000)) return FALSE; 00319 } 00320 00321 /* Is this a 64-bit address? */ 00322 if (!(Address & PCI_ADDRESS_IO_SPACE) && 00323 ((Address & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)) 00324 { 00325 /* Check the next-next entry, since this one 64-bits wide */ 00326 i++; 00327 } 00328 } 00329 00330 /* Header, interrupt and address data all make sense */ 00331 return TRUE; 00332 } 00333 00334 static BOOLEAN WarningsGiven[5]; 00335 00336 NTSTATUS 00337 NTAPI 00338 INIT_FUNCTION 00339 HalpGetChipHacks(IN USHORT VendorId, 00340 IN USHORT DeviceId, 00341 IN UCHAR RevisionId, 00342 IN PULONG HackFlags) 00343 { 00344 UNICODE_STRING KeyName, ValueName; 00345 NTSTATUS Status; 00346 OBJECT_ATTRIBUTES ObjectAttributes; 00347 HANDLE KeyHandle; 00348 WCHAR Buffer[32]; 00349 KEY_VALUE_PARTIAL_INFORMATION PartialInfo; 00350 ULONG ResultLength; 00351 00352 /* Setup the object attributes for the key */ 00353 RtlInitUnicodeString(&KeyName, 00354 L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\" 00355 L"Control\\HAL"); 00356 InitializeObjectAttributes(&ObjectAttributes, 00357 &KeyName, 00358 OBJ_CASE_INSENSITIVE, 00359 NULL, 00360 NULL); 00361 00362 /* Open the key */ 00363 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); 00364 if (!NT_SUCCESS(Status)) return Status; 00365 00366 /* Query value */ 00367 swprintf(Buffer, L"%04X%04X", VendorId, DeviceId); 00368 RtlInitUnicodeString(&ValueName, Buffer); 00369 Status = ZwQueryValueKey(KeyHandle, 00370 &ValueName, 00371 KeyValuePartialInformation, 00372 &PartialInfo, 00373 sizeof(PartialInfo), 00374 &ResultLength); 00375 if (NT_SUCCESS(Status)) 00376 { 00377 /* Return the flags */ 00378 DbgPrint("\tFound HackFlags for your chipset\n"); 00379 *HackFlags = *(PULONG)PartialInfo.Data; 00380 DbgPrint("\t\tHack Flags: %lx (Hack Revision: %lx-Your Revision: %lx)\n", 00381 *HackFlags, HALP_REVISION_FROM_HACK_FLAGS(*HackFlags), RevisionId); 00382 00383 /* Does it apply to this revision? */ 00384 if ((RevisionId) && (RevisionId >= (HALP_REVISION_FROM_HACK_FLAGS(*HackFlags)))) 00385 { 00386 /* Read the revision flags */ 00387 *HackFlags = HALP_REVISION_HACK_FLAGS(*HackFlags); 00388 } 00389 00390 /* Throw out revision data */ 00391 *HackFlags = HALP_HACK_FLAGS(*HackFlags); 00392 if (!*HackFlags) DbgPrint("\tNo HackFlags for your chipset's revision!\n"); 00393 } 00394 00395 /* Close the handle and return */ 00396 ZwClose(KeyHandle); 00397 return Status; 00398 } 00399 00400 BOOLEAN 00401 NTAPI 00402 INIT_FUNCTION 00403 HalpIsRecognizedCard(IN PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo, 00404 IN PPCI_COMMON_CONFIG PciData, 00405 IN ULONG Flags) 00406 { 00407 ULONG ElementCount, i; 00408 PPCI_CARD_DESCRIPTOR CardDescriptor; 00409 00410 /* How many PCI Cards that we know about? */ 00411 ElementCount = PciRegistryInfo->ElementCount; 00412 if (!ElementCount) return FALSE; 00413 00414 /* Loop all descriptors */ 00415 CardDescriptor = &PciRegistryInfo->CardList[0]; 00416 for (i = 0; i < ElementCount; i++, CardDescriptor++) 00417 { 00418 /* Check for flag match */ 00419 if (CardDescriptor->Flags != Flags) continue; 00420 00421 /* Check for VID-PID match */ 00422 if ((CardDescriptor->VendorID != PciData->VendorID) || 00423 (CardDescriptor->DeviceID != PciData->DeviceID)) 00424 { 00425 /* Skip */ 00426 continue; 00427 } 00428 00429 /* Check for revision match, if requested */ 00430 if ((CardDescriptor->Flags & HALP_CHECK_CARD_REVISION_ID) && 00431 (CardDescriptor->RevisionID != PciData->RevisionID)) 00432 { 00433 /* Skip */ 00434 continue; 00435 } 00436 00437 /* Check what kind of device this is */ 00438 switch (PCI_CONFIGURATION_TYPE(PciData)) 00439 { 00440 /* CardBUS Bridge */ 00441 case PCI_CARDBUS_BRIDGE_TYPE: 00442 00443 /* This means the real device header is in the device-specific data */ 00444 PciData = (PPCI_COMMON_CONFIG)PciData->DeviceSpecific; 00445 00446 /* Normal PCI device */ 00447 case PCI_DEVICE_TYPE: 00448 00449 /* Check for subvendor match, if requested */ 00450 if ((CardDescriptor->Flags & HALP_CHECK_CARD_SUBVENDOR_ID) && 00451 (CardDescriptor->SubsystemVendorID != PciData->u.type0.SubVendorID)) 00452 { 00453 /* Skip */ 00454 continue; 00455 } 00456 00457 /* Check for subsystem match, if requested */ 00458 if ((CardDescriptor->Flags & HALP_CHECK_CARD_SUBSYSTEM_ID) && 00459 (CardDescriptor->SubsystemID != PciData->u.type0.SubSystemID)) 00460 { 00461 /* Skip */ 00462 continue; 00463 } 00464 00465 /* You made it! */ 00466 return TRUE; 00467 00468 /* PCI Bridge -- don't bother */ 00469 case PCI_BRIDGE_TYPE: 00470 default: 00471 00472 /* Recognize it */ 00473 return TRUE; 00474 } 00475 } 00476 00477 /* This means the card isn't recognized */ 00478 return FALSE; 00479 } 00480 00481 BOOLEAN 00482 NTAPI 00483 INIT_FUNCTION 00484 HalpIsIdeDevice(IN PPCI_COMMON_CONFIG PciData) 00485 { 00486 /* Simple test first */ 00487 if ((PciData->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) && 00488 (PciData->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR)) 00489 { 00490 /* The device is nice enough to admit it */ 00491 return TRUE; 00492 } 00493 00494 /* Symphony 82C101 */ 00495 if (PciData->VendorID == 0x1C1C) return TRUE; 00496 00497 /* ALi MS4803 or M5219 */ 00498 if ((PciData->VendorID == 0x10B9) && 00499 ((PciData->DeviceID == 0x5215) || (PciData->DeviceID == 0x5219))) 00500 { 00501 return TRUE; 00502 } 00503 00504 /* Appian Technology */ 00505 if ((PciData->VendorID == 0x1097) && (PciData->DeviceID == 0x38)) return TRUE; 00506 00507 /* Compaq Triflex Dual EIDE Controller */ 00508 if ((PciData->VendorID == 0xE11) && (PciData->DeviceID == 0xAE33)) return TRUE; 00509 00510 /* Micron PC Tech RZ1000 */ 00511 if ((PciData->VendorID == 0x1042) && (PciData->DeviceID == 0x1000)) return TRUE; 00512 00513 /* SiS 85C601 or 5513 [IDE] */ 00514 if ((PciData->VendorID == 0x1039) && 00515 ((PciData->DeviceID == 0x601) || (PciData->DeviceID == 0x5513))) 00516 { 00517 return TRUE; 00518 } 00519 00520 /* Symphony Labs W83769F */ 00521 if ((PciData->VendorID == 0x10AD) && 00522 ((PciData->DeviceID == 0x1) || (PciData->DeviceID == 0x150))) 00523 { 00524 return TRUE; 00525 } 00526 00527 /* UMC UM8673F */ 00528 if ((PciData->VendorID == 0x1060) && (PciData->DeviceID == 0x101)) return TRUE; 00529 00530 /* You've survived */ 00531 return FALSE; 00532 } 00533 00534 BOOLEAN 00535 NTAPI 00536 INIT_FUNCTION 00537 HalpIsBridgeDevice(IN PPCI_COMMON_CONFIG PciData) 00538 { 00539 /* Either this is a PCI-to-PCI Bridge, or a CardBUS Bridge */ 00540 return (((PCI_CONFIGURATION_TYPE(PciData) == PCI_BRIDGE_TYPE) && 00541 (PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) && 00542 (PciData->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI)) || 00543 ((PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE) && 00544 (PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) && 00545 (PciData->SubClass == PCI_SUBCLASS_BR_CARDBUS))); 00546 } 00547 00548 BOOLEAN 00549 NTAPI 00550 INIT_FUNCTION 00551 HalpGetPciBridgeConfig(IN ULONG PciType, 00552 IN PUCHAR BusCount) 00553 { 00554 PCI_SLOT_NUMBER PciSlot; 00555 ULONG i, j, k; 00556 UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH]; 00557 PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer; 00558 PBUS_HANDLER BusHandler; 00559 00560 /* Loop PCI buses */ 00561 PciSlot.u.bits.Reserved = 0; 00562 for (i = 0; i < *BusCount; i++) 00563 { 00564 /* Get the bus handler */ 00565 BusHandler = HalHandlerForBus(PCIBus, i); 00566 00567 /* Loop every device */ 00568 for (j = 0; j < PCI_MAX_DEVICES; j++) 00569 { 00570 /* Loop every function */ 00571 PciSlot.u.bits.DeviceNumber = j; 00572 for (k = 0; k < PCI_MAX_FUNCTION; k++) 00573 { 00574 /* Build the final slot structure */ 00575 PciSlot.u.bits.FunctionNumber = k; 00576 00577 /* Read the configuration information */ 00578 HalpReadPCIConfig(BusHandler, 00579 PciSlot, 00580 PciData, 00581 0, 00582 PCI_COMMON_HDR_LENGTH); 00583 00584 /* Skip if this is an invalid function */ 00585 if (PciData->VendorID == PCI_INVALID_VENDORID) continue; 00586 00587 /* Make sure that this is a PCI bridge or a cardbus bridge */ 00588 if (!HalpIsBridgeDevice(PciData)) continue; 00589 00590 /* Not supported */ 00591 if (!WarningsGiven[2]++) DPRINT1("Your machine has a PCI-to-PCI or CardBUS Bridge. PCI devices may fail!\n"); 00592 continue; 00593 } 00594 } 00595 } 00596 00597 /* If we exited the loop, then there's no bridge to worry about */ 00598 return FALSE; 00599 } 00600 00601 VOID 00602 NTAPI 00603 INIT_FUNCTION 00604 HalpFixupPciSupportedRanges(IN ULONG BusCount) 00605 { 00606 ULONG i; 00607 PBUS_HANDLER Bus, ParentBus; 00608 00609 /* Loop all buses */ 00610 for (i = 0; i < BusCount; i++) 00611 { 00612 /* Get PCI bus handler */ 00613 Bus = HalHandlerForBus(PCIBus, i); 00614 00615 /* Loop all parent buses */ 00616 ParentBus = Bus->ParentHandler; 00617 while (ParentBus) 00618 { 00619 /* Should merge addresses */ 00620 if (!WarningsGiven[0]++) DPRINT1("Found parent bus (indicating PCI Bridge). PCI devices may fail!\n"); 00621 00622 /* Check the next parent */ 00623 ParentBus = ParentBus->ParentHandler; 00624 } 00625 } 00626 00627 /* Loop all buses again */ 00628 for (i = 0; i < BusCount; i++) 00629 { 00630 /* Get PCI bus handler */ 00631 Bus = HalHandlerForBus(PCIBus, i); 00632 00633 /* Check if this is a PCI 2.2 Bus with Subtractive Decode */ 00634 if (!((PPCIPBUSDATA)Bus->BusData)->Subtractive) 00635 { 00636 /* Loop all parent buses */ 00637 ParentBus = Bus->ParentHandler; 00638 while (ParentBus) 00639 { 00640 /* But check only PCI parent buses specifically */ 00641 if (ParentBus->InterfaceType == PCIBus) 00642 { 00643 /* Should trim addresses */ 00644 if (!WarningsGiven[1]++) DPRINT1("Found parent PCI Bus (indicating PCI-to-PCI Bridge). PCI devices may fail!\n"); 00645 } 00646 00647 /* Check the next parent */ 00648 ParentBus = ParentBus->ParentHandler; 00649 } 00650 } 00651 } 00652 00653 /* Loop buses one last time */ 00654 for (i = 0; i < BusCount; i++) 00655 { 00656 /* Get the PCI bus handler */ 00657 Bus = HalHandlerForBus(PCIBus, i); 00658 00659 /* Sort and combine (trim) bus address range information */ 00660 DPRINT("Warning: Bus addresses not being optimized!\n"); 00661 } 00662 } 00663 00664 VOID 00665 NTAPI 00666 INIT_FUNCTION 00667 ShowSize(ULONG x) 00668 { 00669 if (!x) return; 00670 DbgPrint(" [size="); 00671 if (x < 1024) 00672 { 00673 DbgPrint("%d", (int) x); 00674 } 00675 else if (x < 1048576) 00676 { 00677 DbgPrint("%dK", (int)(x / 1024)); 00678 } 00679 else if (x < 0x80000000) 00680 { 00681 DbgPrint("%dM", (int)(x / 1048576)); 00682 } 00683 else 00684 { 00685 DbgPrint("%d", x); 00686 } 00687 DbgPrint("]\n"); 00688 } 00689 00690 VOID 00691 NTAPI 00692 INIT_FUNCTION 00693 HalpDebugPciDumpBus(IN ULONG i, 00694 IN ULONG j, 00695 IN ULONG k, 00696 IN PPCI_COMMON_CONFIG PciData) 00697 { 00698 extern CHAR ClassTable[3922]; 00699 extern CHAR VendorTable[642355]; 00700 PCHAR p, ClassName, SubClassName, VendorName, ProductName, SubVendorName; 00701 ULONG Length; 00702 CHAR LookupString[16] = ""; 00703 CHAR bSubClassName[64] = ""; 00704 CHAR bVendorName[64] = ""; 00705 CHAR bProductName[128] = "Unknown device"; 00706 CHAR bSubVendorName[128] = "Unknown"; 00707 ULONG Size, Mem, b; 00708 00709 /* Isolate the class name */ 00710 sprintf(LookupString, "C %02x", PciData->BaseClass); 00711 ClassName = strstr(ClassTable, LookupString); 00712 if (ClassName) 00713 { 00714 /* Isolate the subclass name */ 00715 ClassName += 6; 00716 sprintf(LookupString, "\t%02x", PciData->SubClass); 00717 SubClassName = strstr(ClassName, LookupString); 00718 if (SubClassName) 00719 { 00720 /* Copy the subclass into our buffer */ 00721 SubClassName += 5; 00722 p = strchr(SubClassName, '\r'); 00723 Length = p - SubClassName; 00724 if (Length >= sizeof(bSubClassName)) Length = sizeof(bSubClassName) - 1; 00725 strncpy(bSubClassName, SubClassName, Length); 00726 bSubClassName[Length] = '\0'; 00727 } 00728 } 00729 00730 /* Isolate the vendor name */ 00731 sprintf(LookupString, "\n%04x ", PciData->VendorID); 00732 VendorName = strstr(VendorTable, LookupString); 00733 if (VendorName) 00734 { 00735 /* Copy the vendor name into our buffer */ 00736 VendorName += 7; 00737 p = strchr(VendorName, '\r'); 00738 Length = p - VendorName; 00739 if (Length >= sizeof(bVendorName)) Length = sizeof(bVendorName) - 1; 00740 strncpy(bVendorName, VendorName, Length); 00741 bVendorName[Length] = '\0'; 00742 00743 /* Isolate the product name */ 00744 sprintf(LookupString, "\t%04x", PciData->DeviceID); 00745 ProductName = strstr(VendorName, LookupString); 00746 if (ProductName) 00747 { 00748 /* Copy the product name into our buffer */ 00749 ProductName += 7; 00750 p = strchr(ProductName, '\r'); 00751 Length = p - ProductName; 00752 if (Length >= sizeof(bProductName)) Length = sizeof(bProductName) - 1; 00753 strncpy(bProductName, ProductName, Length); 00754 bProductName[Length] = '\0'; 00755 00756 /* Isolate the subvendor and subsystem name */ 00757 sprintf(LookupString, 00758 "\t\t%04x %04x ", 00759 PciData->u.type0.SubVendorID, 00760 PciData->u.type0.SubSystemID); 00761 SubVendorName = strstr(ProductName, LookupString); 00762 if (SubVendorName) 00763 { 00764 /* Copy the subvendor name into our buffer */ 00765 SubVendorName += 13; 00766 p = strchr(SubVendorName, '\r'); 00767 Length = p - SubVendorName; 00768 if (Length >= sizeof(bSubVendorName)) Length = sizeof(bSubVendorName) - 1; 00769 strncpy(bSubVendorName, SubVendorName, Length); 00770 bSubVendorName[Length] = '\0'; 00771 } 00772 } 00773 } 00774 00775 /* Print out the data */ 00776 DbgPrint("%02x:%02x.%x %s [%02x%02x]: %s %s [%04x:%04x] (rev %02x)\n" 00777 "\tSubsystem: %s [%04x:%04x]\n", 00778 i, 00779 j, 00780 k, 00781 bSubClassName, 00782 PciData->BaseClass, 00783 PciData->SubClass, 00784 bVendorName, 00785 bProductName, 00786 PciData->VendorID, 00787 PciData->DeviceID, 00788 PciData->RevisionID, 00789 bSubVendorName, 00790 PciData->u.type0.SubVendorID, 00791 PciData->u.type0.SubSystemID); 00792 00793 /* Print out and decode flags */ 00794 DbgPrint("\tFlags:"); 00795 if (PciData->Command & PCI_ENABLE_BUS_MASTER) DbgPrint(" bus master,"); 00796 if (PciData->Status & PCI_STATUS_66MHZ_CAPABLE) DbgPrint(" 66MHz,"); 00797 if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x000) DbgPrint(" fast devsel,"); 00798 if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x200) DbgPrint(" medium devsel,"); 00799 if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x400) DbgPrint(" slow devsel,"); 00800 if ((PciData->Status & PCI_STATUS_DEVSEL) == 0x600) DbgPrint(" unknown devsel,"); 00801 DbgPrint(" latency %d", PciData->LatencyTimer); 00802 if (PciData->u.type0.InterruptPin != 0 && 00803 PciData->u.type0.InterruptLine != 0 && 00804 PciData->u.type0.InterruptLine != 0xFF) DbgPrint(", IRQ %02d", PciData->u.type0.InterruptLine); 00805 else if (PciData->u.type0.InterruptPin != 0) DbgPrint(", IRQ assignment required"); 00806 DbgPrint("\n"); 00807 00808 /* Scan addresses */ 00809 Size = 0; 00810 for (b = 0; b < PCI_TYPE0_ADDRESSES; b++) 00811 { 00812 /* Check for a BAR */ 00813 Mem = PciData->u.type0.BaseAddresses[b]; 00814 if (Mem) 00815 { 00816 /* Decode the address type */ 00817 if (Mem & PCI_ADDRESS_IO_SPACE) 00818 { 00819 /* Guess the size */ 00820 Size = 1 << 2; 00821 while (!(Mem & Size) && (Size)) Size <<= 1; 00822 00823 /* Print it out */ 00824 DbgPrint("\tI/O ports at %04lx", Mem & PCI_ADDRESS_IO_ADDRESS_MASK); 00825 ShowSize(Size); 00826 } 00827 else 00828 { 00829 /* Guess the size */ 00830 Size = 1 << 8; 00831 while (!(Mem & Size) && (Size)) Size <<= 1; 00832 00833 /* Print it out */ 00834 DbgPrint("\tMemory at %08lx (%d-bit, %sprefetchable)", 00835 Mem & PCI_ADDRESS_MEMORY_ADDRESS_MASK, 00836 (Mem & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_32BIT ? 32 : 64, 00837 (Mem & PCI_ADDRESS_MEMORY_PREFETCHABLE) ? "" : "non-"); 00838 ShowSize(Size); 00839 } 00840 } 00841 } 00842 } 00843 #endif 00844 00845 VOID 00846 NTAPI 00847 INIT_FUNCTION 00848 HalpInitializePciBus(VOID) 00849 { 00850 #ifndef _MINIHAL_ 00851 PPCI_REGISTRY_INFO_INTERNAL PciRegistryInfo; 00852 UCHAR PciType; 00853 PCI_SLOT_NUMBER PciSlot; 00854 ULONG i, j, k; 00855 UCHAR DataBuffer[PCI_COMMON_HDR_LENGTH]; 00856 PPCI_COMMON_CONFIG PciData = (PPCI_COMMON_CONFIG)DataBuffer; 00857 PBUS_HANDLER BusHandler; 00858 ULONG HackFlags; 00859 BOOLEAN ExtendedAddressDecoding = FALSE; 00860 NTSTATUS Status; 00861 00862 /* Query registry information */ 00863 PciRegistryInfo = HalpQueryPciRegistryInfo(); 00864 if (!PciRegistryInfo) return; 00865 00866 /* Initialize the PCI configuration lock */ 00867 KeInitializeSpinLock(&HalpPCIConfigLock); 00868 00869 /* Get the type and free the info structure */ 00870 PciType = PciRegistryInfo->HardwareMechanism & 0xF; 00871 00872 /* Check if this is a type 2 PCI bus with at least one bus */ 00873 if ((PciRegistryInfo->NoBuses) && (PciType == 2)) 00874 { 00875 /* Setup the PCI slot */ 00876 PciSlot.u.bits.Reserved = 0; 00877 PciSlot.u.bits.FunctionNumber = 0; 00878 00879 /* Loop all slots */ 00880 for (i = 0; i < 32; i++) 00881 { 00882 /* Try to setup a Type 2 PCI slot */ 00883 PciType = 2; 00884 BusHandler = HalpAllocateAndInitPciBusHandler(2, 0, TRUE); 00885 if (!BusHandler) break; 00886 00887 /* Now check if it's valid */ 00888 if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break; 00889 00890 /* Heh, the BIOS lied... try Type 1 */ 00891 PciType = 1; 00892 BusHandler = HalpAllocateAndInitPciBusHandler(1, 0, TRUE); 00893 if (!BusHandler) break; 00894 00895 /* Now check if it's valid */ 00896 if (HalpIsValidPCIDevice(BusHandler, PciSlot)) break; 00897 00898 /* Keep trying */ 00899 PciType = 2; 00900 } 00901 00902 /* Now allocate the correct kind of handler */ 00903 HalpAllocateAndInitPciBusHandler(PciType, 0, FALSE); 00904 } 00905 00906 /* Okay, now loop all PCI bridges */ 00907 do 00908 { 00909 /* Loop all PCI buses */ 00910 for (i = 0; i < PciRegistryInfo->NoBuses; i++) 00911 { 00912 /* Check if we have a handler for it */ 00913 if (!HalHandlerForBus(PCIBus, i)) 00914 { 00915 /* Allocate it */ 00916 HalpAllocateAndInitPciBusHandler(PciType, i, FALSE); 00917 } 00918 } 00919 /* Go to the next bridge */ 00920 } while (HalpGetPciBridgeConfig(PciType, &PciRegistryInfo->NoBuses)); 00921 00922 /* Now build correct address range informaiton */ 00923 HalpFixupPciSupportedRanges(PciRegistryInfo->NoBuses); 00924 00925 /* Loop every bus */ 00926 DbgPrint("\n====== PCI BUS HARDWARE DETECTION =======\n\n"); 00927 PciSlot.u.bits.Reserved = 0; 00928 for (i = 0; i < PciRegistryInfo->NoBuses; i++) 00929 { 00930 /* Get the bus handler */ 00931 BusHandler = HalHandlerForBus(PCIBus, i); 00932 00933 /* Loop every device */ 00934 for (j = 0; j < 32; j++) 00935 { 00936 /* Loop every function */ 00937 PciSlot.u.bits.DeviceNumber = j; 00938 for (k = 0; k < 8; k++) 00939 { 00940 /* Build the final slot structure */ 00941 PciSlot.u.bits.FunctionNumber = k; 00942 00943 /* Read the configuration information */ 00944 HalpReadPCIConfig(BusHandler, 00945 PciSlot, 00946 PciData, 00947 0, 00948 PCI_COMMON_HDR_LENGTH); 00949 00950 /* Skip if this is an invalid function */ 00951 if (PciData->VendorID == PCI_INVALID_VENDORID) continue; 00952 00953 /* Print out the entry */ 00954 HalpDebugPciDumpBus(i, j, k, PciData); 00955 00956 /* Check if this is a Cardbus bridge */ 00957 if (PCI_CONFIGURATION_TYPE(PciData) == PCI_CARDBUS_BRIDGE_TYPE) 00958 { 00959 /* Not supported */ 00960 DbgPrint("\tDevice is a PCI Cardbus Bridge. It will not work!\n"); 00961 continue; 00962 } 00963 00964 /* Check if this is a PCI device */ 00965 if (PCI_CONFIGURATION_TYPE(PciData) != PCI_BRIDGE_TYPE) 00966 { 00967 /* Check if it has an interrupt pin and line registered */ 00968 if ((PciData->u.type1.InterruptPin) && 00969 (PciData->u.type1.InterruptLine)) 00970 { 00971 /* Check if this interrupt line is connected to the bus */ 00972 if (PciData->u.type1.InterruptLine < 16) 00973 { 00974 /* Is this an IDE device? */ 00975 if (!HalpIsIdeDevice(PciData)) 00976 { 00977 /* We'll mask out this interrupt then */ 00978 DbgPrint("\tDevice is using IRQ %d! ISA Cards using that IRQ may fail!\n", 00979 PciData->u.type1.InterruptLine); 00980 HalpPciIrqMask |= (1 << PciData->u.type1.InterruptLine); 00981 } 00982 } 00983 } 00984 } 00985 00986 /* Check for broken Intel chips */ 00987 if (PciData->VendorID == 0x8086) 00988 { 00989 /* Check for broken 82830 PCI controller */ 00990 if ((PciData->DeviceID == 0x04A3) && 00991 (PciData->RevisionID < 0x11)) 00992 { 00993 /* Skip */ 00994 DbgPrint("\tDevice is a broken Intel 82430 PCI Controller. It will not work!\n\n"); 00995 continue; 00996 } 00997 00998 /* Check for broken 82378 PCI-to-ISA Bridge */ 00999 if ((PciData->DeviceID == 0x0484) && 01000 (PciData->RevisionID <= 3)) 01001 { 01002 /* Skip */ 01003 DbgPrint("\tDevice is a broken Intel 82378 PCI-to-ISA Bridge. It will not work!\n\n"); 01004 continue; 01005 } 01006 01007 /* Check for broken 82450 PCI Bridge */ 01008 if ((PciData->DeviceID == 0x84C4) && 01009 (PciData->RevisionID <= 4)) 01010 { 01011 DbgPrint("\tDevice is a Intel Orion 82450 PCI Bridge. It will not work!\n\n"); 01012 continue; 01013 } 01014 } 01015 01016 /* Do we know this card? */ 01017 if (!ExtendedAddressDecoding) 01018 { 01019 /* Check for it */ 01020 if (HalpIsRecognizedCard(PciRegistryInfo, 01021 PciData, 01022 HALP_CARD_FEATURE_FULL_DECODE)) 01023 { 01024 /* We'll do chipset checks later */ 01025 DbgPrint("\tDevice has Extended Address Decoding. It may fail to work on older BIOSes!\n"); 01026 ExtendedAddressDecoding = TRUE; 01027 } 01028 } 01029 01030 /* Check if this is a USB controller */ 01031 if ((PciData->BaseClass == PCI_CLASS_SERIAL_BUS_CTLR) && 01032 (PciData->SubClass == PCI_SUBCLASS_SB_USB)) 01033 { 01034 /* Check if this is an OHCI controller */ 01035 if (PciData->ProgIf == 0x10) 01036 { 01037 DbgPrint("\tDevice is an OHCI (USB) PCI Expansion Card. Turn off Legacy USB in your BIOS!\n\n"); 01038 continue; 01039 } 01040 01041 /* Check for Intel UHCI controller */ 01042 if (PciData->VendorID == 0x8086) 01043 { 01044 DbgPrint("\tDevice is an Intel UHCI (USB) Controller. Turn off Legacy USB in your BIOS!\n\n"); 01045 continue; 01046 } 01047 01048 /* Check for VIA UHCI controller */ 01049 if (PciData->VendorID == 0x1106) 01050 { 01051 DbgPrint("\tDevice is a VIA UHCI (USB) Controller. Turn off Legacy USB in your BIOS!\n\n"); 01052 continue; 01053 } 01054 } 01055 01056 /* Now check the registry for chipset hacks */ 01057 Status = HalpGetChipHacks(PciData->VendorID, 01058 PciData->DeviceID, 01059 PciData->RevisionID, 01060 &HackFlags); 01061 if (NT_SUCCESS(Status)) 01062 { 01063 /* Check for broken ACPI routing */ 01064 if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_ACPI_IRQ_ROUTING) 01065 { 01066 DbgPrint("This chipset has broken ACPI IRQ Routing! Be aware!\n\n"); 01067 continue; 01068 } 01069 01070 /* Check for broken ACPI timer */ 01071 if (HackFlags & HAL_PCI_CHIP_HACK_BROKEN_ACPI_TIMER) 01072 { 01073 DbgPrint("This chipset has a broken ACPI timer! Be aware!\n\n"); 01074 continue; 01075 } 01076 01077 /* Check for hibernate-disable */ 01078 if (HackFlags & HAL_PCI_CHIP_HACK_DISABLE_HIBERNATE) 01079 { 01080 DbgPrint("This chipset has a broken PCI device which is incompatible with hibernation. Be aware!\n\n"); 01081 continue; 01082 } 01083 01084 /* Check for USB controllers that generate SMIs */ 01085 if (HackFlags & HAL_PCI_CHIP_HACK_USB_SMI_DISABLE) 01086 { 01087 DbgPrint("This chipset has a USB controller which generates SMIs. ReactOS will likely fail to boot!\n\n"); 01088 continue; 01089 } 01090 } 01091 01092 /* Terminate the entry */ 01093 DbgPrint("\n"); 01094 } 01095 } 01096 } 01097 01098 /* Initialize NMI Crash Flag */ 01099 HalpGetNMICrashFlag(); 01100 01101 /* Free the registry data */ 01102 ExFreePoolWithTag(PciRegistryInfo, TAG_HAL); 01103 01104 /* Tell PnP if this hard supports correct decoding */ 01105 HalpMarkChipsetDecode(ExtendedAddressDecoding); 01106 DbgPrint("====== PCI BUS DETECTION COMPLETE =======\n\n"); 01107 #endif 01108 } 01109 01110 VOID 01111 NTAPI 01112 INIT_FUNCTION 01113 HalpInitBusHandlers(VOID) 01114 { 01115 /* Register the HAL Bus Handler support */ 01116 HalpRegisterInternalBusHandlers(); 01117 } 01118 01119 VOID 01120 NTAPI 01121 INIT_FUNCTION 01122 HalpRegisterKdSupportFunctions(VOID) 01123 { 01124 /* Register PCI Device Functions */ 01125 KdSetupPciDeviceForDebugging = HalpSetupPciDeviceForDebugging; 01126 KdReleasePciDeviceforDebugging = HalpReleasePciDeviceForDebugging; 01127 01128 /* Register memory functions */ 01129 #ifndef _MINIHAL_ 01130 KdMapPhysicalMemory64 = HalpMapPhysicalMemory64; 01131 KdUnmapVirtualAddress = HalpUnmapVirtualAddress; 01132 #endif 01133 01134 /* Register ACPI stub */ 01135 KdCheckPowerButton = HalpCheckPowerButton; 01136 } 01137 01138 NTSTATUS 01139 NTAPI 01140 HalpAssignSlotResources(IN PUNICODE_STRING RegistryPath, 01141 IN PUNICODE_STRING DriverClassName, 01142 IN PDRIVER_OBJECT DriverObject, 01143 IN PDEVICE_OBJECT DeviceObject, 01144 IN INTERFACE_TYPE BusType, 01145 IN ULONG BusNumber, 01146 IN ULONG SlotNumber, 01147 IN OUT PCM_RESOURCE_LIST *AllocatedResources) 01148 { 01149 PBUS_HANDLER Handler; 01150 NTSTATUS Status; 01151 PAGED_CODE(); 01152 DPRINT1("Slot assignment for %d on bus %d\n", BusType, BusNumber); 01153 01154 /* Find the handler */ 01155 Handler = HalReferenceHandlerForBus(BusType, BusNumber); 01156 if (!Handler) return STATUS_NOT_FOUND; 01157 01158 /* Do the assignment */ 01159 Status = Handler->AssignSlotResources(Handler, 01160 Handler, 01161 RegistryPath, 01162 DriverClassName, 01163 DriverObject, 01164 DeviceObject, 01165 SlotNumber, 01166 AllocatedResources); 01167 01168 /* Dereference the handler and return */ 01169 HalDereferenceBusHandler(Handler); 01170 return Status; 01171 } 01172 01173 BOOLEAN 01174 NTAPI 01175 HaliFindBusAddressTranslation(IN PHYSICAL_ADDRESS BusAddress, 01176 IN OUT PULONG AddressSpace, 01177 OUT PPHYSICAL_ADDRESS TranslatedAddress, 01178 IN OUT PULONG_PTR Context, 01179 IN BOOLEAN NextBus) 01180 { 01181 PHAL_BUS_HANDLER BusHandler; 01182 PBUS_HANDLER Handler; 01183 PLIST_ENTRY NextEntry; 01184 ULONG ContextValue; 01185 01186 /* Make sure we have a context */ 01187 if (!Context) return FALSE; 01188 ASSERT((*Context) || (NextBus == TRUE)); 01189 01190 /* Read the context */ 01191 ContextValue = *Context; 01192 01193 /* Find the bus handler */ 01194 Handler = HalpContextToBusHandler(ContextValue); 01195 if (!Handler) return FALSE; 01196 01197 /* Check if this is an ongoing lookup */ 01198 if (NextBus) 01199 { 01200 /* Get the HAL bus handler */ 01201 BusHandler = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); 01202 NextEntry = &BusHandler->AllHandlers; 01203 01204 /* Get the next one if we were already with one */ 01205 if (ContextValue) NextEntry = NextEntry->Flink; 01206 01207 /* Start scanning */ 01208 while (TRUE) 01209 { 01210 /* Check if this is the last one */ 01211 if (NextEntry == &HalpAllBusHandlers) 01212 { 01213 /* Quit */ 01214 *Context = 1; 01215 return FALSE; 01216 } 01217 01218 /* Call this translator */ 01219 BusHandler = CONTAINING_RECORD(NextEntry, HAL_BUS_HANDLER, AllHandlers); 01220 if (HalTranslateBusAddress(BusHandler->Handler.InterfaceType, 01221 BusHandler->Handler.BusNumber, 01222 BusAddress, 01223 AddressSpace, 01224 TranslatedAddress)) break; 01225 01226 /* Try the next one */ 01227 NextEntry = NextEntry->Flink; 01228 } 01229 01230 /* If we made it, we're done */ 01231 *Context = (ULONG_PTR)Handler; 01232 return TRUE; 01233 } 01234 01235 /* Try the first one through */ 01236 if (!HalTranslateBusAddress(Handler->InterfaceType, 01237 Handler->BusNumber, 01238 BusAddress, 01239 AddressSpace, 01240 TranslatedAddress)) return FALSE; 01241 01242 /* Remember for next time */ 01243 *Context = (ULONG_PTR)Handler; 01244 return TRUE; 01245 } 01246 01247 BOOLEAN 01248 NTAPI 01249 HaliTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, 01250 IN ULONG BusNumber, 01251 IN PHYSICAL_ADDRESS BusAddress, 01252 IN OUT PULONG AddressSpace, 01253 OUT PPHYSICAL_ADDRESS TranslatedAddress) 01254 { 01255 PBUS_HANDLER Handler; 01256 BOOLEAN Status; 01257 01258 /* Find the handler */ 01259 Handler = HalReferenceHandlerForBus(InterfaceType, BusNumber); 01260 if (!(Handler) || !(Handler->TranslateBusAddress)) 01261 { 01262 DPRINT1("No translator Interface: %x, Bus: %x, Handler: %x!\n", InterfaceType, BusNumber, Handler); 01263 return FALSE; 01264 } 01265 01266 /* Do the assignment */ 01267 Status = Handler->TranslateBusAddress(Handler, 01268 Handler, 01269 BusAddress, 01270 AddressSpace, 01271 TranslatedAddress); 01272 01273 /* Dereference the handler and return */ 01274 HalDereferenceBusHandler(Handler); 01275 return Status; 01276 } 01277 01278 /* PUBLIC FUNCTIONS **********************************************************/ 01279 01280 /* 01281 * @implemented 01282 */ 01283 NTSTATUS 01284 NTAPI 01285 HalAdjustResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST *ResourceList) 01286 { 01287 PBUS_HANDLER Handler; 01288 ULONG Status; 01289 PAGED_CODE(); 01290 01291 /* Find the handler */ 01292 Handler = HalReferenceHandlerForBus((*ResourceList)->InterfaceType, 01293 (*ResourceList)->BusNumber); 01294 if (!Handler) return STATUS_SUCCESS; 01295 01296 /* Do the assignment */ 01297 Status = Handler->AdjustResourceList(Handler, 01298 Handler, 01299 ResourceList); 01300 01301 /* Dereference the handler and return */ 01302 HalDereferenceBusHandler(Handler); 01303 return Status; 01304 } 01305 01306 /* 01307 * @implemented 01308 */ 01309 NTSTATUS 01310 NTAPI 01311 HalAssignSlotResources(IN PUNICODE_STRING RegistryPath, 01312 IN PUNICODE_STRING DriverClassName, 01313 IN PDRIVER_OBJECT DriverObject, 01314 IN PDEVICE_OBJECT DeviceObject, 01315 IN INTERFACE_TYPE BusType, 01316 IN ULONG BusNumber, 01317 IN ULONG SlotNumber, 01318 IN OUT PCM_RESOURCE_LIST *AllocatedResources) 01319 { 01320 PAGED_CODE(); 01321 01322 /* Check the bus type */ 01323 if (BusType != PCIBus) 01324 { 01325 /* Call our internal handler */ 01326 return HalpAssignSlotResources(RegistryPath, 01327 DriverClassName, 01328 DriverObject, 01329 DeviceObject, 01330 BusType, 01331 BusNumber, 01332 SlotNumber, 01333 AllocatedResources); 01334 } 01335 else 01336 { 01337 /* Call the PCI registered function */ 01338 return HalPciAssignSlotResources(RegistryPath, 01339 DriverClassName, 01340 DriverObject, 01341 DeviceObject, 01342 PCIBus, 01343 BusNumber, 01344 SlotNumber, 01345 AllocatedResources); 01346 } 01347 } 01348 01349 /* 01350 * @implemented 01351 */ 01352 ULONG 01353 NTAPI 01354 HalGetBusData(IN BUS_DATA_TYPE BusDataType, 01355 IN ULONG BusNumber, 01356 IN ULONG SlotNumber, 01357 IN PVOID Buffer, 01358 IN ULONG Length) 01359 { 01360 /* Call the extended function */ 01361 return HalGetBusDataByOffset(BusDataType, 01362 BusNumber, 01363 SlotNumber, 01364 Buffer, 01365 0, 01366 Length); 01367 } 01368 01369 /* 01370 * @implemented 01371 */ 01372 ULONG 01373 NTAPI 01374 HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, 01375 IN ULONG BusNumber, 01376 IN ULONG SlotNumber, 01377 IN PVOID Buffer, 01378 IN ULONG Offset, 01379 IN ULONG Length) 01380 { 01381 PBUS_HANDLER Handler; 01382 ULONG Status; 01383 01384 /* Find the handler */ 01385 Handler = HaliReferenceHandlerForConfigSpace(BusDataType, BusNumber); 01386 if (!Handler) return 0; 01387 01388 /* Do the assignment */ 01389 Status = Handler->GetBusData(Handler, 01390 Handler, 01391 SlotNumber, 01392 Buffer, 01393 Offset, 01394 Length); 01395 01396 /* Dereference the handler and return */ 01397 HalDereferenceBusHandler(Handler); 01398 return Status; 01399 } 01400 01401 /* 01402 * @implemented 01403 */ 01404 ULONG 01405 NTAPI 01406 HalGetInterruptVector(IN INTERFACE_TYPE InterfaceType, 01407 IN ULONG BusNumber, 01408 IN ULONG BusInterruptLevel, 01409 IN ULONG BusInterruptVector, 01410 OUT PKIRQL Irql, 01411 OUT PKAFFINITY Affinity) 01412 { 01413 PBUS_HANDLER Handler; 01414 ULONG Vector; 01415 PAGED_CODE(); 01416 01417 /* Defaults */ 01418 *Irql = 0; 01419 *Affinity = 0; 01420 01421 /* Find the handler */ 01422 Handler = HalReferenceHandlerForBus(InterfaceType, BusNumber); 01423 if (!Handler) return 0; 01424 01425 /* Do the assignment */ 01426 Vector = Handler->GetInterruptVector(Handler, 01427 Handler, 01428 BusInterruptLevel, 01429 BusInterruptVector, 01430 Irql, 01431 Affinity); 01432 if ((Vector != IRQ2VECTOR(BusInterruptLevel)) || 01433 (*Irql != VECTOR2IRQL(IRQ2VECTOR(BusInterruptLevel)))) 01434 { 01435 DPRINT1("Returning IRQL %lx, Vector %lx for Level/Vector: %lx/%lx\n", 01436 *Irql, Vector, BusInterruptLevel, BusInterruptVector); 01437 DPRINT1("Old HAL would've returned IRQL %lx and Vector %lx\n", 01438 VECTOR2IRQL(IRQ2VECTOR(BusInterruptLevel)), 01439 IRQ2VECTOR(BusInterruptLevel)); 01440 } 01441 01442 /* Dereference the handler and return */ 01443 HalDereferenceBusHandler(Handler); 01444 return Vector; 01445 } 01446 01447 /* 01448 * @implemented 01449 */ 01450 ULONG 01451 NTAPI 01452 HalSetBusData(IN BUS_DATA_TYPE BusDataType, 01453 IN ULONG BusNumber, 01454 IN ULONG SlotNumber, 01455 IN PVOID Buffer, 01456 IN ULONG Length) 01457 { 01458 /* Call the extended function */ 01459 return HalSetBusDataByOffset(BusDataType, 01460 BusNumber, 01461 SlotNumber, 01462 Buffer, 01463 0, 01464 Length); 01465 } 01466 01467 /* 01468 * @implemented 01469 */ 01470 ULONG 01471 NTAPI 01472 HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, 01473 IN ULONG BusNumber, 01474 IN ULONG SlotNumber, 01475 IN PVOID Buffer, 01476 IN ULONG Offset, 01477 IN ULONG Length) 01478 { 01479 PBUS_HANDLER Handler; 01480 ULONG Status; 01481 01482 /* Find the handler */ 01483 Handler = HaliReferenceHandlerForConfigSpace(BusDataType, BusNumber); 01484 if (!Handler) return 0; 01485 01486 /* Do the assignment */ 01487 Status = Handler->SetBusData(Handler, 01488 Handler, 01489 SlotNumber, 01490 Buffer, 01491 Offset, 01492 Length); 01493 01494 /* Dereference the handler and return */ 01495 HalDereferenceBusHandler(Handler); 01496 return Status; 01497 } 01498 01499 /* 01500 * @implemented 01501 */ 01502 BOOLEAN 01503 NTAPI 01504 HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, 01505 IN ULONG BusNumber, 01506 IN PHYSICAL_ADDRESS BusAddress, 01507 IN OUT PULONG AddressSpace, 01508 OUT PPHYSICAL_ADDRESS TranslatedAddress) 01509 { 01510 /* Look as the bus type */ 01511 if (InterfaceType == PCIBus) 01512 { 01513 /* Call the PCI registered function */ 01514 return HalPciTranslateBusAddress(PCIBus, 01515 BusNumber, 01516 BusAddress, 01517 AddressSpace, 01518 TranslatedAddress); 01519 } 01520 else 01521 { 01522 /* Call the bus handler */ 01523 return HaliTranslateBusAddress(InterfaceType, 01524 BusNumber, 01525 BusAddress, 01526 AddressSpace, 01527 TranslatedAddress); 01528 } 01529 } 01530 01531 /* EOF */ Generated on Sun May 27 2012 04:28:44 for ReactOS by
1.7.6.1
|