From: Sir Richard Date: Sun, 12 Sep 2010 06:03:12 +0000 (+0000) Subject: - Fix the ChangeResourceSetting and the Reset configurator callback parameter names X-Git-Tag: ReactOS-0.3.12~54 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=6575a83c33131b13a67ddd9cc05f741292ba3b5b - Fix the ChangeResourceSetting and the Reset configurator callback parameter names - 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 --- diff --git a/reactos/drivers/bus/pcix/debug.c b/reactos/drivers/bus/pcix/debug.c index 8f1ed81616b..bd2465e1ae3 100644 --- a/reactos/drivers/bus/pcix/debug.c +++ b/reactos/drivers/bus/pcix/debug.c @@ -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 */ diff --git a/reactos/drivers/bus/pcix/device.c b/reactos/drivers/bus/pcix/device.c index 4dbd16bcfdc..c26fd92b7fe 100644 --- a/reactos/drivers/bus/pcix/device.c +++ b/reactos/drivers/bus/pcix/device.c @@ -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; diff --git a/reactos/drivers/bus/pcix/enum.c b/reactos/drivers/bus/pcix/enum.c index 4e17a7f700a..1aaebb75dcd 100644 --- a/reactos/drivers/bus/pcix/enum.c +++ b/reactos/drivers/bus/pcix/enum.c @@ -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 */ diff --git a/reactos/drivers/bus/pcix/fdo.c b/reactos/drivers/bus/pcix/fdo.c index bfad380aca4..2054f65703d 100644 --- a/reactos/drivers/bus/pcix/fdo.c +++ b/reactos/drivers/bus/pcix/fdo.c @@ -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; diff --git a/reactos/drivers/bus/pcix/intrface/cardbus.c b/reactos/drivers/bus/pcix/intrface/cardbus.c index a93313ddf6f..e51fb12f308 100644 --- a/reactos/drivers/bus/pcix/intrface/cardbus.c +++ b/reactos/drivers/bus/pcix/intrface/cardbus.c @@ -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); diff --git a/reactos/drivers/bus/pcix/pci.h b/reactos/drivers/bus/pcix/pci.h index 866784ac87f..d1b8f9faec7 100644 --- a/reactos/drivers/bus/pcix/pci.h +++ b/reactos/drivers/bus/pcix/pci.h @@ -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 ); // diff --git a/reactos/drivers/bus/pcix/pci/ppbridge.c b/reactos/drivers/bus/pcix/pci/ppbridge.c index 223bef4f6cf..a6d942a7e61 100644 --- a/reactos/drivers/bus/pcix/pci/ppbridge.c +++ b/reactos/drivers/bus/pcix/pci/ppbridge.c @@ -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); diff --git a/reactos/drivers/bus/pcix/pdo.c b/reactos/drivers/bus/pcix/pdo.c index 8ed578c1251..da24aa7ee74 100644 --- a/reactos/drivers/bus/pcix/pdo.c +++ b/reactos/drivers/bus/pcix/pdo.c @@ -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 diff --git a/reactos/drivers/bus/pcix/utils.c b/reactos/drivers/bus/pcix/utils.c index 031b732c669..24f442ae16d 100644 --- a/reactos/drivers/bus/pcix/utils.c +++ b/reactos/drivers/bus/pcix/utils.c @@ -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 */