3587{
3590
3592 PCDB cdb = (
PCDB)DeviceExtension->PowerContext.Srb.Cdb;
3593 ULONG timeoutValue = DeviceExtension->TimeOutValue;
3594 ULONG retryCount = 1;
3595
3596
3597 DeviceExtension->PowerContext.RetryIntervalIn100ns = 0;
3598 status = PowerContextReuseRequest(DeviceExtension);
3600
3602 {
3604 }
3605
3606
3607 switch(DeviceExtension->PowerContext.PowerChangeState.PowerDown)
3608 {
3612 break;
3613
3615
3616
3618 timeoutValue = DeviceExtension->TimeOutValue;
3619 break;
3620
3622 {
3623
3624
3625
3626 ULONG secondsRemaining = 0;
3627
3628#if (WINVER >= 0x0601)
3629
3630 PoQueryWatchdogTime(DeviceExtension->LowerPdo, &secondsRemaining);
3631#endif
3632
3633 if (secondsRemaining == 0)
3634 {
3635
3638 }
3639 else
3640 {
3641
3642 if (secondsRemaining >= 32)
3643 {
3646
3648 {
3650 }
3651
3652 if (retryCount == 1)
3653 {
3654 timeoutValue = secondsRemaining - 30;
3655 }
3656 }
3657 else
3658 {
3659
3660 retryCount = 1;
3661 timeoutValue = 2;
3662 }
3663 }
3664 }
3665 break;
3666 default:
3670 }
3671
3672 DeviceExtension->PowerContext.RetryCount = retryCount;
3673
3674
3675 while (shouldRetry)
3676 {
3677
3678
3684
3686 DeviceExtension->PowerContext.Srb.TimeOutValue = timeoutValue;
3687
3689 {
3691 }
3693 {
3695 }
3697 {
3698
3699 DeviceExtension->PowerContext.Srb.CdbLength = 10;
3701 }
3703 {
3704
3705 DeviceExtension->PowerContext.Srb.CdbLength = 6;
3709 }
3711 {
3713 }
3714
3715
3717 {
3718 WdfRequestSetCompletionRoutine(DeviceExtension->PowerContext.PowerRequest,
3721 }
3722
3724 DeviceExtension->PowerContext.PowerRequest,
3725 DeviceExtension->IoTarget,
3727 &requestSent);
3728
3729 if (requestSent)
3730 {
3733 {
3735 TRACE_FLAG_POWER,
3736 "%p\tError occured when issuing %s command to device. Srb %p, Status %x\n",
3737 DeviceExtension->PowerContext.PowerRequest,
3738 (DeviceExtension->PowerContext.PowerChangeState.PowerDown ==
PowerDownDeviceQuiesced) ?
"SYNC CACHE" :
"STOP UNIT",
3739 &DeviceExtension->PowerContext.Srb,
3740 DeviceExtension->PowerContext.Srb.SrbStatus));
3741
3743
3745 DeviceExtension->PowerContext.PowerRequest,
3746 &(DeviceExtension->PowerContext.Srb),
3747 retryCount - DeviceExtension->PowerContext.RetryCount,
3749 &(DeviceExtension->PowerContext.RetryIntervalIn100ns));
3750
3751 if (shouldRetry && (DeviceExtension->PowerContext.RetryCount-- == 0))
3752 {
3753 shouldRetry =
FALSE;
3754 }
3755 }
3756 else
3757 {
3758
3759 shouldRetry =
FALSE;
3760 }
3761
3762 }
3763 else
3764 {
3765
3766 shouldRetry =
FALSE;
3767 }
3768
3769 if (shouldRetry)
3770 {
3772 t.QuadPart = -DeviceExtension->PowerContext.RetryIntervalIn100ns;
3774
3775 status = PowerContextReuseRequest(DeviceExtension);
3777 {
3778 shouldRetry =
FALSE;
3779 }
3780 }
3781 }
3782
3784 {
3785
3787 }
3788
3790}
#define SCSI_CDROM_TIMEOUT
BOOLEAN RequestSenseInfoInterpret(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ PSCSI_REQUEST_BLOCK Srb, _In_ ULONG RetriedCount, _Out_ NTSTATUS *Status, _Out_opt_ _Deref_out_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) LONGLONG *RetryIntervalIn100ns)
#define TEST_FLAG(Flags, Bit)
@ PowerDownDeviceQuiesced
#define SCSIOP_START_STOP_UNIT
#define SCSIOP_SYNCHRONIZE_CACHE
#define STATUS_NOT_IMPLEMENTED
NTSTATUS RequestSend(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDFIOTARGET IoTarget, _In_ ULONG Flags, _Out_opt_ PBOOLEAN RequestSent)
VOID RequestClearSendTime(_In_ WDFREQUEST Request)
#define SRB_FUNCTION_EXECUTE_SCSI
#define SRB_FLAGS_NO_DATA_TRANSFER
#define SRB_FUNCTION_LOCK_QUEUE
#define SRB_FUNCTION_UNLOCK_QUEUE
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
#define SRB_STATUS(Status)
#define SRB_STATUS_QUEUE_FROZEN
#define SRB_FLAGS_NO_QUEUE_FREEZE
#define SRB_STATUS_SUCCESS
#define KeDelayExecutionThread(mode, foo, t)
#define SRB_FLAGS_D3_PROCESSING
#define SRB_FUNCTION_QUIESCE_DEVICE
#define KeQueryTickCount(CurrentCount)
#define TRACE_LEVEL_ERROR
struct _CDB::_START_STOP START_STOP
struct _CDB::_SYNCHRONIZE_CACHE10 SYNCHRONIZE_CACHE10
@ WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine