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.

1399 lines
36 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. vihal.h
  5. Abstract:
  6. This module contains the private declarations to verify hal usage & apis.
  7. Author:
  8. Jordan Tigani (jtigani) 12-Nov-1999
  9. Revision History:
  10. 6-23-00: (jtigani) Moved from halverifier.c
  11. --*/
  12. /////////////////////////////////////////////////////////////////////
  13. //////////////////////////////////////////////// Hal verifier defines
  14. /////////////////////////////////////////////////////////////////////
  15. //
  16. // Bugcheck codes -- the major code is HAL_VERIFIER_DETECTED_VIOLATION --
  17. // the sub-code is the HV_*
  18. //
  19. #define HAL_VERIFIER_DETECTED_VIOLATION 0xE6
  20. #define HV_MISCELLANEOUS_ERROR 0x00
  21. #define HV_PERFORMANCE_COUNTER_DECREASED 0x01
  22. #define HV_PERFORMANCE_COUNTER_SKIPPED 0x02
  23. #define HV_FREED_TOO_MANY_COMMON_BUFFERS 0x03
  24. #define HV_FREED_TOO_MANY_ADAPTER_CHANNELS 0x04
  25. #define HV_FREED_TOO_MANY_MAP_REGISTERS 0x05
  26. #define HV_FREED_TOO_MANY_SCATTER_GATHER_LISTS 0x06
  27. #define HV_LEFTOVER_COMMON_BUFFERS 0x07
  28. #define HV_LEFTOVER_ADAPTER_CHANNELS 0x08
  29. #define HV_LEFTOVER_MAP_REGISTERS 0x09
  30. #define HV_LEFTOVER_SCATTER_GATHER_LISTS 0x0A
  31. #define HV_TOO_MANY_ADAPTER_CHANNELS 0x0B
  32. #define HV_TOO_MANY_MAP_REGISTERS 0x0C
  33. #define HV_DID_NOT_FLUSH_ADAPTER_BUFFERS 0x0D
  34. #define HV_DMA_BUFFER_NOT_LOCKED 0x0E
  35. #define HV_BOUNDARY_OVERRUN 0x0F
  36. #define HV_CANNOT_FREE_MAP_REGISTERS 0x10
  37. #define HV_DID_NOT_PUT_ADAPTER 0x11
  38. #define HV_MDL_FLAGS_NOT_SET 0x12
  39. #define HV_BAD_IRQL 0x13
  40. #define HV_BAD_IRQL_JUST_WARN 0x14
  41. #define HV_OUT_OF_MAP_REGISTERS 0x15
  42. #define HV_FLUSH_EMPTY_BUFFERS 0x16
  43. #define HV_MISMATCHED_MAP_FLUSH 0x17
  44. #define HV_ADAPTER_ALREADY_RELEASED 0x18
  45. #define HV_NULL_DMA_ADAPTER 0x19
  46. #define HV_MAP_FLUSH_NO_TRANSFER 0x1A
  47. #define HV_ADDRESS_NOT_IN_MDL 0x1b
  48. #define HV_DATA_LOSS 0x1c
  49. #define HV_DOUBLE_MAP_REGISTER 0x1d
  50. #define HV_OBSOLETE_API 0x1e
  51. #define HV_BAD_MDL 0x1f
  52. #define HV_FLUSH_NOT_MAPPED 0x20
  53. #define HV_MAP_ZERO_LENGTH_BUFFER 0x21
  54. ///
  55. // Codes to decide what to do when we hit a driver problem.
  56. ///
  57. #define HVC_IGNORE 0x00 // Do nothing.
  58. #define HVC_WARN 0x02 // Print message # continue
  59. #define HVC_ASSERT 0x04 // Print message # break
  60. #define HVC_BUGCHECK 0x08 // Print message # bugcheck
  61. #define HVC_ONCE 0x10 // combined with another code,
  62. #define HAL_VERIFIER_POOL_TAG 'VlaH' // HalV backwards //
  63. //
  64. // This is how we can recognize our double buffers
  65. //
  66. #define MAP_REGISTER_FILL_CHAR 0x0E
  67. #define PADDING_FILL_CHAR 0x0F
  68. //
  69. // Since we hook the "MapRegisterBase" with a MapRegisterFile, we sign
  70. // the first four bytes so we can tell the difference between the HAL's
  71. // map register base and our map register file.
  72. //
  73. #define MRF_SIGNATURE 0xACEFD00D
  74. //
  75. // This is what we use if the hal has returned a NULL map register base so
  76. // that drivers don't assume that they don't have flush adapter buffers.
  77. //
  78. #define MRF_NULL_PLACEHOLDER (PVOID)(LONG_PTR)(LONG)0xDEADF00D
  79. //
  80. // This should devide evenly into 2^32
  81. //
  82. #define MAX_COUNTERS 0x20
  83. //
  84. // Flags to indicate where the buffer tagging shall happen
  85. //
  86. #define TAG_BUFFER_START 0x01
  87. #define TAG_BUFFER_END 0x02
  88. //
  89. // How many map registers we can double-buffer at once
  90. // using physical contiguous memory.
  91. // This must be an integral multiple of the number of bits in a ULONG
  92. //
  93. #define MAX_CONTIGUOUS_MAP_REGISTERS 0x20
  94. //
  95. // Flags that describe a map register
  96. //
  97. #define MAP_REGISTER_WRITE 0x01 // the transfer is a write to device
  98. #define MAP_REGISTER_READ 0x02 // the transfer is a read from device
  99. #define MAP_REGISTER_RW_MASK (MAP_REGISTER_WRITE | MAP_REGISTER_READ)
  100. /////////////////////////////////////////////////////////////////////
  101. //////////////////////// Safe multi-processor 64 bit reads and writes
  102. /////////////////////////////////////////////////////////////////////
  103. #if defined (_X86_)
  104. //
  105. // Only save the time stamp counter on x86 machines
  106. //
  107. #define ViRdtsc ViRdtscX86
  108. //
  109. // Structure to do a locked 64 bit write /compare without
  110. // a spinlock.
  111. //
  112. typedef struct _TIMER64 {
  113. ULONG TimeLow;
  114. ULONG TimeHigh1;
  115. ULONG TimeHigh2;
  116. ULONG Reserved; // for packing sake //
  117. } TIMER64, *PTIMER64;
  118. //
  119. // Since we can't do a 64 bit atomic operation
  120. // without a spinlock, we have to monkey around a bit
  121. // This method comes from the acpi timer code.
  122. //
  123. #define SAFE_READ_TIMER64(WriteLargeInteger, ReadTimer64) \
  124. \
  125. while (TRUE) { \
  126. (WriteLargeInteger).HighPart = (ReadTimer64).TimeHigh2; \
  127. (WriteLargeInteger).LowPart = (ReadTimer64).TimeLow; \
  128. \
  129. if ((ULONG)(WriteLargeInteger).HighPart == (ReadTimer64).TimeHigh1) \
  130. break; \
  131. \
  132. _asm { rep nop }; \
  133. }
  134. #define SAFE_WRITE_TIMER64(WriteTimer64, ReadLargeInteger) \
  135. WriteTimer64.TimeHigh1 = (ReadLargeInteger).HighPart; \
  136. WriteTimer64.TimeLow = (ReadLargeInteger).LowPart; \
  137. WriteTimer64.TimeHigh2 = (ReadLargeInteger).HighPart;
  138. // defined (_X86_) //
  139. #else
  140. // ! defined (_X86_) //
  141. #if defined(_IA64_)
  142. #define ViRdtsc ViRdtscIA64
  143. #else // !_IA64_
  144. //
  145. // Only save the time stamp counter on x86 and ia64 machines
  146. //
  147. #define ViRdtsc ViRdtscNull
  148. #endif // !_IA64_
  149. //
  150. // Alpha or IA64 can do atomic 64 bit read/writes.
  151. //
  152. typedef LARGE_INTEGER TIMER64;
  153. #define SAFE_READ_TIMER64(WriteLargeInteger, ReadTimer64) \
  154. InterlockedExchangePointer( \
  155. &((PVOID) (WriteLargeInteger).QuadPart ), \
  156. (PVOID) (ReadTimer64).QuadPart \
  157. );
  158. #define SAFE_WRITE_TIMER64(WriteTimer64, ReadLargeInteger) \
  159. InterlockedExchangePointer( \
  160. &((PVOID) (WriteTimer64).QuadPart ), \
  161. (PVOID) (ReadLargeInteger).QuadPart \
  162. );
  163. // ! defined (_X86_) //
  164. #endif
  165. /////////////////////////////////////////////////////////////////////
  166. ///////////////////////////////////////// Hal verifier global externs
  167. /////////////////////////////////////////////////////////////////////
  168. extern ULONG VfVerifyDma;
  169. extern LOGICAL VfVerifyPerformanceCounter;
  170. extern LOGICAL ViDoubleBufferDma;
  171. extern LOGICAL ViProtectBuffers;
  172. extern LOGICAL ViInjectDmaFailures;
  173. extern LOGICAL ViSuperDebug;
  174. extern LOGICAL ViSufficientlyBootedForPcControl;
  175. extern LOGICAL ViSufficientlyBootedForDmaFailure;
  176. extern ULONG ViMaxMapRegistersPerAdapter;
  177. extern ULONG ViAllocationsFailedDeliberately;
  178. extern LARGE_INTEGER ViRequiredTimeSinceBoot;
  179. extern CHAR ViDmaVerifierTag[];
  180. extern BOOLEAN ViPenalties[];
  181. extern struct _HAL_VERIFIER_LOCKED_LIST ViAdapterList;
  182. extern struct _VF_TIMER_INFORMATION * ViTimerInformation;
  183. extern struct _DMA_OPERATIONS ViDmaOperations;
  184. extern struct _DMA_OPERATIONS ViLegacyDmaOperations;
  185. /////////////////////////////////////////////////////////////////////
  186. ////////////////////////////////// Hal verifier structure definitions
  187. /////////////////////////////////////////////////////////////////////
  188. typedef struct _TIMER_TICK {
  189. ULONG Processor;
  190. ULONG Reserved;
  191. LARGE_INTEGER TimeStampCounter;
  192. LARGE_INTEGER PerformanceCounter;
  193. LARGE_INTEGER TimerTick;
  194. } TIMER_TICK, *PTIMER_TICK;
  195. typedef struct _VF_TIMER_INFORMATION {
  196. KDPC RefreshDpc;
  197. KTIMER RefreshTimer;
  198. TIMER64 LastPerformanceCounter;
  199. TIMER64 UpperBound;
  200. TIMER64 LastTickCount;
  201. TIMER64 LastKdStartTime;
  202. LARGE_INTEGER PerformanceFrequency;
  203. ULONG CountsPerTick;
  204. ULONG CurrentCounter;
  205. TIMER_TICK SavedTicks[MAX_COUNTERS];
  206. } VF_TIMER_INFORMATION, *PVF_TIMER_INFORMATION;
  207. typedef struct _HAL_VERIFIER_LOCKED_LIST {
  208. LIST_ENTRY ListEntry;
  209. KSPIN_LOCK SpinLock;
  210. } HAL_VERIFIER_LOCKED_LIST, *PHAL_VERIFIER_LOCKED_LIST;
  211. typedef struct _HAL_VERIFIER_BUFFER {
  212. USHORT PrePadBytes;
  213. USHORT PostPadBytes;
  214. ULONG RealLength;
  215. ULONG AdvertisedLength;
  216. PVOID RealStartAddress;
  217. PVOID AdvertisedStartAddress;
  218. PHYSICAL_ADDRESS RealLogicalStartAddress;
  219. PVOID AllocatorAddress;
  220. LIST_ENTRY ListEntry;
  221. } HAL_VERIFIER_BUFFER, *PHAL_VERIFIER_BUFFER;
  222. typedef struct _MAP_REGISTER {
  223. PVOID MappedToSa;
  224. ULONG BytesMapped;
  225. ULONG Flags;
  226. PVOID MapRegisterStart;
  227. } MAP_REGISTER, *PMAP_REGISTER;
  228. typedef struct _MAP_REGISTER_FILE {
  229. ULONG Signature;
  230. LIST_ENTRY ListEntry;
  231. BOOLEAN ContiguousMap;
  232. BOOLEAN ScatterGather;
  233. ULONG NumberOfMapRegisters;
  234. ULONG NumberOfRegistersMapped;
  235. PVOID MapRegisterBaseFromHal;
  236. PMDL MapRegisterMdl;
  237. PVOID MapRegisterBuffer;
  238. PVOID OriginalBuffer;
  239. KSPIN_LOCK AllocationLock;
  240. MAP_REGISTER MapRegisters[1];
  241. // Rest of the map registers go here
  242. //
  243. } MAP_REGISTER_FILE, *PMAP_REGISTER_FILE;
  244. typedef struct _VF_WAIT_CONTEXT_BLOCK {
  245. PVOID RealContext;
  246. PVOID RealCallback;
  247. PMDL RealMdl;
  248. PVOID RealStartVa;
  249. ULONG RealLength;
  250. ULONG NumberOfMapRegisters;
  251. struct _ADAPTER_INFORMATION * AdapterInformation;
  252. PSCATTER_GATHER_LIST ScatterGatherList;
  253. LIST_ENTRY ListEntry;
  254. PMAP_REGISTER_FILE MapRegisterFile;
  255. } VF_WAIT_CONTEXT_BLOCK, *PVF_WAIT_CONTEXT_BLOCK;
  256. //
  257. // Needed to allocate storage for the MDL is Get/BuildScatterGatherList
  258. // We declare this structure so we will not worry about alignment issues...
  259. //
  260. typedef struct _VF_WAIT_CONTEXT_BLOCK_EX {
  261. VF_WAIT_CONTEXT_BLOCK;
  262. MDL Mdl;
  263. } VF_WAIT_CONTEXT_BLOCK_EX, *PVF_WAIT_CONTEXT_BLOCK_EX;
  264. //
  265. // Store a list of the real dma operations used by an adapter ...
  266. // when the driver allocates the adapter, we're going to replace all of its
  267. // dma operations with ours
  268. //
  269. typedef struct _ADAPTER_INFORMATION {
  270. LIST_ENTRY ListEntry;
  271. PDMA_ADAPTER DmaAdapter;
  272. PDEVICE_OBJECT DeviceObject;
  273. BOOLEAN DeferredRemove;
  274. BOOLEAN UseContiguousBuffers;
  275. BOOLEAN UseDmaChannel;
  276. BOOLEAN Inactive;
  277. PVOID CallingAddress;
  278. PDMA_OPERATIONS RealDmaOperations;
  279. HAL_VERIFIER_LOCKED_LIST ScatterGatherLists;
  280. HAL_VERIFIER_LOCKED_LIST CommonBuffers;
  281. HAL_VERIFIER_LOCKED_LIST MapRegisterFiles;
  282. ULONG MaximumMapRegisters;
  283. ULONG AllocatedMapRegisters;
  284. LONG ActiveMapRegisters;
  285. ULONG AllocatedScatterGatherLists;
  286. LONG ActiveScatterGatherLists;
  287. ULONG AllocatedCommonBuffers;
  288. ULONG FreedCommonBuffers;
  289. ULONG AllocatedAdapterChannels; // Must be 1 or less ! //
  290. ULONG FreedAdapterChannels;
  291. ULONG MappedTransferWithoutFlushing;
  292. DEVICE_DESCRIPTION DeviceDescription;
  293. ULONG AdapterChannelMapRegisters;
  294. VF_WAIT_CONTEXT_BLOCK AdapterChannelContextBlock;
  295. PVOID *ContiguousBuffers; // array of contiguous 3-page buffers to be used for double-buffering
  296. ULONG SuccessfulContiguousAllocations; // how many times we allocated contiguous space
  297. ULONG FailedContiguousAllocations; // how many times we failed to allocate contiguous space
  298. KSPIN_LOCK AllocationLock; // lock for our allocator routines
  299. ULONG AllocationStorage[MAX_CONTIGUOUS_MAP_REGISTERS / (sizeof(ULONG) * 8)]; // bitmask for allocator routines
  300. RTL_BITMAP AllocationMap;
  301. ULONG ContiguousMapRegisters; // allocated among ContiguousBufers
  302. ULONG NonContiguousMapRegisters; // allocated from non-Paged Pool
  303. } ADAPTER_INFORMATION, *PADAPTER_INFORMATION;
  304. /////////////////////////////////////////////////////////////////////
  305. ////////////////////////////////// Hal verifier function declarations
  306. /////////////////////////////////////////////////////////////////////
  307. //==========================
  308. // Declare our dma apis here
  309. // if NO_LEGACY_DRIVERS *is*
  310. // enabled
  311. // =========================
  312. #if defined(NO_LEGACY_DRIVERS)
  313. VOID
  314. VfPutDmaAdapter(
  315. struct _DMA_ADAPTER * DmaAdapter
  316. );
  317. PVOID
  318. VfAllocateCommonBuffer(
  319. IN struct _DMA_ADAPTER * DmaAdapter,
  320. IN ULONG Length,
  321. OUT PPHYSICAL_ADDRESS LogicalAddress,
  322. IN BOOLEAN CacheEnabled
  323. );
  324. VOID
  325. VfFreeCommonBuffer(
  326. IN struct _DMA_ADAPTER * DmaAdapter,
  327. IN ULONG Length,
  328. IN PHYSICAL_ADDRESS LogicalAddress,
  329. IN PVOID VirtualAddress,
  330. IN BOOLEAN CacheEnabled
  331. );
  332. NTSTATUS
  333. VfAllocateAdapterChannel(
  334. IN struct _DMA_ADAPTER * DmaAdapter,
  335. IN PDEVICE_OBJECT DeviceObject,
  336. IN ULONG NumberOfMapRegisters,
  337. IN PDRIVER_CONTROL ExecutionRoutine,
  338. IN PVOID Context
  339. );
  340. PHYSICAL_ADDRESS
  341. VfMapTransfer(
  342. IN struct _DMA_ADAPTER * DmaAdapter,
  343. IN PMDL Mdl,
  344. IN PVOID MapRegisterBase,
  345. IN PVOID CurrentVa,
  346. IN OUT PULONG Length,
  347. IN BOOLEAN WriteToDevice
  348. );
  349. BOOLEAN
  350. VfFlushAdapterBuffers(
  351. IN struct _DMA_ADAPTER * DmaAdapter,
  352. IN PMDL Mdl,
  353. IN PVOID MapRegisterBase,
  354. IN PVOID CurrentVa,
  355. IN ULONG Length,
  356. IN BOOLEAN WriteToDevice
  357. );
  358. VOID
  359. VfFreeAdapterChannel(
  360. IN struct _DMA_ADAPTER * DmaAdapter
  361. );
  362. VOID
  363. VfFreeMapRegisters(
  364. IN struct _DMA_ADAPTER * DmaAdapter,
  365. PVOID MapRegisterBase,
  366. ULONG NumberOfMapRegisters
  367. );
  368. ULONG
  369. VfGetDmaAlignment(
  370. IN struct _DMA_ADAPTER * DmaAdapter
  371. );
  372. ULONG
  373. VfReadDmaCounter(
  374. IN struct _DMA_ADAPTER * DmaAdapter
  375. );
  376. NTSTATUS
  377. VfGetScatterGatherList (
  378. IN struct _DMA_ADAPTER * DmaAdapter,
  379. IN PDEVICE_OBJECT DeviceObject,
  380. IN PMDL Mdl,
  381. IN PVOID CurrentVa,
  382. IN ULONG Length,
  383. IN PVOID ExecutionRoutine,
  384. IN PVOID Context,
  385. IN BOOLEAN WriteToDevice
  386. );
  387. VOID
  388. VfPutScatterGatherList(
  389. IN struct _DMA_ADAPTER * DmaAdapter,
  390. IN struct _SCATTER_GATHER_LIST * ScatterGather,
  391. IN BOOLEAN WriteToDevice
  392. );
  393. #endif
  394. // =====================
  395. // New verified dma apis
  396. // =====================
  397. NTSTATUS
  398. VfCalculateScatterGatherListSize(
  399. IN PDMA_ADAPTER DmaAdapter,
  400. IN OPTIONAL PMDL Mdl,
  401. IN PVOID CurrentVa,
  402. IN ULONG Length,
  403. OUT PULONG ScatterGatherListSize,
  404. OUT OPTIONAL PULONG pNumberOfMapRegisters
  405. );
  406. NTSTATUS
  407. VfBuildScatterGatherList(
  408. IN PDMA_ADAPTER DmaAdapter,
  409. IN PDEVICE_OBJECT DeviceObject,
  410. IN PMDL Mdl,
  411. IN PVOID CurrentVa,
  412. IN ULONG Length,
  413. IN PDRIVER_LIST_CONTROL ExecutionRoutine,
  414. IN PVOID Context,
  415. IN BOOLEAN WriteToDevice,
  416. IN PVOID ScatterGatherBuffer,
  417. IN ULONG ScatterGatherLength
  418. );
  419. NTSTATUS
  420. VfBuildMdlFromScatterGatherList(
  421. IN PDMA_ADAPTER DmaAdapter,
  422. IN PSCATTER_GATHER_LIST ScatterGather,
  423. IN PMDL OriginalMdl,
  424. OUT PMDL *TargetMdl
  425. );
  426. IO_ALLOCATION_ACTION
  427. VfAdapterCallback(
  428. IN PDEVICE_OBJECT DeviceObject,
  429. IN PIRP Irp,
  430. IN PVOID MapRegisterBase,
  431. IN PVOID Context
  432. );
  433. VOID
  434. VfScatterGatherCallback(
  435. IN struct _DEVICE_OBJECT *DeviceObject,
  436. IN struct _IRP *Irp,
  437. IN struct _SCATTER_GATHER_LIST * ScatterGather,
  438. IN PVOID Context
  439. );
  440. // =================================
  441. // Hook for HalpAllocateMapRegisters
  442. // =================================
  443. NTSTATUS
  444. VfHalAllocateMapRegisters(
  445. IN PADAPTER_OBJECT DmaAdapter,
  446. IN ULONG NumberOfMapRegisters,
  447. IN ULONG BaseAddressCount,
  448. OUT PMAP_REGISTER_ENTRY MapRegisterArray
  449. );
  450. // ==============================
  451. // Hal verifier internal routines
  452. // ==============================
  453. PADAPTER_INFORMATION
  454. ViHookDmaAdapter(
  455. IN PDMA_ADAPTER DmaAdapter,
  456. IN PDEVICE_DESCRIPTION DeviceDescription,
  457. IN ULONG NumberOfMapRegisters
  458. );
  459. VOID
  460. ViReleaseDmaAdapter(
  461. IN PADAPTER_INFORMATION AdapterInformation
  462. );
  463. PADAPTER_INFORMATION
  464. ViGetAdapterInformation(
  465. IN PDMA_ADAPTER DmaAdapter
  466. );
  467. PVOID
  468. ViGetRealDmaOperation(
  469. IN PDMA_ADAPTER DmaAdapter,
  470. IN ULONG AdapterInformationOffset
  471. );
  472. LARGE_INTEGER
  473. ViRdtsc(
  474. VOID
  475. );
  476. VOID
  477. VfInitializeTimerInformation(
  478. VOID
  479. );
  480. VOID
  481. ViRefreshCallback(
  482. IN PKDPC Dpc,
  483. IN PVOID DeferredContext,
  484. IN PVOID SystemArgument1,
  485. IN PVOID SystemArgument2
  486. );
  487. LOGICAL
  488. VfInjectDmaFailure (
  489. VOID
  490. );
  491. // =================================================
  492. // Hal verfier special routines to track allocations
  493. // =================================================
  494. PVOID
  495. ViSpecialAllocateCommonBuffer(
  496. IN PALLOCATE_COMMON_BUFFER AllocateCommonBuffer,
  497. IN PADAPTER_INFORMATION AdapterInformation,
  498. IN PVOID CallingAddress,
  499. IN ULONG Length,
  500. IN OUT PPHYSICAL_ADDRESS LogicalAddress,
  501. IN LOGICAL CacheEnabled
  502. );
  503. LOGICAL
  504. ViSpecialFreeCommonBuffer(
  505. IN PFREE_COMMON_BUFFER FreeCommonBuffer,
  506. IN PADAPTER_INFORMATION AdapterInformation,
  507. IN PVOID CommonBuffer,
  508. LOGICAL CacheEnabled
  509. );
  510. // ===================================================
  511. // Hal verfier special routines to do double buffering
  512. // ===================================================
  513. PMAP_REGISTER_FILE
  514. ViAllocateMapRegisterFile(
  515. IN PADAPTER_INFORMATION AdapterInformation,
  516. IN ULONG NumberOfMapRegisters
  517. );
  518. LOGICAL
  519. ViFreeMapRegisterFile(
  520. IN PADAPTER_INFORMATION AdapterInformation,
  521. IN PMAP_REGISTER_FILE MapRegisterFile
  522. );
  523. ULONG
  524. ViMapDoubleBuffer(
  525. IN PMAP_REGISTER_FILE MapRegisterFile,
  526. IN OUT PMDL Mdl,
  527. IN OUT PVOID CurrentVa,
  528. IN ULONG Length,
  529. IN BOOLEAN WriteToDevice
  530. );
  531. LOGICAL
  532. ViFlushDoubleBuffer(
  533. IN PMAP_REGISTER_FILE MapRegisterFile,
  534. IN PMDL Mdl,
  535. IN PVOID CurrentVa,
  536. IN ULONG Length,
  537. IN BOOLEAN WriteToDevice
  538. );
  539. LOGICAL
  540. ViAllocateMapRegistersFromFile(
  541. IN PMAP_REGISTER_FILE MapRegisterFile,
  542. IN PVOID CurrentSa,
  543. IN ULONG Length,
  544. IN BOOLEAN WriteToDevice,
  545. OUT PULONG MapRegisterNumber
  546. );
  547. LOGICAL
  548. ViFreeMapRegistersToFile(
  549. IN PMAP_REGISTER_FILE MapRegisterFile,
  550. IN PVOID CurrentSa,
  551. IN ULONG Length
  552. );
  553. PMAP_REGISTER
  554. ViFindMappedRegisterInFile(
  555. IN PMAP_REGISTER_FILE MapRegisterFile,
  556. IN PVOID CurrentSa,
  557. OUT PULONG MapRegisterNumber OPTIONAL
  558. );
  559. LOGICAL
  560. ViSwap(IN OUT PVOID * MapRegisterBase,
  561. IN OUT PMDL * Mdl,
  562. IN OUT PVOID * CurrentVa
  563. );
  564. VOID
  565. ViCheckAdapterBuffers(
  566. IN PADAPTER_INFORMATION AdapterInformation
  567. );
  568. VOID
  569. ViTagBuffer(
  570. IN PVOID AdvertisedBuffer,
  571. IN ULONG AdvertisedLength,
  572. IN USHORT WhereToTag
  573. );
  574. VOID
  575. ViCheckTag(
  576. IN PVOID AdvertisedBuffer,
  577. IN ULONG AdvertisedLength,
  578. IN BOOLEAN RemoveTag,
  579. IN USHORT WhereToCheck
  580. );
  581. VOID
  582. ViInitializePadding(
  583. IN PVOID RealBufferStart,
  584. IN ULONG RealBufferLength,
  585. IN PVOID AdvertisedBufferStart, OPTIONAL
  586. IN ULONG AdvertisedBufferLength OPTIONAL
  587. );
  588. VOID
  589. ViCheckPadding(
  590. IN PVOID RealBufferStart,
  591. IN ULONG RealBufferLength,
  592. IN PVOID AdvertisedBufferStart, OPTIONAL
  593. IN ULONG AdvertisedBufferLength OPTIONAL
  594. );
  595. PULONG_PTR
  596. ViHasBufferBeenTouched(
  597. IN PVOID Address,
  598. IN ULONG_PTR Length,
  599. IN UCHAR ExpectedFillChar
  600. );
  601. VOID
  602. VfAssert(
  603. IN LOGICAL Condition,
  604. IN ULONG Code,
  605. IN OUT PULONG Enable
  606. );
  607. VOID
  608. ViMapTransferHelper(
  609. IN PMDL Mdl,
  610. IN PVOID CurrentVa,
  611. IN ULONG TransferLength,
  612. IN PULONG PageFrame,
  613. IN OUT PULONG Length
  614. );
  615. VOID
  616. ViCommonBufferCalculatePadding(
  617. IN ULONG Length,
  618. OUT PULONG PrePadding,
  619. OUT PULONG PostPadding
  620. );
  621. VOID
  622. ViAllocateContiguousMemory (
  623. IN OUT PADAPTER_INFORMATION AdapterInformation
  624. );
  625. PVOID
  626. ViAllocateFromContiguousMemory (
  627. IN OUT PADAPTER_INFORMATION AdapterInformation,
  628. IN ULONG HintIndex
  629. );
  630. LOGICAL
  631. ViFreeToContiguousMemory (
  632. IN OUT PADAPTER_INFORMATION AdapterInformation,
  633. IN PVOID Address,
  634. IN ULONG HintIndex
  635. );
  636. LOGICAL
  637. VfIsPCIBus (
  638. IN PDEVICE_OBJECT PhysicalDeviceObject
  639. );
  640. PDEVICE_OBJECT
  641. VfGetPDO (
  642. IN PDEVICE_OBJECT DeviceObject
  643. );
  644. VOID
  645. ViCopyBackModifiedBuffer (
  646. OUT PUCHAR Dest,
  647. IN PUCHAR Source,
  648. IN PUCHAR Original,
  649. IN SIZE_T Length
  650. );
  651. /////////////////////////////////////////////////////////////////////
  652. ///////////////////////////////////////////////// Hal verifier macros
  653. /////////////////////////////////////////////////////////////////////
  654. //
  655. // This is a kind of long macro but it lets us decide what to
  656. // do on certain kinds of errors. For instance, if we know
  657. // we are going to hit something once, we might set it to
  658. // HVC_WARN. Or if we know we will hit it 1000 times, but don't
  659. // want to take the code out completely (especially if we're doing
  660. // it on the fly), we can set it to HVC_IGNORE
  661. //
  662. #define VF_ASSERT(condition, code, message) \
  663. { \
  664. static ULONG enable = (ULONG) -1; \
  665. if (enable == (ULONG) -1) \
  666. enable = ViPenalties[code]; \
  667. if (!(condition) && enable) \
  668. { \
  669. DbgPrint("* * * * * * * * HAL Verifier Detected Violation * * * * * * * *\n");\
  670. DbgPrint("* *\n"); \
  671. DbgPrint("* * VF: "); \
  672. DbgPrint message; \
  673. DbgPrint("\n"); \
  674. DbgPrint("* *\n"); \
  675. DbgPrint("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");\
  676. \
  677. VfAssert(condition, code, &enable); \
  678. } \
  679. }
  680. //
  681. // Old favorite:
  682. //
  683. // Control macro (used like a for loop) which iterates over all entries in
  684. // a standard doubly linked list. Head is the list head and the entries
  685. // are of type Type. A member called ListEntry is assumed to be the
  686. // LIST_ENTRY structure linking the entries together. Current contains a
  687. // pointer to each entry in turn.
  688. //
  689. #define FOR_ALL_IN_LIST(Type, Head, Current) \
  690. for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \
  691. (Head) != &(Current)->ListEntry; \
  692. (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  693. Type, \
  694. ListEntry) \
  695. )
  696. #ifndef MIN
  697. #define MIN(a,b) ( ( (ULONG) (a)<(ULONG) (b))?(a):(b) )
  698. #endif
  699. #define NOP
  700. #define VF_INITIALIZE_LOCKED_LIST(LockedList) \
  701. KeInitializeSpinLock(&(LockedList)->SpinLock); \
  702. InitializeListHead(&(LockedList)->ListEntry);
  703. #define VF_LOCK_LIST(ListToLock, OldIrql) \
  704. KeAcquireSpinLock(&(ListToLock)->SpinLock, &OldIrql)
  705. #define VF_UNLOCK_LIST(ListToUnlock, OldIrql) \
  706. KeReleaseSpinLock(&(ListToUnlock)->SpinLock, OldIrql)
  707. #define VF_IS_LOCKED_LIST_EMPTY(LockedList) \
  708. IsListEmpty( &(LockedList)->ListEntry )
  709. #define VF_ADD_TO_LOCKED_LIST(LockedList, AddMe) \
  710. ExInterlockedInsertHeadList( \
  711. &(LockedList)->ListEntry, \
  712. &(AddMe)->ListEntry, \
  713. &(LockedList)->SpinLock )
  714. #define VF_REMOVE_FROM_LOCKED_LIST(LockedList, RemoveMe) \
  715. { \
  716. KIRQL OldIrql; \
  717. VF_LOCK_LIST((LockedList), OldIrql); \
  718. RemoveEntryList(&(RemoveMe)->ListEntry); \
  719. VF_UNLOCK_LIST((LockedList), OldIrql); \
  720. }
  721. #define VF_REMOVE_FROM_LOCKED_LIST_DONT_LOCK(LockedList, RemoveMe) \
  722. RemoveEntryList(&(RemoveMe)->ListEntry);
  723. //
  724. // This is a bit of a hack so that reference counting for adapters will work.
  725. // If the device uses a dma channel, the HAL wants to keep it around.
  726. // There is a bit of funky logic that goes on to determine whether
  727. // a device uses an adapter channel so I've included it here, free of
  728. // charge.
  729. //
  730. #define VF_DOES_DEVICE_USE_DMA_CHANNEL(deviceDescription) \
  731. ( \
  732. ( (deviceDescription)->InterfaceType == Isa && \
  733. (deviceDescription)->DmaChannel < 8 ) || \
  734. ! (deviceDescription)->Master )
  735. #define VF_DOES_DEVICE_REQUIRE_CONTIGUOUS_BUFFERS(deviceDescription) \
  736. ( !(deviceDescription)->Master || ! (deviceDescription)->ScatterGather )
  737. #define DMA_OFFSET(DmaOperationsField) \
  738. FIELD_OFFSET(DMA_OPERATIONS, DmaOperationsField)
  739. #define DMA_INDEX(DmaOperations, Offset) \
  740. (PVOID) \
  741. *( (PVOID *) \
  742. ( ( (PUCHAR) (DmaOperations) ) + \
  743. (Offset) ) )
  744. #define SIGN_MAP_REGISTER_FILE(MapRegisterFile) \
  745. (MapRegisterFile)->Signature = MRF_SIGNATURE;
  746. #define VALIDATE_MAP_REGISTER_FILE_SIGNATURE(MapRegisterFile ) \
  747. ((MapRegisterFile) && (MapRegisterFile)->Signature == MRF_SIGNATURE )
  748. //
  749. // System dependent way to get the caller's address
  750. //
  751. #if defined(_X86_)
  752. #define GET_CALLING_ADDRESS(CallingAddress) \
  753. { \
  754. PVOID callersCaller; \
  755. RtlGetCallersAddress(&CallingAddress, &callersCaller); \
  756. }
  757. #else // ! defined(_X86_) //
  758. #define GET_CALLING_ADDRESS(CallingAddress) \
  759. CallingAddress = (PVOID)_ReturnAddress();
  760. #endif // ! defined(_X86_)
  761. //
  762. // From a map register file, map register number and the corresponding system address,
  763. // return the corresponding mapped address in system space.
  764. //
  765. #define MAP_REGISTER_SYSTEM_ADDRESS(MapRegisterFile, DriverCurrentSa, MapRegisterNumber) \
  766. (PUCHAR) (MapRegisterFile)->MapRegisterBuffer + \
  767. ( (MapRegisterNumber) << PAGE_SHIFT ) + \
  768. BYTE_OFFSET(DriverCurrentSa)
  769. //
  770. // From a map register file's OriginalBuffer, map register number and system address
  771. // returns the address in the original buffer. Used to do a 3-way merge between
  772. // the driver's buffer, verifier's buffer (passed to the hardware) and the original
  773. // buffer
  774. //
  775. #define ORIGINAL_BUFFER_SYSTEM_ADDRESS(MapRegisterFile, DriverCurrentSa, MapRegisterNumber) \
  776. (PUCHAR) (MapRegisterFile)->OriginalBuffer + \
  777. ( (MapRegisterNumber) << PAGE_SHIFT ) + \
  778. BYTE_OFFSET(DriverCurrentSa)
  779. //
  780. // From a map register file, map register number and the corresponding system address,
  781. // return the corresponding mapped address as an index into the map register file's
  782. // MDL (i.e virtual address).
  783. //
  784. #define MAP_REGISTER_VIRTUAL_ADDRESS(MapRegisterFile, DriverCurrentSa, MapRegisterNumber) \
  785. (PUCHAR) MmGetMdlVirtualAddress((MapRegisterFile)->MapRegisterMdl) + \
  786. ( (MapRegisterNumber) << PAGE_SHIFT ) + \
  787. BYTE_OFFSET(DriverCurrentSa)
  788. /////////////////////////////////////////////////////////////////////
  789. //////////////////////////// Hal verifier inline function definitions
  790. /////////////////////////////////////////////////////////////////////
  791. //
  792. // Since so many people don't raise the irql when they put the dma adapter,
  793. // just warn them.
  794. //
  795. __inline
  796. VOID
  797. VF_ASSERT_SPECIAL_IRQL(IN KIRQL Irql)
  798. {
  799. KIRQL currentIrql = KeGetCurrentIrql();
  800. VF_ASSERT(
  801. currentIrql == Irql,
  802. HV_BAD_IRQL_JUST_WARN,
  803. ("**** Bad IRQL -- needed %x, got %x ****",
  804. (ULONG) Irql, (ULONG) currentIrql)
  805. );
  806. } // VF_ASSERT_IRQL //
  807. __inline
  808. VOID
  809. VF_ASSERT_IRQL(IN KIRQL Irql)
  810. {
  811. KIRQL currentIrql = KeGetCurrentIrql();
  812. VF_ASSERT(
  813. currentIrql == Irql,
  814. HV_BAD_IRQL,
  815. ("**** Bad IRQL -- needed %x, got %x ****",
  816. (ULONG) Irql, (ULONG) currentIrql)
  817. );
  818. } // VF_ASSERT_IRQL //
  819. __inline
  820. VOID
  821. VF_ASSERT_MAX_IRQL(IN KIRQL MaxIrql)
  822. {
  823. KIRQL currentIrql = KeGetCurrentIrql();
  824. VF_ASSERT(
  825. currentIrql <= MaxIrql,
  826. HV_BAD_IRQL,
  827. ("**** Bad IRQL -- needed %x or less, got %x ****",
  828. (ULONG) MaxIrql, (ULONG) currentIrql)
  829. );
  830. }
  831. // =========================================
  832. // Inlined functions to help with accounting
  833. // =========================================
  834. __inline
  835. VOID
  836. ADD_MAP_REGISTERS(
  837. IN PADAPTER_INFORMATION AdapterInformation,
  838. IN ULONG NumberOfMapRegisters,
  839. IN BOOLEAN ScatterGather
  840. )
  841. {
  842. ULONG activeMapRegisters =
  843. InterlockedExchangeAdd(
  844. &AdapterInformation->ActiveMapRegisters,
  845. NumberOfMapRegisters
  846. ) + NumberOfMapRegisters;
  847. InterlockedExchangeAdd((PLONG)(&AdapterInformation->AllocatedMapRegisters),
  848. NumberOfMapRegisters);
  849. VF_ASSERT(
  850. NumberOfMapRegisters <= AdapterInformation->MaximumMapRegisters,
  851. HV_TOO_MANY_MAP_REGISTERS,
  852. ( "Allocating too many map registers at a time: %x (max %x)",
  853. NumberOfMapRegisters,
  854. AdapterInformation->MaximumMapRegisters )
  855. );
  856. if (! ScatterGather ) {
  857. VF_ASSERT(
  858. activeMapRegisters <= AdapterInformation->MaximumMapRegisters,
  859. HV_OUT_OF_MAP_REGISTERS,
  860. ( "Allocated too many map registers : %x (max %x)",
  861. activeMapRegisters,
  862. AdapterInformation->MaximumMapRegisters )
  863. );
  864. }
  865. } // ADD_MAP_REGISTERS //
  866. __inline
  867. VOID
  868. SUBTRACT_MAP_REGISTERS(
  869. IN PADAPTER_INFORMATION AdapterInformation,
  870. IN ULONG NumberOfMapRegisters
  871. )
  872. {
  873. LONG activeMapRegisters =
  874. InterlockedExchangeAdd(
  875. &AdapterInformation->ActiveMapRegisters,
  876. -((LONG) NumberOfMapRegisters)
  877. ) - NumberOfMapRegisters;
  878. VF_ASSERT(
  879. activeMapRegisters >= 0,
  880. HV_FREED_TOO_MANY_MAP_REGISTERS,
  881. ( "Freed too many map registers: %x",
  882. activeMapRegisters )
  883. );
  884. InterlockedExchange((PLONG)(&AdapterInformation->MappedTransferWithoutFlushing),
  885. 0);
  886. } // SUBTRACT_MAP_REGISTERS //
  887. __inline
  888. VOID
  889. INCREMENT_COMMON_BUFFERS(
  890. IN PADAPTER_INFORMATION AdapterInformation
  891. )
  892. {
  893. InterlockedIncrement((PLONG)(&AdapterInformation->AllocatedCommonBuffers) );
  894. } // INCREMENT_COMMON_BUFFERS //
  895. __inline
  896. VOID
  897. DECREMENT_COMMON_BUFFERS(
  898. IN PADAPTER_INFORMATION AdapterInformation
  899. )
  900. {
  901. ULONG commonBuffersFreed =
  902. (ULONG) InterlockedIncrement(
  903. (PLONG)(&AdapterInformation->FreedCommonBuffers) );
  904. VF_ASSERT(
  905. commonBuffersFreed <= AdapterInformation->AllocatedCommonBuffers,
  906. HV_FREED_TOO_MANY_COMMON_BUFFERS,
  907. ("Freed too many common buffers")
  908. );
  909. } // DECREMENT_COMMON_BUFFERS //
  910. __inline
  911. VOID
  912. INCREASE_MAPPED_TRANSFER_BYTE_COUNT(
  913. IN PADAPTER_INFORMATION AdapterInformation,
  914. IN ULONG Length
  915. )
  916. {
  917. ULONG mappedTransferCount;
  918. ULONG maxMappedTransfer;
  919. maxMappedTransfer = AdapterInformation->ActiveMapRegisters << PAGE_SHIFT;
  920. mappedTransferCount =
  921. InterlockedExchangeAdd(
  922. (PLONG)(&AdapterInformation->MappedTransferWithoutFlushing),
  923. (LONG) Length
  924. ) + Length;
  925. VF_ASSERT(
  926. mappedTransferCount <= maxMappedTransfer,
  927. HV_DID_NOT_FLUSH_ADAPTER_BUFFERS,
  928. ("Driver did not flush adapter buffers -- bytes mapped: %x (%x max)",
  929. mappedTransferCount,
  930. maxMappedTransfer
  931. ));
  932. } // INCREASE_MAPPED_TRANSFER_BYTE_COUNT //
  933. __inline
  934. VOID
  935. DECREASE_MAPPED_TRANSFER_BYTE_COUNT(
  936. IN PADAPTER_INFORMATION AdapterInformation,
  937. IN ULONG Length
  938. )
  939. {
  940. UNREFERENCED_PARAMETER (Length);
  941. InterlockedExchange(
  942. (PLONG)(&AdapterInformation->MappedTransferWithoutFlushing),
  943. 0);
  944. } // DECREASE_MAPPED_TRANSFER_BYTE_COUNT //
  945. __inline
  946. VOID
  947. INCREMENT_ADAPTER_CHANNELS(
  948. IN PADAPTER_INFORMATION AdapterInformation
  949. )
  950. {
  951. ULONG allocatedAdapterChannels = (ULONG)
  952. InterlockedIncrement(
  953. (PLONG)(&AdapterInformation->AllocatedAdapterChannels) );
  954. VF_ASSERT(
  955. allocatedAdapterChannels ==
  956. AdapterInformation->FreedAdapterChannels + 1,
  957. HV_TOO_MANY_ADAPTER_CHANNELS,
  958. ( "Driver has allocated too many simultaneous adapter channels"
  959. ));
  960. } // INCREMENT_ADAPTER_CHANNELS //
  961. __inline
  962. VOID
  963. DECREMENT_ADAPTER_CHANNELS(
  964. IN PADAPTER_INFORMATION AdapterInformation
  965. )
  966. {
  967. ULONG adapterChannelsFreed = (ULONG)
  968. InterlockedIncrement( (PLONG)(&AdapterInformation->FreedAdapterChannels) );
  969. VF_ASSERT(
  970. adapterChannelsFreed == AdapterInformation->AllocatedAdapterChannels,
  971. HV_FREED_TOO_MANY_ADAPTER_CHANNELS,
  972. ( "Driver has freed too many simultaneous adapter channels"
  973. ));
  974. } // DECREMENT_ADAPTER_CHANNELS //
  975. _inline
  976. VOID
  977. INCREMENT_SCATTER_GATHER_LISTS(
  978. IN PADAPTER_INFORMATION AdapterInformation
  979. )
  980. {
  981. InterlockedIncrement( (PLONG)(&AdapterInformation->AllocatedScatterGatherLists) );
  982. InterlockedIncrement( &AdapterInformation->ActiveScatterGatherLists);
  983. } // INCREMENT_SCATTER_GATHER_LISTS //
  984. __inline
  985. VOID
  986. DECREMENT_SCATTER_GATHER_LISTS (
  987. IN PADAPTER_INFORMATION AdapterInformation
  988. )
  989. {
  990. LONG activeScatterGatherLists = InterlockedDecrement(
  991. &AdapterInformation->ActiveScatterGatherLists );
  992. VF_ASSERT(
  993. activeScatterGatherLists >= 0,
  994. HV_FREED_TOO_MANY_SCATTER_GATHER_LISTS,
  995. ( "Driver has freed too many scatter gather lists %x allocated, %x freed",
  996. AdapterInformation->AllocatedScatterGatherLists,
  997. AdapterInformation->AllocatedScatterGatherLists -
  998. activeScatterGatherLists)
  999. );
  1000. } // DECREMENT_SCATTER_GATHER_LISTS //
  1001. __inline
  1002. VOID
  1003. VERIFY_BUFFER_LOCKED(
  1004. IN PMDL Mdl
  1005. )
  1006. {
  1007. VF_ASSERT(
  1008. MmAreMdlPagesLocked(Mdl),
  1009. HV_DMA_BUFFER_NOT_LOCKED,
  1010. ( "DMA Pages Not Locked! MDL %p for DMA not locked", Mdl)
  1011. );
  1012. } // VERIFY_BUFFER_LOCKED //
  1013. __inline
  1014. PHAL_VERIFIER_BUFFER
  1015. VF_FIND_BUFFER (
  1016. IN PHAL_VERIFIER_LOCKED_LIST LockedList,
  1017. IN PVOID AdvertisedStartAddress
  1018. )
  1019. {
  1020. PHAL_VERIFIER_BUFFER verifierBuffer;
  1021. KIRQL OldIrql;
  1022. VF_LOCK_LIST(LockedList, OldIrql);
  1023. FOR_ALL_IN_LIST(HAL_VERIFIER_BUFFER,
  1024. &LockedList->ListEntry,
  1025. verifierBuffer ) {
  1026. if ((PUCHAR) verifierBuffer->RealStartAddress +
  1027. verifierBuffer->PrePadBytes == AdvertisedStartAddress) {
  1028. VF_UNLOCK_LIST(LockedList, OldIrql);
  1029. return verifierBuffer;
  1030. }
  1031. }
  1032. VF_UNLOCK_LIST(LockedList, OldIrql);
  1033. return NULL;
  1034. } // VF_FIND_BUFFER //
  1035. __inline
  1036. PADAPTER_INFORMATION
  1037. VF_FIND_DEVICE_INFORMATION(
  1038. IN PDEVICE_OBJECT DeviceObject
  1039. )
  1040. {
  1041. PADAPTER_INFORMATION adapterInformation;
  1042. KIRQL OldIrql;
  1043. VF_LOCK_LIST(&ViAdapterList, OldIrql);
  1044. FOR_ALL_IN_LIST(ADAPTER_INFORMATION, &ViAdapterList.ListEntry, adapterInformation) {
  1045. if (adapterInformation->DeviceObject == DeviceObject) {
  1046. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1047. return adapterInformation;
  1048. }
  1049. }
  1050. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1051. return NULL;
  1052. } // VF_FIND_DEVICE_INFORMATION //
  1053. __inline
  1054. PADAPTER_INFORMATION
  1055. VF_FIND_INACTIVE_ADAPTER(
  1056. IN PDEVICE_OBJECT DeviceObject
  1057. )
  1058. {
  1059. PADAPTER_INFORMATION adapterInformation;
  1060. KIRQL OldIrql;
  1061. VF_LOCK_LIST(&ViAdapterList, OldIrql);
  1062. FOR_ALL_IN_LIST(ADAPTER_INFORMATION, &ViAdapterList.ListEntry, adapterInformation) {
  1063. if (adapterInformation->DeviceObject == DeviceObject &&
  1064. (adapterInformation->Inactive == TRUE ||
  1065. adapterInformation->DeferredRemove == TRUE)) {
  1066. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1067. return adapterInformation;
  1068. }
  1069. }
  1070. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1071. return NULL;
  1072. } // VF_FIND_INACTIVE_ADAPTER //
  1073. __inline
  1074. VOID
  1075. VF_MARK_FOR_DEFERRED_REMOVE(
  1076. IN PDEVICE_OBJECT DeviceObject
  1077. )
  1078. {
  1079. PADAPTER_INFORMATION adapterInformation;
  1080. KIRQL OldIrql;
  1081. VF_LOCK_LIST(&ViAdapterList, OldIrql);
  1082. FOR_ALL_IN_LIST(ADAPTER_INFORMATION, &ViAdapterList.ListEntry, adapterInformation) {
  1083. if (adapterInformation->DeviceObject == DeviceObject) {
  1084. adapterInformation->DeferredRemove = TRUE;
  1085. }
  1086. }
  1087. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1088. return ;
  1089. } // VF_MARK_FOR_DEFERRED_REMOVE //
  1090. __inline
  1091. VOID
  1092. VF_ASSERT_MAP_REGISTERS_CAN_BE_FREED(
  1093. IN PADAPTER_INFORMATION AdapterInformation,
  1094. IN PMAP_REGISTER_FILE MapRegisterFile
  1095. )
  1096. {
  1097. UNREFERENCED_PARAMETER (AdapterInformation);
  1098. VF_ASSERT(
  1099. MapRegisterFile->NumberOfRegistersMapped,
  1100. HV_CANNOT_FREE_MAP_REGISTERS,
  1101. ( "Cannot free map registers -- %x registers still mapped",
  1102. MapRegisterFile->NumberOfMapRegisters)
  1103. );
  1104. } // VF_ASSERT_MAP_REGISTERS_CAN_BE_FREED