- Fix the ChangeResourceSetting and the Reset configurator callback parameter names
authorSir Richard <sir_richard@svn.reactos.org>
Sun, 12 Sep 2010 06:03:12 +0000 (06:03 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Sun, 12 Sep 2010 06:03:12 +0000 (06:03 +0000)
- Part support for resource change with PciComputeNewCurrentSettings... full support for PciSetResources, PciUpdateHardware, PcipUpdateHardare
- IRP_MN_START_DEVICE for PDO (PciPdoIrpStartDevice) implement
- PciNextPartialDescriptor, PciDebugPrintCmResList, PciDebugPrintPartialResource helpers implement
- Now full PDO support almost done, PCIX driver ready for test
- Thanks to cgoodman assert fix
- PnP forever recursion in enumerate, must fix to finish
- Goodbye sir_richard, nice to have you

svn path=/trunk/; revision=48748

reactos/drivers/bus/pcix/debug.c
reactos/drivers/bus/pcix/device.c
reactos/drivers/bus/pcix/enum.c
reactos/drivers/bus/pcix/fdo.c
reactos/drivers/bus/pcix/intrface/cardbus.c
reactos/drivers/bus/pcix/pci.h
reactos/drivers/bus/pcix/pci/ppbridge.c
reactos/drivers/bus/pcix/pdo.c
reactos/drivers/bus/pcix/utils.c

index 8f1ed81..bd2465e 100644 (file)
@@ -341,4 +341,60 @@ PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
     DPRINT1("\n");
 }
 
+VOID
+NTAPI
+PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)
+{
+    /* Dump all the data in the partial */
+    DPRINT1("     Partial Resource Descriptor @0x%x\n", PartialResource);
+    DPRINT1("        Type             = %d (%s)\n", PartialResource->Type, PciDebugCmResourceTypeToText(PartialResource->Type));
+    DPRINT1("        ShareDisposition = %d\n", PartialResource->ShareDisposition);
+    DPRINT1("        Flags            = 0x%04X\n", PartialResource->Flags);
+    DPRINT1("        Data[%d] = %08x  %08x  %08x\n",
+            0,
+            PartialResource->u.Generic.Start.LowPart,
+            PartialResource->u.Generic.Start.HighPart,
+            PartialResource->u.Generic.Length);
+}
+
+VOID
+NTAPI
+PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
+{
+    PCM_FULL_RESOURCE_DESCRIPTOR FullDescriptor;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+    ULONG Count, i, ListCount;
+
+    /* Make sure there's something to dump */
+    if (!PartialList) return;
+
+    /* Get the full list count */
+    ListCount = PartialList->Count;
+    FullDescriptor = PartialList->List;
+    DPRINT1("  CM_RESOURCE_LIST (PCI Bus Driver) (List Count = %d)\n", PartialList->Count);
+    
+    /* Loop full list */
+    for (i = 0; i < ListCount; i++)
+    {
+        /* Loop full descriptor */
+        DPRINT1("     InterfaceType        %d\n", FullDescriptor->InterfaceType);
+        DPRINT1("     BusNumber            0x%x\n", FullDescriptor->BusNumber);
+
+        /* Get partial count and loop partials */
+        Count = FullDescriptor->PartialResourceList.Count;
+        for (PartialDescriptor = FullDescriptor->PartialResourceList.PartialDescriptors;
+             Count;
+             PartialDescriptor = PciNextPartialDescriptor(PartialDescriptor))
+        {
+            /* Print each partial */
+            PciDebugPrintPartialResource(PartialDescriptor);
+            Count--;
+        }
+    }
+
+    /* Done printing data */
+    DPRINT1("\n");
+}
+
+
 /* EOF */
index 4dbd16b..c26fd92 100644 (file)
@@ -267,7 +267,8 @@ Device_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context,
 
 VOID
 NTAPI
