NTSTATUS NTAPI PciFdoIrpStartDevice(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_FDO_EXTENSION DeviceExtension) { NTSTATUS Status; PCM_RESOURCE_LIST Resources; PAGED_CODE(); /* The device stack must be starting the FDO in a success path */ if (!NT_SUCCESS(Irp->IoStatus.Status)) return STATUS_NOT_SUPPORTED; /* Attempt to switch the state machine to the started state */ Status = PciBeginStateTransition(DeviceExtension, PciStarted); if (!NT_SUCCESS(Status)) return Status; /* Check for any boot-provided resources */ Resources = IoStackLocation->Parameters.StartDevice.AllocatedResources; if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension))) { /* These resources would only be for non-root FDOs, unhandled for now */ ASSERT(Resources->Count == 1); UNIMPLEMENTED_DBGBREAK(); } /* Initialize the arbiter for this FDO */ Status = PciInitializeArbiterRanges(DeviceExtension, Resources); if (!NT_SUCCESS(Status)) { /* Cancel the transition if this failed */ PciCancelStateTransition(DeviceExtension, PciStarted); return Status; } /* Again, check for boot-provided resources for non-root FDO */ if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension))) { /* Unhandled for now */ ASSERT(Resources->Count == 1); UNIMPLEMENTED_DBGBREAK(); } /* Commit the transition to the started state */ PciCommitStateTransition(DeviceExtension, PciStarted); return STATUS_SUCCESS; }
NTSTATUS NTAPI PciPdoIrpStartDevice(IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation, IN PPCI_PDO_EXTENSION DeviceExtension) { 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; }