[NDK]
[reactos.git] / reactos / ntoskrnl / fstub / translate.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/fstub/translate.c
5 * PURPOSE: Interrupt Translator Routines
6 * PROGRAMMERS: Pierre Schweitzer (pierre.schweitzer@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* PRIVATE FUNCTIONS *********************************************************/
16
17 /*
18 * @implemented
19 */
20 VOID
21 NTAPI
22 FstubTranslatorNull(PVOID Context)
23 {
24 PAGED_CODE();
25
26 /* Do nothing */
27 return;
28 }
29
30 /*
31 * @implemented
32 */
33 NTSTATUS
34 NTAPI
35 FstubTranslateResource(IN OUT PVOID Context OPTIONAL,
36 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source,
37 IN RESOURCE_TRANSLATION_DIRECTION Direction,
38 IN ULONG AlternativesCount OPTIONAL,
39 IN IO_RESOURCE_DESCRIPTOR Alternatives[],
40 IN PDEVICE_OBJECT PhysicalDeviceObject,
41 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target)
42 {
43 INT k;
44 KIRQL Irql;
45 KAFFINITY Affinity;
46 ULONG MinimumVector, Vector;
47 PIO_RESOURCE_DESCRIPTOR Alternative;
48 NTSTATUS Status = STATUS_UNSUCCESSFUL;
49 PAGED_CODE();
50
51 ASSERT(Source->Type == CmResourceTypeInterrupt);
52
53 /* Copy common information */
54 Target->Type = Source->Type;
55 Target->ShareDisposition = Source->ShareDisposition;
56 Target->Flags = Source->Flags;
57
58 if (Direction == TranslateChildToParent)
59 {
60 /* Get IRQL, affinity & system vector for the device vector */
61 Target->u.Interrupt.Vector = HalGetInterruptVector((INTERFACE_TYPE)Context, 0,
62 Source->u.Interrupt.Vector,
63 Source->u.Interrupt.Vector,
64 &Irql, &Affinity);
65 Target->u.Interrupt.Level = Irql;
66 Target->u.Interrupt.Affinity = Affinity;
67 Status = STATUS_TRANSLATION_COMPLETE;
68 }
69 else if (Direction == TranslateParentToChild)
70 {
71 /* Browse all the resources */
72 for (k = 0; k < AlternativesCount; k++)
73 {
74 Alternative = &(Alternatives[k]);
75
76 ASSERT(Alternative->Type == CmResourceTypeInterrupt);
77
78 /* Try to find the device vector, proceeding by trial & error
79 * We try a vector, and translate it
80 */
81 MinimumVector = Alternative->u.Interrupt.MinimumVector;
82 while (MinimumVector <= Alternative->u.Interrupt.MaximumVector)
83 {
84 /* Translate the vector */
85 Vector = HalGetInterruptVector((INTERFACE_TYPE)Context, 0,
86 MinimumVector,
87 MinimumVector,
88 &Irql, &Affinity);
89
90 /* If the translated vector is matching the given translated vector */
91 if (Vector == Source->u.Interrupt.Vector)
92 {
93 /* We are done, send back device vector */
94 Target->u.Interrupt.Affinity = -1;
95 Target->u.Interrupt.Vector = MinimumVector;
96 Target->u.Interrupt.Level = MinimumVector;
97
98 return STATUS_SUCCESS;
99 }
100
101 MinimumVector++;
102 }
103 }
104 }
105
106 return Status;
107 }
108
109 /*
110 * @implemented
111 */
112 NTSTATUS
113 NTAPI
114 FstubTranslateRequirement(IN OUT PVOID Context OPTIONAL,
115 IN PIO_RESOURCE_DESCRIPTOR Source,
116 IN PDEVICE_OBJECT PhysicalDeviceObject,
117 OUT PULONG TargetCount,
118 OUT PIO_RESOURCE_DESCRIPTOR *Target)
119 {
120 KIRQL Irql;
121 KAFFINITY Affinity;
122 PAGED_CODE();
123
124 ASSERT(Source->Type == CmResourceTypeInterrupt);
125
126 /* Allocate output buffer */
127 *Target = ExAllocatePoolWithTag(PagedPool, sizeof(IO_RESOURCE_DESCRIPTOR), 'btsF');
128 if (!*Target)
129 {
130 return STATUS_INSUFFICIENT_RESOURCES;
131 }
132
133 /* Zero & set out count to 1 */
134 RtlZeroMemory(*Target, sizeof(IO_RESOURCE_DESCRIPTOR));
135 *TargetCount = 1;
136
137 /* Translate minimum interrupt vector */
138 (*Target)->u.Interrupt.MinimumVector = HalGetInterruptVector((INTERFACE_TYPE)Context, 0,
139 Source->u.Interrupt.MinimumVector,
140 Source->u.Interrupt.MinimumVector,
141 &Irql, &Affinity);
142
143 /* Translate maximum interrupt vector */
144 (*Target)->u.Interrupt.MaximumVector = HalGetInterruptVector((INTERFACE_TYPE)Context, 0,
145 Source->u.Interrupt.MaximumVector,
146 Source->u.Interrupt.MaximumVector,
147 &Irql, &Affinity);
148
149 return STATUS_TRANSLATION_COMPLETE;
150 }
151
152 /*
153 * @implemented
154 */
155 NTSTATUS
156 NTAPI
157 xHalGetInterruptTranslator(IN INTERFACE_TYPE ParentInterfaceType,
158 IN ULONG ParentBusNumber,
159 IN INTERFACE_TYPE BridgeInterfaceType,
160 IN USHORT Size,
161 IN USHORT Version,
162 OUT PTRANSLATOR_INTERFACE Translator,
163 OUT PULONG BridgeBusNumber)
164 {
165 PAGED_CODE();
166
167 ASSERT(Version == HAL_IRQ_TRANSLATOR_VERSION);
168 ASSERT(Size >= sizeof(TRANSLATOR_INTERFACE));
169
170 /* Only (E)ISA interfaces are supported */
171 if (BridgeInterfaceType == Internal || BridgeInterfaceType >= MicroChannel)
172 {
173 return STATUS_NOT_IMPLEMENTED;
174 }
175
176 /* Fill in output struct */
177 Translator->Size = sizeof(TRANSLATOR_INTERFACE);
178 Translator->Version = HAL_IRQ_TRANSLATOR_VERSION;
179 /* In case caller set interface to undefined, faulty it to ISA */
180 Translator->Context = (PVOID)((BridgeInterfaceType == InterfaceTypeUndefined) ? Isa : BridgeInterfaceType);
181 Translator->InterfaceReference = FstubTranslatorNull;
182 Translator->InterfaceDereference = FstubTranslatorNull;
183 Translator->TranslateResources = FstubTranslateResource;
184 Translator->TranslateResourceRequirements = FstubTranslateRequirement;
185
186 return STATUS_SUCCESS;
187 }