-Device_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Device_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension,
+                   IN PPCI_COMMON_HEADER PciData)
 {
     /* Not yet implemented */
     UNIMPLEMENTED;
@@ -276,7 +277,8 @@ Device_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
 
 VOID
 NTAPI
-Device_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Device_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+                              IN PPCI_COMMON_HEADER PciData)
 {
     /* Not yet implemented */
     UNIMPLEMENTED;
index 4e17a7f..1aaebb7 100644 (file)
@@ -49,6 +49,244 @@ PCI_CONFIGURATOR PciConfigurators[] =
 
 /* FUNCTIONS ******************************************************************/
 
+BOOLEAN
+NTAPI
+PciComputeNewCurrentSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+                             IN PCM_RESOURCE_LIST ResourceList)
+{
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, InterruptResource;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR BaseResource, CurrentDescriptor;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PreviousDescriptor;
+    CM_PARTIAL_RESOURCE_DESCRIPTOR ResourceArray[7];
+    PCM_FULL_RESOURCE_DESCRIPTOR FullList;
+    BOOLEAN DrainPartial, RangeChange;
+    ULONG i, j;
+    PPCI_FUNCTION_RESOURCES PciResources;
+    PAGED_CODE();
+
+    /* Make sure we have either no resources, or at least one */
+    ASSERT((ResourceList == NULL) || (ResourceList->Count == 1));
+
+    /* Initialize no partial, interrupt descriptor, or range change */
+    Partial = NULL;
+    InterruptResource = NULL;
+    RangeChange = FALSE;
+
+    /* Check if there's not actually any resources */
+    if (!(ResourceList) || !(ResourceList->Count))
+    {
+        /* Then just return the hardware update state */
+        return PdoExtension->UpdateHardware;
+    }
+
+    /* Print the new specified resource list */
+    PciDebugPrintCmResList(ResourceList);
+
+    /* Clear the temporary resource array */
+    for (i = 0; i < 7; i++) ResourceArray[i].Type = CmResourceTypeNull;
+
+    /* Loop the full resource descriptor */
+    FullList = ResourceList->List;
+    for (i = 0; i < ResourceList->Count; i++)
+    {
+        /* Initialize loop variables */
+        DrainPartial = FALSE;
+        BaseResource = NULL;
+
+        /* Loop the partial descriptors */
+        Partial = FullList->PartialResourceList.PartialDescriptors;
+        for (j = 0; j < FullList->PartialResourceList.Count; j++)
+        {
+            /* Check if we were supposed to drain a partial due to device data */
+            if (DrainPartial)
+            {
+                /* Draining complete, move on to the next descriptor then */
+                DrainPartial--;
+                continue;
+            }
+
+            /* Check what kind of descriptor this was */
+            switch (Partial->Type)
+            {
+                /* Base BAR resources */
+                case CmResourceTypePort:
+                case CmResourceTypeMemory:
+
+                    /* Set it as the base */
+                    ASSERT(BaseResource == NULL);
+                    BaseResource = Partial;
+                    break;
+
+                /* Interrupt resource */
+                case CmResourceTypeInterrupt:
+
+                    /* Make sure it's a compatible (and the only) PCI interrupt */
+                    ASSERT(InterruptResource == NULL);
+                    ASSERT(Partial->u.Interrupt.Level == Partial->u.Interrupt.Vector);
+                    InterruptResource = Partial;
+
+                    /* Only 255 interrupts on x86/x64 hardware */
+                    if (Partial->u.Interrupt.Level < 256)
+                    {
+                        /* Use the passed interrupt line */
+                        PdoExtension->AdjustedInterruptLine = Partial->u.Interrupt.Level;
+                    }
+                    else
+                    {
+                        /* Invalid vector, so ignore it */
+                        PdoExtension->AdjustedInterruptLine = 0;
+                    }
+
+                    break;
+
+                /* Check for specific device data */
+                case CmResourceTypeDevicePrivate:
+
+                    /* Check what kind of data this was */
+                    switch (Partial->u.DevicePrivate.Data[0])
+                    {
+                        /* Not used in the driver yet */
+                        case 1:
+                            UNIMPLEMENTED;
+                            while (TRUE);
+                            break;
+
+                        /* Not used in the driver yet */
+                        case 2:
+                            UNIMPLEMENTED;
+                            while (TRUE);
+                            break;
+
+                        /* A drain request */
+                        case 3:
+                            /* Shouldn't be a base resource, this is a drain */
+                            ASSERT(BaseResource == NULL);
+                            DrainPartial = Partial->u.DevicePrivate.Data[1];
+                            ASSERT(DrainPartial == TRUE);
+                            break;
+                    }
+                    break;
+            }
+
+            /* Move to the next descriptor */
+            Partial = PciNextPartialDescriptor(Partial);
+        }
+
+        /* We should be starting a new list now */
+        ASSERT(BaseResource == NULL);
+        FullList = (PVOID)Partial;
+    }
+
+    /* Check the current assigned PCI resources */
+    PciResources = PdoExtension->Resources;
+    if (!PciResources) return FALSE;
+
+    //if... // MISSING CODE
+    UNIMPLEMENTED;
+    DPRINT1("Missing sanity checking code!\n");
+
+    /* Loop all the PCI function resources */
+    for (i = 0; i < 7; i++)
+    {
+        /* Get the current function resource descriptor, and the new one */
+        CurrentDescriptor = &PciResources->Current[i];
+        Partial = &ResourceArray[i];
+
+        /* Previous is current during the first loop iteration */
+        PreviousDescriptor = &PciResources->Current[(i == 0) ? (0) : (i - 1)];
+
+        /* Check if this new descriptor is different than the old one */
+        if (((Partial->Type != CurrentDescriptor->Type) ||
+             (Partial->Type != CmResourceTypeNull)) &&
+            ((Partial->u.Generic.Start.QuadPart !=
+              CurrentDescriptor->u.Generic.Start.QuadPart) ||
+             (Partial->u.Generic.Length != CurrentDescriptor->u.Generic.Length)))
+        {
+            /* Record a change */
+            RangeChange = TRUE;
+
+            /* Was there a range before? */
+            if (CurrentDescriptor->Type != CmResourceTypeNull)
+            {
+                /* Print it */
+                DbgPrint("      Old range-\n");
+                PciDebugPrintPartialResource(CurrentDescriptor);
+            }
+            else
+            {
+                /* There was no range */
+                DbgPrint("      Previously unset range\n");
+            }
+
+            /* Print new one */
+            DbgPrint("      changed to\n");
+            PciDebugPrintPartialResource(Partial);
+
+            /* Update to new range */
+            CurrentDescriptor->Type = Partial->Type;
+            PreviousDescriptor->u.Generic.Start = Partial->u.Generic.Start;
+            PreviousDescriptor->u.Generic.Length = Partial->u.Generic.Length;
+            CurrentDescriptor = PreviousDescriptor;
+        }
+    }
+
+    /* Either the hardware was updated, or a resource range changed */
+    return ((RangeChange) || (PdoExtension->UpdateHardware));
+}
+
+VOID
+NTAPI
+PcipUpdateHardware(IN PVOID Context,
+                   IN PVOID Context2)
+{
+    PPCI_PDO_EXTENSION PdoExtension = Context;
+    PPCI_COMMON_HEADER PciData = Context2;
+
+    /* Check if we're allowed to disable decodes */
+    PciData->Command = PdoExtension->CommandEnables;
+    if (!(PdoExtension->HackFlags & PCI_HACK_PRESERVE_COMMAND))
+    {
+        /* Disable all decodes */
+        PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
+                              PCI_ENABLE_MEMORY_SPACE |
+                              PCI_ENABLE_BUS_MASTER |
+                              PCI_ENABLE_WRITE_AND_INVALIDATE);
+    }
+
+    /* Update the device configuration */
+    PciData->Status = 0;
+    PciWriteDeviceConfig(PdoExtension, PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+    /* Turn decodes back on */
+    PciDecodeEnable(PdoExtension, TRUE, &PdoExtension->CommandEnables);
+}
+
+VOID
+NTAPI
+PciUpdateHardware(IN PPCI_PDO_EXTENSION PdoExtension,
+                  IN PPCI_COMMON_HEADER PciData)
+{
+    PCI_IPI_CONTEXT Context;
+
+    /* Check for critical devices and PCI Debugging devices */
+    if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
+        (PdoExtension->OnDebugPath))
+    {
+        /* Build the context and send an IPI */
+        Context.RunCount = 1;
+        Context.Barrier = 1;
+        Context.Context = PciData;
+        Context.Function = PcipUpdateHardware;
+        Context.DeviceExtension = PdoExtension;
+        KeIpiGenericCall(PciExecuteCriticalSystemRoutine, (ULONG_PTR)&Context);
+    }
+    else
+    {
+        /* Just to the update inline */
+        PcipUpdateHardware(PdoExtension, PciData);
+    }
+}
+
 PIO_RESOURCE_REQUIREMENTS_LIST
 NTAPI
 PciAllocateIoRequirementsList(IN ULONG Count,
@@ -666,8 +904,8 @@ PciApplyHacks(IN PPCI_FDO_EXTENSION DeviceExtension,
                      * Controller to Native Mode" in the Storage section of the
                      * Windows Driver Kit for more details.
                      */
-                    PdoExtension->SwitchedIDEToNativeMode =
-                        PciConfigureIdeController(PdoExtension, PciData, 1);
+                    PdoExtension->IDEInNativeMode =
+                        PciConfigureIdeController(PdoExtension, PciData, TRUE);
                 }
 
                 /* Is native mode enabled after all? */
@@ -1044,8 +1282,9 @@ PciGetEnhancedCapabilities(IN PPCI_PDO_EXTENSION PdoExtension,
 VOID
 NTAPI
 PciWriteLimitsAndRestoreCurrent(IN PVOID Reserved,
-                                IN PPCI_CONFIGURATOR_CONTEXT Context)
+                                IN PVOID Context2)
 {
+    PPCI_CONFIGURATOR_CONTEXT Context = Context2;
     PPCI_COMMON_HEADER PciData, Current;
     PPCI_PDO_EXTENSION PdoExtension;
 
@@ -1140,7 +1379,7 @@ PcipGetFunctionLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
         /* For these devices, an IPI must be sent to force high-IRQL discovery */
         IpiContext.Barrier = 1;
         IpiContext.RunCount = 1;
-        IpiContext.PdoExtension = PdoExtension;
+        IpiContext.DeviceExtension = PdoExtension;
         IpiContext.Function = PciWriteLimitsAndRestoreCurrent;
         IpiContext.Context = Context;
         KeIpiGenericCall(PciExecuteCriticalSystemRoutine, (ULONG_PTR)&IpiContext);
@@ -1886,4 +2125,122 @@ PciQueryDeviceRelations(IN PPCI_FDO_EXTENSION DeviceExtension,
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+NTAPI
+PciSetResources(IN PPCI_PDO_EXTENSION PdoExtension,
+                IN BOOLEAN DoReset,
+                IN BOOLEAN SomethingSomethingDarkSide)
+{
+    PPCI_FDO_EXTENSION FdoExtension;
+    UCHAR NewCacheLineSize, NewLatencyTimer;
+    PCI_COMMON_HEADER PciData;
+    BOOLEAN Native;
+    PPCI_CONFIGURATOR Configurator;
+
+    /* Get the FDO and read the configuration data */
+    FdoExtension = PdoExtension->ParentFdoExtension;
+    PciReadDeviceConfig(PdoExtension, &PciData, 0, PCI_COMMON_HDR_LENGTH);
+
+    /* Make sure this is still the same device */
+    if (!PcipIsSameDevice(PdoExtension, &PciData))
+    {
+        /* Fail */
+        ASSERTMSG(FALSE, "PCI Set resources - not same device");
+        return STATUS_DEVICE_DOES_NOT_EXIST;
+    }
+
+    /* Nothing to set for a host bridge */
+    if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
+        (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST))
+    {
+        /* Fake success */
+        return STATUS_SUCCESS;
+    }
+
+    /* Check if an IDE controller is being reset */
+    if ((DoReset) &&
+        (PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
+        (PdoExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
+    {
+        /* Turn off native mode */
+        Native = PciConfigureIdeController(PdoExtension, &PciData, FALSE);
+        ASSERT(Native == PdoExtension->IDEInNativeMode);
+    }
+
+    /* Check for update of a hotplug device, or first configuration of one */
+    if ((PdoExtension->NeedsHotPlugConfiguration) &&
+        (FdoExtension->HotPlugParameters.Acquired))
+    {
+        /* Don't have hotplug devices to test with yet, QEMU 0.14 should */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+
+    /* Locate the correct resource configurator for this type of device */
+    Configurator = &PciConfigurators[PdoExtension->HeaderType];
+
+    /* Apply the settings change */
+    Configurator->ChangeResourceSettings(PdoExtension, &PciData);
+
+    /* Assume no update needed */
+    PdoExtension->UpdateHardware = FALSE;
+
+    /* Check if a reset is needed */
+    if (DoReset)
+    {
+        /* Reset resources */
+        Configurator->ResetDevice(PdoExtension, &PciData);
+        PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
+    }
+
+    /* Check if the latency timer changed */
+    NewLatencyTimer = PdoExtension->SavedLatencyTimer;
+    if (PciData.LatencyTimer != NewLatencyTimer)
+    {
+        /* Debug notification */
+        DPRINT1("PCI (pdox %08x) changing latency from %02x to %02x.\n",
+                PdoExtension,
+                PciData.LatencyTimer,
+                NewLatencyTimer);
+    }
+
+    /* Check if the cache line changed */
+    NewCacheLineSize = PdoExtension->SavedCacheLineSize;
+    if (PciData.CacheLineSize != NewCacheLineSize)
+    {
+        /* Debug notification */
+        DPRINT1("PCI (pdox %08x) changing cache line size from %02x to %02x.\n",
+                PdoExtension,
+                PciData.CacheLineSize,
+                NewCacheLineSize);
+    }
+
+    /* Inherit data from PDO extension */
+    PciData.LatencyTimer = PdoExtension->SavedLatencyTimer;
+    PciData.CacheLineSize = PdoExtension->SavedCacheLineSize;
+    PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
+
+    /* Apply any resource hacks required */
+    PciApplyHacks(FdoExtension,
+                  &PciData,
+                  PdoExtension->Slot,
+                  PCI_HACK_FIXUP_BEFORE_UPDATE,
+                  PdoExtension);
+
+    /* Check if I/O space was disabled by administrator or driver */
+    if (PdoExtension->IoSpaceNotRequired)
+    {
+        /* Don't turn on the decode */
+        PdoExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
+    }
+
+    /* Update the device with the new settings */
+    PciUpdateHardware(PdoExtension, &PciData);
+
+    /* Update complete */
+    PdoExtension->RawInterruptLine = PciData.u.type0.InterruptLine;
+    PdoExtension->NeedsHotPlugConfiguration = FALSE;
+    return STATUS_SUCCESS;
+}
+
 /* EOF */
index bfad380..2054f65 100644 (file)
@@ -298,10 +298,10 @@ PciFdoIrpQueryCapabilities(IN PIRP Irp,
     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;
index a93313d..e51fb12 100644 (file)
@@ -73,7 +73,8 @@ Cardbus_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context,
 
 VOID
 NTAPI
-Cardbus_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Cardbus_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension,
+                    IN PPCI_COMMON_HEADER PciData)
 {
     UNIMPLEMENTED;
     while (TRUE);
@@ -81,7 +82,8 @@ Cardbus_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
 
 VOID
 NTAPI
-Cardbus_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
+Cardbus_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+                               IN PPCI_COMMON_HEADER PciData)
 {
     UNIMPLEMENTED;
     while (TRUE);
index 866784a..d1b8f9f 100644 (file)
@@ -298,10 +298,11 @@ typedef struct _PCI_PDO_EXTENSION
     BOOLEAN MovedDevice;
     BOOLEAN DisablePowerDown;
     BOOLEAN NeedsHotPlugConfiguration;
-    BOOLEAN SwitchedIDEToNativeMode;
+    BOOLEAN IDEInNativeMode;
     BOOLEAN BIOSAllowsIDESwitchToNativeMode;
     BOOLEAN IoSpaceUnderNativeIdeControl;
     BOOLEAN OnDebugPath;
+    BOOLEAN IoSpaceNotRequired;
     PCI_POWER_STATE PowerState;
     PCI_HEADER_TYPE_DEPENDENT Dependent;
     ULONGLONG HackFlags;
@@ -450,7 +451,8 @@ typedef VOID (NTAPI *PCI_CONFIGURATOR_SAVE_CURRENT_SETTINGS)(
 );
 
 typedef VOID (NTAPI *PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS)(
-    IN struct _PCI_CONFIGURATOR_CONTEXT* Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 typedef VOID (NTAPI *PCI_CONFIGURATOR_GET_ADDITIONAL_RESOURCE_DESCRIPTORS)(
@@ -460,7 +462,8 @@ typedef VOID (NTAPI *PCI_CONFIGURATOR_GET_ADDITIONAL_RESOURCE_DESCRIPTORS)(
 );
 
 typedef VOID (NTAPI *PCI_CONFIGURATOR_RESET_DEVICE)(
-    IN struct _PCI_CONFIGURATOR_CONTEXT* Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 //
@@ -496,7 +499,7 @@ typedef struct _PCI_CONFIGURATOR_CONTEXT
 //
 typedef VOID (NTAPI *PCI_IPI_FUNCTION)(
     IN PVOID Reserved,
-    IN PPCI_CONFIGURATOR_CONTEXT Context
+    IN PVOID Context
 );
 
 //
@@ -506,7 +509,7 @@ typedef struct _PCI_IPI_CONTEXT
 {
     LONG RunCount;
     ULONG Barrier;
-    PPCI_PDO_EXTENSION PdoExtension;
+    PVOID DeviceExtension;
     PCI_IPI_FUNCTION Function;
     PVOID Context;
 } PCI_IPI_CONTEXT, *PPCI_IPI_CONTEXT;
@@ -1143,6 +1146,12 @@ PciQueryCapabilities(
     IN OUT PDEVICE_CAPABILITIES DeviceCapability
 );
 
+PCM_PARTIAL_RESOURCE_DESCRIPTOR
+NTAPI
+PciNextPartialDescriptor(
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor
+);
+
 //
 // Configuration Routines
 //
@@ -1261,6 +1270,18 @@ PciDebugPrintIoResReqList(
     IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements
 );
 
+VOID
+NTAPI
+PciDebugPrintCmResList(
+    IN PCM_RESOURCE_LIST ResourceList
+);
+
+VOID
+NTAPI
+PciDebugPrintPartialResource(
+    IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource
+);
+
 //
 // Interface Support
 //
@@ -1524,6 +1545,21 @@ PciQueryRequirements(
     IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList
 );
 
+BOOLEAN
+NTAPI
+PciComputeNewCurrentSettings(
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PCM_RESOURCE_LIST ResourceList
+);
+
+NTSTATUS
+NTAPI
+PciSetResources(
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN BOOLEAN DoReset,
+    IN BOOLEAN SomethingSomethingDarkSide
+);
+
 //
 // Identification Functions
 //
@@ -1589,13 +1625,15 @@ Cardbus_GetAdditionalResourceDescriptors(
 VOID
 NTAPI
 Cardbus_ResetDevice(
-    IN PPCI_CONFIGURATOR_CONTEXT Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 VOID
 NTAPI
 Cardbus_ChangeResourceSettings(
-    IN PPCI_CONFIGURATOR_CONTEXT Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 //
@@ -1636,13 +1674,15 @@ Device_GetAdditionalResourceDescriptors(
 VOID
 NTAPI
 Device_ResetDevice(
-    IN PPCI_CONFIGURATOR_CONTEXT Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 VOID
 NTAPI
 Device_ChangeResourceSettings(
-    IN PPCI_CONFIGURATOR_CONTEXT Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 //
@@ -1683,13 +1723,15 @@ PPBridge_GetAdditionalResourceDescriptors(
 VOID
 NTAPI
 PPBridge_ResetDevice(
-    IN PPCI_CONFIGURATOR_CONTEXT Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 VOID
 NTAPI
 PPBridge_ChangeResourceSettings(
-    IN PPCI_CONFIGURATOR_CONTEXT Context
+    IN PPCI_PDO_EXTENSION PdoExtension,
+    IN PPCI_COMMON_HEADER PciData
 );
 
 //
index 223bef4..a6d942a 100644 (file)
@@ -668,7 +668,8 @@ PPBridge_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context,
 
 VOID
 NTAPI
-PPBridge_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
+PPBridge_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension,
+                     IN PPCI_COMMON_HEADER PciData)
 {
     UNIMPLEMENTED;
     while (TRUE);
@@ -676,7 +677,8 @@ PPBridge_ResetDevice(IN PPCI_CONFIGURATOR_CONTEXT Context)
 
 VOID
 NTAPI
-PPBridge_ChangeResourceSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
+PPBridge_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension,
+                                IN PPCI_COMMON_HEADER PciData)
 {
     UNIMPLEMENTED;
     while (TRUE);
index 8ed578c..da24aa7 100644 (file)
@@ -112,9 +112,95 @@ PciPdoIrpStartDevice(IN PIRP Irp,
                      IN PIO_STACK_LOCATION IoStackLocation,
                      IN PPCI_PDO_EXTENSION DeviceExtension)
 {
-    UNIMPLEMENTED;
-    while (TRUE);
-    return STATUS_NOT_SUPPORTED;
+    NTSTATUS Status;
+    BOOLEAN Changed, DoReset;
+    POWER_STATE PowerState;
+    PAGED_CODE();
+
+    DoReset = FALSE;
+
+    /* Begin entering the start phase */
+    Status = PciBeginStateTransition((PVOID)DeviceExtension, PciStarted);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Check if this is a VGA device */
+    if (((DeviceExtension->BaseClass == PCI_CLASS_PRE_20) &&
+         (DeviceExtension->SubClass == PCI_SUBCLASS_PRE_20_VGA)) ||
+        ((DeviceExtension->BaseClass == PCI_CLASS_DISPLAY_CTLR) &&
+         (DeviceExtension->SubClass -= PCI_SUBCLASS_VID_VGA_CTLR)))
+    {
+        /* Always force it on */
+        DeviceExtension->CommandEnables |= (PCI_ENABLE_IO_SPACE |
+                                            PCI_ENABLE_MEMORY_SPACE);
+    }
+
+    /* Check if native IDE is enabled and it owns the I/O ports */
+    if (DeviceExtension->IoSpaceUnderNativeIdeControl)
+    {
+        /* Then don't allow I/O access */
+        DeviceExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
+    }
+
+    /* Always enable bus mastering */
+    DeviceExtension->CommandEnables |= PCI_ENABLE_BUS_MASTER;
+
+    /* Check if the OS assigned resources differ from the PCI configuration */
+    Changed = PciComputeNewCurrentSettings(DeviceExtension,
+                                           IoStackLocation->Parameters.
+                                           StartDevice.AllocatedResources);
+    if (Changed)
+    {
+        /* Remember this for later */
+        DeviceExtension->MovedDevice = TRUE;
+    }
+    else
+    {
+        /* All good */
+        DPRINT1("PCI - START not changing resource settings.\n");
+    }
+
+    /* Check if the device was sleeping */
+    if (DeviceExtension->PowerState.CurrentDeviceState != PowerDeviceD0)
+    {
+        /* Power it up */
+        Status = PciSetPowerManagedDevicePowerState(DeviceExtension,
+                                                    PowerDeviceD0,
+                                                    FALSE);
+        if (!NT_SUCCESS(Status))
+        {
+            /* Powerup fail, fail the request */
+            PciCancelStateTransition((PVOID)DeviceExtension, PciStarted);
+            return STATUS_DEVICE_POWER_FAILURE;
+        }
+
+        /* Tell the power manager that the device is powered up */
+        PowerState.DeviceState = PowerDeviceD0;
+        PoSetPowerState(DeviceExtension->PhysicalDeviceObject,
+                        DevicePowerState,
+                        PowerState);
+
+        /* Update internal state */
+        DeviceExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
+
+        /* This device's resources and decodes will need to be reset */
+        DoReset = TRUE;
+    }
+
+    /* Update resource information now that the device is powered up and active */
+    Status = PciSetResources(DeviceExtension, DoReset, TRUE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* That failed, so cancel the transition */
+        PciCancelStateTransition((PVOID)DeviceExtension, PciStarted);
+    }
+    else
+    {
+        /* Fully commit, as the device is now started up and ready to go */
+        PciCommitStateTransition((PVOID)DeviceExtension, PciStarted);
+    }
+
+    /* Return the result of the start request */
+    return Status;
 }
 
 NTSTATUS
index 031b732..24f442a 100644 (file)
@@ -1069,7 +1069,7 @@ PciExecuteCriticalSystemRoutine(IN ULONG_PTR IpiContext)
     if (!InterlockedDecrement(&Context->RunCount))
     {
         /* Nope, this is the first instance, so execute the IPI function */
-        Context->Function(Context->PdoExtension, Context->Context);
+        Context->Function(Context->DeviceExtension, Context->Context);
 
         /* Notify anyone that was spinning that they can stop now */
         Context->Barrier = 0;
@@ -1757,4 +1757,25 @@ PciQueryCapabilities(IN PPCI_PDO_EXTENSION PdoExtension,
     return Status;
 }
 
+PCM_PARTIAL_RESOURCE_DESCRIPTOR
+NTAPI
+PciNextPartialDescriptor(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor)
+{
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR NextDescriptor;
+
+    /* Assume the descriptors are the fixed size ones */
+    NextDescriptor = CmDescriptor + 1;
+
+    /* But check if this is actually a variable-sized descriptor */
+    if (CmDescriptor->Type == CmResourceTypeDeviceSpecific)
+    {
+        /* Add the size of the variable section as well */
+        NextDescriptor = (PVOID)((ULONG_PTR)NextDescriptor +
+                                 CmDescriptor->u.DeviceSpecificData.DataSize);
+    }
+
+    /* Now the correct pointer has been computed, return it */
+    return NextDescriptor;
+}
+
 /* EOF */