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.

430 lines
8.9 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. pnpirq.c
  5. Abstract:
  6. Root IRQ 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. IopIrqInitialize(
  22. VOID
  23. );
  24. NTSTATUS
  25. IopIrqUnpackRequirement(
  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. IopIrqPackResource(
  34. IN PIO_RESOURCE_DESCRIPTOR Requirement,
  35. IN ULONGLONG Start,
  36. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  37. );
  38. LONG
  39. IopIrqScoreRequirement(
  40. IN PIO_RESOURCE_DESCRIPTOR Descriptor
  41. );
  42. NTSTATUS
  43. IopIrqUnpackResource(
  44. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
  45. OUT PULONGLONG Start,
  46. OUT PULONG Length
  47. );
  48. NTSTATUS
  49. IopIrqTranslateOrdering(
  50. OUT PIO_RESOURCE_DESCRIPTOR Target,
  51. IN PIO_RESOURCE_DESCRIPTOR Source
  52. );
  53. BOOLEAN
  54. IopIrqFindSuitableRange(
  55. PARBITER_INSTANCE Arbiter,
  56. PARBITER_ALLOCATION_STATE State
  57. );
  58. //
  59. // Make everything pageable
  60. //
  61. #ifdef ALLOC_PRAGMA
  62. #pragma alloc_text(PAGE, IopIrqInitialize)
  63. #pragma alloc_text(PAGE, IopIrqUnpackRequirement)
  64. #pragma alloc_text(PAGE, IopIrqPackResource)
  65. #pragma alloc_text(PAGE, IopIrqScoreRequirement)
  66. #pragma alloc_text(PAGE, IopIrqUnpackResource)
  67. #pragma alloc_text(PAGE, IopIrqTranslateOrdering)
  68. #pragma alloc_text(PAGE, IopIrqFindSuitableRange)
  69. #endif // ALLOC_PRAGMA
  70. //
  71. // Implementation
  72. //
  73. #if !defined(NO_LEGACY_DRIVERS)
  74. NTSTATUS
  75. IopIrqTranslateOrdering(
  76. OUT PIO_RESOURCE_DESCRIPTOR Target,
  77. IN PIO_RESOURCE_DESCRIPTOR Source
  78. )
  79. /*
  80. Routine Description:
  81. This routine is called during arbiter initialization to translate the
  82. orderings.
  83. Parameters:
  84. Target - Place to put the translated descriptor
  85. Source - Descriptor to translate
  86. Return Value:
  87. Status code
  88. */
  89. {
  90. KIRQL level;
  91. KAFFINITY affinity;
  92. PAGED_CODE();
  93. //
  94. // Copy the source to the target
  95. //
  96. *Target = *Source;
  97. if (Source->Type != CmResourceTypeInterrupt) {
  98. return STATUS_SUCCESS;
  99. }
  100. //
  101. // Translate the vector
  102. //
  103. ARB_PRINT(
  104. 2,
  105. ("Translating Vector 0x%x-0x%x =>",
  106. Source->u.Interrupt.MinimumVector,
  107. Source->u.Interrupt.MaximumVector
  108. ));
  109. Target->u.Interrupt.MinimumVector =
  110. HalGetInterruptVector(Isa,
  111. 0,
  112. Source->u.Interrupt.MinimumVector,
  113. Source->u.Interrupt.MinimumVector,
  114. &level,
  115. &affinity
  116. );
  117. if (affinity == 0) {
  118. ARB_PRINT(2,("Translation failed\n"));
  119. *Target = *Source;
  120. return STATUS_SUCCESS;
  121. }
  122. Target->u.Interrupt.MaximumVector =
  123. HalGetInterruptVector(Isa,
  124. 0,
  125. Source->u.Interrupt.MaximumVector,
  126. Source->u.Interrupt.MaximumVector,
  127. &level,
  128. &affinity
  129. );
  130. if (affinity == 0) {
  131. ARB_PRINT(2,("Translation failed\n"));
  132. *Target = *Source;
  133. return STATUS_SUCCESS;
  134. }
  135. ARB_PRINT(
  136. 2,
  137. ("0x%x-0x%x\n",
  138. Target->u.Interrupt.MinimumVector,
  139. Target->u.Interrupt.MaximumVector
  140. ));
  141. return STATUS_SUCCESS;
  142. }
  143. #endif // NO_LEGACY_DRIVERS
  144. NTSTATUS
  145. IopIrqInitialize(
  146. VOID
  147. )
  148. /*++
  149. Routine Description:
  150. This routine initializes the arbiter
  151. Parameters:
  152. None
  153. Return Value:
  154. None
  155. --*/
  156. {
  157. IopRootIrqArbiter.UnpackRequirement = IopIrqUnpackRequirement;
  158. IopRootIrqArbiter.PackResource = IopIrqPackResource;
  159. IopRootIrqArbiter.UnpackResource = IopIrqUnpackResource;
  160. IopRootIrqArbiter.ScoreRequirement = IopIrqScoreRequirement;
  161. return ArbInitializeArbiterInstance(&IopRootIrqArbiter,
  162. NULL, // Indicates ROOT arbiter
  163. CmResourceTypeInterrupt,
  164. L"RootIRQ",
  165. L"Root",
  166. #if defined(NO_LEGACY_DRIVERS)
  167. NULL
  168. #else
  169. IopIrqTranslateOrdering
  170. #endif // NO_LEGACY_DRIVERS
  171. );
  172. }
  173. //
  174. // Arbiter callbacks
  175. //
  176. NTSTATUS
  177. IopIrqUnpackRequirement(
  178. IN PIO_RESOURCE_DESCRIPTOR Descriptor,
  179. OUT PULONGLONG Minimum,
  180. OUT PULONGLONG Maximum,
  181. OUT PULONG Length,
  182. OUT PULONG Alignment
  183. )
  184. /*++
  185. Routine Description:
  186. This routine unpacks an resource requirement descriptor.
  187. Arguments:
  188. Descriptor - The descriptor describing the requirement to unpack.
  189. Minimum - Pointer to where the minimum acceptable start value should be
  190. unpacked to.
  191. Maximum - Pointer to where the maximum acceptable end value should be
  192. unpacked to.
  193. Length - Pointer to where the required length should be unpacked to.
  194. Minimum - Pointer to where the required alignment should be unpacked to.
  195. Return Value:
  196. Returns the status of this operation.
  197. --*/
  198. {
  199. ASSERT(Descriptor);
  200. ASSERT(Descriptor->Type == CmResourceTypeInterrupt);
  201. ARB_PRINT(2,
  202. ("Unpacking IRQ requirement %p => 0x%I64x-0x%I64x\n",
  203. Descriptor,
  204. (ULONGLONG) Descriptor->u.Interrupt.MinimumVector,
  205. (ULONGLONG) Descriptor->u.Interrupt.MaximumVector
  206. ));
  207. *Minimum = (ULONGLONG) Descriptor->u.Interrupt.MinimumVector;
  208. *Maximum = (ULONGLONG) Descriptor->u.Interrupt.MaximumVector;
  209. *Length = 1;
  210. *Alignment = 1;
  211. return STATUS_SUCCESS;
  212. }
  213. LONG
  214. IopIrqScoreRequirement(
  215. IN PIO_RESOURCE_DESCRIPTOR Descriptor
  216. )
  217. /*++
  218. Routine Description:
  219. This routine scores a requirement based on how flexible it is. The least
  220. flexible devices are scored the least and so when the arbitration list is
  221. sorted we try to allocate their resources first.
  222. Arguments:
  223. Descriptor - The descriptor describing the requirement to score.
  224. Return Value:
  225. The score.
  226. --*/
  227. {
  228. LONG score;
  229. ASSERT(Descriptor);
  230. ASSERT(Descriptor->Type == CmResourceTypeInterrupt);
  231. score = Descriptor->u.Interrupt.MaximumVector -
  232. Descriptor->u.Interrupt.MinimumVector + 1;
  233. ARB_PRINT(2,
  234. ("Scoring IRQ resource %p => %i\n",
  235. Descriptor,
  236. score
  237. ));
  238. return score;
  239. }
  240. NTSTATUS
  241. IopIrqPackResource(
  242. IN PIO_RESOURCE_DESCRIPTOR Requirement,
  243. IN ULONGLONG Start,
  244. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  245. )
  246. /*++
  247. Routine Description:
  248. This routine packs an resource descriptor.
  249. Arguments:
  250. Requirement - The requirement from which this resource was chosen.
  251. Start - The start value of the resource.
  252. Descriptor - Pointer to the descriptor to pack into.
  253. Return Value:
  254. Returns the status of this operation.
  255. --*/
  256. {
  257. ASSERT(Descriptor);
  258. ASSERT(Start < ((ULONG)-1));
  259. ASSERT(Requirement);
  260. ASSERT(Requirement->Type == CmResourceTypeInterrupt);
  261. ARB_PRINT(2,
  262. ("Packing IRQ resource %p => 0x%I64x\n",
  263. Descriptor,
  264. Start
  265. ));
  266. Descriptor->Type = CmResourceTypeInterrupt;
  267. Descriptor->Flags = Requirement->Flags;
  268. Descriptor->ShareDisposition = Requirement->ShareDisposition;
  269. Descriptor->u.Interrupt.Vector = (ULONG) Start;
  270. Descriptor->u.Interrupt.Level = (ULONG) Start;
  271. Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
  272. return STATUS_SUCCESS;
  273. }
  274. NTSTATUS
  275. IopIrqUnpackResource(
  276. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
  277. OUT PULONGLONG Start,
  278. OUT PULONG Length
  279. )
  280. /*++
  281. Routine Description:
  282. This routine unpacks an resource descriptor.
  283. Arguments:
  284. Descriptor - The descriptor describing the requirement to unpack.
  285. Start - Pointer to where the start value should be unpacked to.
  286. End - Pointer to where the end value should be unpacked to.
  287. Return Value:
  288. Returns the status of this operation.
  289. --*/
  290. {
  291. ASSERT(Descriptor);
  292. ASSERT(Descriptor->Type == CmResourceTypeInterrupt);
  293. *Start = Descriptor->u.Interrupt.Vector;
  294. *Length = 1;
  295. ARB_PRINT(2,
  296. ("Unpacking IRQ resource %p => 0x%I64x\n",
  297. Descriptor,
  298. *Start
  299. ));
  300. return STATUS_SUCCESS;
  301. }