test: halfnc.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# halfnc.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1990  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     hanfnc.c
    00008
    00009 Abstract:
    00010
    00011     default handlers for hal functions which don't get handlers
    00012     installed by the hal
    00013
    00014 Author:
    00015
    00016     Ken Reneris (kenr) 19-July-1994
    00017
    00018 Revision History:
    00019
    00020 --*/
    00021
    00022 #include "ntos.h"
    00023 #include "haldisp.h"
    00024
    00025 HAL_DISPATCH HalDispatchTable = {
    00026     HAL_DISPATCH_VERSION,
    00027     xHalQuerySystemInformation,
    00028     xHalSetSystemInformation,
    00029     xHalQueryBusSlots,
    00030     0,
    00031     xHalExamineMBR,
    00032     xHalIoAssignDriveLetters,
    00033     xHalIoReadPartitionTable,
    00034     xHalIoSetPartitionInformation,
    00035     xHalIoWritePartitionTable,
    00036     xHalHandlerForBus,                  // HalReferenceHandlerByBus
    00037     xHalReferenceHandler,               // HalReferenceBusHandler
    00038     xHalReferenceHandler,               // HalDereferenceBusHandler
    00039     xHalInitPnpDriver,
    00040     xHalInitPowerManagement,
    00041     0,
    00042     xHalGetInterruptTranslator
    00043     };
    00044
    00045
    00046 HAL_PRIVATE_DISPATCH HalPrivateDispatchTable = {
    00047     HAL_PRIVATE_DISPATCH_VERSION,
    00048     xHalHandlerForBus,
    00049     xHalHandlerForBus,
    00050     xHalLocateHiberRanges,
    00051     xHalRegisterBusHandler,
    00052     xHalSetWakeEnable,
    00053     xHalSetWakeAlarm,
    00054     xHalTranslateBusAddress,
    00055     xHalAssignSlotResources,
    00056     xHalHaltSystem,
    00057     (NULL),                             // HalFindBusAddressTranslation
    00058     (NULL)                              // HalResetDisplay
    00059     };
    00060
    00061 #if 0
    00062 DMA_OPERATIONS HalPrivateDmaOperations = {
    00063     sizeof(DMA_OPERATIONS),
    00064     xHalPutDmaAdapter,
    00065     xHalAllocateCommonBuffer,
    00066     xHalFreeCommonBuffer,
    00067     xHalAllocateAdapterChannel,
    00068     xHalFlushAdapterBuffers,
    00069     xHalFreeAdapterChannel,
    00070     xHalFreeMapRegisters,
    00071     xHalMapTransfer,
    00072     xHalGetDmaAlignment,
    00073     xHalReadDmaCounter,
    00074     xHalGetScatterGatherList,
    00075     xHalPutScatterGatherList
    00076     };
    00077 #endif
    00078
    00079 #ifdef ALLOC_PRAGMA
    00080 #pragma alloc_text(PAGE,   xHalLocateHiberRanges)
    00081 #pragma alloc_text(PAGE,   xHalQuerySystemInformation)
    00082 #pragma alloc_text(PAGE,   xHalSetSystemInformation)
    00083 #pragma alloc_text(PAGE,   xHalQueryBusSlots)
    00084 #pragma alloc_text(PAGE,   xHalRegisterBusHandler)
    00085 #pragma alloc_text(PAGELK, xHalSetWakeEnable)
    00086 #pragma alloc_text(PAGELK, xHalSetWakeAlarm)
    00087 #endif
    00088
    00089
    00090 //
    00091 // Global dispatch table for HAL apis
    00092 //
    00093
    00094
    00095 //
    00096 // Stub handlers for hals which don't provide the above functions
    00097 //
    00098
    00099 NTSTATUS
    00100 xHalQuerySystemInformation(
    00101     IN HAL_QUERY_INFORMATION_CLASS InformationClass,
    00102     IN ULONG     BufferSize,
    00103     OUT PVOID    Buffer,
    00104     OUT PULONG   ReturnedLength
    00105     )
    00106 {
    00107     PAGED_CODE ();
    00108     return STATUS_INVALID_LEVEL;
    00109 }
    00110
    00111 NTSTATUS
    00112 xHalSetSystemInformation(
    00113     IN HAL_SET_INFORMATION_CLASS InformationClass,
    00114     IN ULONG     BufferSize,
    00115     OUT PVOID    Buffer
    00116     )
    00117 {
    00118     PAGED_CODE ();
    00119     return STATUS_INVALID_LEVEL;
    00120 }
    00121
    00122 NTSTATUS
    00123 xHalQueryBusSlots(
    00124     IN PBUS_HANDLER         BusHandler,
    00125     IN ULONG                BufferSize,
    00126     OUT PULONG              SlotNumbers,
    00127     OUT PULONG              ReturnedLength
    00128     )
    00129 {
    00130     PAGED_CODE ();
    00131     return STATUS_NOT_SUPPORTED;
    00132 }
    00133
    00134
    00135 NTSTATUS
    00136 xHalRegisterBusHandler(
    00137     IN INTERFACE_TYPE          InterfaceType,
    00138     IN BUS_DATA_TYPE           ConfigurationSpace,
    00139     IN ULONG                   BusNumber,
    00140     IN INTERFACE_TYPE          ParentBusType,
    00141     IN ULONG                   ParentBusNumber,
    00142     IN ULONG                   SizeofBusExtensionData,
    00143     IN PINSTALL_BUS_HANDLER    InstallBusHandler,
    00144     OUT PBUS_HANDLER           *BusHandler
    00145     )
    00146 {
    00147     PAGED_CODE ();
    00148     return STATUS_NOT_SUPPORTED;
    00149 }
    00150
    00151
    00152 VOID
    00153 xHalSetWakeEnable(
    00154     IN BOOLEAN              Enable
    00155     )
    00156 {
    00157 }
    00158
    00159
    00160 VOID
    00161 xHalSetWakeAlarm(
    00162     IN ULONGLONG        WakeTime,
    00163     IN PTIME_FIELDS     WakeTimeFields
    00164     )
    00165 {
    00166 }
    00167
    00168 VOID
    00169 xHalLocateHiberRanges (
    00170     IN PVOID MemoryMap
    00171     )
    00172 {
    00173 }
    00174
    00175 PBUS_HANDLER
    00176 FASTCALL
    00177 xHalHandlerForBus (
    00178     IN INTERFACE_TYPE InterfaceType,
    00179     IN ULONG          BusNumber
    00180     )
    00181 {
    00182     return NULL;
    00183 }
    00184
    00185 VOID
    00186 FASTCALL
    00187 xHalReferenceHandler (
    00188     IN PBUS_HANDLER     Handler
    00189     )
    00190 {
    00191 }
    00192 NTSTATUS
    00193 xHalInitPnpDriver(
    00194     VOID
    00195     )
    00196 {
    00197     return STATUS_NOT_SUPPORTED;
    00198 }
    00199
    00200 NTSTATUS
    00201 xHalInitPowerManagement(
    00202     IN PPM_DISPATCH_TABLE  PmDriverDispatchTable,
    00203     IN OUT PPM_DISPATCH_TABLE *PmHalDispatchTable
    00204     )
    00205 {
    00206     return STATUS_NOT_SUPPORTED;
    00207 }
    00208
    00209 #if 0
    00210 PDMA_ADAPTER
    00211 xHalGetDmaAdapter (
    00212     IN PVOID Context,
    00213     IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
    00214     OUT PULONG NumberOfMapRegisters
    00215     )
    00216 {
    00217     PADAPTER_OBJECT AdapterObject;
    00218
    00219     AdapterObject = ExAllocatePoolWithTag( NonPagedPool,
    00220                                            sizeof( ADAPTER_OBJECT ),
    00221                                            ' laH');
    00222
    00223     if (AdapterObject == NULL) {
    00224         return NULL;
    00225     }
    00226
    00227     AdapterObject->DmaAdapter.Size = sizeof( ADAPTER_OBJECT );
    00228     AdapterObject->DmaAdapter.Version = 1;
    00229     AdapterObject->DmaAdapter.DmaOperations = &HalPrivateDmaOperations;
    00230     AdapterObject->RealAdapterObject = HalGetAdapter( DeviceDescriptor,
    00231                                                       NumberOfMapRegisters );
    00232
    00233     if (AdapterObject->RealAdapterObject == NULL) {
    00234
    00235         //
    00236         // No adapter object was returned.  Just return NULL to the caller.
    00237         //
    00238
    00239         ExFreePool( AdapterObject );
    00240         return NULL;
    00241     }
    00242
    00243     return &AdapterObject->DmaAdapter;
    00244 }
    00245
    00246 VOID
    00247 xHalPutDmaAdapter (
    00248     PDMA_ADAPTER DmaAdapter
    00249     )
    00250 {
    00251     ExFreePool( DmaAdapter );
    00252 }
    00253
    00254 PVOID
    00255 xHalAllocateCommonBuffer (
    00256     IN PDMA_ADAPTER DmaAdapter,
    00257     IN ULONG Length,
    00258     OUT PPHYSICAL_ADDRESS LogicalAddress,
    00259     IN BOOLEAN CacheEnabled
    00260     )
    00261 {
    00262     return HalAllocateCommonBuffer( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
    00263                                     Length,
    00264                                     LogicalAddress,
    00265                                     CacheEnabled );
    00266
    00267 }
    00268
    00269 VOID
    00270 xHalFreeCommonBuffer (
    00271     IN PDMA_ADAPTER DmaAdapter,
    00272     IN ULONG Length,
    00273     IN PHYSICAL_ADDRESS LogicalAddress,
    00274     IN PVOID VirtualAddress,
    00275     IN BOOLEAN CacheEnabled
    00276     )
    00277 {
    00278     HalFreeCommonBuffer( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
    00279                          Length,
    00280                          LogicalAddress,
    00281                          VirtualAddress,
    00282                          CacheEnabled );
    00283
    00284 }
    00285
    00286 NTSTATUS
    00287 xHalAllocateAdapterChannel (
    00288     IN PDMA_ADAPTER DmaAdapter,
    00289     IN PDEVICE_OBJECT DeviceObject,
    00290     IN ULONG NumberOfMapRegisters,
    00291     IN PDRIVER_CONTROL ExecutionRoutine,
    00292     IN PVOID Context
    00293     )
    00294 {
    00295     return IoAllocateAdapterChannel( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
    00296                                      DeviceObject,
    00297                                      NumberOfMapRegisters,
    00298                                      ExecutionRoutine,
    00299                                      Context );
    00300
    00301 }
    00302
    00303 BOOLEAN
    00304 xHalFlushAdapterBuffers (
    00305     IN PDMA_ADAPTER DmaAdapter,
    00306     IN PMDL Mdl,
    00307     IN PVOID MapRegisterBase,
    00308     IN PVOID CurrentVa,
    00309     IN ULONG Length,
    00310     IN BOOLEAN WriteToDevice
    00311     )
    00312 {
    00313     return IoFlushAdapterBuffers( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
    00314                                   Mdl,
    00315                                   MapRegisterBase,
    00316                                   CurrentVa,
    00317                                   Length,
    00318                                   WriteToDevice );
    00319
    00320 }
    00321
    00322 VOID
    00323 xHalFreeAdapterChannel (
    00324     IN PDMA_ADAPTER DmaAdapter
    00325     )
    00326 {
    00327     IoFreeAdapterChannel( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject );
    00328 }
    00329
    00330 VOID
    00331 xHalFreeMapRegisters (
    00332     IN PDMA_ADAPTER DmaAdapter,
    00333     PVOID MapRegisterBase,
    00334     ULONG NumberOfMapRegisters
    00335     )
    00336
    00337 {
    00338     IoFreeMapRegisters( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
    00339                         MapRegisterBase,
    00340                         NumberOfMapRegisters );
    00341 }
    00342
    00343 PHYSICAL_ADDRESS
    00344 xHalMapTransfer (
    00345     IN PDMA_ADAPTER DmaAdapter,
    00346     IN PMDL Mdl,
    00347     IN PVOID MapRegisterBase,
    00348     IN PVOID CurrentVa,
    00349     IN OUT PULONG Length,
    00350     IN BOOLEAN WriteToDevice
    00351     )
    00352 {
    00353     return IoMapTransfer( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
    00354                            Mdl,
    00355                            MapRegisterBase,
    00356                            CurrentVa,
    00357                            Length,
    00358                            WriteToDevice );
    00359 }
    00360
    00361 ULONG
    00362 xHalGetDmaAlignment (
    00363     IN PDMA_ADAPTER DmaAdapter
    00364     )
    00365 {
    00366     return HalGetDmaAlignmentRequirement();
    00367 }
    00368
    00369 ULONG
    00370 xHalReadDmaCounter (
    00371     IN PDMA_ADAPTER DmaAdapter
    00372     )
    00373 {
    00374     return HalReadDmaCounter( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject );
    00375 }
    00376
    00377
    00378 NTSTATUS
    00379 xHalGetScatterGatherList (
    00380     IN PDMA_ADAPTER DmaAdapter,
    00381     IN PDEVICE_OBJECT DeviceObject,
    00382     IN PMDL Mdl,
    00383     IN PVOID CurrentVa,
    00384     IN ULONG Length,
    00385     IN PDRIVER_LIST_CONTROL ExecutionRoutine,
    00386     IN PVOID Context,
    00387     IN BOOLEAN WriteToDevice
    00388     )
    00389 /*++
    00390
    00391 Routine Description:
    00392
    00393     This routine allocates the adapter channel specified by the adapter
    00394     object.  Next a scatter/gather list is built based on the MDL, the
    00395     CurrentVa and the requested Length.  Finally the driver?s execution
    00396     function is called with the scatter/gather list.  The adapter is
    00397     released when after the execution function returns.
    00398
    00399     The scatter/gather list is freed by calling PutScatterGatherList.
    00400
    00401 Arguments:
    00402
    00403     DmaAdapter - Pointer to the adapter control object to allocate to the
    00404         driver.
    00405
    00406     DeviceObject - Pointer to the device object that is allocating the
    00407         adapter.
    00408
    00409     Mdl - Pointer to the MDL that describes the pages of memory that are being
    00410         read or written.
    00411
    00412     CurrentVa - Current virtual address in the buffer described by the MDL
    00413         that the transfer is being done to or from.
    00414
    00415     Length - Supplies the length of the transfer.
    00416
    00417     ExecutionRoutine - The address of the driver's execution routine that is
    00418         invoked once the adapter channel (and possibly map registers) have been
    00419         allocated.
    00420
    00421     Context - An untyped longword context parameter passed to the driver's
    00422         execution routine.
    00423
    00424     WriteToDevice - Supplies the value that indicates whether this is a
    00425         write to the device from memory (TRUE), or vice versa.
    00426
    00427 Return Value:
    00428
    00429     Returns STATUS_SUCESS unless too many map registers are requested or
    00430     memory for the scatter/gather list could not be allocated.
    00431
    00432 Notes:
    00433
    00434     Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
    00435
    00436     The data in the buffer cannot be accessed until the put scatter/gather function has been called.
    00437
    00438 --*/
    00439
    00440 {
    00441     PXHAL_WAIT_CONTEXT_BLOCK WaitBlock;
    00442     PWAIT_CONTEXT_BLOCK Wcb;
    00443     PMDL TempMdl;
    00444     ULONG NumberOfMapRegisters;
    00445     ULONG ContextSize;
    00446     ULONG TransferLength;
    00447     ULONG MdlLength;
    00448     ULONG MdlCount;
    00449     PUCHAR MdlVa;
    00450     NTSTATUS Status;
    00451
    00452     MdlVa = MmGetMdlVirtualAddress(Mdl);
    00453
    00454     //
    00455     // Calculate the number of required map registers.
    00456     //
    00457
    00458     TempMdl = Mdl;
    00459     TransferLength = TempMdl->ByteCount - (ULONG)((PUCHAR) CurrentVa - MdlVa);
    00460     MdlLength = TransferLength;
    00461
    00462     MdlVa = (PUCHAR) BYTE_OFFSET(CurrentVa);
    00463     NumberOfMapRegisters = 0;
    00464     MdlCount = 1;
    00465
    00466     //
    00467     // Loop through the any chained MDLs accumulating the the required
    00468     // number of map registers.
    00469     //
    00470
    00471     while (TransferLength < Length && TempMdl->Next != NULL) {
    00472
    00473         NumberOfMapRegisters += (ULONG)(((ULONG_PTR) MdlVa + MdlLength + PAGE_SIZE - 1) >>
    00474                                     PAGE_SHIFT);
    00475
    00476         TempMdl = TempMdl->Next;
    00477         MdlVa = (PUCHAR) TempMdl->ByteOffset;
    00478         MdlLength = TempMdl->ByteCount;
    00479         TransferLength += MdlLength;
    00480         MdlCount++;
    00481     }
    00482
    00483     if (TransferLength + PAGE_SIZE < (ULONG_PTR)(Length + MdlVa) ) {
    00484         ASSERT(TransferLength >= Length);
    00485         return(STATUS_BUFFER_TOO_SMALL);
    00486     }
    00487
    00488     //
    00489     // Calculate the last number of map registers base on the requested
    00490     // length not the length of the last MDL.
    00491     //
    00492
    00493     ASSERT( TransferLength <= MdlLength + Length );
    00494
    00495     NumberOfMapRegisters += (ULONG)(((ULONG_PTR) MdlVa + Length + MdlLength - TransferLength +
    00496                              PAGE_SIZE - 1) >> PAGE_SHIFT);
    00497
    00498     //
    00499     // Calculate how much memory is required for context structure.  This
    00500     // this actually layed out as follows:
    00501     //
    00502     //   XHAL_WAIT_CONTEXT_BLOCK;
    00503     //   MapRegisterBase[ MdlCount ];
    00504     //   union {
    00505     //      WAIT_CONTEXT_BLOCK[ MdlCount ];
    00506     //      SCATTER_GATER_LIST [ NumberOfMapRegisters ];
    00507     //   };
    00508     //
    00509
    00510     ContextSize = NumberOfMapRegisters * sizeof( SCATTER_GATHER_ELEMENT ) +
    00511                   sizeof( SCATTER_GATHER_LIST );
    00512
    00513     //
    00514     // For each Mdl a separate Wcb is required since a separate map
    00515     // registers base must be allocated.
    00516     //
    00517
    00518     if (ContextSize < sizeof( WAIT_CONTEXT_BLOCK ) * MdlCount) {
    00519
    00520         ContextSize = sizeof( WAIT_CONTEXT_BLOCK ) * MdlCount;
    00521     }
    00522
    00523     ContextSize += sizeof( XHAL_WAIT_CONTEXT_BLOCK ) +
    00524                     MdlCount * sizeof( PVOID );
    00525     WaitBlock = ExAllocatePoolWithTag( NonPagedPool, ContextSize, ' laH' );
    00526
    00527     if (WaitBlock == NULL) {
    00528         return( STATUS_INSUFFICIENT_RESOURCES );
    00529     }
    00530
    00531     //
    00532     // Store the wait context block at the end of our block.
    00533     // All of the information in wait block can be over written
    00534     // by the scatter/gather list.
    00535     //
    00536
    00537     Wcb = (PWAIT_CONTEXT_BLOCK) ((PVOID *) (WaitBlock + 1) + MdlCount);
    00538
    00539     //
    00540     // Save the interesting data in the wait block.
    00541     //
    00542
    00543     WaitBlock->Mdl = Mdl;
    00544     WaitBlock->CurrentVa = CurrentVa;
    00545     WaitBlock->Length = Length;
    00546     WaitBlock->RealAdapterObject = ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject;
    00547     WaitBlock->DriverExecutionRoutine = ExecutionRoutine;
    00548     WaitBlock->DriverContext = Context;
    00549     WaitBlock->CurrentIrp = DeviceObject->CurrentIrp;
    00550     WaitBlock->MapRegisterLock = MdlCount;
    00551     WaitBlock->WriteToDevice = WriteToDevice;
    00552     WaitBlock->MdlCount = (UCHAR) MdlCount;
    00553
    00554     //
    00555     // Loop through each of the required MDL's calling
    00556     // IoAllocateAdapterChannel.
    00557     //
    00558
    00559     MdlCount = 0;
    00560
    00561     TempMdl = Mdl;
    00562     TransferLength = Length;
    00563     MdlLength = TempMdl->ByteCount - (ULONG)((PUCHAR) CurrentVa - (PUCHAR) MmGetMdlVirtualAddress(Mdl));
    00564
    00565     MdlVa = (PUCHAR) BYTE_OFFSET(CurrentVa);
    00566     NumberOfMapRegisters = 0;
    00567
    00568     //
    00569     // Loop through the any chained MDLs accumulating the the required
    00570     // number of map registers.
    00571     //
    00572
    00573     while (TransferLength > 0) {
    00574
    00575         if (MdlLength > TransferLength) {
    00576
    00577             MdlLength = TransferLength;
    00578         }
    00579
    00580         TransferLength -= MdlLength;
    00581
    00582         NumberOfMapRegisters = (ULONG)(((ULONG_PTR) MdlVa + MdlLength + PAGE_SIZE - 1) >>
    00583                                     PAGE_SHIFT);
    00584
    00585         Wcb->DeviceContext = WaitBlock;
    00586         Wcb->DeviceObject = DeviceObject;
    00587
    00588         //
    00589         // Store the map register index in IRP pointer.
    00590         //
    00591
    00592         Wcb->CurrentIrp = (PVOID) MdlCount;
    00593
    00594         //
    00595         // Call the HAL to allocate the adapter channel.
    00596         // xHalpAllocateAdapterCallback will fill in the scatter/gather list.
    00597         //
    00598
    00599         Status = HalAllocateAdapterChannel( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
    00600                                             Wcb,
    00601                                             NumberOfMapRegisters,
    00602                                             xHalpAllocateAdapterCallback );
    00603
    00604         if (TempMdl->Next == NULL) {
    00605             break;
    00606         }
    00607
    00608         //
    00609         // Advance to next MDL.
    00610         //
    00611
    00612         TempMdl = TempMdl->Next;
    00613         MdlVa = (PUCHAR) TempMdl->ByteOffset;
    00614         MdlLength = TempMdl->ByteCount;
    00615         MdlCount++;
    00616         Wcb++;
    00617     }
    00618
    00619     //
    00620     // If HalAllocateAdapterChannel failed then free the wait block.
    00621     //
    00622
    00623     if (!NT_SUCCESS( Status)) {
    00624         ExFreePool( WaitBlock );
    00625     }
    00626
    00627     return( Status );
    00628 }
    00629
    00630
    00631
    00632 VOID
    00633 xHalPutScatterGatherList (
    00634     IN PDMA_ADAPTER DmaAdapter,
    00635     IN PSCATTER_GATHER_LIST ScatterGather,
    00636     IN BOOLEAN WriteToDevice
    00637     )
    00638 {
    00639     PXHAL_WAIT_CONTEXT_BLOCK WaitBlock = (PVOID) ScatterGather->Reserved;
    00640     ULONG TransferLength;
    00641     ULONG MdlLength;
    00642     ULONG MdlCount = 0;
    00643     PMDL Mdl;
    00644     PUCHAR CurrentVa;
    00645
    00646     //
    00647     // Setup for the first MDL.  We expect the MDL pointer to be pointing
    00648     // at the first used mdl.
    00649     //
    00650
    00651     Mdl = WaitBlock->Mdl;
    00652     CurrentVa = WaitBlock->CurrentVa;
    00653     ASSERT( CurrentVa >= (PUCHAR) MmGetMdlVirtualAddress(Mdl) && CurrentVa < (PUCHAR) MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount );
    00654
    00655     MdlLength = Mdl->ByteCount - (ULONG)(CurrentVa - (PUCHAR) MmGetMdlVirtualAddress(Mdl));
    00656     TransferLength = WaitBlock->Length;
    00657
    00658     //
    00659     // Loop through the used MDLs call IoFlushAdapterBuffers.
    00660     //
    00661
    00662     while (TransferLength >  0) {
    00663
    00664         if (MdlLength > TransferLength) {
    00665
    00666             MdlLength = TransferLength;
    00667         }
    00668
    00669         TransferLength -= MdlLength;
    00670
    00671         IoFlushAdapterBuffers( WaitBlock->RealAdapterObject,
    00672                                 Mdl,
    00673                                 WaitBlock->MapRegisterBase[MdlCount],
    00674                                 CurrentVa,
    00675                                 MdlLength,
    00676                                 WriteToDevice );
    00677
    00678
    00679         if (Mdl->Next == NULL) {
    00680             break;
    00681         }
    00682
    00683         //
    00684         // Advance to the next MDL.  Update the current VA and the MdlLength.
    00685         //
    00686
    00687         Mdl = Mdl->Next;
    00688         CurrentVa = MmGetMdlVirtualAddress(Mdl);
    00689         MdlLength = Mdl->ByteCount;
    00690         MdlCount++;
    00691     }
    00692
    00693     ExFreePool( WaitBlock );
    00694
    00695 }
    00696
    00697 IO_ALLOCATION_ACTION
    00698 xHalpAllocateAdapterCallback (
    00699     IN struct _DEVICE_OBJECT *DeviceObject,
    00700     IN struct _IRP *Irp,
    00701     IN PVOID MapRegisterBase,
    00702     IN PVOID Context
    00703     )
    00704 /*++
    00705
    00706 Routine Description:
    00707
    00708     This routine is called when the adapter object and map registers are
    00709     available for the data transfer. This routines saves the map register
    00710     base away.  If all of the required bases have not been saved then it
    00711     returns. Otherwise it routine builds the entire scatter/gather
    00712     list by calling IoMapTransfer.  After the list is build it is passed to
    00713     the driver.
    00714
    00715 Arguments:
    00716
    00717     DeviceObject - Pointer to the device object that is allocating the
    00718         adapter.
    00719
    00720     Irp - Supplies the map register offset assigned for this callback.
    00721
    00722     MapRegisterBase - Supplies the map register base for use by the adapter
    00723         routines.
    00724
    00725     Context - Supplies a pointer to the xhal wait contorl block.
    00726
    00727 Return Value:
    00728
    00729     Returns DeallocateObjectKeepRegisters.
    00730
    00731
    00732 --*/
    00733 {
    00734     PXHAL_WAIT_CONTEXT_BLOCK WaitBlock = Context;
    00735     PVOID *MapRegisterBasePtr;
    00736     ULONG TransferLength;
    00737     LONG MdlLength;
    00738     PMDL Mdl;
    00739     PUCHAR CurrentVa;
    00740     PSCATTER_GATHER_LIST ScatterGather;
    00741     PSCATTER_GATHER_ELEMENT Element;
    00742
    00743     //
    00744     // Save the map register base in the appropriate slot.
    00745     //
    00746
    00747     WaitBlock->MapRegisterBase[ (ULONG_PTR) Irp ] = MapRegisterBase;
    00748
    00749     //
    00750     // See if this is the last callback;
    00751     //
    00752
    00753     if (InterlockedDecrement( &WaitBlock->MapRegisterLock ) != 0) {
    00754
    00755         //
    00756         // More to come, wait for the rest.
    00757         //
    00758
    00759         return( DeallocateObjectKeepRegisters );
    00760
    00761     }
    00762
    00763     //
    00764     // Put the scatter gatther list after wait block. Add a back pointer to
    00765     // the begining of the wait block.
    00766     //
    00767
    00768     MapRegisterBasePtr = (PVOID *) (WaitBlock + 1);
    00769     ScatterGather = (PSCATTER_GATHER_LIST) (MapRegisterBasePtr +
    00770                         WaitBlock->MdlCount);
    00771     ScatterGather->Reserved = (ULONG_PTR) WaitBlock;
    00772     Element = ScatterGather->Elements;
    00773
    00774     //
    00775     // Setup for the first MDL.  We expect the MDL pointer to be pointing
    00776     // at the first used MDL.
    00777     //
    00778
    00779     Mdl = WaitBlock->Mdl;
    00780     CurrentVa = WaitBlock->CurrentVa;
    00781     ASSERT( CurrentVa >= (PUCHAR) MmGetMdlVirtualAddress(Mdl) && CurrentVa < (PUCHAR) MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount );
    00782
    00783     MdlLength = Mdl->ByteCount - (ULONG)(CurrentVa - (PUCHAR) MmGetMdlVirtualAddress(Mdl));
    00784     TransferLength = WaitBlock->Length;
    00785
    00786     //
    00787     // Loop build the list for each MDL.
    00788     //
    00789
    00790     while (TransferLength >  0) {
    00791
    00792         if ((ULONG) MdlLength > TransferLength) {
    00793
    00794             MdlLength = TransferLength;
    00795         }
    00796
    00797         TransferLength -= MdlLength;
    00798
    00799         //
    00800         // Loop building the list for the elments within and MDL.
    00801         //
    00802
    00803         while (MdlLength > 0) {
    00804
    00805             Element->Length = MdlLength;
    00806             Element->Address = IoMapTransfer( WaitBlock->RealAdapterObject,
    00807                                             Mdl,
    00808                                             *MapRegisterBasePtr,
    00809                                             CurrentVa,
    00810                                             &Element->Length,
    00811                                             WaitBlock->WriteToDevice );
    00812
    00813             ASSERT( (ULONG) MdlLength >= Element->Length );
    00814             MdlLength -= Element->Length;
    00815             CurrentVa += Element->Length;
    00816             Element++;
    00817         }
    00818
    00819         if (Mdl->Next == NULL) {
    00820
    00821             //
    00822             // There is a few cases where the buffer described by the MDL
    00823             // is less than the transfer length.  This occurs when the
    00824             // file system transfering the last page of file and MM defines
    00825             // the MDL to be file size and the file system round the write
    00826             // up to a sector.  This extra should never cross a page
    00827             // bountry. Add this extra to the length of the last element.
    00828             //
    00829
    00830             ASSERT(((Element - 1)->Length & (PAGE_SIZE - 1)) + TransferLength <= PAGE_SIZE );
    00831             (Element - 1)->Length += TransferLength;
    00832
    00833             break;
    00834         }
    00835
    00836         //
    00837         // Advance to the next MDL.  Update the current VA and the MdlLength.
    00838         //
    00839
    00840         Mdl = Mdl->Next;
    00841         CurrentVa = MmGetMdlVirtualAddress(Mdl);
    00842         MdlLength = Mdl->ByteCount;
    00843         MapRegisterBasePtr++;
    00844
    00845     }
    00846
    00847     //
    00848     // Set the number of elements actually used.
    00849     //
    00850
    00851     ScatterGather->NumberOfElements = (ULONG)(Element - ScatterGather->Elements);
    00852
    00853     //
    00854     // Call the driver with the scatter/gather list.
    00855     //
    00856
    00857     WaitBlock->DriverExecutionRoutine( DeviceObject,
    00858                                        WaitBlock->CurrentIrp,
    00859                                        ScatterGather,
    00860                                        WaitBlock->DriverContext );
    00861
    00862     return( DeallocateObjectKeepRegisters );
    00863 }
    00864 #endif
    00865 BOOLEAN
    00866 xHalTranslateBusAddress(
    00867     IN INTERFACE_TYPE  InterfaceType,
    00868     IN ULONG BusNumber,
    00869     IN PHYSICAL_ADDRESS BusAddress,
    00870     IN OUT PULONG AddressSpace,
    00871     OUT PPHYSICAL_ADDRESS TranslatedAddress
    00872     )
    00873 {
    00874     //
    00875     // If the HAL fails to override this function, then
    00876     // the HAL has clearly failed to initialize.
    00877     //
    00878
    00879     KeBugCheckEx(HAL_INITIALIZATION_FAILED, 0, 0, 0, 7);
    00880     return FALSE;
    00881 }
    00882
    00883 NTSTATUS
    00884 xHalAssignSlotResources (
    00885     IN PUNICODE_STRING RegistryPath,
    00886     IN PUNICODE_STRING DriverClassName OPTIONAL,
    00887     IN PDRIVER_OBJECT DriverObject,
    00888     IN PDEVICE_OBJECT DeviceObject OPTIONAL,
    00889     IN INTERFACE_TYPE BusType,
    00890     IN ULONG BusNumber,
    00891     IN ULONG SlotNumber,
    00892     IN OUT PCM_RESOURCE_LIST *AllocatedResources
    00893     )
    00894 {
    00895     //
    00896     // If the HAL fails to override this function, then
    00897     // the HAL has clearly failed to initialize.
    00898     //
    00899
    00900     KeBugCheckEx(HAL_INITIALIZATION_FAILED, 0, 0, 0, 7);
    00901     return STATUS_NOT_IMPLEMENTED;
    00902 }
    00903
    00904 VOID
    00905 xHalHaltSystem(
    00906     VOID
    00907     )
    00908 {
    00909     for (;;) ;
    00910 }