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