[USB]
[reactos.git] / reactos / drivers / bus / pcix / fdo.c
index bee6e7b..785dfca 100644 (file)
@@ -19,41 +19,41 @@ BOOLEAN PciBreakOnDefault;
 
 PCI_MN_DISPATCH_TABLE PciFdoDispatchPowerTable[] =
 {
-    {IRP_DISPATCH, PciFdoWaitWake},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciFdoSetPowerState},
-    {IRP_DOWNWARD, PciFdoIrpQueryPower},
-    {IRP_DOWNWARD, PciIrpNotSupported}
+    {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoWaitWake},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoSetPowerState},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryPower},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
 };
 
 PCI_MN_DISPATCH_TABLE PciFdoDispatchPnpTable[] =
 {
-    {IRP_UPWARD,   PciFdoIrpStartDevice},
-    {IRP_DOWNWARD, PciFdoIrpQueryRemoveDevice},
-    {IRP_DISPATCH, PciFdoIrpRemoveDevice},
-    {IRP_DOWNWARD, PciFdoIrpCancelRemoveDevice},
-    {IRP_DOWNWARD, PciFdoIrpStopDevice},
-    {IRP_DOWNWARD, PciFdoIrpQueryStopDevice},
-    {IRP_DOWNWARD, PciFdoIrpCancelStopDevice},
-    {IRP_DOWNWARD, PciFdoIrpQueryDeviceRelations},
-    {IRP_DISPATCH, PciFdoIrpQueryInterface},
-    {IRP_UPWARD,   PciFdoIrpQueryCapabilities},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_DOWNWARD, PciIrpNotSupported},
-    {IRP_UPWARD,   PciFdoIrpDeviceUsageNotification},
-    {IRP_DOWNWARD, PciFdoIrpSurpriseRemoval},
-    {IRP_DOWNWARD, PciFdoIrpQueryLegacyBusInformation},
-    {IRP_DOWNWARD, PciIrpNotSupported}
+    {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpStartDevice},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryRemoveDevice},
+    {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpRemoveDevice},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelRemoveDevice},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpStopDevice},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryStopDevice},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpCancelStopDevice},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryDeviceRelations},
+    {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryInterface},
+    {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryCapabilities},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+    {IRP_UPWARD,   (PCI_DISPATCH_FUNCTION)PciFdoIrpDeviceUsageNotification},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpSurpriseRemoval},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciFdoIrpQueryLegacyBusInformation},
+    {IRP_DOWNWARD, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
 };
 
 PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable =
@@ -63,9 +63,9 @@ PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable =
     IRP_MN_QUERY_POWER,
     PciFdoDispatchPowerTable,
     IRP_DOWNWARD,
-    PciIrpNotSupported,
+    (PCI_DISPATCH_FUNCTION)PciIrpNotSupported,
     IRP_DOWNWARD,
-    PciIrpNotSupported
+    (PCI_DISPATCH_FUNCTION)PciIrpNotSupported
 };
 
 /* FUNCTIONS ******************************************************************/
@@ -89,7 +89,6 @@ 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 */
@@ -128,7 +127,6 @@ PciFdoIrpQueryRemoveDevice(IN PIRP Irp,
                            IN PPCI_FDO_EXTENSION DeviceExtension)
 {
     UNIMPLEMENTED;
-    while (TRUE);
     return STATUS_NOT_SUPPORTED;
 }
 
@@ -227,7 +225,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 +293,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
@@ -422,6 +434,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 +448,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 +457,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 +520,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
         {
@@ -491,7 +545,9 @@ PciAddDevice(IN PDRIVER_OBJECT DriverObject,
             {
                 /* Root PDO in ReactOS does not assign boot resources */
                 UNIMPLEMENTED;
-                while (TRUE);
+//                while (TRUE);
+                DPRINT1("Encountered during setup\n");
+                Descriptor = NULL;
             }
 
             if (Descriptor)
@@ -568,12 +624,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;