Source code of Windows XP (NT5)
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
9.3 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. translate.c
  5. Abstract:
  6. This is the default pnp IRQ translator.
  7. Author:
  8. Andy Thornton (andrewth) 7-June-97
  9. Environment:
  10. Kernel Mode Driver.
  11. Notes:
  12. This should only be temporary and will be replaced by a call into the HAL
  13. to retrieve its translators.
  14. Revision History:
  15. --*/
  16. #include "ntos.h"
  17. #include "haldisp.h"
  18. #include <wdmguid.h>
  19. //
  20. // Iteration macros
  21. //
  22. //
  23. // Control macro (used like a for loop) which iterates over all entries in
  24. // a standard doubly linked list. Head is the list head and the entries are of
  25. // type Type. A member called ListEntry is assumed to be the LIST_ENTRY
  26. // structure linking the entries together. Current contains a pointer to each
  27. // entry in turn.
  28. //
  29. #define FOR_ALL_IN_LIST(Type, Head, Current) \
  30. for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \
  31. (Head) != &(Current)->ListEntry; \
  32. (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  33. Type, \
  34. ListEntry) \
  35. )
  36. //
  37. // Similar to the above only iteration is over an array of length _Size.
  38. //
  39. #define FOR_ALL_IN_ARRAY(_Array, _Size, _Current) \
  40. for ( (_Current) = (_Array); \
  41. (_Current) < (_Array) + (_Size); \
  42. (_Current)++ )
  43. //
  44. // As above only iteration begins with the entry _Current
  45. //
  46. #define FOR_REST_IN_ARRAY(_Array, _Size, _Current) \
  47. for ( ; \
  48. (_Current) < (_Array) + (_Size); \
  49. (_Current)++ )
  50. #define HAL_IRQ_TRANSLATOR_VERSION 0
  51. NTSTATUS
  52. FstubTranslateResource(
  53. IN PVOID Context,
  54. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  55. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  56. IN ULONG AlternativesCount OPTIONAL,
  57. IN IO_RESOURCE_DESCRIPTOR Alternatives[] OPTIONAL,
  58. IN PDEVICE_OBJECT PhysicalDeviceObject,
  59. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  60. );
  61. NTSTATUS
  62. FstubTranslateRequirement (
  63. IN PVOID Context,
  64. IN PIO_RESOURCE_DESCRIPTOR Source,
  65. IN PDEVICE_OBJECT PhysicalDeviceObject,
  66. OUT PULONG TargetCount,
  67. OUT PIO_RESOURCE_DESCRIPTOR *Target
  68. );
  69. VOID
  70. FstubTranslatorNull(
  71. IN PVOID Context
  72. );
  73. #ifdef ALLOC_PRAGMA
  74. #pragma alloc_text(PAGE,xHalGetInterruptTranslator)
  75. #pragma alloc_text(PAGE,FstubTranslateResource)
  76. #pragma alloc_text(PAGE,FstubTranslateRequirement)
  77. #pragma alloc_text(PAGE,FstubTranslatorNull)
  78. #endif
  79. NTSTATUS
  80. xHalGetInterruptTranslator(
  81. IN INTERFACE_TYPE ParentInterfaceType,
  82. IN ULONG ParentBusNumber,
  83. IN INTERFACE_TYPE BridgeInterfaceType,
  84. IN USHORT Size,
  85. IN USHORT Version,
  86. OUT PTRANSLATOR_INTERFACE Translator,
  87. OUT PULONG BridgeBusNumber
  88. )
  89. /*++
  90. Routine Description:
  91. Arguments:
  92. ParentInterfaceType - The type of the bus the bridge lives on (normally PCI).
  93. ParentBusNumber - The number of the bus the bridge lives on.
  94. ParentSlotNumber - The slot number the bridge lives in (where valid).
  95. BridgeInterfaceType - The bus type the bridge provides (ie ISA for a PCI-ISA bridge).
  96. ResourceType - The resource type we want to translate.
  97. Size - The size of the translator buffer.
  98. Version - The version of the translator interface requested.
  99. Translator - Pointer to the buffer where the translator should be returned
  100. BridgeBusNumber - Pointer to where the bus number of the bridge bus should be returned
  101. Return Value:
  102. Returns the status of this operation.
  103. --*/
  104. {
  105. PAGED_CODE();
  106. #if defined(NO_LEGACY_DRIVERS)
  107. return STATUS_SUCCESS;
  108. }
  109. #else
  110. UNREFERENCED_PARAMETER(ParentInterfaceType);
  111. UNREFERENCED_PARAMETER(ParentBusNumber);
  112. ASSERT(Version == HAL_IRQ_TRANSLATOR_VERSION);
  113. ASSERT(Size >= sizeof (TRANSLATOR_INTERFACE));
  114. switch (BridgeInterfaceType) {
  115. case Eisa:
  116. case Isa:
  117. case MicroChannel:
  118. case InterfaceTypeUndefined: // special "IDE" cookie
  119. //
  120. // Pass back an interface for an IRQ translator.
  121. //
  122. RtlZeroMemory(Translator, sizeof (TRANSLATOR_INTERFACE));
  123. Translator->Size = sizeof (TRANSLATOR_INTERFACE);
  124. Translator->Version = HAL_IRQ_TRANSLATOR_VERSION;
  125. Translator->InterfaceReference = &FstubTranslatorNull;
  126. Translator->InterfaceDereference = &FstubTranslatorNull;
  127. Translator->TranslateResources = &FstubTranslateResource;
  128. Translator->TranslateResourceRequirements = &FstubTranslateRequirement;
  129. if (BridgeInterfaceType == InterfaceTypeUndefined) {
  130. Translator->Context = (PVOID)Isa;
  131. } else {
  132. Translator->Context = (PVOID)BridgeInterfaceType;
  133. }
  134. return STATUS_SUCCESS;
  135. default:
  136. return STATUS_NOT_IMPLEMENTED;
  137. }
  138. }
  139. NTSTATUS
  140. FstubTranslateResource(
  141. IN PVOID Context,
  142. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
  143. IN RESOURCE_TRANSLATION_DIRECTION Direction,
  144. IN ULONG AlternativesCount OPTIONAL,
  145. IN IO_RESOURCE_DESCRIPTOR Alternatives[] OPTIONAL,
  146. IN PDEVICE_OBJECT PhysicalDeviceObject,
  147. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target
  148. )
  149. {
  150. NTSTATUS status;
  151. ULONG affinity, currentVector, translatedVector;
  152. KIRQL irql;
  153. PIO_RESOURCE_DESCRIPTOR currentAlternative;
  154. PAGED_CODE();
  155. ASSERT(Source->Type == CmResourceTypeInterrupt);
  156. //
  157. // Copy unchanged fields
  158. //
  159. *Target = *Source;
  160. switch (Direction) {
  161. case TranslateChildToParent:
  162. //
  163. // Perform the translation - The interrupt source is
  164. // ISA.
  165. //
  166. Target->u.Interrupt.Vector = HalGetInterruptVector(
  167. (INTERFACE_TYPE)(ULONG_PTR)Context,
  168. 0, // assume bus 0
  169. Source->u.Interrupt.Vector,
  170. Source->u.Interrupt.Vector,
  171. &irql,
  172. &affinity
  173. );
  174. Target->u.Interrupt.Level = irql;
  175. Target->u.Interrupt.Affinity = affinity;
  176. status = STATUS_TRANSLATION_COMPLETE;
  177. break;
  178. case TranslateParentToChild:
  179. //
  180. // Translate each alternative and when we match then use the value we
  181. // just translated
  182. //
  183. FOR_ALL_IN_ARRAY(Alternatives, AlternativesCount, currentAlternative) {
  184. ASSERT(currentAlternative->Type == CmResourceTypeInterrupt);
  185. currentVector = currentAlternative->u.Interrupt.MinimumVector;
  186. while (currentVector <=
  187. currentAlternative->u.Interrupt.MaximumVector) {
  188. translatedVector = HalGetInterruptVector((INTERFACE_TYPE)(ULONG_PTR)Context,
  189. 0, // assume bus 0
  190. currentVector,
  191. currentVector,
  192. &irql,
  193. &affinity
  194. );
  195. if (translatedVector == Source->u.Interrupt.Vector) {
  196. //
  197. // We found our vector - fill in the target and return
  198. //
  199. Target->u.Interrupt.Vector = currentVector;
  200. Target->u.Interrupt.Level = Target->u.Interrupt.Vector;
  201. Target->u.Interrupt.Affinity = 0xFFFFFFFF;
  202. return STATUS_SUCCESS;
  203. }
  204. currentVector++;
  205. }
  206. }
  207. status = STATUS_UNSUCCESSFUL;
  208. break;
  209. }
  210. return status;
  211. }
  212. NTSTATUS
  213. FstubTranslateRequirement (
  214. IN PVOID Context,
  215. IN PIO_RESOURCE_DESCRIPTOR Source,
  216. IN PDEVICE_OBJECT PhysicalDeviceObject,
  217. OUT PULONG TargetCount,
  218. OUT PIO_RESOURCE_DESCRIPTOR *Target
  219. )
  220. {
  221. ULONG affinity;
  222. KIRQL irql;
  223. PAGED_CODE();
  224. ASSERT(Source->Type == CmResourceTypeInterrupt);
  225. *Target = ExAllocatePoolWithTag(PagedPool,
  226. sizeof(IO_RESOURCE_DESCRIPTOR),
  227. 'btsF'
  228. );
  229. if (!*Target) {
  230. return STATUS_INSUFFICIENT_RESOURCES;
  231. }
  232. *TargetCount = 1;
  233. //
  234. // Copy unchanged fields
  235. //
  236. **Target = *Source;
  237. (*Target)->u.Interrupt.MinimumVector =
  238. HalGetInterruptVector(
  239. (INTERFACE_TYPE)(ULONG_PTR)Context,
  240. 0, // assume bus 0
  241. Source->u.Interrupt.MinimumVector,
  242. Source->u.Interrupt.MinimumVector,
  243. &irql,
  244. &affinity
  245. );
  246. (*Target)->u.Interrupt.MaximumVector =
  247. HalGetInterruptVector(
  248. (INTERFACE_TYPE)(ULONG_PTR)Context,
  249. 0, // assume bus 0
  250. Source->u.Interrupt.MaximumVector,
  251. Source->u.Interrupt.MaximumVector,
  252. &irql,
  253. &affinity
  254. );
  255. return STATUS_TRANSLATION_COMPLETE;
  256. }
  257. VOID
  258. FstubTranslatorNull(
  259. IN PVOID Context
  260. )
  261. {
  262. PAGED_CODE();
  263. return;
  264. }
  265. #endif // NO_LEGACY_DRIVERS