Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1125 lines
28 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. hanfnc.c
  5. Abstract:
  6. Default handlers for HAL functions which don't get handlers
  7. installed by the HAL.
  8. Author:
  9. Ken Reneris (kenr) 19-July-1994
  10. Revision History:
  11. --*/
  12. #pragma warning(disable:4214) // bit field types other than int
  13. #pragma warning(disable:4201) // nameless struct/union
  14. #pragma warning(disable:4115) // named type definition in parentheses
  15. #pragma warning(disable:4127) // condition expression is constant
  16. #include "ntos.h"
  17. #include "haldisp.h"
  18. HAL_DISPATCH HalDispatchTable = {
  19. HAL_DISPATCH_VERSION,
  20. xHalQuerySystemInformation,
  21. xHalSetSystemInformation,
  22. xHalQueryBusSlots,
  23. 0,
  24. HalExamineMBR,
  25. IoAssignDriveLetters,
  26. IoReadPartitionTable,
  27. IoSetPartitionInformation,
  28. IoWritePartitionTable,
  29. xHalHandlerForBus, // HalReferenceHandlerByBus
  30. xHalReferenceHandler, // HalReferenceBusHandler
  31. xHalReferenceHandler, // HalDereferenceBusHandler
  32. xHalInitPnpDriver,
  33. xHalInitPowerManagement,
  34. 0,
  35. xHalGetInterruptTranslator,
  36. xHalStartMirroring,
  37. xHalEndMirroring,
  38. xHalMirrorPhysicalMemory,
  39. xHalEndOfBoot,
  40. xHalMirrorVerify
  41. };
  42. HAL_PRIVATE_DISPATCH HalPrivateDispatchTable = {
  43. HAL_PRIVATE_DISPATCH_VERSION,
  44. xHalHandlerForBus,
  45. xHalHandlerForBus,
  46. xHalLocateHiberRanges,
  47. xHalRegisterBusHandler,
  48. xHalSetWakeEnable,
  49. xHalSetWakeAlarm,
  50. xHalTranslateBusAddress,
  51. xHalAssignSlotResources,
  52. xHalHaltSystem,
  53. (NULL), // HalFindBusAddressTranslation
  54. (NULL), // HalResetDisplay
  55. xHalAllocateMapRegisters,
  56. xKdSetupPciDeviceForDebugging,
  57. xKdReleasePciDeviceForDebugging,
  58. xKdGetAcpiTablePhase0,
  59. xKdCheckPowerButton,
  60. xHalVectorToIDTEntry,
  61. xKdMapPhysicalMemory64,
  62. xKdUnmapVirtualAddress,
  63. };
  64. #if 0
  65. DMA_OPERATIONS HalPrivateDmaOperations = {
  66. sizeof(DMA_OPERATIONS),
  67. xHalPutDmaAdapter,
  68. xHalAllocateCommonBuffer,
  69. xHalFreeCommonBuffer,
  70. xHalAllocateAdapterChannel,
  71. xHalFlushAdapterBuffers,
  72. xHalFreeAdapterChannel,
  73. xHalFreeMapRegisters,
  74. xHalMapTransfer,
  75. xHalGetDmaAlignment,
  76. xHalReadDmaCounter,
  77. xHalGetScatterGatherList,
  78. xHalPutScatterGatherList
  79. };
  80. #endif
  81. #ifdef ALLOC_PRAGMA
  82. #pragma alloc_text(PAGE, xHalLocateHiberRanges)
  83. #pragma alloc_text(PAGE, xHalQuerySystemInformation)
  84. #pragma alloc_text(PAGE, xHalSetSystemInformation)
  85. #pragma alloc_text(PAGE, xHalQueryBusSlots)
  86. #pragma alloc_text(PAGE, xHalRegisterBusHandler)
  87. #pragma alloc_text(PAGE, xHalStartMirroring)
  88. #pragma alloc_text(PAGE, xHalEndOfBoot)
  89. #pragma alloc_text(PAGELK, xHalSetWakeEnable)
  90. #pragma alloc_text(PAGELK, xHalSetWakeAlarm)
  91. #endif
  92. //
  93. // Global dispatch table for HAL apis
  94. //
  95. //
  96. // Stub handlers for HALs which don't provide the above functions
  97. //
  98. NTSTATUS
  99. xHalQuerySystemInformation(
  100. IN HAL_QUERY_INFORMATION_CLASS InformationClass,
  101. IN ULONG BufferSize,
  102. OUT PVOID Buffer,
  103. OUT PULONG ReturnedLength
  104. )
  105. {
  106. PAGED_CODE ();
  107. UNREFERENCED_PARAMETER (InformationClass);
  108. UNREFERENCED_PARAMETER (BufferSize);
  109. UNREFERENCED_PARAMETER (Buffer);
  110. UNREFERENCED_PARAMETER (ReturnedLength);
  111. return STATUS_INVALID_LEVEL;
  112. }
  113. NTSTATUS
  114. xHalSetSystemInformation(
  115. IN HAL_SET_INFORMATION_CLASS InformationClass,
  116. IN ULONG BufferSize,
  117. OUT PVOID Buffer
  118. )
  119. {
  120. PAGED_CODE ();
  121. UNREFERENCED_PARAMETER (InformationClass);
  122. UNREFERENCED_PARAMETER (BufferSize);
  123. UNREFERENCED_PARAMETER (Buffer);
  124. return STATUS_INVALID_LEVEL;
  125. }
  126. NTSTATUS
  127. xHalQueryBusSlots(
  128. IN PBUS_HANDLER BusHandler,
  129. IN ULONG BufferSize,
  130. OUT PULONG SlotNumbers,
  131. OUT PULONG ReturnedLength
  132. )
  133. {
  134. PAGED_CODE ();
  135. UNREFERENCED_PARAMETER (BusHandler);
  136. UNREFERENCED_PARAMETER (BufferSize);
  137. UNREFERENCED_PARAMETER (SlotNumbers);
  138. UNREFERENCED_PARAMETER (ReturnedLength);
  139. return STATUS_NOT_SUPPORTED;
  140. }
  141. NTSTATUS
  142. xHalRegisterBusHandler(
  143. IN INTERFACE_TYPE InterfaceType,
  144. IN BUS_DATA_TYPE ConfigurationSpace,
  145. IN ULONG BusNumber,
  146. IN INTERFACE_TYPE ParentBusType,
  147. IN ULONG ParentBusNumber,
  148. IN ULONG SizeofBusExtensionData,
  149. IN PINSTALL_BUS_HANDLER InstallBusHandler,
  150. OUT PBUS_HANDLER *BusHandler
  151. )
  152. {
  153. PAGED_CODE ();
  154. UNREFERENCED_PARAMETER (InterfaceType);
  155. UNREFERENCED_PARAMETER (ConfigurationSpace);
  156. UNREFERENCED_PARAMETER (BusNumber);
  157. UNREFERENCED_PARAMETER (ParentBusType);
  158. UNREFERENCED_PARAMETER (ParentBusNumber);
  159. UNREFERENCED_PARAMETER (SizeofBusExtensionData);
  160. UNREFERENCED_PARAMETER (InstallBusHandler);
  161. UNREFERENCED_PARAMETER (BusHandler);
  162. return STATUS_NOT_SUPPORTED;
  163. }
  164. VOID
  165. xHalSetWakeEnable(
  166. IN BOOLEAN Enable
  167. )
  168. {
  169. UNREFERENCED_PARAMETER (Enable);
  170. }
  171. VOID
  172. xHalSetWakeAlarm(
  173. IN ULONGLONG WakeTime,
  174. IN PTIME_FIELDS WakeTimeFields
  175. )
  176. {
  177. UNREFERENCED_PARAMETER (WakeTime);
  178. UNREFERENCED_PARAMETER (WakeTimeFields);
  179. }
  180. VOID
  181. xHalLocateHiberRanges (
  182. IN PVOID MemoryMap
  183. )
  184. {
  185. UNREFERENCED_PARAMETER (MemoryMap);
  186. }
  187. PBUS_HANDLER
  188. FASTCALL
  189. xHalHandlerForBus (
  190. IN INTERFACE_TYPE InterfaceType,
  191. IN ULONG BusNumber
  192. )
  193. {
  194. UNREFERENCED_PARAMETER (InterfaceType);
  195. UNREFERENCED_PARAMETER (BusNumber);
  196. return NULL;
  197. }
  198. VOID
  199. FASTCALL
  200. xHalReferenceHandler (
  201. IN PBUS_HANDLER Handler
  202. )
  203. {
  204. UNREFERENCED_PARAMETER (Handler);
  205. }
  206. NTSTATUS
  207. xHalInitPnpDriver(
  208. VOID
  209. )
  210. {
  211. return STATUS_NOT_SUPPORTED;
  212. }
  213. NTSTATUS
  214. xHalInitPowerManagement(
  215. IN PPM_DISPATCH_TABLE PmDriverDispatchTable,
  216. IN OUT PPM_DISPATCH_TABLE *PmHalDispatchTable
  217. )
  218. {
  219. UNREFERENCED_PARAMETER (PmDriverDispatchTable);
  220. UNREFERENCED_PARAMETER (PmHalDispatchTable);
  221. return STATUS_NOT_SUPPORTED;
  222. }
  223. NTSTATUS
  224. xHalStartMirroring(
  225. VOID
  226. )
  227. {
  228. PAGED_CODE ();
  229. return STATUS_NOT_SUPPORTED;
  230. }
  231. NTSTATUS
  232. xHalEndMirroring(
  233. IN ULONG PassNumber
  234. )
  235. {
  236. UNREFERENCED_PARAMETER (PassNumber);
  237. return STATUS_NOT_SUPPORTED;
  238. }
  239. NTSTATUS
  240. xHalMirrorPhysicalMemory(
  241. IN PHYSICAL_ADDRESS PhysicalAddress,
  242. IN LARGE_INTEGER NumberOfBytes
  243. )
  244. {
  245. UNREFERENCED_PARAMETER (PhysicalAddress);
  246. UNREFERENCED_PARAMETER (NumberOfBytes);
  247. return STATUS_NOT_SUPPORTED;
  248. }
  249. NTSTATUS
  250. xHalMirrorVerify(
  251. IN PHYSICAL_ADDRESS PhysicalAddress,
  252. IN LARGE_INTEGER NumberOfBytes
  253. )
  254. {
  255. UNREFERENCED_PARAMETER (PhysicalAddress);
  256. UNREFERENCED_PARAMETER (NumberOfBytes);
  257. return STATUS_NOT_SUPPORTED;
  258. }
  259. #if 0
  260. PDMA_ADAPTER
  261. xHalGetDmaAdapter (
  262. IN PVOID Context,
  263. IN struct _DEVICE_DESCRIPTION *DeviceDescriptor,
  264. OUT PULONG NumberOfMapRegisters
  265. )
  266. {
  267. PADAPTER_OBJECT AdapterObject;
  268. AdapterObject = ExAllocatePoolWithTag( NonPagedPool,
  269. sizeof( ADAPTER_OBJECT ),
  270. ' laH');
  271. if (AdapterObject == NULL) {
  272. return NULL;
  273. }
  274. AdapterObject->DmaAdapter.Size = sizeof( ADAPTER_OBJECT );
  275. AdapterObject->DmaAdapter.Version = 1;
  276. AdapterObject->DmaAdapter.DmaOperations = &HalPrivateDmaOperations;
  277. AdapterObject->RealAdapterObject = HalGetAdapter( DeviceDescriptor,
  278. NumberOfMapRegisters );
  279. if (AdapterObject->RealAdapterObject == NULL) {
  280. //
  281. // No adapter object was returned. Just return NULL to the caller.
  282. //
  283. ExFreePool( AdapterObject );
  284. return NULL;
  285. }
  286. return &AdapterObject->DmaAdapter;
  287. }
  288. VOID
  289. xHalPutDmaAdapter (
  290. PDMA_ADAPTER DmaAdapter
  291. )
  292. {
  293. ExFreePool( DmaAdapter );
  294. }
  295. PVOID
  296. xHalAllocateCommonBuffer (
  297. IN PDMA_ADAPTER DmaAdapter,
  298. IN ULONG Length,
  299. OUT PPHYSICAL_ADDRESS LogicalAddress,
  300. IN BOOLEAN CacheEnabled
  301. )
  302. {
  303. return HalAllocateCommonBuffer( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
  304. Length,
  305. LogicalAddress,
  306. CacheEnabled );
  307. }
  308. VOID
  309. xHalFreeCommonBuffer (
  310. IN PDMA_ADAPTER DmaAdapter,
  311. IN ULONG Length,
  312. IN PHYSICAL_ADDRESS LogicalAddress,
  313. IN PVOID VirtualAddress,
  314. IN BOOLEAN CacheEnabled
  315. )
  316. {
  317. HalFreeCommonBuffer( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
  318. Length,
  319. LogicalAddress,
  320. VirtualAddress,
  321. CacheEnabled );
  322. }
  323. NTSTATUS
  324. xHalAllocateAdapterChannel (
  325. IN PDMA_ADAPTER DmaAdapter,
  326. IN PDEVICE_OBJECT DeviceObject,
  327. IN ULONG NumberOfMapRegisters,
  328. IN PDRIVER_CONTROL ExecutionRoutine,
  329. IN PVOID Context
  330. )
  331. {
  332. return IoAllocateAdapterChannel( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
  333. DeviceObject,
  334. NumberOfMapRegisters,
  335. ExecutionRoutine,
  336. Context );
  337. }
  338. BOOLEAN
  339. xHalFlushAdapterBuffers (
  340. IN PDMA_ADAPTER DmaAdapter,
  341. IN PMDL Mdl,
  342. IN PVOID MapRegisterBase,
  343. IN PVOID CurrentVa,
  344. IN ULONG Length,
  345. IN BOOLEAN WriteToDevice
  346. )
  347. {
  348. return IoFlushAdapterBuffers( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
  349. Mdl,
  350. MapRegisterBase,
  351. CurrentVa,
  352. Length,
  353. WriteToDevice );
  354. }
  355. VOID
  356. xHalFreeAdapterChannel (
  357. IN PDMA_ADAPTER DmaAdapter
  358. )
  359. {
  360. IoFreeAdapterChannel( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject );
  361. }
  362. VOID
  363. xHalFreeMapRegisters (
  364. IN PDMA_ADAPTER DmaAdapter,
  365. PVOID MapRegisterBase,
  366. ULONG NumberOfMapRegisters
  367. )
  368. {
  369. IoFreeMapRegisters( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
  370. MapRegisterBase,
  371. NumberOfMapRegisters );
  372. }
  373. PHYSICAL_ADDRESS
  374. xHalMapTransfer (
  375. IN PDMA_ADAPTER DmaAdapter,
  376. IN PMDL Mdl,
  377. IN PVOID MapRegisterBase,
  378. IN PVOID CurrentVa,
  379. IN OUT PULONG Length,
  380. IN BOOLEAN WriteToDevice
  381. )
  382. {
  383. return IoMapTransfer( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
  384. Mdl,
  385. MapRegisterBase,
  386. CurrentVa,
  387. Length,
  388. WriteToDevice );
  389. }
  390. ULONG
  391. xHalGetDmaAlignment (
  392. IN PDMA_ADAPTER DmaAdapter
  393. )
  394. {
  395. return HalGetDmaAlignmentRequirement();
  396. }
  397. ULONG
  398. xHalReadDmaCounter (
  399. IN PDMA_ADAPTER DmaAdapter
  400. )
  401. {
  402. return HalReadDmaCounter( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject );
  403. }
  404. NTSTATUS
  405. xHalGetScatterGatherList (
  406. IN PDMA_ADAPTER DmaAdapter,
  407. IN PDEVICE_OBJECT DeviceObject,
  408. IN PMDL Mdl,
  409. IN PVOID CurrentVa,
  410. IN ULONG Length,
  411. IN PDRIVER_LIST_CONTROL ExecutionRoutine,
  412. IN PVOID Context,
  413. IN BOOLEAN WriteToDevice
  414. )
  415. /*++
  416. Routine Description:
  417. This routine allocates the adapter channel specified by the adapter
  418. object. Next a scatter/gather list is built based on the MDL, the
  419. CurrentVa and the requested Length. Finally the driver's execution
  420. function is called with the scatter/gather list. The adapter is
  421. released after the execution function returns.
  422. The scatter/gather list is freed by calling PutScatterGatherList.
  423. Arguments:
  424. DmaAdapter - Pointer to the adapter control object to allocate for the
  425. driver.
  426. DeviceObject - Pointer to the device object that is allocating the
  427. adapter.
  428. Mdl - Pointer to the MDL that describes the pages of memory that are being
  429. read or written.
  430. CurrentVa - Current virtual address in the buffer described by the MDL
  431. that the transfer is being done to or from.
  432. Length - Supplies the length of the transfer.
  433. ExecutionRoutine - The address of the driver's execution routine that is
  434. invoked once the adapter channel (and possibly map registers) have been
  435. allocated.
  436. Context - An untyped longword context parameter passed to the driver's
  437. execution routine.
  438. WriteToDevice - Supplies the value that indicates whether this is a
  439. write to the device from memory (TRUE), or vice versa.
  440. Return Value:
  441. Returns STATUS_SUCCESS unless too many map registers are requested or
  442. memory for the scatter/gather list could not be allocated.
  443. Notes:
  444. Note that this routine MUST be invoked at DISPATCH_LEVEL or above.
  445. The data in the buffer cannot be accessed until the put scatter/gather function has been called.
  446. --*/
  447. {
  448. PXHAL_WAIT_CONTEXT_BLOCK WaitBlock;
  449. PWAIT_CONTEXT_BLOCK Wcb;
  450. PMDL TempMdl;
  451. ULONG NumberOfMapRegisters;
  452. ULONG ContextSize;
  453. ULONG TransferLength;
  454. ULONG MdlLength;
  455. ULONG MdlCount;
  456. PUCHAR MdlVa;
  457. NTSTATUS Status;
  458. MdlVa = MmGetMdlVirtualAddress(Mdl);
  459. //
  460. // Calculate the number of required map registers.
  461. //
  462. TempMdl = Mdl;
  463. TransferLength = TempMdl->ByteCount - (ULONG)((PUCHAR) CurrentVa - MdlVa);
  464. MdlLength = TransferLength;
  465. MdlVa = (PUCHAR) BYTE_OFFSET(CurrentVa);
  466. NumberOfMapRegisters = 0;
  467. MdlCount = 1;
  468. //
  469. // Loop through the any chained MDLs accumulating the required
  470. // number of map registers.
  471. //
  472. while (TransferLength < Length && TempMdl->Next != NULL) {
  473. NumberOfMapRegisters += (ULONG)(((ULONG_PTR) MdlVa + MdlLength + PAGE_SIZE - 1) >>
  474. PAGE_SHIFT);
  475. TempMdl = TempMdl->Next;
  476. MdlVa = (PUCHAR) TempMdl->ByteOffset;
  477. MdlLength = TempMdl->ByteCount;
  478. TransferLength += MdlLength;
  479. MdlCount++;
  480. }
  481. if (TransferLength + PAGE_SIZE < (ULONG_PTR)(Length + MdlVa) ) {
  482. ASSERT(TransferLength >= Length);
  483. return(STATUS_BUFFER_TOO_SMALL);
  484. }
  485. //
  486. // Calculate the last number of map registers based on the requested
  487. // length - not the length of the last MDL.
  488. //
  489. ASSERT( TransferLength <= MdlLength + Length );
  490. NumberOfMapRegisters += (ULONG)(((ULONG_PTR) MdlVa + Length + MdlLength - TransferLength +
  491. PAGE_SIZE - 1) >> PAGE_SHIFT);
  492. //
  493. // Calculate how much memory is required for the context structure. This
  494. // this actually laid out as follows:
  495. //
  496. // XHAL_WAIT_CONTEXT_BLOCK;
  497. // MapRegisterBase[ MdlCount ];
  498. // union {
  499. // WAIT_CONTEXT_BLOCK[ MdlCount ];
  500. // SCATTER_GATHER_LIST [ NumberOfMapRegisters ];
  501. // };
  502. //
  503. ContextSize = NumberOfMapRegisters * sizeof( SCATTER_GATHER_ELEMENT ) +
  504. sizeof( SCATTER_GATHER_LIST );
  505. //
  506. // For each Mdl a separate Wcb is required since a separate map
  507. // register base must be allocated.
  508. //
  509. if (ContextSize < sizeof( WAIT_CONTEXT_BLOCK ) * MdlCount) {
  510. ContextSize = sizeof( WAIT_CONTEXT_BLOCK ) * MdlCount;
  511. }
  512. ContextSize += sizeof( XHAL_WAIT_CONTEXT_BLOCK ) +
  513. MdlCount * sizeof( PVOID );
  514. WaitBlock = ExAllocatePoolWithTag( NonPagedPool, ContextSize, ' laH' );
  515. if (WaitBlock == NULL) {
  516. return( STATUS_INSUFFICIENT_RESOURCES );
  517. }
  518. //
  519. // Store the wait context block at the end of our block.
  520. // All of the information in the wait block can be overwritten
  521. // by the scatter/gather list.
  522. //
  523. Wcb = (PWAIT_CONTEXT_BLOCK) ((PVOID *) (WaitBlock + 1) + MdlCount);
  524. //
  525. // Save the interesting data in the wait block.
  526. //
  527. WaitBlock->Mdl = Mdl;
  528. WaitBlock->CurrentVa = CurrentVa;
  529. WaitBlock->Length = Length;
  530. WaitBlock->RealAdapterObject = ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject;
  531. WaitBlock->DriverExecutionRoutine = ExecutionRoutine;
  532. WaitBlock->DriverContext = Context;
  533. WaitBlock->CurrentIrp = DeviceObject->CurrentIrp;
  534. WaitBlock->MapRegisterLock = MdlCount;
  535. WaitBlock->WriteToDevice = WriteToDevice;
  536. WaitBlock->MdlCount = (UCHAR) MdlCount;
  537. //
  538. // Loop through each of the required MDLs, calling
  539. // IoAllocateAdapterChannel.
  540. //
  541. MdlCount = 0;
  542. TempMdl = Mdl;
  543. TransferLength = Length;
  544. MdlLength = TempMdl->ByteCount - (ULONG)((PUCHAR) CurrentVa - (PUCHAR) MmGetMdlVirtualAddress(Mdl));
  545. MdlVa = (PUCHAR) BYTE_OFFSET(CurrentVa);
  546. NumberOfMapRegisters = 0;
  547. //
  548. // Loop through the chained MDLs accumulating the required
  549. // number of map registers.
  550. //
  551. while (TransferLength > 0) {
  552. if (MdlLength > TransferLength) {
  553. MdlLength = TransferLength;
  554. }
  555. TransferLength -= MdlLength;
  556. NumberOfMapRegisters = (ULONG)(((ULONG_PTR) MdlVa + MdlLength + PAGE_SIZE - 1) >>
  557. PAGE_SHIFT);
  558. Wcb->DeviceContext = WaitBlock;
  559. Wcb->DeviceObject = DeviceObject;
  560. //
  561. // Store the map register index in the IRP pointer.
  562. //
  563. Wcb->CurrentIrp = (PVOID) MdlCount;
  564. //
  565. // Call the HAL to allocate the adapter channel.
  566. // xHalpAllocateAdapterCallback will fill in the scatter/gather list.
  567. //
  568. Status = HalAllocateAdapterChannel( ((PADAPTER_OBJECT) DmaAdapter)->RealAdapterObject,
  569. Wcb,
  570. NumberOfMapRegisters,
  571. xHalpAllocateAdapterCallback );
  572. if (TempMdl->Next == NULL) {
  573. break;
  574. }
  575. //
  576. // Advance to next MDL.
  577. //
  578. TempMdl = TempMdl->Next;
  579. MdlVa = (PUCHAR) TempMdl->ByteOffset;
  580. MdlLength = TempMdl->ByteCount;
  581. MdlCount++;
  582. Wcb++;
  583. }
  584. //
  585. // If HalAllocateAdapterChannel failed then free the wait block.
  586. //
  587. if (!NT_SUCCESS( Status)) {
  588. ExFreePool( WaitBlock );
  589. }
  590. return( Status );
  591. }
  592. VOID
  593. xHalPutScatterGatherList (
  594. IN PDMA_ADAPTER DmaAdapter,
  595. IN PSCATTER_GATHER_LIST ScatterGather,
  596. IN BOOLEAN WriteToDevice
  597. )
  598. {
  599. PXHAL_WAIT_CONTEXT_BLOCK WaitBlock = (PVOID) ScatterGather->Reserved;
  600. ULONG TransferLength;
  601. ULONG MdlLength;
  602. ULONG MdlCount = 0;
  603. PMDL Mdl;
  604. PUCHAR CurrentVa;
  605. //
  606. // Setup for the first MDL. We expect the MDL pointer to be pointing
  607. // at the first used MDL.
  608. //
  609. Mdl = WaitBlock->Mdl;
  610. CurrentVa = WaitBlock->CurrentVa;
  611. ASSERT( CurrentVa >= (PUCHAR) MmGetMdlVirtualAddress(Mdl) && CurrentVa < (PUCHAR) MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount );
  612. MdlLength = Mdl->ByteCount - (ULONG)(CurrentVa - (PUCHAR) MmGetMdlVirtualAddress(Mdl));
  613. TransferLength = WaitBlock->Length;
  614. //
  615. // Loop through the used MDLs calling IoFlushAdapterBuffers.
  616. //
  617. while (TransferLength > 0) {
  618. if (MdlLength > TransferLength) {
  619. MdlLength = TransferLength;
  620. }
  621. TransferLength -= MdlLength;
  622. IoFlushAdapterBuffers( WaitBlock->RealAdapterObject,
  623. Mdl,
  624. WaitBlock->MapRegisterBase[MdlCount],
  625. CurrentVa,
  626. MdlLength,
  627. WriteToDevice );
  628. if (Mdl->Next == NULL) {
  629. break;
  630. }
  631. //
  632. // Advance to the next MDL. Update the current VA and the MdlLength.
  633. //
  634. Mdl = Mdl->Next;
  635. CurrentVa = MmGetMdlVirtualAddress(Mdl);
  636. MdlLength = Mdl->ByteCount;
  637. MdlCount++;
  638. }
  639. ExFreePool( WaitBlock );
  640. }
  641. IO_ALLOCATION_ACTION
  642. xHalpAllocateAdapterCallback (
  643. IN struct _DEVICE_OBJECT *DeviceObject,
  644. IN struct _IRP *Irp,
  645. IN PVOID MapRegisterBase,
  646. IN PVOID Context
  647. )
  648. /*++
  649. Routine Description:
  650. This routine is called when the adapter object and map registers are
  651. available for the data transfer. This routine saves the map register
  652. base away. If all of the required bases have not been saved then it
  653. returns. Otherwise it builds the entire scatter/gather list by calling
  654. IoMapTransfer. After the list is built, it is passed to the driver.
  655. Arguments:
  656. DeviceObject - Pointer to the device object that is allocating the
  657. adapter.
  658. Irp - Supplies the map register offset assigned for this callback.
  659. MapRegisterBase - Supplies the map register base for use by the adapter
  660. routines.
  661. Context - Supplies a pointer to the xhal wait control block.
  662. Return Value:
  663. Returns DeallocateObjectKeepRegisters.
  664. --*/
  665. {
  666. PXHAL_WAIT_CONTEXT_BLOCK WaitBlock = Context;
  667. PVOID *MapRegisterBasePtr;
  668. ULONG TransferLength;
  669. LONG MdlLength;
  670. PMDL Mdl;
  671. PUCHAR CurrentVa;
  672. PSCATTER_GATHER_LIST ScatterGather;
  673. PSCATTER_GATHER_ELEMENT Element;
  674. //
  675. // Save the map register base in the appropriate slot.
  676. //
  677. WaitBlock->MapRegisterBase[ (ULONG_PTR) Irp ] = MapRegisterBase;
  678. //
  679. // See if this is the last callback.
  680. //
  681. if (InterlockedDecrement( &WaitBlock->MapRegisterLock ) != 0) {
  682. //
  683. // More to come, wait for the rest.
  684. //
  685. return( DeallocateObjectKeepRegisters );
  686. }
  687. //
  688. // Put the scatter gather list after wait block. Add a back pointer to
  689. // the beginning of the wait block.
  690. //
  691. MapRegisterBasePtr = (PVOID *) (WaitBlock + 1);
  692. ScatterGather = (PSCATTER_GATHER_LIST) (MapRegisterBasePtr +
  693. WaitBlock->MdlCount);
  694. ScatterGather->Reserved = (ULONG_PTR) WaitBlock;
  695. Element = ScatterGather->Elements;
  696. //
  697. // Setup for the first MDL. We expect the MDL pointer to be pointing
  698. // at the first used MDL.
  699. //
  700. Mdl = WaitBlock->Mdl;
  701. CurrentVa = WaitBlock->CurrentVa;
  702. ASSERT( CurrentVa >= (PUCHAR) MmGetMdlVirtualAddress(Mdl) && CurrentVa < (PUCHAR) MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount );
  703. MdlLength = Mdl->ByteCount - (ULONG)(CurrentVa - (PUCHAR) MmGetMdlVirtualAddress(Mdl));
  704. TransferLength = WaitBlock->Length;
  705. //
  706. // Loop build the list for each MDL.
  707. //
  708. while (TransferLength > 0) {
  709. if ((ULONG) MdlLength > TransferLength) {
  710. MdlLength = TransferLength;
  711. }
  712. TransferLength -= MdlLength;
  713. //
  714. // Loop building the list for the elements within an MDL.
  715. //
  716. while (MdlLength > 0) {
  717. Element->Length = MdlLength;
  718. Element->Address = IoMapTransfer( WaitBlock->RealAdapterObject,
  719. Mdl,
  720. *MapRegisterBasePtr,
  721. CurrentVa,
  722. &Element->Length,
  723. WaitBlock->WriteToDevice );
  724. ASSERT( (ULONG) MdlLength >= Element->Length );
  725. MdlLength -= Element->Length;
  726. CurrentVa += Element->Length;
  727. Element++;
  728. }
  729. if (Mdl->Next == NULL) {
  730. //
  731. // There are a few cases where the buffer described by the MDL
  732. // is less than the transfer length. This occurs when the
  733. // file system is transfering the last page of the file and MM
  734. // defines the MDL to be file size and the file system rounds
  735. // the write up to a sector. This extra amount should never
  736. // cross a page boundary. Add this extra to the length of the
  737. // last element.
  738. //
  739. ASSERT(((Element - 1)->Length & (PAGE_SIZE - 1)) + TransferLength <= PAGE_SIZE );
  740. (Element - 1)->Length += TransferLength;
  741. break;
  742. }
  743. //
  744. // Advance to the next MDL. Update the current VA and the MdlLength.
  745. //
  746. Mdl = Mdl->Next;
  747. CurrentVa = MmGetMdlVirtualAddress(Mdl);
  748. MdlLength = Mdl->ByteCount;
  749. MapRegisterBasePtr++;
  750. }
  751. //
  752. // Set the number of elements actually used.
  753. //
  754. ScatterGather->NumberOfElements = (ULONG)(Element - ScatterGather->Elements);
  755. //
  756. // Call the driver with the scatter/gather list.
  757. //
  758. WaitBlock->DriverExecutionRoutine( DeviceObject,
  759. WaitBlock->CurrentIrp,
  760. ScatterGather,
  761. WaitBlock->DriverContext );
  762. return( DeallocateObjectKeepRegisters );
  763. }
  764. #endif
  765. BOOLEAN
  766. xHalTranslateBusAddress(
  767. IN INTERFACE_TYPE InterfaceType,
  768. IN ULONG BusNumber,
  769. IN PHYSICAL_ADDRESS BusAddress,
  770. IN OUT PULONG AddressSpace,
  771. OUT PPHYSICAL_ADDRESS TranslatedAddress
  772. )
  773. {
  774. //
  775. // If the HAL fails to override this function, then
  776. // the HAL has clearly failed to initialize.
  777. //
  778. UNREFERENCED_PARAMETER (InterfaceType);
  779. UNREFERENCED_PARAMETER (BusNumber);
  780. UNREFERENCED_PARAMETER (BusAddress);
  781. UNREFERENCED_PARAMETER (AddressSpace);
  782. UNREFERENCED_PARAMETER (TranslatedAddress);
  783. KeBugCheckEx(HAL_INITIALIZATION_FAILED, 0, 0, 0, 7);
  784. }
  785. NTSTATUS
  786. xHalAssignSlotResources (
  787. IN PUNICODE_STRING RegistryPath,
  788. IN PUNICODE_STRING DriverClassName OPTIONAL,
  789. IN PDRIVER_OBJECT DriverObject,
  790. IN PDEVICE_OBJECT DeviceObject OPTIONAL,
  791. IN INTERFACE_TYPE BusType,
  792. IN ULONG BusNumber,
  793. IN ULONG SlotNumber,
  794. IN OUT PCM_RESOURCE_LIST *AllocatedResources
  795. )
  796. {
  797. //
  798. // If the HAL fails to override this function, then
  799. // the HAL has clearly failed to initialize.
  800. //
  801. UNREFERENCED_PARAMETER (RegistryPath);
  802. UNREFERENCED_PARAMETER (DriverClassName);
  803. UNREFERENCED_PARAMETER (DriverObject);
  804. UNREFERENCED_PARAMETER (DeviceObject);
  805. UNREFERENCED_PARAMETER (BusType);
  806. UNREFERENCED_PARAMETER (BusNumber);
  807. UNREFERENCED_PARAMETER (SlotNumber);
  808. UNREFERENCED_PARAMETER (AllocatedResources);
  809. KeBugCheckEx(HAL_INITIALIZATION_FAILED, 0, 0, 0, 7);
  810. }
  811. VOID
  812. xHalHaltSystem(
  813. VOID
  814. )
  815. {
  816. for (;;) ;
  817. }
  818. NTSTATUS
  819. xHalAllocateMapRegisters(
  820. IN PADAPTER_OBJECT DmaAdapter,
  821. IN ULONG NumberOfMapRegisters,
  822. IN ULONG BaseAddressCount,
  823. OUT PMAP_REGISTER_ENTRY MapRegisterArray
  824. )
  825. {
  826. PAGED_CODE();
  827. UNREFERENCED_PARAMETER (DmaAdapter);
  828. UNREFERENCED_PARAMETER (NumberOfMapRegisters);
  829. UNREFERENCED_PARAMETER (BaseAddressCount);
  830. UNREFERENCED_PARAMETER (MapRegisterArray);
  831. return STATUS_NOT_IMPLEMENTED;
  832. }
  833. NTSTATUS
  834. xKdSetupPciDeviceForDebugging(
  835. IN PVOID LoaderBlock, OPTIONAL
  836. IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
  837. )
  838. {
  839. UNREFERENCED_PARAMETER (LoaderBlock);
  840. UNREFERENCED_PARAMETER (PciDevice);
  841. return STATUS_NOT_IMPLEMENTED;
  842. }
  843. NTSTATUS
  844. xKdReleasePciDeviceForDebugging(
  845. IN OUT PDEBUG_DEVICE_DESCRIPTOR PciDevice
  846. )
  847. {
  848. UNREFERENCED_PARAMETER (PciDevice);
  849. return STATUS_NOT_IMPLEMENTED;
  850. }
  851. PVOID
  852. xKdGetAcpiTablePhase0(
  853. IN PLOADER_PARAMETER_BLOCK LoaderBlock,
  854. IN ULONG Signature
  855. )
  856. {
  857. UNREFERENCED_PARAMETER (LoaderBlock);
  858. UNREFERENCED_PARAMETER (Signature);
  859. return NULL;
  860. }
  861. VOID
  862. xKdCheckPowerButton(
  863. VOID
  864. )
  865. {
  866. return;
  867. }
  868. VOID
  869. xHalEndOfBoot(
  870. VOID
  871. )
  872. {
  873. PAGED_CODE();
  874. return;
  875. }
  876. UCHAR
  877. xHalVectorToIDTEntry(
  878. ULONG Vector
  879. )
  880. {
  881. return (UCHAR)Vector;
  882. }
  883. PVOID
  884. xKdMapPhysicalMemory64(
  885. IN PHYSICAL_ADDRESS PhysicalAddress,
  886. IN ULONG NumberPages
  887. )
  888. {
  889. UNREFERENCED_PARAMETER (PhysicalAddress);
  890. UNREFERENCED_PARAMETER (NumberPages);
  891. return NULL;
  892. }
  893. VOID
  894. xKdUnmapVirtualAddress(
  895. IN PVOID VirtualAddress,
  896. IN ULONG NumberPages
  897. )
  898. {
  899. UNREFERENCED_PARAMETER (VirtualAddress);
  900. UNREFERENCED_PARAMETER (NumberPages);
  901. return;
  902. }