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

pnpirq.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1997 Microsoft Corporation 00004 00005 Module Name: 00006 00007 pnpirq.c 00008 00009 Abstract: 00010 00011 Root IRQ arbiter 00012 00013 Author: 00014 00015 Andy Thornton (andrewth) 04/17/97 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "iop.h" 00022 #pragma hdrstop 00023 00024 // 00025 // Constants 00026 // 00027 00028 #define MAX_ULONGLONG ((ULONGLONG) -1) 00029 00030 // 00031 // Prototypes 00032 // 00033 00034 NTSTATUS 00035 IopIrqInitialize( 00036 VOID 00037 ); 00038 00039 NTSTATUS 00040 IopIrqUnpackRequirement( 00041 IN PIO_RESOURCE_DESCRIPTOR Descriptor, 00042 OUT PULONGLONG Minimum, 00043 OUT PULONGLONG Maximum, 00044 OUT PULONG Length, 00045 OUT PULONG Alignment 00046 ); 00047 00048 NTSTATUS 00049 IopIrqPackResource( 00050 IN PIO_RESOURCE_DESCRIPTOR Requirement, 00051 IN ULONGLONG Start, 00052 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor 00053 ); 00054 00055 LONG 00056 IopIrqScoreRequirement( 00057 IN PIO_RESOURCE_DESCRIPTOR Descriptor 00058 ); 00059 00060 NTSTATUS 00061 IopIrqUnpackResource( 00062 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, 00063 OUT PULONGLONG Start, 00064 OUT PULONG Length 00065 ); 00066 00067 NTSTATUS 00068 IopIrqTranslateOrdering( 00069 OUT PIO_RESOURCE_DESCRIPTOR Target, 00070 IN PIO_RESOURCE_DESCRIPTOR Source 00071 ); 00072 00073 BOOLEAN 00074 IopIrqFindSuitableRange( 00075 PARBITER_INSTANCE Arbiter, 00076 PARBITER_ALLOCATION_STATE State 00077 ); 00078 00079 00080 // 00081 // Make everything pageable 00082 // 00083 00084 #ifdef ALLOC_PRAGMA 00085 00086 #pragma alloc_text(PAGE, IopIrqInitialize) 00087 #pragma alloc_text(PAGE, IopIrqUnpackRequirement) 00088 #pragma alloc_text(PAGE, IopIrqPackResource) 00089 #pragma alloc_text(PAGE, IopIrqScoreRequirement) 00090 #pragma alloc_text(PAGE, IopIrqUnpackResource) 00091 #pragma alloc_text(PAGE, IopIrqTranslateOrdering) 00092 #pragma alloc_text(PAGE, IopIrqFindSuitableRange) 00093 #endif // ALLOC_PRAGMA 00094 00095 // 00096 // Implementation 00097 // 00098 #if !defined(NO_LEGACY_DRIVERS) 00099 NTSTATUS 00100 IopIrqTranslateOrdering( 00101 OUT PIO_RESOURCE_DESCRIPTOR Target, 00102 IN PIO_RESOURCE_DESCRIPTOR Source 00103 ) 00104 00105 /* 00106 00107 Routine Description: 00108 00109 This routine is called during arbiter initialization to translate the 00110 orderings. 00111 00112 Parameters: 00113 00114 Target - Place to put the translated descriptor 00115 00116 Source - Descriptor to translate 00117 00118 Return Value: 00119 00120 Status code 00121 00122 */ 00123 00124 { 00125 00126 KIRQL level; 00127 KAFFINITY affinity; 00128 00129 PAGED_CODE(); 00130 00131 // 00132 // Copy the source to the target 00133 // 00134 00135 *Target = *Source; 00136 00137 if (Source->Type != CmResourceTypeInterrupt) { 00138 return STATUS_SUCCESS; 00139 } 00140 00141 // 00142 // Translate the vector 00143 // 00144 00145 00146 ARB_PRINT( 00147 2, 00148 ("Translating Vector 0x%x-0x%x =>", 00149 Source->u.Interrupt.MinimumVector, 00150 Source->u.Interrupt.MaximumVector 00151 )); 00152 00153 Target->u.Interrupt.MinimumVector = 00154 HalGetInterruptVector(Isa, 00155 0, 00156 Source->u.Interrupt.MinimumVector, 00157 Source->u.Interrupt.MinimumVector, 00158 &level, 00159 &affinity 00160 ); 00161 00162 if (affinity == 0) { 00163 ARB_PRINT(2,("Translation failed\n")); 00164 *Target = *Source; 00165 return STATUS_SUCCESS; 00166 } 00167 00168 Target->u.Interrupt.MaximumVector = 00169 HalGetInterruptVector(Isa, 00170 0, 00171 Source->u.Interrupt.MaximumVector, 00172 Source->u.Interrupt.MaximumVector, 00173 &level, 00174 &affinity 00175 ); 00176 00177 if (affinity == 0) { 00178 ARB_PRINT(2,("Translation failed\n")); 00179 *Target = *Source; 00180 return STATUS_SUCCESS; 00181 } 00182 00183 ARB_PRINT( 00184 2, 00185 ("0x%x-0x%x\n", 00186 Target->u.Interrupt.MinimumVector, 00187 Target->u.Interrupt.MaximumVector 00188 )); 00189 00190 00191 return STATUS_SUCCESS; 00192 } 00193 #endif // NO_LEGACY_DRIVERS 00194 00195 NTSTATUS 00196 IopIrqInitialize( 00197 VOID 00198 ) 00199 00200 /*++ 00201 00202 Routine Description: 00203 00204 This routine initializes the arbiter 00205 00206 Parameters: 00207 00208 None 00209 00210 Return Value: 00211 00212 None 00213 00214 --*/ 00215 00216 { 00217 00218 IopRootIrqArbiter.UnpackRequirement = IopIrqUnpackRequirement; 00219 IopRootIrqArbiter.PackResource = IopIrqPackResource; 00220 IopRootIrqArbiter.UnpackResource = IopIrqUnpackResource; 00221 IopRootIrqArbiter.ScoreRequirement = IopIrqScoreRequirement; 00222 00223 return ArbInitializeArbiterInstance(&IopRootIrqArbiter, 00224 NULL, // Indicates ROOT arbiter 00225 CmResourceTypeInterrupt, 00226 L"RootIRQ", 00227 L"Root", 00228 #if defined(NO_LEGACY_DRIVERS) 00229 NULL 00230 #else 00231 IopIrqTranslateOrdering 00232 #endif // NO_LEGACY_DRIVERS 00233 ); 00234 } 00235 00236 // 00237 // Arbiter callbacks 00238 // 00239 00240 NTSTATUS 00241 IopIrqUnpackRequirement( 00242 IN PIO_RESOURCE_DESCRIPTOR Descriptor, 00243 OUT PULONGLONG Minimum, 00244 OUT PULONGLONG Maximum, 00245 OUT PULONG Length, 00246 OUT PULONG Alignment 00247 ) 00248 00249 /*++ 00250 00251 Routine Description: 00252 00253 This routine unpacks an resource requirement descriptor. 00254 00255 Arguments: 00256 00257 Descriptor - The descriptor describing the requirement to unpack. 00258 00259 Minimum - Pointer to where the minimum acceptable start value should be 00260 unpacked to. 00261 00262 Maximum - Pointer to where the maximum acceptable end value should be 00263 unpacked to. 00264 00265 Length - Pointer to where the required length should be unpacked to. 00266 00267 Minimum - Pointer to where the required alignment should be unpacked to. 00268 00269 Return Value: 00270 00271 Returns the status of this operation. 00272 00273 --*/ 00274 00275 { 00276 ASSERT(Descriptor); 00277 ASSERT(Descriptor->Type == CmResourceTypeInterrupt); 00278 00279 ARB_PRINT(2, 00280 ("Unpacking IRQ requirement %p => 0x%I64x-0x%I64x\n", 00281 Descriptor, 00282 (ULONGLONG) Descriptor->u.Interrupt.MinimumVector, 00283 (ULONGLONG) Descriptor->u.Interrupt.MaximumVector 00284 )); 00285 00286 *Minimum = (ULONGLONG) Descriptor->u.Interrupt.MinimumVector; 00287 *Maximum = (ULONGLONG) Descriptor->u.Interrupt.MaximumVector; 00288 *Length = 1; 00289 *Alignment = 1; 00290 00291 return STATUS_SUCCESS; 00292 00293 } 00294 00295 LONG 00296 IopIrqScoreRequirement( 00297 IN PIO_RESOURCE_DESCRIPTOR Descriptor 00298 ) 00299 00300 /*++ 00301 00302 Routine Description: 00303 00304 This routine scores a requirement based on how flexible it is. The least 00305 flexible devices are scored the least and so when the arbitration list is 00306 sorted we try to allocate their resources first. 00307 00308 Arguments: 00309 00310 Descriptor - The descriptor describing the requirement to score. 00311 00312 00313 Return Value: 00314 00315 The score. 00316 00317 --*/ 00318 00319 { 00320 LONG score; 00321 00322 ASSERT(Descriptor); 00323 ASSERT(Descriptor->Type == CmResourceTypeInterrupt); 00324 00325 score = Descriptor->u.Interrupt.MaximumVector - 00326 Descriptor->u.Interrupt.MinimumVector + 1; 00327 00328 ARB_PRINT(2, 00329 ("Scoring IRQ resource %p => %i\n", 00330 Descriptor, 00331 score 00332 )); 00333 00334 return score; 00335 } 00336 00337 NTSTATUS 00338 IopIrqPackResource( 00339 IN PIO_RESOURCE_DESCRIPTOR Requirement, 00340 IN ULONGLONG Start, 00341 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor 00342 ) 00343 00344 /*++ 00345 00346 Routine Description: 00347 00348 This routine packs an resource descriptor. 00349 00350 Arguments: 00351 00352 Requirement - The requirement from which this resource was chosen. 00353 00354 Start - The start value of the resource. 00355 00356 Descriptor - Pointer to the descriptor to pack into. 00357 00358 Return Value: 00359 00360 Returns the status of this operation. 00361 00362 --*/ 00363 00364 { 00365 ASSERT(Descriptor); 00366 ASSERT(Start < ((ULONG)-1)); 00367 ASSERT(Requirement); 00368 ASSERT(Requirement->Type == CmResourceTypeInterrupt); 00369 00370 ARB_PRINT(2, 00371 ("Packing IRQ resource %p => 0x%I64x\n", 00372 Descriptor, 00373 Start 00374 )); 00375 00376 Descriptor->Type = CmResourceTypeInterrupt; 00377 Descriptor->Flags = Requirement->Flags; // BUGBUG - is this correct? 00378 Descriptor->ShareDisposition = Requirement->ShareDisposition; 00379 Descriptor->u.Interrupt.Vector = (ULONG) Start; 00380 Descriptor->u.Interrupt.Level = (ULONG) Start; 00381 Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF; 00382 00383 return STATUS_SUCCESS; 00384 } 00385 00386 NTSTATUS 00387 IopIrqUnpackResource( 00388 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, 00389 OUT PULONGLONG Start, 00390 OUT PULONG Length 00391 ) 00392 00393 /*++ 00394 00395 Routine Description: 00396 00397 This routine unpacks an resource descriptor. 00398 00399 Arguments: 00400 00401 Descriptor - The descriptor describing the requirement to unpack. 00402 00403 Start - Pointer to where the start value should be unpacked to. 00404 00405 End - Pointer to where the end value should be unpacked to. 00406 00407 Return Value: 00408 00409 Returns the status of this operation. 00410 00411 --*/ 00412 00413 00414 { 00415 00416 ASSERT(Descriptor); 00417 ASSERT(Descriptor->Type == CmResourceTypeInterrupt); 00418 00419 *Start = Descriptor->u.Interrupt.Vector; 00420 *Length = 1; 00421 00422 ARB_PRINT(2, 00423 ("Unpacking IRQ resource %p => 0x%I64x\n", 00424 Descriptor, 00425 *Start 00426 )); 00427 00428 return STATUS_SUCCESS; 00429 00430 }

Generated on Sat May 15 19:41:18 2004 for test by doxygen 1.3.7