Sync with trunk r58740.
[reactos.git] / drivers / bus / pcix / fdo.c
index 256df1a..fbb6971 100644 (file)
@@ -89,13 +89,11 @@ PciFdoIrpStartDevice(IN PIRP Irp,
 
     /* Check for any boot-provided resources */
     Resources = IoStackLocation->Parameters.StartDevice.AllocatedResources;
-    DPRINT1("Resources: %p\n", Resources);
     if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
     {
         /* These resources would only be for non-root FDOs, unhandled for now */
         ASSERT(Resources->Count == 1);
-        UNIMPLEMENTED;
-        while (TRUE);
+        UNIMPLEMENTED_DBGBREAK();
     }
 
     /* Initialize the arbiter for this FDO */
@@ -112,8 +110,7 @@ PciFdoIrpStartDevice(IN PIRP Irp,
     {
         /* Unhandled for now */
         ASSERT(Resources->Count == 1);
-        UNIMPLEMENTED;
-        while (TRUE);
+        UNIMPLEMENTED_DBGBREAK();
     }
 
     /* Commit the transition to the started state */
@@ -128,7 +125,6 @@ PciFdoIrpQueryRemoveDevice(IN PIRP Irp,
                            IN PPCI_FDO_EXTENSION DeviceExtension)
 {
     UNIMPLEMENTED;
-    while (TRUE);
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -138,8 +134,7 @@ PciFdoIrpRemoveDevice(IN PIRP Irp,
                       IN PIO_STACK_LOCATION IoStackLocation,
                       IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -149,8 +144,7 @@ PciFdoIrpCancelRemoveDevice(IN PIRP Irp,
                             IN PIO_STACK_LOCATION IoStackLocation,
                             IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -160,8 +154,7 @@ PciFdoIrpStopDevice(IN PIRP Irp,
                     IN PIO_STACK_LOCATION IoStackLocation,
                     IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -171,8 +164,7 @@ PciFdoIrpQueryStopDevice(IN PIRP Irp,
                          IN PIO_STACK_LOCATION IoStackLocation,
                          IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -182,8 +174,7 @@ PciFdoIrpCancelStopDevice(IN PIRP Irp,
                           IN PIO_STACK_LOCATION IoStackLocation,
                           IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -227,7 +218,7 @@ PciFdoIrpQueryInterface(IN PIRP Irp,
     /* Deleted extensions don't respond to IRPs */
     if (DeviceExtension->DeviceState == PciDeleted)
     {
-        /* Hand it bacO try to deal with it */
+        /* Hand it back to try to deal with it */
         return PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
     }
 
@@ -295,9 +286,23 @@ PciFdoIrpQueryCapabilities(IN PIRP Irp,
                            IN PIO_STACK_LOCATION IoStackLocation,
                            IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_NOT_SUPPORTED;
+    PDEVICE_CAPABILITIES Capabilities;
+    PAGED_CODE();
+    ASSERT_FDO(DeviceExtension);
+
+    /* Get the capabilities */
+    Capabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities;
+
+    /* Inherit wake levels and power mappings from the higher-up capabilities */
+    DeviceExtension->PowerState.SystemWakeLevel = Capabilities->SystemWake;
+    DeviceExtension->PowerState.DeviceWakeLevel = Capabilities->DeviceWake;
+    RtlCopyMemory(DeviceExtension->PowerState.SystemStateMapping,
+                  Capabilities->DeviceState,
+                  sizeof(DeviceExtension->PowerState.SystemStateMapping));
+
+    /* Dump the capabilities and return success */
+    PciDebugDumpQueryCapabilities(Capabilities);
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -306,8 +311,7 @@ PciFdoIrpDeviceUsageNotification(IN PIRP Irp,
                                  IN PIO_STACK_LOCATION IoStackLocation,
                                  IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -317,8 +321,7 @@ PciFdoIrpSurpriseRemoval(IN PIRP Irp,
                          IN PIO_STACK_LOCATION IoStackLocation,
                          IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -328,8 +331,7 @@ PciFdoIrpQueryLegacyBusInformation(IN PIRP Irp,
                                    IN PIO_STACK_LOCATION IoStackLocation,
                                    IN PPCI_FDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
+    UNIMPLEMENTED_DBGBREAK();
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -380,8 +382,7 @@ PciGetHotPlugParameters(IN PPCI_FDO_EXTENSION FdoExtension)
         if (OutputBuffer->Count != 4) break;
 
         /* HotPlug PCI Support not yet implemented */
-        UNIMPLEMENTED;
-        while (TRUE);
+        UNIMPLEMENTED_DBGBREAK();
     } while (FALSE);
 
     /* Free the buffer and return */
@@ -422,6 +423,7 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
     PDEVICE_OBJECT AttachedTo;
     PPCI_FDO_EXTENSION FdoExtension;
     PPCI_FDO_EXTENSION ParentExtension;
+    PPCI_PDO_EXTENSION PdoExtension;
     PDEVICE_OBJECT DeviceObject;
     UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
     PKEY_VALUE_PARTIAL_INFORMATION ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
@@ -435,6 +437,8 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
 
     /* Zero out variables so failure path knows what to do */
     AttachedTo = NULL;
+    FdoExtension = NULL;
+    PdoExtension = NULL;
     do
     {
         /* Check if there's already a device extension for this bus */
@@ -442,9 +446,44 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
                                                        &PciGlobalLock);
         if (ParentExtension)
         {
-            /* More than one PCI bus, this is not expected yet */
-            UNIMPLEMENTED;
-            while (TRUE);
+            /* Make sure we find a real PDO */
+            PdoExtension = PhysicalDeviceObject->DeviceExtension;
+            ASSERT_PDO(PdoExtension);
+
+            /* Make sure it's a PCI-to-PCI bridge */
+            if ((PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) ||
+                (PdoExtension->SubClass != PCI_SUBCLASS_BR_PCI_TO_PCI))
+            {
+                /* This should never happen */
+                DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n"
+                        "      Class %02x, SubClass %02x, will not add.\n",
+                        PdoExtension->BaseClass,
+                        PdoExtension->SubClass);
+                ASSERT((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
+                       (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI));
+
+                /* Enter the failure path */
+                Status = STATUS_INVALID_DEVICE_REQUEST;
+                break;
+            }
+
+            /* Subordinate bus on the bridge */
+            DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n",
+                    ParentExtension->BaseBus);
+
+            /* Make sure PCI bus numbers are configured */
+            if (!PciAreBusNumbersConfigured(PdoExtension))
+            {
+                /* This is a critical failure */
+                DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n",
+                        ParentExtension->BaseBus,
+                        PdoExtension->Slot.u.bits.DeviceNumber,
+                        PdoExtension->Slot.u.bits.FunctionNumber);
+
+                /* Enter the failure path */
+                Status = STATUS_INVALID_DEVICE_REQUEST;
+                break;
+            }
         }
 
         /* Create the FDO for the bus */
@@ -470,11 +509,15 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
         ASSERT(AttachedTo != NULL);
         if (!AttachedTo) break;
         FdoExtension->AttachedDeviceObject = AttachedTo;
+
+        /* Check if this is a child bus, or the root */
         if (ParentExtension)
         {
-            /* More than one PCI bus, this is not expected yet */
-            UNIMPLEMENTED;
-            while (TRUE);
+            /* The child inherits root data */
+            FdoExtension->BaseBus = PdoExtension->Dependent.type1.SecondaryBus;
+            FdoExtension->BusRootFdoExtension = ParentExtension->BusRootFdoExtension;
+            PdoExtension->BridgeFdoExtension = FdoExtension;
+            FdoExtension->ParentFdoExtension = ParentExtension;
         }
         else
         {
@@ -490,15 +533,14 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
             else
             {
                 /* Root PDO in ReactOS does not assign boot resources */
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK("Encountered during setup\n");
+                Descriptor = NULL;
             }
 
             if (Descriptor)
             {
                 /* Root PDO in ReactOS does not assign boot resources */
-                UNIMPLEMENTED;
-                while (TRUE);
+                UNIMPLEMENTED_DBGBREAK();
             }
             else
             {
@@ -506,15 +548,11 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
                 if (PciBreakOnDefault)
                 {
                     /* If a second bus is found and there's still no data, crash */
-                    #if 0 // ros bug?
                     KeBugCheckEx(PCI_BUS_DRIVER_INTERNAL,
                                  0xDEAD0010u,
                                  (ULONG_PTR)DeviceObject,
                                  0,
                                  0);
-                    #else
-                    DPRINT1("Windows would crash!\n");
-                    #endif
                 }
 
                 /* Warn that a default configuration will be used, and set bus 0 */
@@ -572,12 +610,16 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
 
         /* The Bus FDO is now initialized */
         DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-        DPRINT1("PCI Root FDO Added: %p %p\n", DeviceObject, FdoExtension);
         return STATUS_SUCCESS;
     } while (FALSE);
 
     /* This is the failure path */
     ASSERT(!NT_SUCCESS(Status));
+
+    /* Check if the FDO extension exists */
+    if (FdoExtension) DPRINT1("Should destroy secondaries\n");
+
+    /* Delete device objects */
     if (AttachedTo) IoDetachDevice(AttachedTo);
     if (DeviceObject) IoDeleteDevice(DeviceObject);
     return Status;