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)
9 /* INCLUDES ******************************************************************/
15 /* PRIVATE FUNCTIONS *********************************************************/
22 FstubTranslatorNull(PVOID Context
)
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
)
45 ULONG MinimumVector
, Vector
, k
;
46 PIO_RESOURCE_DESCRIPTOR Alternative
;
47 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
50 ASSERT(Source
->Type
== CmResourceTypeInterrupt
);
52 /* Copy common information */
53 Target
->Type
= Source
->Type
;
54 Target
->ShareDisposition
= Source
->ShareDisposition
;
55 Target
->Flags
= Source
->Flags
;
57 if (Direction
== TranslateChildToParent
)
59 /* Get IRQL, affinity & system vector for the device vector */
60 Target
->u
.Interrupt
.Vector
= HalGetInterruptVector((INTERFACE_TYPE
)Context
, 0,
61 Source
->u
.Interrupt
.Vector
,
62 Source
->u
.Interrupt
.Vector
,
64 Target
->u
.Interrupt
.Level
= Irql
;
65 Target
->u
.Interrupt
.Affinity
= Affinity
;
66 Status
= STATUS_TRANSLATION_COMPLETE
;
68 else if (Direction
== TranslateParentToChild
)
70 /* Browse all the resources */
71 for (k
= 0; k
< AlternativesCount
; k
++)
73 Alternative
= &(Alternatives
[k
]);
75 ASSERT(Alternative
->Type
== CmResourceTypeInterrupt
);
77 /* Try to find the device vector, proceeding by trial & error
78 * We try a vector, and translate it
80 MinimumVector
= Alternative
->u
.Interrupt
.MinimumVector
;
81 while (MinimumVector
<= Alternative
->u
.Interrupt
.MaximumVector
)
83 /* Translate the vector */
84 Vector
= HalGetInterruptVector((INTERFACE_TYPE
)Context
, 0,
89 /* If the translated vector is matching the given translated vector */
90 if (Vector
== Source
->u
.Interrupt
.Vector
)
92 /* We are done, send back device vector */
93 Target
->u
.Interrupt
.Affinity
= -1;
94 Target
->u
.Interrupt
.Vector
= MinimumVector
;
95 Target
->u
.Interrupt
.Level
= MinimumVector
;
97 return STATUS_SUCCESS
;
113 FstubTranslateRequirement(IN OUT PVOID Context OPTIONAL
,
114 IN PIO_RESOURCE_DESCRIPTOR Source
,
115 IN PDEVICE_OBJECT PhysicalDeviceObject
,
116 OUT PULONG TargetCount
,
117 OUT PIO_RESOURCE_DESCRIPTOR
*Target
)
123 ASSERT(Source
->Type
== CmResourceTypeInterrupt
);
125 /* Allocate output buffer */
126 *Target
= ExAllocatePoolWithTag(PagedPool
, sizeof(IO_RESOURCE_DESCRIPTOR
), 'btsF');
129 return STATUS_INSUFFICIENT_RESOURCES
;
132 /* Zero & set out count to 1 */
133 RtlZeroMemory(*Target
, sizeof(IO_RESOURCE_DESCRIPTOR
));
136 /* Translate minimum interrupt vector */
137 (*Target
)->u
.Interrupt
.MinimumVector
= HalGetInterruptVector((INTERFACE_TYPE
)Context
, 0,
138 Source
->u
.Interrupt
.MinimumVector
,
139 Source
->u
.Interrupt
.MinimumVector
,
142 /* Translate maximum interrupt vector */
143 (*Target
)->u
.Interrupt
.MaximumVector
= HalGetInterruptVector((INTERFACE_TYPE
)Context
, 0,
144 Source
->u
.Interrupt
.MaximumVector
,
145 Source
->u
.Interrupt
.MaximumVector
,
148 return STATUS_TRANSLATION_COMPLETE
;
156 xHalGetInterruptTranslator(IN INTERFACE_TYPE ParentInterfaceType
,
157 IN ULONG ParentBusNumber
,
158 IN INTERFACE_TYPE BridgeInterfaceType
,
161 OUT PTRANSLATOR_INTERFACE Translator
,
162 OUT PULONG BridgeBusNumber
)
166 ASSERT(Version
== HAL_IRQ_TRANSLATOR_VERSION
);
167 ASSERT(Size
>= sizeof(TRANSLATOR_INTERFACE
));
169 /* Only (E)ISA interfaces are supported */
170 if (BridgeInterfaceType
== Internal
|| BridgeInterfaceType
>= MicroChannel
)
172 return STATUS_NOT_IMPLEMENTED
;
175 /* Fill in output struct */
176 Translator
->Size
= sizeof(TRANSLATOR_INTERFACE
);
177 Translator
->Version
= HAL_IRQ_TRANSLATOR_VERSION
;
178 /* In case caller set interface to undefined, faulty it to ISA */
179 Translator
->Context
= UlongToPtr((BridgeInterfaceType
== InterfaceTypeUndefined
) ? Isa
: BridgeInterfaceType
);
180 Translator
->InterfaceReference
= FstubTranslatorNull
;
181 Translator
->InterfaceDereference
= FstubTranslatorNull
;
182 Translator
->TranslateResources
= FstubTranslateResource
;
183 Translator
->TranslateResourceRequirements
= FstubTranslateRequirement
;
185 return STATUS_SUCCESS
;