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 KIRQL Irql; 44 KAFFINITY Affinity; 45 ULONG MinimumVector, Vector, k; 46 PIO_RESOURCE_DESCRIPTOR Alternative; 47 NTSTATUS Status = STATUS_UNSUCCESSFUL; 48 PAGED_CODE(); 49 50 ASSERT(Source->Type == CmResourceTypeInterrupt); 51 52 /* Copy common information */ 53 Target->Type = Source->Type; 54 Target->ShareDisposition = Source->ShareDisposition; 55 Target->Flags = Source->Flags; 56 57 if (Direction == TranslateChildToParent) 58 { 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, 63 &Irql, &Affinity); 64 Target->u.Interrupt.Level = Irql; 65 Target->u.Interrupt.Affinity = Affinity; 66 Status = STATUS_TRANSLATION_COMPLETE; 67 } 68 else if (Direction == TranslateParentToChild) 69 { 70 /* Browse all the resources */ 71 for (k = 0; k < AlternativesCount; k++) 72 { 73 Alternative = &(Alternatives[k]); 74 75 ASSERT(Alternative->Type == CmResourceTypeInterrupt); 76 77 /* Try to find the device vector, proceeding by trial & error 78 * We try a vector, and translate it 79 */ 80 MinimumVector = Alternative->u.Interrupt.MinimumVector; 81 while (MinimumVector <= Alternative->u.Interrupt.MaximumVector) 82 { 83 /* Translate the vector */ 84 Vector = HalGetInterruptVector((INTERFACE_TYPE)Context, 0, 85 MinimumVector, 86 MinimumVector, 87 &Irql, &Affinity); 88 89 /* If the translated vector is matching the given translated vector */ 90 if (Vector == Source->u.Interrupt.Vector) 91 { 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; 96 97 return STATUS_SUCCESS; 98 } 99 100 MinimumVector++; 101 } 102 } 103 } 104 105 return Status; 106 } 107 108 /* 109 * @implemented 110 */ 111 NTSTATUS 112 NTAPI 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) 118 { 119 KIRQL Irql; 120 KAFFINITY Affinity; 121 PAGED_CODE(); 122 123 ASSERT(Source->Type == CmResourceTypeInterrupt); 124 125 /* Allocate output buffer */ 126 *Target = ExAllocatePoolWithTag(PagedPool, sizeof(IO_RESOURCE_DESCRIPTOR), 'btsF'); 127 if (!*Target) 128 { 129 return STATUS_INSUFFICIENT_RESOURCES; 130 } 131 132 /* Zero & set out count to 1 */ 133 RtlZeroMemory(*Target, sizeof(IO_RESOURCE_DESCRIPTOR)); 134 *TargetCount = 1; 135 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, 140 &Irql, &Affinity); 141 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, 146 &Irql, &Affinity); 147 148 return STATUS_TRANSLATION_COMPLETE; 149 } 150 151 /* 152 * @implemented 153 */ 154 NTSTATUS 155 NTAPI 156 xHalGetInterruptTranslator(IN INTERFACE_TYPE ParentInterfaceType, 157 IN ULONG ParentBusNumber, 158 IN INTERFACE_TYPE BridgeInterfaceType, 159 IN USHORT Size, 160 IN USHORT Version, 161 OUT PTRANSLATOR_INTERFACE Translator, 162 OUT PULONG BridgeBusNumber) 163 { 164 PAGED_CODE(); 165 166 ASSERT(Version == HAL_IRQ_TRANSLATOR_VERSION); 167 ASSERT(Size >= sizeof(TRANSLATOR_INTERFACE)); 168 169 /* Only (E)ISA interfaces are supported */ 170 if (BridgeInterfaceType == Internal || BridgeInterfaceType >= MicroChannel) 171 { 172 return STATUS_NOT_IMPLEMENTED; 173 } 174 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; 184 185 return STATUS_SUCCESS; 186 } 187