ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fdo.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/fdo.c
00005  * PURPOSE:         FDO 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 SINGLE_LIST_ENTRY PciFdoExtensionListHead;
00018 BOOLEAN PciBreakOnDefault;
00019 
00020 PCI_MN_DISPATCH_TABLE PciFdoDispatchPowerTable[] =
00021 {
00022     {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoWaitWake},
00023     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00024     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoSetPowerState},
00025     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryPower},
00026     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
00027 };
00028 
00029 PCI_MN_DISPATCH_TABLE PciFdoDispatchPnpTable[] =
00030 {
00031     {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpStartDevice},
00032     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryRemoveDevice},
00033     {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpRemoveDevice},
00034     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelRemoveDevice},
00035     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpStopDevice},
00036     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryStopDevice},
00037     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelStopDevice},
00038     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryDeviceRelations},
00039     {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryInterface},
00040     {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryCapabilities},
00041     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00042     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00043     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00044     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00045     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00046     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00047     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00048     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00049     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00050     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00051     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00052     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
00053     {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpDeviceUsageNotification},
00054     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpSurpriseRemoval},
00055     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryLegacyBusInformation},
00056     {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
00057 };
00058 
00059 PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable =
00060 {
00061     IRP_MN_QUERY_LEGACY_BUS_INFORMATION,
00062     PciFdoDispatchPnpTable,
00063     IRP_MN_QUERY_POWER,
00064     PciFdoDispatchPowerTable,
00065     IRP_DOWNWARD,
00066     (PCI_DISPATCH_FUNCTION)PciIrpNotSupported,
00067     IRP_DOWNWARD,
00068     (PCI_DISPATCH_FUNCTION)PciIrpNotSupported
00069 };
00070 
00071 /* FUNCTIONS ******************************************************************/
00072 
00073 NTSTATUS
00074 NTAPI
00075 PciFdoIrpStartDevice(IN PIRP Irp,
00076                      IN PIO_STACK_LOCATION IoStackLocation,
00077                      IN PPCI_FDO_EXTENSION DeviceExtension)
00078 {
00079     NTSTATUS Status;
00080     PCM_RESOURCE_LIST Resources;
00081     PAGED_CODE();
00082 
00083     /* The device stack must be starting the FDO in a success path */
00084     if (!NT_SUCCESS(Irp->IoStatus.Status)) return STATUS_NOT_SUPPORTED;
00085 
00086     /* Attempt to switch the state machine to the started state */
00087     Status = PciBeginStateTransition(DeviceExtension, PciStarted);
00088     if (!NT_SUCCESS(Status)) return Status;
00089 
00090     /* Check for any boot-provided resources */
00091     Resources = IoStackLocation->Parameters.StartDevice.AllocatedResources;
00092     if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
00093     {
00094         /* These resources would only be for non-root FDOs, unhandled for now */
00095         ASSERT(Resources->Count == 1);
00096         UNIMPLEMENTED;
00097         while (TRUE);
00098     }
00099 
00100     /* Initialize the arbiter for this FDO */
00101     Status = PciInitializeArbiterRanges(DeviceExtension, Resources);
00102     if (!NT_SUCCESS(Status))
00103     {
00104         /* Cancel the transition if this failed */
00105         PciCancelStateTransition(DeviceExtension, PciStarted);
00106         return Status;
00107     }
00108 
00109     /* Again, check for boot-provided resources for non-root FDO */
00110     if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
00111     {
00112         /* Unhandled for now */
00113         ASSERT(Resources->Count == 1);
00114         UNIMPLEMENTED;
00115         while (TRUE);
00116     }
00117 
00118     /* Commit the transition to the started state */
00119     PciCommitStateTransition(DeviceExtension, PciStarted);
00120     return STATUS_SUCCESS;
00121 }
00122 
00123 NTSTATUS
00124 NTAPI
00125 PciFdoIrpQueryRemoveDevice(IN PIRP Irp,
00126                            IN PIO_STACK_LOCATION IoStackLocation,
00127                            IN PPCI_FDO_EXTENSION DeviceExtension)
00128 {
00129     UNIMPLEMENTED;
00130     return STATUS_NOT_SUPPORTED;
00131 }
00132 
00133 NTSTATUS
00134 NTAPI
00135 PciFdoIrpRemoveDevice(IN PIRP Irp,
00136                       IN PIO_STACK_LOCATION IoStackLocation,
00137                       IN PPCI_FDO_EXTENSION DeviceExtension)
00138 {
00139     UNIMPLEMENTED;
00140     while (TRUE);
00141     return STATUS_NOT_SUPPORTED;
00142 }
00143 
00144 NTSTATUS
00145 NTAPI
00146 PciFdoIrpCancelRemoveDevice(IN PIRP Irp,
00147                             IN PIO_STACK_LOCATION IoStackLocation,
00148                             IN PPCI_FDO_EXTENSION DeviceExtension)
00149 {
00150     UNIMPLEMENTED;
00151     while (TRUE);
00152     return STATUS_NOT_SUPPORTED;
00153 }
00154 
00155 NTSTATUS
00156 NTAPI
00157 PciFdoIrpStopDevice(IN PIRP Irp,
00158                     IN PIO_STACK_LOCATION IoStackLocation,
00159                     IN PPCI_FDO_EXTENSION DeviceExtension)
00160 {
00161     UNIMPLEMENTED;
00162     while (TRUE);
00163     return STATUS_NOT_SUPPORTED;
00164 }
00165 
00166 NTSTATUS
00167 NTAPI
00168 PciFdoIrpQueryStopDevice(IN PIRP Irp,
00169                          IN PIO_STACK_LOCATION IoStackLocation,
00170                          IN PPCI_FDO_EXTENSION DeviceExtension)
00171 {
00172     UNIMPLEMENTED;
00173     while (TRUE);
00174     return STATUS_NOT_SUPPORTED;
00175 }
00176 
00177 NTSTATUS
00178 NTAPI
00179 PciFdoIrpCancelStopDevice(IN PIRP Irp,
00180                           IN PIO_STACK_LOCATION IoStackLocation,
00181                           IN PPCI_FDO_EXTENSION DeviceExtension)
00182 {
00183     UNIMPLEMENTED;
00184     while (TRUE);
00185     return STATUS_NOT_SUPPORTED;
00186 }
00187 
00188 NTSTATUS
00189 NTAPI
00190 PciFdoIrpQueryDeviceRelations(IN PIRP Irp,
00191                               IN PIO_STACK_LOCATION IoStackLocation,
00192                               IN PPCI_FDO_EXTENSION DeviceExtension)
00193 {
00194     NTSTATUS Status;
00195     PAGED_CODE();
00196 
00197     /* Are bus relations being queried? */
00198     if (IoStackLocation->Parameters.QueryDeviceRelations.Type != BusRelations)
00199     {
00200         /* The FDO is a bus, so only bus relations can be obtained */
00201         Status = STATUS_NOT_SUPPORTED;
00202     }
00203     else
00204     {
00205         /* Scan the PCI bus and build the device relations for the caller */
00206         Status = PciQueryDeviceRelations(DeviceExtension,
00207                                          (PDEVICE_RELATIONS*)
00208                                          &Irp->IoStatus.Information);
00209     }
00210 
00211     /* Return the enumeration status back */
00212     return Status;
00213 }
00214 
00215 NTSTATUS
00216 NTAPI
00217 PciFdoIrpQueryInterface(IN PIRP Irp,
00218                         IN PIO_STACK_LOCATION IoStackLocation,
00219                         IN PPCI_FDO_EXTENSION DeviceExtension)
00220 {
00221     NTSTATUS Status;
00222     PAGED_CODE();
00223     ASSERT(DeviceExtension->ExtensionType == PciFdoExtensionType);
00224 
00225     /* Deleted extensions don't respond to IRPs */
00226     if (DeviceExtension->DeviceState == PciDeleted)
00227     {
00228         /* Hand it back to try to deal with it */
00229         return PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
00230     }
00231 
00232     /* Query our driver for this interface */
00233     Status = PciQueryInterface(DeviceExtension,
00234                                IoStackLocation->Parameters.QueryInterface.
00235                                InterfaceType,
00236                                IoStackLocation->Parameters.QueryInterface.
00237                                Size,
00238                                IoStackLocation->Parameters.QueryInterface.
00239                                Version,
00240                                IoStackLocation->Parameters.QueryInterface.
00241                                InterfaceSpecificData,
00242                                IoStackLocation->Parameters.QueryInterface.
00243                                Interface,
00244                                FALSE);
00245     if (NT_SUCCESS(Status))
00246     {
00247         /* We found it, let the PDO handle it */
00248         Irp->IoStatus.Status = Status;
00249         return PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
00250     }
00251     else if (Status == STATUS_NOT_SUPPORTED)
00252     {
00253         /* Otherwise, we can't handle it, let someone else down the stack try */
00254         Status = PciCallDownIrpStack(DeviceExtension, Irp);
00255         if (Status == STATUS_NOT_SUPPORTED)
00256         {
00257             /* They can't either, try a last-resort interface lookup */
00258             Status = PciQueryInterface(DeviceExtension,
00259                                        IoStackLocation->Parameters.QueryInterface.
00260                                        InterfaceType,
00261                                        IoStackLocation->Parameters.QueryInterface.
00262                                        Size,
00263                                        IoStackLocation->Parameters.QueryInterface.
00264                                        Version,
00265                                        IoStackLocation->Parameters.QueryInterface.
00266                                        InterfaceSpecificData,
00267                                        IoStackLocation->Parameters.QueryInterface.
00268                                        Interface,
00269                                        TRUE);
00270         }
00271     }
00272 
00273     /* Has anyone claimed this interface yet? */
00274     if (Status == STATUS_NOT_SUPPORTED)
00275     {
00276         /* No, return the original IRP status */
00277         Status = Irp->IoStatus.Status;
00278     }
00279     else
00280     {
00281         /* Yes, set the new IRP status */
00282         Irp->IoStatus.Status = Status;
00283     }
00284 
00285     /* Complete this IRP */
00286     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00287     return Status;
00288 }
00289 
00290 NTSTATUS
00291 NTAPI
00292 PciFdoIrpQueryCapabilities(IN PIRP Irp,
00293                            IN PIO_STACK_LOCATION IoStackLocation,
00294                            IN PPCI_FDO_EXTENSION DeviceExtension)
00295 {
00296     PDEVICE_CAPABILITIES Capabilities;
00297     PAGED_CODE();
00298     ASSERT_FDO(DeviceExtension);
00299 
00300     /* Get the capabilities */
00301     Capabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities;
00302 
00303     /* Inherit wake levels and power mappings from the higher-up capabilities */
00304     DeviceExtension->PowerState.SystemWakeLevel = Capabilities->SystemWake;
00305     DeviceExtension->PowerState.DeviceWakeLevel = Capabilities->DeviceWake;
00306     RtlCopyMemory(DeviceExtension->PowerState.SystemStateMapping,
00307                   Capabilities->DeviceState,
00308                   sizeof(DeviceExtension->PowerState.SystemStateMapping));
00309 
00310     /* Dump the capabilities and return success */
00311     PciDebugDumpQueryCapabilities(Capabilities);
00312     return STATUS_SUCCESS;
00313 }
00314 
00315 NTSTATUS
00316 NTAPI
00317 PciFdoIrpDeviceUsageNotification(IN PIRP Irp,
00318                                  IN PIO_STACK_LOCATION IoStackLocation,
00319                                  IN PPCI_FDO_EXTENSION DeviceExtension)
00320 {
00321     UNIMPLEMENTED;
00322     while (TRUE);
00323     return STATUS_NOT_SUPPORTED;
00324 }
00325 
00326 NTSTATUS
00327 NTAPI
00328 PciFdoIrpSurpriseRemoval(IN PIRP Irp,
00329                          IN PIO_STACK_LOCATION IoStackLocation,
00330                          IN PPCI_FDO_EXTENSION DeviceExtension)
00331 {
00332     UNIMPLEMENTED;
00333     while (TRUE);
00334     return STATUS_NOT_SUPPORTED;
00335 }
00336 
00337 NTSTATUS
00338 NTAPI
00339 PciFdoIrpQueryLegacyBusInformation(IN PIRP Irp,
00340                                    IN PIO_STACK_LOCATION IoStackLocation,
00341                                    IN PPCI_FDO_EXTENSION DeviceExtension)
00342 {
00343     UNIMPLEMENTED;
00344     while (TRUE);
00345     return STATUS_NOT_SUPPORTED;
00346 }
00347 
00348 VOID
00349 NTAPI
00350 PciGetHotPlugParameters(IN PPCI_FDO_EXTENSION FdoExtension)
00351 {
00352     ACPI_EVAL_INPUT_BUFFER InputBuffer;
00353     PACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
00354     ULONG Length;
00355     NTSTATUS Status;
00356     PAGED_CODE();
00357 
00358     /* We should receive 4 parameters, per the HPP specification */
00359     Length = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 4 * sizeof(ACPI_METHOD_ARGUMENT);
00360 
00361     /* Allocate the buffer to hold the parameters */
00362     OutputBuffer = ExAllocatePoolWithTag(PagedPool, Length, PCI_POOL_TAG);
00363     if (!OutputBuffer) return;
00364 
00365     /* Initialize the output and input buffers. The method is _HPP */
00366     RtlZeroMemory(OutputBuffer, Length);
00367     *(PULONG)InputBuffer.MethodName = 'PPH_';
00368     InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
00369     do
00370     {
00371         /* Send the IOCTL to the ACPI driver */
00372         Status = PciSendIoctl(FdoExtension->PhysicalDeviceObject,
00373                               IOCTL_ACPI_EVAL_METHOD,
00374                               &InputBuffer,
00375                               sizeof(InputBuffer),
00376                               OutputBuffer,
00377                               Length);
00378         if (!NT_SUCCESS(Status))
00379         {
00380             /* The method failed, check if we can salvage data from parent */
00381             if (!PCI_IS_ROOT_FDO(FdoExtension))
00382             {
00383                 /* Copy the root bus' hot plug parameters */
00384                 FdoExtension->HotPlugParameters = FdoExtension->ParentFdoExtension->HotPlugParameters;
00385             }
00386 
00387             /* Nothing more to do on this path */
00388             break;
00389         }
00390 
00391         /* ACPI sent back some data. 4 parameters are expected in the output */
00392         if (OutputBuffer->Count != 4) break;
00393 
00394         /* HotPlug PCI Support not yet implemented */
00395         UNIMPLEMENTED;
00396         while (TRUE);
00397     } while (FALSE);
00398 
00399     /* Free the buffer and return */
00400     ExFreePoolWithTag(OutputBuffer, 0);
00401 }
00402 
00403 VOID
00404 NTAPI
00405 PciInitializeFdoExtensionCommonFields(PPCI_FDO_EXTENSION FdoExtension,
00406                                       IN PDEVICE_OBJECT DeviceObject,
00407                                       IN PDEVICE_OBJECT PhysicalDeviceObject)
00408 {
00409     /* Initialize the extension */
00410     RtlZeroMemory(FdoExtension, sizeof(PCI_FDO_EXTENSION));
00411 
00412     /* Setup the common fields */
00413     FdoExtension->PhysicalDeviceObject = PhysicalDeviceObject;
00414     FdoExtension->FunctionalDeviceObject = DeviceObject;
00415     FdoExtension->ExtensionType = PciFdoExtensionType;
00416     FdoExtension->PowerState.CurrentSystemState = PowerSystemWorking;
00417     FdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
00418     FdoExtension->IrpDispatchTable = &PciFdoDispatchTable;
00419 
00420     /* Initialize the extension locks */
00421     KeInitializeEvent(&FdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE);
00422     KeInitializeEvent(&FdoExtension->ChildListLock, SynchronizationEvent, TRUE);
00423 
00424     /* Initialize the default state */
00425     PciInitializeState(FdoExtension);
00426 }
00427 
00428 NTSTATUS
00429 NTAPI
00430 PciAddDevice(IN PDRIVER_OBJECT DriverObject,
00431              IN PDEVICE_OBJECT PhysicalDeviceObject)
00432 {
00433     PCM_RESOURCE_LIST Descriptor;
00434     PDEVICE_OBJECT AttachedTo;
00435     PPCI_FDO_EXTENSION FdoExtension;
00436     PPCI_FDO_EXTENSION ParentExtension;
00437     PPCI_PDO_EXTENSION PdoExtension;
00438     PDEVICE_OBJECT DeviceObject;
00439     UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
00440     PKEY_VALUE_PARTIAL_INFORMATION ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
00441     NTSTATUS Status;
00442     HANDLE KeyHandle;
00443     UNICODE_STRING ValueName;
00444     ULONG ResultLength;
00445     PAGED_CODE();
00446     DPRINT1("PCI - AddDevice (a new bus). PDO: %p (Driver: %wZ)\n",
00447             PhysicalDeviceObject, &PhysicalDeviceObject->DriverObject->DriverName);
00448 
00449     /* Zero out variables so failure path knows what to do */
00450     AttachedTo = NULL;
00451     FdoExtension = NULL;
00452     PdoExtension = NULL;
00453     do
00454     {
00455         /* Check if there's already a device extension for this bus */
00456         ParentExtension = PciFindParentPciFdoExtension(PhysicalDeviceObject,
00457                                                        &PciGlobalLock);
00458         if (ParentExtension)
00459         {
00460             /* Make sure we find a real PDO */
00461             PdoExtension = PhysicalDeviceObject->DeviceExtension;
00462             ASSERT_PDO(PdoExtension);
00463 
00464             /* Make sure it's a PCI-to-PCI bridge */
00465             if ((PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) ||
00466                 (PdoExtension->SubClass != PCI_SUBCLASS_BR_PCI_TO_PCI))
00467             {
00468                 /* This should never happen */
00469                 DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n"
00470                         "      Class %02x, SubClass %02x, will not add.\n",
00471                         PdoExtension->BaseClass,
00472                         PdoExtension->SubClass);
00473                 ASSERT((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
00474                        (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI));
00475 
00476                 /* Enter the failure path */
00477                 Status = STATUS_INVALID_DEVICE_REQUEST;
00478                 break;
00479             }
00480 
00481             /* Subordinate bus on the bridge */
00482             DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n",
00483                     ParentExtension->BaseBus);
00484 
00485             /* Make sure PCI bus numbers are configured */
00486             if (!PciAreBusNumbersConfigured(PdoExtension))
00487             {
00488                 /* This is a critical failure */
00489                 DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n",
00490                         ParentExtension->BaseBus,
00491                         PdoExtension->Slot.u.bits.DeviceNumber,
00492                         PdoExtension->Slot.u.bits.FunctionNumber);
00493 
00494                 /* Enter the failure path */
00495                 Status = STATUS_INVALID_DEVICE_REQUEST;
00496                 break;
00497             }
00498         }
00499 
00500         /* Create the FDO for the bus */
00501         Status = IoCreateDevice(DriverObject,
00502                                 sizeof(PCI_FDO_EXTENSION),
00503                                 NULL,
00504                                 FILE_DEVICE_BUS_EXTENDER,
00505                                 0,
00506                                 0,
00507                                 &DeviceObject);
00508         if (!NT_SUCCESS(Status)) break;
00509 
00510         /* Initialize the extension for the FDO */
00511         FdoExtension = DeviceObject->DeviceExtension;
00512         PciInitializeFdoExtensionCommonFields(DeviceObject->DeviceExtension,
00513                                               DeviceObject,
00514                                               PhysicalDeviceObject);
00515 
00516         /* Attach to the root PDO */
00517         Status = STATUS_NO_SUCH_DEVICE;
00518         AttachedTo = IoAttachDeviceToDeviceStack(DeviceObject,
00519                                                  PhysicalDeviceObject);
00520         ASSERT(AttachedTo != NULL);
00521         if (!AttachedTo) break;
00522         FdoExtension->AttachedDeviceObject = AttachedTo;
00523 
00524         /* Check if this is a child bus, or the root */
00525         if (ParentExtension)
00526         {
00527             /* The child inherits root data */
00528             FdoExtension->BaseBus = PdoExtension->Dependent.type1.SecondaryBus;
00529             FdoExtension->BusRootFdoExtension = ParentExtension->BusRootFdoExtension;
00530             PdoExtension->BridgeFdoExtension = FdoExtension;
00531             FdoExtension->ParentFdoExtension = ParentExtension;
00532         }
00533         else
00534         {
00535             /* Query the boot configuration */
00536             Status = PciGetDeviceProperty(PhysicalDeviceObject,
00537                                           DevicePropertyBootConfiguration,
00538                                           (PVOID*)&Descriptor);
00539             if (!NT_SUCCESS(Status))
00540             {
00541                 /* No configuration has been set */
00542                 Descriptor = NULL;
00543             }
00544             else
00545             {
00546                 /* Root PDO in ReactOS does not assign boot resources */
00547                 UNIMPLEMENTED;
00548 //                while (TRUE);
00549                 DPRINT1("Encountered during setup\n");
00550                 Descriptor = NULL;
00551             }
00552 
00553             if (Descriptor)
00554             {
00555                 /* Root PDO in ReactOS does not assign boot resources */
00556                 UNIMPLEMENTED;
00557                 while (TRUE);
00558             }
00559             else
00560             {
00561                 /* Default configuration isn't the normal path on Windows */
00562                 if (PciBreakOnDefault)
00563                 {
00564                     /* If a second bus is found and there's still no data, crash */
00565                     KeBugCheckEx(PCI_BUS_DRIVER_INTERNAL,
00566                                  0xDEAD0010u,
00567                                  (ULONG_PTR)DeviceObject,
00568                                  0,
00569                                  0);
00570                 }
00571 
00572                 /* Warn that a default configuration will be used, and set bus 0 */
00573                 DPRINT1("PCI   Will use default configuration.\n");
00574                 PciBreakOnDefault = TRUE;
00575                 FdoExtension->BaseBus = 0;
00576             }
00577 
00578             /* This is the root bus */
00579             FdoExtension->BusRootFdoExtension = FdoExtension;
00580         }
00581 
00582         /* Get the HAL or ACPI Bus Handler Callbacks for Configuration Access */
00583         Status = PciGetConfigHandlers(FdoExtension);
00584         if (!NT_SUCCESS(Status)) break;
00585 
00586         /* Initialize all the supported PCI arbiters */
00587         Status = PciInitializeArbiters(FdoExtension);
00588         if (!NT_SUCCESS(Status)) break;
00589 
00590         /* This is a real FDO, insert it into the list */
00591         FdoExtension->Fake = FALSE;
00592         PciInsertEntryAtTail(&PciFdoExtensionListHead,
00593                              FdoExtension,
00594                              &PciGlobalLock);
00595 
00596         /* Open the device registry key so that we can query the errata flags */
00597         IoOpenDeviceRegistryKey(DeviceObject,
00598                                 PLUGPLAY_REGKEY_DEVICE,
00599                                 KEY_ALL_ACCESS,
00600                                 &KeyHandle),
00601 
00602         /* Open the value that contains errata flags for this bus instance */
00603         RtlInitUnicodeString(&ValueName, L"HackFlags");
00604         Status = ZwQueryValueKey(KeyHandle,
00605                                  &ValueName,
00606                                  KeyValuePartialInformation,
00607                                  ValueInfo,
00608                                  sizeof(Buffer),
00609                                  &ResultLength);
00610         ZwClose(KeyHandle);
00611         if (NT_SUCCESS(Status))
00612         {
00613             /* Make sure the data is of expected type and size */
00614             if ((ValueInfo->Type == REG_DWORD) &&
00615                 (ValueInfo->DataLength == sizeof(ULONG)))
00616             {
00617                 /* Read the flags for this bus */
00618                 FdoExtension->BusHackFlags = *(PULONG)&ValueInfo->Data;
00619             }
00620         }
00621 
00622         /* Query ACPI for PCI HotPlug Support */
00623         PciGetHotPlugParameters(FdoExtension);
00624 
00625         /* The Bus FDO is now initialized */
00626         DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
00627         return STATUS_SUCCESS;
00628     } while (FALSE);
00629 
00630     /* This is the failure path */
00631     ASSERT(!NT_SUCCESS(Status));
00632 
00633     /* Check if the FDO extension exists */
00634     if (FdoExtension) DPRINT1("Should destroy secondaries\n");
00635 
00636     /* Delete device objects */
00637     if (AttachedTo) IoDetachDevice(AttachedTo);
00638     if (DeviceObject) IoDeleteDevice(DeviceObject);
00639     return Status;
00640 }
00641 
00642 /* EOF */

Generated on Fri May 25 2012 04:25:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.