ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bussupp.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.