Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbushndlr.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS HAL 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: hal/halx86/generic/bus/bushndlr.c 00005 * PURPOSE: Generic HAL Bus Handler Support 00006 * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <hal.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS ********************************************************************/ 00016 00017 KSPIN_LOCK HalpBusDatabaseSpinLock; 00018 KEVENT HalpBusDatabaseEvent; 00019 LIST_ENTRY HalpAllBusHandlers; 00020 PARRAY HalpBusTable; 00021 PARRAY HalpConfigTable; 00022 00023 /* PRIVATE FUNCTIONS **********************************************************/ 00024 00025 PARRAY 00026 NTAPI 00027 HalpAllocateArray(IN ULONG ArraySize) 00028 { 00029 PARRAY Array; 00030 ULONG Size; 00031 00032 /* Compute array size */ 00033 if (ArraySize == MAXULONG) ArraySize = 0; 00034 Size = ArraySize * sizeof(PARRAY) + sizeof(ARRAY); 00035 00036 /* Allocate the array */ 00037 Array = ExAllocatePoolWithTag(NonPagedPool, 00038 Size, 00039 TAG_BUS_HANDLER); 00040 if (!Array) KeBugCheckEx(HAL_MEMORY_ALLOCATION, Size, 0, (ULONG_PTR)__FILE__, __LINE__); 00041 00042 /* Initialize it */ 00043 Array->ArraySize = ArraySize; 00044 RtlZeroMemory(Array->Element, sizeof(PVOID) * (ArraySize + 1)); 00045 return Array; 00046 } 00047 00048 VOID 00049 NTAPI 00050 HalpGrowArray(IN PARRAY *CurrentArray, 00051 IN PARRAY *NewArray) 00052 { 00053 PVOID Tmp; 00054 00055 /* Check if the current array doesn't exist yet, or if it's smaller than the new one */ 00056 if (!(*CurrentArray) || ((*NewArray)->ArraySize > (*CurrentArray)->ArraySize)) 00057 { 00058 /* Does it exist (and can it fit?) */ 00059 if (*CurrentArray) 00060 { 00061 /* Copy the current array into the new one */ 00062 RtlCopyMemory(&(*NewArray)->Element, 00063 &(*CurrentArray)->Element, 00064 sizeof(PVOID) * ((*CurrentArray)->ArraySize + 1)); 00065 } 00066 00067 /* Swap the pointers (XOR swap would be more l33t) */ 00068 Tmp = *CurrentArray; 00069 *CurrentArray = *NewArray; 00070 *NewArray = Tmp; 00071 } 00072 } 00073 00074 PBUS_HANDLER 00075 FASTCALL 00076 HalpLookupHandler(IN PARRAY Array, 00077 IN ULONG Type, 00078 IN ULONG Number, 00079 IN BOOLEAN AddReference) 00080 { 00081 PHAL_BUS_HANDLER Bus; 00082 PBUS_HANDLER Handler = NULL; 00083 00084 /* Make sure the entry exists */ 00085 if (Array->ArraySize >= Type) 00086 { 00087 /* Retrieve it */ 00088 Array = Array->Element[Type]; 00089 00090 /* Make sure the entry array exists */ 00091 if ((Array) && (Array->ArraySize >= Number)) 00092 { 00093 /* Retrieve the bus and its handler */ 00094 Bus = Array->Element[Number]; 00095 Handler = &Bus->Handler; 00096 00097 /* Reference the handler if needed */ 00098 if (AddReference) Bus->ReferenceCount++; 00099 } 00100 } 00101 00102 /* Return the handler */ 00103 return Handler; 00104 } 00105 00106 ULONG 00107 NTAPI 00108 HalpNoBusData(IN PBUS_HANDLER BusHandler, 00109 IN PBUS_HANDLER RootHandler, 00110 IN ULONG SlotNumber, 00111 IN PVOID Buffer, 00112 IN ULONG Offset, 00113 IN ULONG Length) 00114 { 00115 /* Not implemented */ 00116 DPRINT1("STUB GetSetBusData\n"); 00117 return 0; 00118 } 00119 00120 NTSTATUS 00121 NTAPI 00122 HalpNoAdjustResourceList(IN PBUS_HANDLER BusHandler, 00123 IN PBUS_HANDLER RootHandler, 00124 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList) 00125 { 00126 DPRINT1("STUB Adjustment\n"); 00127 return STATUS_UNSUCCESSFUL; 00128 } 00129 00130 NTSTATUS 00131 NTAPI 00132 HalpNoAssignSlotResources(IN PBUS_HANDLER BusHandler, 00133 IN PBUS_HANDLER RootHandler, 00134 IN PUNICODE_STRING RegistryPath, 00135 IN PUNICODE_STRING DriverClassName OPTIONAL, 00136 IN PDRIVER_OBJECT DriverObject, 00137 IN PDEVICE_OBJECT DeviceObject OPTIONAL, 00138 IN ULONG SlotNumber, 00139 IN OUT PCM_RESOURCE_LIST *AllocatedResources) 00140 { 00141 DPRINT1("STUB Assignment\n"); 00142 return STATUS_NOT_SUPPORTED; 00143 } 00144 00145 VOID 00146 FASTCALL 00147 HaliReferenceBusHandler(IN PBUS_HANDLER Handler) 00148 { 00149 PHAL_BUS_HANDLER Bus; 00150 00151 /* Find and reference the bus handler */ 00152 Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); 00153 Bus->ReferenceCount++; 00154 } 00155 00156 VOID 00157 FASTCALL 00158 HaliDereferenceBusHandler(IN PBUS_HANDLER Handler) 00159 { 00160 PHAL_BUS_HANDLER Bus; 00161 00162 /* Find and dereference the bus handler */ 00163 Bus = CONTAINING_RECORD(Handler, HAL_BUS_HANDLER, Handler); 00164 Bus->ReferenceCount--; 00165 ASSERT(Bus->ReferenceCount != 0); 00166 } 00167 00168 PBUS_HANDLER 00169 FASTCALL 00170 HaliHandlerForBus(IN INTERFACE_TYPE InterfaceType, 00171 IN ULONG BusNumber) 00172 { 00173 /* Lookup the interface in the bus table */ 00174 return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, FALSE); 00175 } 00176 00177 PBUS_HANDLER 00178 FASTCALL 00179 HaliHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, 00180 IN ULONG BusNumber) 00181 { 00182 /* Lookup the configuration in the configuration table */ 00183 return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, FALSE); 00184 } 00185 00186 PBUS_HANDLER 00187 FASTCALL 00188 HaliReferenceHandlerForBus(IN INTERFACE_TYPE InterfaceType, 00189 IN ULONG BusNumber) 00190 { 00191 /* Lookup the interface in the bus table, and reference the handler */ 00192 return HalpLookupHandler(HalpBusTable, InterfaceType, BusNumber, TRUE); 00193 } 00194 00195 PBUS_HANDLER 00196 FASTCALL 00197 HaliReferenceHandlerForConfigSpace(IN BUS_DATA_TYPE ConfigType, 00198 IN ULONG BusNumber) 00199 { 00200 /* Lookup the configuration in the configuration table and add a reference */ 00201 return HalpLookupHandler(HalpConfigTable, ConfigType, BusNumber, TRUE); 00202 } 00203 00204 PBUS_HANDLER 00205 NTAPI 00206 HalpContextToBusHandler(IN ULONG_PTR ContextValue) 00207 { 00208 PLIST_ENTRY NextEntry; 00209 PHAL_BUS_HANDLER BusHandler, ThisHandler; 00210 00211 /* Start lookup */ 00212 NextEntry = HalpAllBusHandlers.Flink; 00213 ThisHandler = CONTAINING_RECORD(NextEntry, HAL_BUS_HANDLER, AllHandlers); 00214 if (ContextValue) 00215 { 00216 /* If the list is empty, quit */ 00217 if (IsListEmpty(&HalpAllBusHandlers)) return NULL; 00218 00219 /* Otherwise, scan the list */ 00220 BusHandler = CONTAINING_RECORD(ContextValue, HAL_BUS_HANDLER, Handler); 00221 do 00222 { 00223 /* Check if we've reached the right one */ 00224 ThisHandler = CONTAINING_RECORD(NextEntry, HAL_BUS_HANDLER, AllHandlers); 00225 if (ThisHandler == BusHandler) break; 00226 00227 /* Try the next one */ 00228 NextEntry = NextEntry->Flink; 00229 } while (NextEntry != &HalpAllBusHandlers); 00230 } 00231 00232 /* If we looped back to the end, we didn't find anything */ 00233 if (NextEntry == &HalpAllBusHandlers) return NULL; 00234 00235 /* Otherwise return the handler */ 00236 return &ThisHandler->Handler; 00237 } 00238 00239 #ifndef _MINIHAL_ 00240 NTSTATUS 00241 NTAPI 00242 HaliRegisterBusHandler(IN INTERFACE_TYPE InterfaceType, 00243 IN BUS_DATA_TYPE ConfigType, 00244 IN ULONG BusNumber, 00245 IN INTERFACE_TYPE ParentBusType, 00246 IN ULONG ParentBusNumber, 00247 IN ULONG ExtraData, 00248 IN PINSTALL_BUS_HANDLER InstallCallback, 00249 OUT PBUS_HANDLER *ReturnedBusHandler) 00250 { 00251 PHAL_BUS_HANDLER Bus, OldHandler = NULL; 00252 PHAL_BUS_HANDLER* BusEntry; 00253 //PVOID CodeHandle; 00254 PARRAY InterfaceArray, InterfaceBusNumberArray, ConfigArray, ConfigBusNumberArray; 00255 PBUS_HANDLER ParentHandler; 00256 KIRQL OldIrql; 00257 NTSTATUS Status; 00258 00259 /* Make sure we have a valid handler */ 00260 ASSERT((InterfaceType != InterfaceTypeUndefined) || 00261 (ConfigType != ConfigurationSpaceUndefined)); 00262 00263 /* Allocate the bus handler */ 00264 Bus = ExAllocatePoolWithTag(NonPagedPool, 00265 sizeof(HAL_BUS_HANDLER) + ExtraData, 00266 TAG_BUS_HANDLER); 00267 if (!Bus) return STATUS_INSUFFICIENT_RESOURCES; 00268 00269 /* Return the handler */ 00270 *ReturnedBusHandler = &Bus->Handler; 00271 00272 /* FIXME: Fix the kernel first. Don't page us out */ 00273 //CodeHandle = MmLockPagableDataSection(&HaliRegisterBusHandler); 00274 00275 /* Synchronize with anyone else */ 00276 KeWaitForSingleObject(&HalpBusDatabaseEvent, 00277 WrExecutive, 00278 KernelMode, 00279 FALSE, 00280 NULL); 00281 00282 /* Check for unknown/root bus */ 00283 if (BusNumber == -1) 00284 { 00285 /* We must have an interface */ 00286 ASSERT(InterfaceType != InterfaceTypeUndefined); 00287 00288 /* Find the right bus */ 00289 BusNumber = 0; 00290 while (HaliHandlerForBus(InterfaceType, BusNumber)) BusNumber++; 00291 } 00292 00293 /* Allocate arrays for the handler */ 00294 InterfaceArray = HalpAllocateArray(InterfaceType); 00295 InterfaceBusNumberArray = HalpAllocateArray(BusNumber); 00296 ConfigArray = HalpAllocateArray(ConfigType); 00297 ConfigBusNumberArray = HalpAllocateArray(BusNumber); 00298 00299 /* Only proceed if all allocations succeeded */ 00300 if ((InterfaceArray) && (InterfaceBusNumberArray) && (ConfigArray) && (ConfigBusNumberArray)) 00301 { 00302 /* Find the parent handler if any */ 00303 ParentHandler = HaliReferenceHandlerForBus(ParentBusType, ParentBusNumber); 00304 00305 /* Initialize the handler */ 00306 RtlZeroMemory(Bus, sizeof(HAL_BUS_HANDLER) + ExtraData); 00307 Bus->ReferenceCount = 1; 00308 00309 /* Fill out bus data */ 00310 Bus->Handler.BusNumber = BusNumber; 00311 Bus->Handler.InterfaceType = InterfaceType; 00312 Bus->Handler.ConfigurationType = ConfigType; 00313 Bus->Handler.ParentHandler = ParentHandler; 00314 00315 /* Fill out dummy handlers */ 00316 Bus->Handler.GetBusData = HalpNoBusData; 00317 Bus->Handler.SetBusData = HalpNoBusData; 00318 Bus->Handler.AdjustResourceList = HalpNoAdjustResourceList; 00319 Bus->Handler.AssignSlotResources = HalpNoAssignSlotResources; 00320 00321 /* Make space for extra data */ 00322 if (ExtraData) Bus->Handler.BusData = Bus + 1; 00323 00324 /* Check for a parent handler */ 00325 if (ParentHandler) 00326 { 00327 /* Inherit the parent routines */ 00328 Bus->Handler.GetBusData = ParentHandler->GetBusData; 00329 Bus->Handler.SetBusData = ParentHandler->SetBusData; 00330 Bus->Handler.AdjustResourceList = ParentHandler->AdjustResourceList; 00331 Bus->Handler.AssignSlotResources = ParentHandler->AssignSlotResources; 00332 Bus->Handler.TranslateBusAddress = ParentHandler->TranslateBusAddress; 00333 Bus->Handler.GetInterruptVector = ParentHandler->GetInterruptVector; 00334 } 00335 00336 /* We don't support this yet */ 00337 ASSERT(!InstallCallback); 00338 00339 /* Lock the buses */ 00340 KeAcquireSpinLock(&HalpBusDatabaseSpinLock, &OldIrql); 00341 00342 /* Make space for the interface */ 00343 HalpGrowArray(&HalpBusTable, &InterfaceArray); 00344 00345 /* Check if we really have an interface */ 00346 if (InterfaceType != InterfaceTypeUndefined) 00347 { 00348 /* Make space for the association */ 00349 HalpGrowArray((PARRAY*)&HalpBusTable->Element[InterfaceType], 00350 &InterfaceBusNumberArray); 00351 00352 /* Get the bus handler pointer */ 00353 BusEntry = (PHAL_BUS_HANDLER*)&((PARRAY)HalpBusTable->Element[InterfaceType])->Element[BusNumber]; 00354 00355 /* Check if there was already a handler there, and set the new one */ 00356 if (*BusEntry) OldHandler = *BusEntry; 00357 *BusEntry = Bus; 00358 } 00359 00360 /* Now add a space for the configuration space */ 00361 HalpGrowArray(&HalpConfigTable, &ConfigArray); 00362 00363 /* Check if we really have one */ 00364 if (ConfigType != ConfigurationSpaceUndefined) 00365 { 00366 /* Make space for this association */ 00367 HalpGrowArray((PARRAY*)&HalpConfigTable->Element[ConfigType], 00368 &ConfigBusNumberArray); 00369 00370 /* Get the bus handler pointer */ 00371 BusEntry = (PHAL_BUS_HANDLER*)&((PARRAY)HalpConfigTable->Element[ConfigType])->Element[BusNumber]; 00372 if (*BusEntry) 00373 { 00374 /* Get the old entry, but make sure it's the same we had before */ 00375 ASSERT((OldHandler == NULL) || (OldHandler == *BusEntry)); 00376 OldHandler = *BusEntry; 00377 } 00378 00379 /* Set the new entry */ 00380 *BusEntry = Bus; 00381 } 00382 00383 /* Link the adapter */ 00384 InsertTailList(&HalpAllBusHandlers, &Bus->AllHandlers); 00385 00386 /* Remove the old linkage */ 00387 Bus = OldHandler; 00388 if (Bus) RemoveEntryList(&Bus->AllHandlers); 00389 00390 /* Release the lock */ 00391 KeReleaseSpinLock(&HalpBusDatabaseSpinLock, OldIrql); 00392 Status = STATUS_SUCCESS; 00393 } 00394 else 00395 { 00396 /* Fail */ 00397 Status = STATUS_INSUFFICIENT_RESOURCES; 00398 } 00399 00400 /* Signal the event */ 00401 KeSetEvent(&HalpBusDatabaseEvent, 0, FALSE); 00402 00403 /* FIXME: Fix the kernel first. Re-page the function */ 00404 //MmUnlockPagableImageSection(CodeHandle); 00405 00406 /* Free all allocations */ 00407 if (Bus) ExFreePoolWithTag(Bus, TAG_BUS_HANDLER); 00408 if (InterfaceArray) ExFreePoolWithTag(InterfaceArray, TAG_BUS_HANDLER); 00409 if (InterfaceBusNumberArray) ExFreePoolWithTag(InterfaceBusNumberArray, TAG_BUS_HANDLER); 00410 if (ConfigArray) ExFreePoolWithTag(ConfigArray, TAG_BUS_HANDLER); 00411 if (ConfigBusNumberArray) ExFreePoolWithTag(ConfigBusNumberArray, TAG_BUS_HANDLER); 00412 00413 /* And we're done */ 00414 return Status; 00415 } 00416 #endif 00417 00418 VOID 00419 NTAPI 00420 HalpInitBusHandler(VOID) 00421 { 00422 /* Setup the bus lock */ 00423 KeInitializeSpinLock(&HalpBusDatabaseSpinLock); 00424 00425 /* Setup the bus event */ 00426 KeInitializeEvent(&HalpBusDatabaseEvent, SynchronizationEvent, TRUE); 00427 00428 /* Setup the bus configuration and bus table */ 00429 HalpBusTable = HalpAllocateArray(0); 00430 HalpConfigTable = HalpAllocateArray(0); 00431 00432 /* Setup the bus list */ 00433 InitializeListHead(&HalpAllBusHandlers); 00434 00435 /* Setup the HAL Dispatch routines */ 00436 #ifndef _MINIHAL_ 00437 HalRegisterBusHandler = HaliRegisterBusHandler; 00438 HalHandlerForBus = HaliHandlerForBus; 00439 HalHandlerForConfigSpace = HaliHandlerForConfigSpace; 00440 HalReferenceHandlerForBus = HaliReferenceHandlerForBus; 00441 HalReferenceBusHandler = HaliReferenceBusHandler; 00442 HalDereferenceBusHandler = HaliDereferenceBusHandler; 00443 #endif 00444 HalPciAssignSlotResources = HalpAssignSlotResources; 00445 HalPciTranslateBusAddress = HaliTranslateBusAddress; /* PCI Driver can override */ 00446 if (!HalFindBusAddressTranslation) HalFindBusAddressTranslation = HaliFindBusAddressTranslation; 00447 } 00448 00449 /* EOF */ Generated on Mon May 28 2012 04:28:32 for ReactOS by
1.7.6.1
|