test: translate.c Source File

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