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.

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