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

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

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