Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

translate.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1997 Microsoft Corporation 00004 00005 Module Name: 00006 00007 translate.c 00008 00009 Abstract: 00010 00011 This is the default pnp IRQ translator. 00012 00013 Author: 00014 00015 Andy Thornton (andrewth) 7-June-97 00016 00017 Environment: 00018 00019 Kernel Mode Driver. 00020 00021 Notes: 00022 00023 This should only be temporary and will be replaced by a call into the HAL 00024 to retrieve its translators. 00025 00026 Revision History: 00027 00028 --*/ 00029 00030 00031 #include "ntos.h" 00032 #include "haldisp.h" 00033 #include <wdmguid.h> 00034 00035 // 00036 // Iteration macros 00037 // 00038 00039 // 00040 // Control macro (used like a for loop) which iterates over all entries in 00041 // a standard doubly linked list. Head is the list head and the entries are of 00042 // type Type. A member called ListEntry is assumed to be the LIST_ENTRY 00043 // structure linking the entries together. Current contains a pointer to each 00044 // entry in turn. 00045 // 00046 #define FOR_ALL_IN_LIST(Type, Head, Current) \ 00047 for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \ 00048 (Head) != &(Current)->ListEntry; \ 00049 (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ 00050 Type, \ 00051 ListEntry) \ 00052 ) 00053 // 00054 // Similar to the above only iteration is over an array of length _Size. 00055 // 00056 #define FOR_ALL_IN_ARRAY(_Array, _Size, _Current) \ 00057 for ( (_Current) = (_Array); \ 00058 (_Current) < (_Array) + (_Size); \ 00059 (_Current)++ ) 00060 00061 // 00062 // As above only iteration begins with the entry _Current 00063 // 00064 #define FOR_REST_IN_ARRAY(_Array, _Size, _Current) \ 00065 for ( ; \ 00066 (_Current) < (_Array) + (_Size); \ 00067 (_Current)++ ) 00068 00069 #define HAL_IRQ_TRANSLATOR_VERSION 0 00070 00071 NTSTATUS 00072 FstubTranslateResource( 00073 IN PVOID Context, 00074 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, 00075 IN RESOURCE_TRANSLATION_DIRECTION Direction, 00076 IN ULONG AlternativesCount OPTIONAL, 00077 IN IO_RESOURCE_DESCRIPTOR Alternatives[] OPTIONAL, 00078 IN PDEVICE_OBJECT PhysicalDeviceObject, 00079 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target 00080 ); 00081 00082 NTSTATUS 00083 FstubTranslateRequirement ( 00084 IN PVOID Context, 00085 IN PIO_RESOURCE_DESCRIPTOR Source, 00086 IN PDEVICE_OBJECT PhysicalDeviceObject, 00087 OUT PULONG TargetCount, 00088 OUT PIO_RESOURCE_DESCRIPTOR *Target 00089 ); 00090 00091 VOID 00092 FstubTranslatorNull( 00093 IN PVOID Context 00094 ); 00095 00096 extern PDEVICE_OBJECT McaPhysicalBusDevice; 00097 00098 #ifdef ALLOC_PRAGMA 00099 #pragma alloc_text(PAGE,xHalGetInterruptTranslator) 00100 #pragma alloc_text(PAGE,FstubTranslateResource) 00101 #pragma alloc_text(PAGE,FstubTranslateRequirement) 00102 #pragma alloc_text(PAGE,FstubTranslatorNull) 00103 #endif 00104 00105 00106 NTSTATUS 00107 xHalGetInterruptTranslator( 00108 IN INTERFACE_TYPE ParentInterfaceType, 00109 IN ULONG ParentBusNumber, 00110 IN INTERFACE_TYPE BridgeInterfaceType, 00111 IN USHORT Size, 00112 IN USHORT Version, 00113 OUT PTRANSLATOR_INTERFACE Translator, 00114 OUT PULONG BridgeBusNumber 00115 ) 00116 /*++ 00117 00118 Routine Description: 00119 00120 00121 Arguments: 00122 00123 ParentInterfaceType - The type of the bus the bridge lives on (normally PCI). 00124 00125 ParentBusNumber - The number of the bus the bridge lives on. 00126 00127 ParentSlotNumber - The slot number the bridge lives in (where valid). 00128 00129 BridgeInterfaceType - The bus type the bridge provides (ie ISA for a PCI-ISA bridge). 00130 00131 ResourceType - The resource type we want to translate. 00132 00133 Size - The size of the translator buffer. 00134 00135 Version - The version of the translator interface requested. 00136 00137 Translator - Pointer to the buffer where the translator should be returned 00138 00139 BridgeBusNumber - Pointer to where the bus number of the bridge bus should be returned 00140 00141 Return Value: 00142 00143 Returns the status of this operation. 00144 00145 --*/ 00146 { 00147 PAGED_CODE(); 00148 00149 #if defined(NO_LEGACY_DRIVERS) 00150 return STATUS_SUCCESS; 00151 } 00152 #else 00153 00154 UNREFERENCED_PARAMETER(ParentInterfaceType); 00155 UNREFERENCED_PARAMETER(ParentBusNumber); 00156 00157 ASSERT(Version == HAL_IRQ_TRANSLATOR_VERSION); 00158 ASSERT(Size >= sizeof (TRANSLATOR_INTERFACE)); 00159 00160 switch (BridgeInterfaceType) { 00161 case Eisa: 00162 case Isa: 00163 case MicroChannel: 00164 case InterfaceTypeUndefined: // special "IDE" cookie 00165 00166 // 00167 // Pass back an interface for an IRQ translator. 00168 // 00169 RtlZeroMemory(Translator, sizeof (TRANSLATOR_INTERFACE)); 00170 00171 Translator->Size = sizeof (TRANSLATOR_INTERFACE); 00172 Translator->Version = HAL_IRQ_TRANSLATOR_VERSION; 00173 Translator->InterfaceReference = &FstubTranslatorNull; 00174 Translator->InterfaceDereference = &FstubTranslatorNull; 00175 Translator->TranslateResources = &FstubTranslateResource; 00176 Translator->TranslateResourceRequirements = &FstubTranslateRequirement; 00177 00178 if (BridgeInterfaceType == InterfaceTypeUndefined) { 00179 Translator->Context = (PVOID)Isa; 00180 } else { 00181 Translator->Context = (PVOID)BridgeInterfaceType; 00182 } 00183 00184 return STATUS_SUCCESS; 00185 00186 default: 00187 return STATUS_NOT_IMPLEMENTED; 00188 } 00189 } 00190 00191 NTSTATUS 00192 FstubTranslateResource( 00193 IN PVOID Context, 00194 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Source, 00195 IN RESOURCE_TRANSLATION_DIRECTION Direction, 00196 IN ULONG AlternativesCount OPTIONAL, 00197 IN IO_RESOURCE_DESCRIPTOR Alternatives[] OPTIONAL, 00198 IN PDEVICE_OBJECT PhysicalDeviceObject, 00199 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Target 00200 ) 00201 { 00202 NTSTATUS status; 00203 ULONG affinity, currentVector, translatedVector; 00204 KIRQL irql; 00205 PIO_RESOURCE_DESCRIPTOR currentAlternative; 00206 00207 PAGED_CODE(); 00208 ASSERT(Source->Type == CmResourceTypeInterrupt); 00209 00210 // 00211 // Copy unchanged fields 00212 // 00213 00214 *Target = *Source; 00215 00216 switch (Direction) { 00217 case TranslateChildToParent: 00218 00219 // 00220 // Perform the translation - The interrupt source is 00221 // ISA. 00222 // 00223 00224 Target->u.Interrupt.Vector = HalGetInterruptVector( 00225 (INTERFACE_TYPE)(ULONG_PTR)Context, 00226 0, // assume bus 0 ??? BUGBUG ??? 00227 Source->u.Interrupt.Vector, 00228 Source->u.Interrupt.Vector, 00229 &irql, 00230 &affinity 00231 ); 00232 00233 Target->u.Interrupt.Level = irql; 00234 Target->u.Interrupt.Affinity = affinity; 00235 00236 status = STATUS_TRANSLATION_COMPLETE; 00237 00238 break; 00239 00240 case TranslateParentToChild: 00241 00242 // 00243 // Translate each alternative and when we match then use the value we 00244 // just translated 00245 // 00246 00247 FOR_ALL_IN_ARRAY(Alternatives, AlternativesCount, currentAlternative) { 00248 00249 ASSERT(currentAlternative->Type == CmResourceTypeInterrupt); 00250 00251 currentVector = currentAlternative->u.Interrupt.MinimumVector; 00252 00253 while (currentVector <= 00254 currentAlternative->u.Interrupt.MaximumVector) { 00255 00256 translatedVector = HalGetInterruptVector((INTERFACE_TYPE)(ULONG_PTR)Context, 00257 0,// BUGBUG - assume bus 0 00258 currentVector, 00259 currentVector, 00260 &irql, 00261 &affinity 00262 ); 00263 00264 00265 00266 if (translatedVector == Source->u.Interrupt.Vector) { 00267 00268 // 00269 // We found our vector - fill in the target and return 00270 // 00271 00272 Target->u.Interrupt.Vector = currentVector; 00273 Target->u.Interrupt.Level = Target->u.Interrupt.Vector; 00274 Target->u.Interrupt.Affinity = 0xFFFFFFFF; 00275 return STATUS_SUCCESS; 00276 } 00277 00278 currentVector++; 00279 } 00280 00281 } 00282 00283 status = STATUS_UNSUCCESSFUL; 00284 00285 break; 00286 } 00287 00288 return status; 00289 } 00290 NTSTATUS 00291 FstubTranslateRequirement ( 00292 IN PVOID Context, 00293 IN PIO_RESOURCE_DESCRIPTOR Source, 00294 IN PDEVICE_OBJECT PhysicalDeviceObject, 00295 OUT PULONG TargetCount, 00296 OUT PIO_RESOURCE_DESCRIPTOR *Target 00297 ) 00298 { 00299 ULONG affinity; 00300 KIRQL irql; 00301 00302 PAGED_CODE(); 00303 ASSERT(Source->Type == CmResourceTypeInterrupt); 00304 00305 *Target = ExAllocatePoolWithTag(PagedPool, 00306 sizeof(IO_RESOURCE_DESCRIPTOR), 00307 'btsF' 00308 ); 00309 00310 if (!*Target) { 00311 return STATUS_INSUFFICIENT_RESOURCES; 00312 } 00313 00314 *TargetCount = 1; 00315 00316 // 00317 // Copy unchanged fields 00318 // 00319 00320 **Target = *Source; 00321 00322 (*Target)->u.Interrupt.MinimumVector = 00323 HalGetInterruptVector( 00324 (INTERFACE_TYPE)(ULONG_PTR)Context, 00325 0, // assume bus 0 ??? BUGBUG ??? 00326 Source->u.Interrupt.MinimumVector, 00327 Source->u.Interrupt.MinimumVector, 00328 &irql, 00329 &affinity 00330 ); 00331 00332 00333 (*Target)->u.Interrupt.MaximumVector = 00334 HalGetInterruptVector( 00335 (INTERFACE_TYPE)(ULONG_PTR)Context, 00336 0, // assume bus 0 ??? BUGBUG ??? 00337 Source->u.Interrupt.MaximumVector, 00338 Source->u.Interrupt.MaximumVector, 00339 &irql, 00340 &affinity 00341 ); 00342 00343 00344 return STATUS_TRANSLATION_COMPLETE; 00345 } 00346 00347 VOID 00348 FstubTranslatorNull( 00349 IN PVOID Context 00350 ) 00351 { 00352 PAGED_CODE(); 00353 return; 00354 } 00355 #endif // NO_LEGACY_DRIVERS 00356 00357

Generated on Sat May 15 19:42:03 2004 for test by doxygen 1.3.7