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.

355 lines
6.8 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. pnpdma.c
  5. Abstract:
  6. Root DMA arbiter
  7. Author:
  8. Andy Thornton (andrewth) 04/17/97
  9. Revision History:
  10. --*/
  11. #include "pnpmgrp.h"
  12. #pragma hdrstop
  13. //
  14. // Constants
  15. //
  16. #define MAX_ULONGLONG ((ULONGLONG) -1)
  17. //
  18. // Prototypes
  19. //
  20. NTSTATUS
  21. IopDmaInitialize(
  22. VOID
  23. );
  24. NTSTATUS
  25. IopDmaUnpackRequirement(
  26. IN PIO_RESOURCE_DESCRIPTOR Descriptor,
  27. OUT PULONGLONG Minimum,
  28. OUT PULONGLONG Maximum,
  29. OUT PULONG Length,
  30. OUT PULONG Alignment
  31. );
  32. NTSTATUS
  33. IopDmaPackResource(
  34. IN PIO_RESOURCE_DESCRIPTOR Requirement,
  35. IN ULONGLONG Start,
  36. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  37. );
  38. LONG
  39. IopDmaScoreRequirement(
  40. IN PIO_RESOURCE_DESCRIPTOR Descriptor
  41. );
  42. NTSTATUS
  43. IopDmaUnpackResource(
  44. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
  45. OUT PULONGLONG Start,
  46. OUT PULONG Length
  47. );
  48. BOOLEAN
  49. IopDmaOverrideConflict(
  50. IN PARBITER_INSTANCE Arbiter,
  51. IN PARBITER_ALLOCATION_STATE State
  52. );
  53. //
  54. // Make everything pageable
  55. //
  56. #ifdef ALLOC_PRAGMA
  57. #pragma alloc_text(PAGE, IopDmaInitialize)
  58. #pragma alloc_text(PAGE, IopDmaUnpackRequirement)
  59. #pragma alloc_text(PAGE, IopDmaPackResource)
  60. #pragma alloc_text(PAGE, IopDmaScoreRequirement)
  61. #pragma alloc_text(PAGE, IopDmaUnpackResource)
  62. #pragma alloc_text(PAGE, IopDmaOverrideConflict)
  63. #endif // ALLOC_PRAGMA
  64. //
  65. // Implementation
  66. //
  67. NTSTATUS
  68. IopDmaInitialize(
  69. VOID
  70. )
  71. /*++
  72. Routine Description:
  73. This routine initializes the arbiter
  74. Parameters:
  75. None
  76. Return Value:
  77. None
  78. --*/
  79. {
  80. IopRootDmaArbiter.UnpackRequirement = IopDmaUnpackRequirement;
  81. IopRootDmaArbiter.PackResource = IopDmaPackResource;
  82. IopRootDmaArbiter.UnpackResource = IopDmaUnpackResource;
  83. IopRootDmaArbiter.ScoreRequirement = IopDmaScoreRequirement;
  84. IopRootDmaArbiter.OverrideConflict = IopDmaOverrideConflict;
  85. return ArbInitializeArbiterInstance(&IopRootDmaArbiter,
  86. NULL,
  87. CmResourceTypeDma,
  88. L"RootDMA",
  89. L"Root",
  90. NULL // no translation of DMA
  91. );
  92. }
  93. //
  94. // Arbiter callbacks
  95. //
  96. NTSTATUS
  97. IopDmaUnpackRequirement(
  98. IN PIO_RESOURCE_DESCRIPTOR Descriptor,
  99. OUT PULONGLONG Minimum,
  100. OUT PULONGLONG Maximum,
  101. OUT PULONG Length,
  102. OUT PULONG Alignment
  103. )
  104. /*++
  105. Routine Description:
  106. This routine unpacks an resource requirement descriptor.
  107. Arguments:
  108. Descriptor - The descriptor describing the requirement to unpack.
  109. Minimum - Pointer to where the minimum acceptable start value should be
  110. unpacked to.
  111. Maximum - Pointer to where the maximum acceptable end value should be
  112. unpacked to.
  113. Length - Pointer to where the required length should be unpacked to.
  114. Minimum - Pointer to where the required alignment should be unpacked to.
  115. Return Value:
  116. Returns the status of this operation.
  117. --*/
  118. {
  119. ASSERT(Descriptor);
  120. ASSERT(Descriptor->Type == CmResourceTypeDma);
  121. ARB_PRINT(2,
  122. ("Unpacking DMA requirement %p => 0x%I64x-0x%I64x\n",
  123. Descriptor,
  124. (ULONGLONG) Descriptor->u.Dma.MinimumChannel,
  125. (ULONGLONG) Descriptor->u.Dma.MaximumChannel
  126. ));
  127. *Minimum = (ULONGLONG) Descriptor->u.Dma.MinimumChannel;
  128. *Maximum = (ULONGLONG) Descriptor->u.Dma.MaximumChannel;
  129. *Length = 1;
  130. *Alignment = 1;
  131. return STATUS_SUCCESS;
  132. }
  133. LONG
  134. IopDmaScoreRequirement(
  135. IN PIO_RESOURCE_DESCRIPTOR Descriptor
  136. )
  137. /*++
  138. Routine Description:
  139. This routine scores a requirement based on how flexible it is. The least
  140. flexible devices are scored the least and so when the arbitration list is
  141. sorted we try to allocate their resources first.
  142. Arguments:
  143. Descriptor - The descriptor describing the requirement to score.
  144. Return Value:
  145. The score.
  146. --*/
  147. {
  148. LONG score;
  149. ASSERT(Descriptor);
  150. ASSERT(Descriptor->Type == CmResourceTypeDma);
  151. score = Descriptor->u.Dma.MaximumChannel - Descriptor->u.Dma.MinimumChannel;
  152. ARB_PRINT(2,
  153. ("Scoring DMA resource %p => %i\n",
  154. Descriptor,
  155. score
  156. ));
  157. return score;
  158. }
  159. NTSTATUS
  160. IopDmaPackResource(
  161. IN PIO_RESOURCE_DESCRIPTOR Requirement,
  162. IN ULONGLONG Start,
  163. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  164. )
  165. /*++
  166. Routine Description:
  167. This routine packs an resource descriptor.
  168. Arguments:
  169. Requirement - The requirement from which this resource was chosen.
  170. Start - The start value of the resource.
  171. Descriptor - Pointer to the descriptor to pack into.
  172. Return Value:
  173. Returns the status of this operation.
  174. --*/
  175. {
  176. ASSERT(Descriptor);
  177. ASSERT(Start < ((ULONG)-1));
  178. ASSERT(Requirement);
  179. ASSERT(Requirement->Type == CmResourceTypeDma);
  180. ARB_PRINT(2,
  181. ("Packing DMA resource %p => 0x%I64x\n",
  182. Descriptor,
  183. Start
  184. ));
  185. Descriptor->Type = CmResourceTypeDma;
  186. Descriptor->ShareDisposition = Requirement->ShareDisposition;
  187. Descriptor->Flags = Requirement->Flags;
  188. Descriptor->u.Dma.Channel = (ULONG) Start;
  189. Descriptor->u.Dma.Port = 0;
  190. return STATUS_SUCCESS;
  191. }
  192. NTSTATUS
  193. IopDmaUnpackResource(
  194. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
  195. OUT PULONGLONG Start,
  196. OUT PULONG Length
  197. )
  198. /*++
  199. Routine Description:
  200. This routine unpacks an resource descriptor.
  201. Arguments:
  202. Descriptor - The descriptor describing the resource to unpack.
  203. Start - Pointer to where the start value should be unpacked to.
  204. Length - Pointer to where the length value should be unpacked to.
  205. Return Value:
  206. Returns the status of this operation.
  207. --*/
  208. {
  209. *Start = Descriptor->u.Dma.Channel;
  210. *Length = 1;
  211. ARB_PRINT(2,
  212. ("Unpacking DMA resource %p => 0x%I64x\n",
  213. Descriptor,
  214. *Start
  215. ));
  216. return STATUS_SUCCESS;
  217. }
  218. BOOLEAN
  219. IopDmaOverrideConflict(
  220. IN PARBITER_INSTANCE Arbiter,
  221. IN PARBITER_ALLOCATION_STATE State
  222. )
  223. /*++
  224. Routine Description:
  225. Just say no.
  226. Arguments:
  227. Arbiter - The instance data of the arbiter who was called.
  228. State - The state of the current arbitration.
  229. Return Value:
  230. TRUE if the conflict is allowable, false otherwise
  231. --*/
  232. {
  233. UNREFERENCED_PARAMETER( Arbiter );
  234. UNREFERENCED_PARAMETER( State );
  235. PAGED_CODE();
  236. return FALSE;
  237. }