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 }

Generated on Sat May 15 19:40:14 2004 for test by doxygen 1.3.7