Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpdo.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS PCI Bus Driver 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: drivers/bus/pci/pdo.c 00005 * PURPOSE: PDO Device Management 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <pci.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS ********************************************************************/ 00016 00017 LONG PciPdoSequenceNumber; 00018 00019 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, DeviceState) == FIELD_OFFSET(PCI_PDO_EXTENSION, DeviceState)); 00020 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, TentativeNextState) == FIELD_OFFSET(PCI_PDO_EXTENSION, TentativeNextState)); 00021 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, List) == FIELD_OFFSET(PCI_PDO_EXTENSION, Next)); 00022 00023 PCI_MN_DISPATCH_TABLE PciPdoDispatchPowerTable[] = 00024 { 00025 {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciPdoWaitWake}, 00026 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 00027 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoSetPowerState}, 00028 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryPower}, 00029 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported} 00030 }; 00031 00032 PCI_MN_DISPATCH_TABLE PciPdoDispatchPnpTable[] = 00033 { 00034 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStartDevice}, 00035 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryRemoveDevice}, 00036 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpRemoveDevice}, 00037 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelRemoveDevice}, 00038 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStopDevice}, 00039 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryStopDevice}, 00040 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelStopDevice}, 00041 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceRelations}, 00042 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryInterface}, 00043 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryCapabilities}, 00044 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResources}, 00045 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResourceRequirements}, 00046 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceText}, 00047 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 00048 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 00049 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpReadConfig}, 00050 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpWriteConfig}, 00051 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 00052 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 00053 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryId}, 00054 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceState}, 00055 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryBusInformation}, 00056 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpDeviceUsageNotification}, 00057 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpSurpriseRemoval}, 00058 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryLegacyBusInformation}, 00059 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported} 00060 }; 00061 00062 PCI_MJ_DISPATCH_TABLE PciPdoDispatchTable = 00063 { 00064 IRP_MN_QUERY_LEGACY_BUS_INFORMATION, 00065 PciPdoDispatchPnpTable, 00066 IRP_MN_QUERY_POWER, 00067 PciPdoDispatchPowerTable, 00068 IRP_COMPLETE, 00069 (PCI_DISPATCH_FUNCTION)PciIrpNotSupported, 00070 IRP_COMPLETE, 00071 (PCI_DISPATCH_FUNCTION)PciIrpInvalidDeviceRequest 00072 }; 00073 00074 /* FUNCTIONS ******************************************************************/ 00075 00076 NTSTATUS 00077 NTAPI 00078 PciPdoWaitWake(IN PIRP Irp, 00079 IN PIO_STACK_LOCATION IoStackLocation, 00080 IN PPCI_PDO_EXTENSION DeviceExtension) 00081 { 00082 UNIMPLEMENTED; 00083 while (TRUE); 00084 return STATUS_NOT_SUPPORTED; 00085 } 00086 00087 NTSTATUS 00088 NTAPI 00089 PciPdoSetPowerState(IN PIRP Irp, 00090 IN PIO_STACK_LOCATION IoStackLocation, 00091 IN PPCI_PDO_EXTENSION DeviceExtension) 00092 { 00093 UNIMPLEMENTED; 00094 return STATUS_NOT_SUPPORTED; 00095 } 00096 00097 NTSTATUS 00098 NTAPI 00099 PciPdoIrpQueryPower(IN PIRP Irp, 00100 IN PIO_STACK_LOCATION IoStackLocation, 00101 IN PPCI_PDO_EXTENSION DeviceExtension) 00102 { 00103 UNIMPLEMENTED; 00104 while (TRUE); 00105 return STATUS_NOT_SUPPORTED; 00106 } 00107 00108 NTSTATUS 00109 NTAPI 00110 PciPdoIrpStartDevice(IN PIRP Irp, 00111 IN PIO_STACK_LOCATION IoStackLocation, 00112 IN PPCI_PDO_EXTENSION DeviceExtension) 00113 { 00114 NTSTATUS Status; 00115 BOOLEAN Changed, DoReset; 00116 POWER_STATE PowerState; 00117 PAGED_CODE(); 00118 00119 DoReset = FALSE; 00120 00121 /* Begin entering the start phase */ 00122 Status = PciBeginStateTransition((PVOID)DeviceExtension, PciStarted); 00123 if (!NT_SUCCESS(Status)) return Status; 00124 00125 /* Check if this is a VGA device */ 00126 if (((DeviceExtension->BaseClass == PCI_CLASS_PRE_20) && 00127 (DeviceExtension->SubClass == PCI_SUBCLASS_PRE_20_VGA)) || 00128 ((DeviceExtension->BaseClass == PCI_CLASS_DISPLAY_CTLR) && 00129 (DeviceExtension->SubClass == PCI_SUBCLASS_VID_VGA_CTLR))) 00130 { 00131 /* Always force it on */ 00132 DeviceExtension->CommandEnables |= (PCI_ENABLE_IO_SPACE | 00133 PCI_ENABLE_MEMORY_SPACE); 00134 } 00135 00136 /* Check if native IDE is enabled and it owns the I/O ports */ 00137 if (DeviceExtension->IoSpaceUnderNativeIdeControl) 00138 { 00139 /* Then don't allow I/O access */ 00140 DeviceExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE; 00141 } 00142 00143 /* Always enable bus mastering */ 00144 DeviceExtension->CommandEnables |= PCI_ENABLE_BUS_MASTER; 00145 00146 /* Check if the OS assigned resources differ from the PCI configuration */ 00147 Changed = PciComputeNewCurrentSettings(DeviceExtension, 00148 IoStackLocation->Parameters. 00149 StartDevice.AllocatedResources); 00150 if (Changed) 00151 { 00152 /* Remember this for later */ 00153 DeviceExtension->MovedDevice = TRUE; 00154 } 00155 else 00156 { 00157 /* All good */ 00158 DPRINT1("PCI - START not changing resource settings.\n"); 00159 } 00160 00161 /* Check if the device was sleeping */ 00162 if (DeviceExtension->PowerState.CurrentDeviceState != PowerDeviceD0) 00163 { 00164 /* Power it up */ 00165 Status = PciSetPowerManagedDevicePowerState(DeviceExtension, 00166 PowerDeviceD0, 00167 FALSE); 00168 if (!NT_SUCCESS(Status)) 00169 { 00170 /* Powerup fail, fail the request */ 00171 PciCancelStateTransition((PVOID)DeviceExtension, PciStarted); 00172 return STATUS_DEVICE_POWER_FAILURE; 00173 } 00174 00175 /* Tell the power manager that the device is powered up */ 00176 PowerState.DeviceState = PowerDeviceD0; 00177 PoSetPowerState(DeviceExtension->PhysicalDeviceObject, 00178 DevicePowerState, 00179 PowerState); 00180 00181 /* Update internal state */ 00182 DeviceExtension->PowerState.CurrentDeviceState = PowerDeviceD0; 00183 00184 /* This device's resources and decodes will need to be reset */ 00185 DoReset = TRUE; 00186 } 00187 00188 /* Update resource information now that the device is powered up and active */ 00189 Status = PciSetResources(DeviceExtension, DoReset, TRUE); 00190 if (!NT_SUCCESS(Status)) 00191 { 00192 /* That failed, so cancel the transition */ 00193 PciCancelStateTransition((PVOID)DeviceExtension, PciStarted); 00194 } 00195 else 00196 { 00197 /* Fully commit, as the device is now started up and ready to go */ 00198 PciCommitStateTransition((PVOID)DeviceExtension, PciStarted); 00199 } 00200 00201 /* Return the result of the start request */ 00202 return Status; 00203 } 00204 00205 NTSTATUS 00206 NTAPI 00207 PciPdoIrpQueryRemoveDevice(IN PIRP Irp, 00208 IN PIO_STACK_LOCATION IoStackLocation, 00209 IN PPCI_PDO_EXTENSION DeviceExtension) 00210 { 00211 UNIMPLEMENTED; 00212 return STATUS_NOT_SUPPORTED; 00213 } 00214 00215 NTSTATUS 00216 NTAPI 00217 PciPdoIrpRemoveDevice(IN PIRP Irp, 00218 IN PIO_STACK_LOCATION IoStackLocation, 00219 IN PPCI_PDO_EXTENSION DeviceExtension) 00220 { 00221 UNIMPLEMENTED; 00222 while (TRUE); 00223 return STATUS_NOT_SUPPORTED; 00224 } 00225 00226 NTSTATUS 00227 NTAPI 00228 PciPdoIrpCancelRemoveDevice(IN PIRP Irp, 00229 IN PIO_STACK_LOCATION IoStackLocation, 00230 IN PPCI_PDO_EXTENSION DeviceExtension) 00231 { 00232 UNIMPLEMENTED; 00233 while (TRUE); 00234 return STATUS_NOT_SUPPORTED; 00235 } 00236 00237 NTSTATUS 00238 NTAPI 00239 PciPdoIrpStopDevice(IN PIRP Irp, 00240 IN PIO_STACK_LOCATION IoStackLocation, 00241 IN PPCI_PDO_EXTENSION DeviceExtension) 00242 { 00243 UNIMPLEMENTED; 00244 while (TRUE); 00245 return STATUS_NOT_SUPPORTED; 00246 } 00247 00248 NTSTATUS 00249 NTAPI 00250 PciPdoIrpQueryStopDevice(IN PIRP Irp, 00251 IN PIO_STACK_LOCATION IoStackLocation, 00252 IN PPCI_PDO_EXTENSION DeviceExtension) 00253 { 00254 UNIMPLEMENTED; 00255 while (TRUE); 00256 return STATUS_NOT_SUPPORTED; 00257 } 00258 00259 NTSTATUS 00260 NTAPI 00261 PciPdoIrpCancelStopDevice(IN PIRP Irp, 00262 IN PIO_STACK_LOCATION IoStackLocation, 00263 IN PPCI_PDO_EXTENSION DeviceExtension) 00264 { 00265 UNIMPLEMENTED; 00266 while (TRUE); 00267 return STATUS_NOT_SUPPORTED; 00268 } 00269 00270 NTSTATUS 00271 NTAPI 00272 PciPdoIrpQueryInterface(IN PIRP Irp, 00273 IN PIO_STACK_LOCATION IoStackLocation, 00274 IN PPCI_PDO_EXTENSION DeviceExtension) 00275 { 00276 UNIMPLEMENTED; 00277 while (TRUE); 00278 return STATUS_NOT_SUPPORTED; 00279 } 00280 00281 NTSTATUS 00282 NTAPI 00283 PciPdoIrpQueryDeviceRelations(IN PIRP Irp, 00284 IN PIO_STACK_LOCATION IoStackLocation, 00285 IN PPCI_PDO_EXTENSION DeviceExtension) 00286 { 00287 NTSTATUS Status; 00288 PAGED_CODE(); 00289 00290 /* Are ejection relations being queried? */ 00291 if (IoStackLocation->Parameters.QueryDeviceRelations.Type == EjectionRelations) 00292 { 00293 /* Call the worker function */ 00294 Status = PciQueryEjectionRelations(DeviceExtension, 00295 (PDEVICE_RELATIONS*)&Irp-> 00296 IoStatus.Information); 00297 } 00298 else if (IoStackLocation->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) 00299 { 00300 /* The only other relation supported is the target device relation */ 00301 Status = PciQueryTargetDeviceRelations(DeviceExtension, 00302 (PDEVICE_RELATIONS*)&Irp-> 00303 IoStatus.Information); 00304 } 00305 else 00306 { 00307 /* All other relations are unsupported */ 00308 Status = STATUS_NOT_SUPPORTED; 00309 } 00310 00311 /* Return either the result of the worker function, or unsupported status */ 00312 return Status; 00313 } 00314 00315 NTSTATUS 00316 NTAPI 00317 PciPdoIrpQueryCapabilities(IN PIRP Irp, 00318 IN PIO_STACK_LOCATION IoStackLocation, 00319 IN PPCI_PDO_EXTENSION DeviceExtension) 00320 { 00321 PAGED_CODE(); 00322 00323 /* Call the worker function */ 00324 return PciQueryCapabilities(DeviceExtension, 00325 IoStackLocation-> 00326 Parameters.DeviceCapabilities.Capabilities); 00327 } 00328 00329 NTSTATUS 00330 NTAPI 00331 PciPdoIrpQueryResources(IN PIRP Irp, 00332 IN PIO_STACK_LOCATION IoStackLocation, 00333 IN PPCI_PDO_EXTENSION DeviceExtension) 00334 { 00335 PAGED_CODE(); 00336 00337 /* Call the worker function */ 00338 return PciQueryResources(DeviceExtension, 00339 (PCM_RESOURCE_LIST*)&Irp->IoStatus.Information); 00340 } 00341 00342 NTSTATUS 00343 NTAPI 00344 PciPdoIrpQueryResourceRequirements(IN PIRP Irp, 00345 IN PIO_STACK_LOCATION IoStackLocation, 00346 IN PPCI_PDO_EXTENSION DeviceExtension) 00347 { 00348 PAGED_CODE(); 00349 00350 /* Call the worker function */ 00351 return PciQueryRequirements(DeviceExtension, 00352 (PIO_RESOURCE_REQUIREMENTS_LIST*)&Irp-> 00353 IoStatus.Information); 00354 } 00355 00356 NTSTATUS 00357 NTAPI 00358 PciPdoIrpQueryDeviceText(IN PIRP Irp, 00359 IN PIO_STACK_LOCATION IoStackLocation, 00360 IN PPCI_PDO_EXTENSION DeviceExtension) 00361 { 00362 PAGED_CODE(); 00363 00364 /* Call the worker function */ 00365 return PciQueryDeviceText(DeviceExtension, 00366 IoStackLocation-> 00367 Parameters.QueryDeviceText.DeviceTextType, 00368 IoStackLocation-> 00369 Parameters.QueryDeviceText.LocaleId, 00370 (PWCHAR*)&Irp->IoStatus.Information); 00371 } 00372 00373 NTSTATUS 00374 NTAPI 00375 PciPdoIrpQueryId(IN PIRP Irp, 00376 IN PIO_STACK_LOCATION IoStackLocation, 00377 IN PPCI_PDO_EXTENSION DeviceExtension) 00378 { 00379 PAGED_CODE(); 00380 00381 /* Call the worker function */ 00382 return PciQueryId(DeviceExtension, 00383 IoStackLocation->Parameters.QueryId.IdType, 00384 (PWCHAR*)&Irp->IoStatus.Information); 00385 } 00386 00387 NTSTATUS 00388 NTAPI 00389 PciPdoIrpQueryBusInformation(IN PIRP Irp, 00390 IN PIO_STACK_LOCATION IoStackLocation, 00391 IN PPCI_PDO_EXTENSION DeviceExtension) 00392 { 00393 PAGED_CODE(); 00394 00395 /* Call the worker function */ 00396 return PciQueryBusInformation(DeviceExtension, 00397 (PPNP_BUS_INFORMATION*)&Irp-> 00398 IoStatus.Information); 00399 } 00400 00401 NTSTATUS 00402 NTAPI 00403 PciPdoIrpReadConfig(IN PIRP Irp, 00404 IN PIO_STACK_LOCATION IoStackLocation, 00405 IN PPCI_PDO_EXTENSION DeviceExtension) 00406 { 00407 UNIMPLEMENTED; 00408 while (TRUE); 00409 return STATUS_NOT_SUPPORTED; 00410 } 00411 00412 NTSTATUS 00413 NTAPI 00414 PciPdoIrpWriteConfig(IN PIRP Irp, 00415 IN PIO_STACK_LOCATION IoStackLocation, 00416 IN PPCI_PDO_EXTENSION DeviceExtension) 00417 { 00418 UNIMPLEMENTED; 00419 while (TRUE); 00420 return STATUS_NOT_SUPPORTED; 00421 } 00422 00423 NTSTATUS 00424 NTAPI 00425 PciPdoIrpQueryDeviceState(IN PIRP Irp, 00426 IN PIO_STACK_LOCATION IoStackLocation, 00427 IN PPCI_PDO_EXTENSION DeviceExtension) 00428 { 00429 UNIMPLEMENTED; 00430 return STATUS_NOT_SUPPORTED; 00431 } 00432 00433 NTSTATUS 00434 NTAPI 00435 PciPdoIrpDeviceUsageNotification(IN PIRP Irp, 00436 IN PIO_STACK_LOCATION IoStackLocation, 00437 IN PPCI_PDO_EXTENSION DeviceExtension) 00438 { 00439 UNIMPLEMENTED; 00440 while (TRUE); 00441 return STATUS_NOT_SUPPORTED; 00442 } 00443 00444 NTSTATUS 00445 NTAPI 00446 PciPdoIrpSurpriseRemoval(IN PIRP Irp, 00447 IN PIO_STACK_LOCATION IoStackLocation, 00448 IN PPCI_PDO_EXTENSION DeviceExtension) 00449 { 00450 UNIMPLEMENTED; 00451 while (TRUE); 00452 return STATUS_NOT_SUPPORTED; 00453 } 00454 00455 NTSTATUS 00456 NTAPI 00457 PciPdoIrpQueryLegacyBusInformation(IN PIRP Irp, 00458 IN PIO_STACK_LOCATION IoStackLocation, 00459 IN PPCI_PDO_EXTENSION DeviceExtension) 00460 { 00461 UNIMPLEMENTED; 00462 while (TRUE); 00463 return STATUS_NOT_SUPPORTED; 00464 } 00465 00466 NTSTATUS 00467 NTAPI 00468 PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension, 00469 IN PCI_SLOT_NUMBER Slot, 00470 OUT PDEVICE_OBJECT *PdoDeviceObject) 00471 { 00472 WCHAR DeviceName[32]; 00473 UNICODE_STRING DeviceString; 00474 NTSTATUS Status; 00475 PDEVICE_OBJECT DeviceObject; 00476 PPCI_PDO_EXTENSION PdoExtension; 00477 ULONG SequenceNumber; 00478 PAGED_CODE(); 00479 00480 /* Pick an atomically unique sequence number for this device */ 00481 SequenceNumber = InterlockedIncrement(&PciPdoSequenceNumber); 00482 00483 /* Create the standard PCI device name for a PDO */ 00484 swprintf(DeviceName, L"\\Device\\NTPNP_PCI%04d", SequenceNumber); 00485 RtlInitUnicodeString(&DeviceString, DeviceName); 00486 00487 /* Create the actual device now */ 00488 Status = IoCreateDevice(DeviceExtension->FunctionalDeviceObject->DriverObject, 00489 sizeof(PCI_PDO_EXTENSION), 00490 &DeviceString, 00491 FILE_DEVICE_BUS_EXTENDER, 00492 0, 00493 0, 00494 &DeviceObject); 00495 ASSERT(NT_SUCCESS(Status)); 00496 00497 /* Get the extension for it */ 00498 PdoExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension; 00499 DPRINT1("PCI: New PDO (b=0x%x, d=0x%x, f=0x%x) @ %p, ext @ %p\n", 00500 DeviceExtension->BaseBus, 00501 Slot.u.bits.DeviceNumber, 00502 Slot.u.bits.FunctionNumber, 00503 DeviceObject, 00504 DeviceObject->DeviceExtension); 00505 00506 /* Configure the extension */ 00507 PdoExtension->ExtensionType = PciPdoExtensionType; 00508 PdoExtension->IrpDispatchTable = &PciPdoDispatchTable; 00509 PdoExtension->PhysicalDeviceObject = DeviceObject; 00510 PdoExtension->Slot = Slot; 00511 PdoExtension->PowerState.CurrentSystemState = PowerDeviceD0; 00512 PdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0; 00513 PdoExtension->ParentFdoExtension = DeviceExtension; 00514 00515 /* Initialize the lock for arbiters and other interfaces */ 00516 KeInitializeEvent(&PdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE); 00517 00518 /* Initialize the state machine */ 00519 PciInitializeState((PPCI_FDO_EXTENSION)PdoExtension); 00520 00521 /* Add the PDO to the parent's list */ 00522 PdoExtension->Next = NULL; 00523 PciInsertEntryAtTail((PSINGLE_LIST_ENTRY)&DeviceExtension->ChildPdoList, 00524 (PPCI_FDO_EXTENSION)PdoExtension, 00525 &DeviceExtension->ChildListLock); 00526 00527 /* And finally return it to the caller */ 00528 *PdoDeviceObject = DeviceObject; 00529 return STATUS_SUCCESS; 00530 } 00531 00532 /* EOF */ Generated on Sun May 27 2012 04:27:27 for ReactOS by
1.7.6.1
|