ReactOS  0.4.14-dev-342-gdc047f9
power.c File Reference
#include "classp.h"
Include dependency graph for power.c:

Go to the source code of this file.

Macros

#define CLASS_TAG_POWER   'WLcS'
 

Functions

NTSTATUS NTAPI ClasspPowerHandler (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CLASS_POWER_OPTIONS Options)
 
VOID NTAPI RetryPowerRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp, PCLASS_POWER_CONTEXT Context)
 
NTSTATUS NTAPI ClasspStartNextPowerIrpCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI ClassDispatchPower (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ClasspPowerUpCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID CompletionContext)
 
NTSTATUS NTAPI ClasspPowerDownCompletion (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID CompletionContext)
 
NTSTATUS NTAPI ClassMinimalPowerHandler (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ClassSpinDownPowerHandler (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ClassStopUnitPowerHandler (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 

Variables

IO_COMPLETION_ROUTINE ClasspPowerDownCompletion
 
IO_COMPLETION_ROUTINE ClasspPowerUpCompletion
 

Macro Definition Documentation

◆ CLASS_TAG_POWER

#define CLASS_TAG_POWER   'WLcS'

Definition at line 26 of file power.c.

Function Documentation

◆ ClassDispatchPower()

NTSTATUS NTAPI ClassDispatchPower ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 76 of file power.c.

80 {
82  ULONG isRemoved;
83 
84  //
85  // NOTE: This code may be called at PASSIVE or DISPATCH, depending
86  // upon the device object it is being called for.
87  // don't do anything that would break under either circumstance.
88  //
89 
91 
92  if(isRemoved) {
94  Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
98  }
99 
100  return commonExtension->DevInfo->ClassPowerDevice(DeviceObject, Irp);
101 } // end ClassDispatchPower()
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
_In_ PIRP Irp
Definition: csq.h:116
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PCLASS_POWER_DEVICE ClassPowerDevice
Definition: classpnp.h:512
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
PCLASS_DEV_INFO DevInfo
Definition: classpnp.h:596
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212

◆ ClassMinimalPowerHandler()

NTSTATUS NTAPI ClassMinimalPowerHandler ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 1302 of file power.c.

1306 {
1309  NTSTATUS status;
1310 
1313 
1314  if(commonExtension->IsFdo) {
1315 
1316  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1317 
1318  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
1320 
1321  //
1322  // Check if the system is going to hibernate or standby.
1323  //
1324  if (irpStack->MinorFunction == IRP_MN_SET_POWER){
1325  PVPB vpb;
1326 
1327  switch (irpStack->Parameters.Power.ShutdownType){
1328 
1329  case PowerActionSleep:
1330  case PowerActionHibernate:
1331  //
1332  // If the volume is mounted, set the verify bit so that
1333  // the filesystem will be forced re-read the media
1334  // after coming out of hibernation or standby.
1335  //
1336  vpb = ClassGetVpb(fdoExtension->DeviceObject);
1337  if (vpb && (vpb->Flags & VPB_MOUNTED)){
1338  SET_FLAG(fdoExtension->DeviceObject->Flags, DO_VERIFY_VOLUME);
1339  }
1340  break;
1341  default:
1342  break;
1343  }
1344  }
1345  }
1346 
1348  return PoCallDriver(commonExtension->LowerDeviceObject, Irp);
1349 
1350  } else {
1351 
1352  if (irpStack->MinorFunction != IRP_MN_SET_POWER &&
1353  irpStack->MinorFunction != IRP_MN_QUERY_POWER) {
1354 
1355  NOTHING;
1356 
1357  } else {
1358 
1359  Irp->IoStatus.Status = STATUS_SUCCESS;
1360  Irp->IoStatus.Information = 0;
1361 
1362  }
1363  status = Irp->IoStatus.Status;
1364 
1366  return status;
1367  }
1368 } // end ClassMinimalPowerHandler()
USHORT Flags
Definition: iotypes.h:169
#define IRP_MN_QUERY_POWER
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PVPB NTAPI ClassGetVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: class.c:8048
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:693
#define IRP_MN_SET_POWER
#define NOTHING
Definition: env_spec_w32.h:461
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
Definition: iotypes.h:166
#define IO_NO_INCREMENT
Definition: iotypes.h:566
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define VPB_MOUNTED
Definition: iotypes.h:1764
static SERVICE_STATUS status
Definition: service.c:31
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
Definition: ps.c:97

Referenced by ClassInitialize().

◆ ClasspPowerDownCompletion()

NTSTATUS NTAPI ClasspPowerDownCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  CompletionContext 
)

Definition at line 519 of file power.c.

524 {
528 
531 
533 
534  DebugPrint((1, "ClasspPowerDownCompletion: Device Object %p, "
535  "Irp %p, Context %p\n",
537 
540  ASSERT(context->Options.PowerDown == TRUE);
541  ASSERT(context->Options.HandleSpinDown);
542 
543  if(Irp->PendingReturned) {
545  }
546 
547  context->PowerChangeState.PowerDown2++;
548 
549  switch(context->PowerChangeState.PowerDown2) {
550 
551  case PowerDownDeviceLocked2: {
552 
553  PCDB cdb;
554 
555  DebugPrint((1, "(%p)\tPreviously sent power lock\n", Irp));
556 
557  if ((context->Options.LockQueue != FALSE) &&
558  (!NT_SUCCESS(Irp->IoStatus.Status))) {
559 
560  DebugPrint((1, "(%p)\tIrp status was %lx\n",
561  Irp,
562  Irp->IoStatus.Status));
563  DebugPrint((1, "(%p)\tSrb status was %lx\n",
564  Irp,
565  context->Srb.SrbStatus));
566 
567  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
568 
569  //
570  // Lock was not successful - throw down the power IRP
571  // by itself and don't try to spin down the drive or unlock
572  // the queue.
573  //
574 
575  context->InUse = FALSE;
576  context = NULL;
577 
578  //
579  // Set the new power state
580  //
581 
582  fdoExtension->DevicePowerState =
583  currentStack->Parameters.Power.State.DeviceState;
584 
585  //
586  // Indicate to Po that we've been successfully powered down
587  // so it can do it's notification stuff.
588  //
589 
593  NULL,
594  TRUE,
595  TRUE,
596  TRUE);
597 
599  currentStack->Parameters.Power.Type,
600  currentStack->Parameters.Power.State);
601 
602  fdoExtension->PowerDownInProgress = FALSE;
603 
604  PoCallDriver(commonExtension->LowerDeviceObject, Irp);
605 
606  ClassReleaseRemoveLock(commonExtension->DeviceObject,
607  Irp);
608 
610 
611  } else {
612  context->QueueLocked = (UCHAR) context->Options.LockQueue;
613  }
614 
615  if (!TEST_FLAG(fdoExtension->PrivateFdoData->HackFlags,
617 
618  //
619  // send SCSIOP_SYNCHRONIZE_CACHE
620  //
621 
622  context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
623  context->Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
624 
625  context->Srb.TimeOutValue = fdoExtension->TimeOutValue;
626 
627  context->Srb.SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
632 
633  context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
634  context->Srb.DataTransferLength = 0;
635 
636  context->Srb.CdbLength = 10;
637 
638  cdb = (PCDB) context->Srb.Cdb;
639 
640  RtlZeroMemory(cdb, sizeof(CDB));
641  cdb->SYNCHRONIZE_CACHE10.OperationCode = SCSIOP_SYNCHRONIZE_CACHE;
642 
645  context,
646  TRUE,
647  TRUE,
648  TRUE);
649 
650  nextStack->Parameters.Scsi.Srb = &(context->Srb);
651  nextStack->MajorFunction = IRP_MJ_SCSI;
652 
653  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
654 
655  DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n", Irp, status));
656  break;
657 
658  } else {
659 
660  DebugPrint((1, "(%p)\tPower Down: not sending SYNCH_CACHE\n",
661  DeviceObject));
662  context->PowerChangeState.PowerDown2++;
663  context->Srb.SrbStatus = SRB_STATUS_SUCCESS;
664  // and fall through....
665  }
666  // no break in case the device doesn't like synch_cache commands
667 
668  }
669 
671 
672  PCDB cdb;
673 
674  DebugPrint((1, "(%p)\tPreviously send SCSIOP_SYNCHRONIZE_CACHE\n",
675  Irp));
676 
677  //
678  // SCSIOP_SYNCHRONIZE_CACHE was sent
679  //
680 
681  if(SRB_STATUS(context->Srb.SrbStatus) != SRB_STATUS_SUCCESS) {
682 
683  BOOLEAN retry;
684 
685  DebugPrint((1, "(%p)\tError occured when issuing "
686  "SYNCHRONIZE_CACHE command to device. "
687  "Srb %p, Status %lx\n",
688  Irp,
689  &context->Srb,
690  context->Srb.SrbStatus));
691 
692  ASSERT(!(TEST_FLAG(context->Srb.SrbStatus,
694  ASSERT(context->Srb.Function == SRB_FUNCTION_EXECUTE_SCSI);
695 
696  context->RetryInterval = 0;
697  retry = ClassInterpretSenseInfo(
698  commonExtension->DeviceObject,
699  &context->Srb,
700  IRP_MJ_SCSI,
701  IRP_MJ_POWER,
702  MAXIMUM_RETRIES - context->RetryCount,
703  &status,
704  &context->RetryInterval);
705 
706  if ((retry != FALSE) && (context->RetryCount-- != 0)) {
707 
708  DebugPrint((1, "(%p)\tRetrying failed request\n", Irp));
709 
710  //
711  // decrement the state so we come back through here
712  // the next time.
713  //
714 
715  context->PowerChangeState.PowerDown2--;
716  RetryPowerRequest(commonExtension->DeviceObject,
717  Irp,
718  context);
719  break;
720  }
721 
722  DebugPrint((1, "(%p)\tSYNCHRONIZE_CACHE not retried\n", Irp));
723  context->RetryCount = MAXIMUM_RETRIES;
724 
725  } // end !SRB_STATUS_SUCCESS
726 
727  //
728  // note: we are purposefully ignoring any errors. if the drive
729  // doesn't support a synch_cache, then we're up a creek
730  // anyways.
731  //
732 
733  DebugPrint((1, "(%p)\tSending stop unit to device\n", Irp));
734 
735  //
736  // Issue the start unit command to the device.
737  //
738 
739  context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
740  context->Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
741 
742  context->Srb.TimeOutValue = START_UNIT_TIMEOUT;
743 
744  context->Srb.SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
749 
750  context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
751  context->Srb.DataTransferLength = 0;
752 
753  context->Srb.CdbLength = 6;
754 
755  cdb = (PCDB) context->Srb.Cdb;
756  RtlZeroMemory(cdb, sizeof(CDB));
757 
758  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
759  cdb->START_STOP.Start = 0;
760  cdb->START_STOP.Immediate = 1;
761 
764  context,
765  TRUE,
766  TRUE,
767  TRUE);
768 
769  nextStack->Parameters.Scsi.Srb = &(context->Srb);
770  nextStack->MajorFunction = IRP_MJ_SCSI;
771 
772  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
773 
774  DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n", Irp, status));
775  break;
776 
777  }
778 
780 
781  BOOLEAN ignoreError = TRUE;
782 
783  //
784  // stop was sent
785  //
786 
787  if(SRB_STATUS(context->Srb.SrbStatus) != SRB_STATUS_SUCCESS) {
788 
789  BOOLEAN retry;
790 
791  DebugPrint((1, "(%p)\tError occured when issuing STOP_UNIT "
792  "command to device. Srb %p, Status %lx\n",
793  Irp,
794  &context->Srb,
795  context->Srb.SrbStatus));
796 
797  ASSERT(!(TEST_FLAG(context->Srb.SrbStatus,
799  ASSERT(context->Srb.Function == SRB_FUNCTION_EXECUTE_SCSI);
800 
801  context->RetryInterval = 0;
802  retry = ClassInterpretSenseInfo(
803  commonExtension->DeviceObject,
804  &context->Srb,
805  IRP_MJ_SCSI,
806  IRP_MJ_POWER,
807  MAXIMUM_RETRIES - context->RetryCount,
808  &status,
809  &context->RetryInterval);
810 
811  if ((retry != FALSE) && (context->RetryCount-- != 0)) {
812 
813  DebugPrint((1, "(%p)\tRetrying failed request\n", Irp));
814 
815  //
816  // decrement the state so we come back through here
817  // the next time.
818  //
819 
820  context->PowerChangeState.PowerDown2--;
821  RetryPowerRequest(commonExtension->DeviceObject,
822  Irp,
823  context);
824  break;
825  }
826 
827  DebugPrint((1, "(%p)\tSTOP_UNIT not retried\n", Irp));
828  context->RetryCount = MAXIMUM_RETRIES;
829 
830  } // end !SRB_STATUS_SUCCESS
831 
832 
833  DebugPrint((1, "(%p)\tPreviously sent stop unit\n", Irp));
834 
835  //
836  // some operations, such as a physical format in progress,
837  // should not be ignored and should fail the power operation.
838  //
839 
840  if (!NT_SUCCESS(status)) {
841 
842  PSENSE_DATA senseBuffer = context->Srb.SenseInfoBuffer;
843 
844  if (TEST_FLAG(context->Srb.SrbStatus,
846  ((senseBuffer->SenseKey & 0xf) == SCSI_SENSE_NOT_READY) &&
849  ) {
850  ignoreError = FALSE;
851  context->FinalStatus = STATUS_DEVICE_BUSY;
852  status = context->FinalStatus;
853  }
854 
855  }
856 
857  if (NT_SUCCESS(status) || ignoreError) {
858 
859  //
860  // Issue the actual power request to the lower driver.
861  //
862 
863  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
864 
866 
869  context,
870  TRUE,
871  TRUE,
872  TRUE);
873 
874  status = PoCallDriver(commonExtension->LowerDeviceObject, Irp);
875 
876  DebugPrint((1, "(%p)\tPoCallDriver returned %lx\n", Irp, status));
877  break;
878  }
879 
880  // else fall through w/o sending the power irp, since the device
881  // is reporting an error that would be "really bad" to power down
882  // during.
883 
884  }
885 
886  case PowerDownDeviceOff2: {
887 
888  //
889  // SpinDown request completed ... whether it succeeded or not is
890  // another matter entirely.
891  //
892 
893  DebugPrint((1, "(%p)\tPreviously sent power irp\n", Irp));
894 
895  if (context->QueueLocked) {
896 
897  DebugPrint((1, "(%p)\tUnlocking queue\n", Irp));
898 
899  context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
900 
901  context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
902  context->Srb.DataTransferLength = 0;
903 
904  context->Srb.Function = SRB_FUNCTION_UNLOCK_QUEUE;
905  context->Srb.SrbFlags = SRB_FLAGS_BYPASS_LOCKED_QUEUE;
906  nextStack->Parameters.Scsi.Srb = &(context->Srb);
907  nextStack->MajorFunction = IRP_MJ_SCSI;
908 
911  context,
912  TRUE,
913  TRUE,
914  TRUE);
915 
916  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
917  DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n",
918  Irp,
919  status));
920  break;
921  }
922 
923  }
924 
926 
927  //
928  // This is the end of the dance. Free the srb and complete the
929  // request finally. We're ignoring possible intermediate
930  // error conditions ....
931  //
932 
933  if (context->QueueLocked == FALSE) {
934  DebugPrint((1, "(%p)\tFall through (queue not locked)\n", Irp));
935  } else {
936  DebugPrint((1, "(%p)\tPreviously unlocked queue\n", Irp));
937  ASSERT(NT_SUCCESS(Irp->IoStatus.Status));
938  ASSERT(context->Srb.SrbStatus == SRB_STATUS_SUCCESS);
939  }
940 
941  DebugPrint((1, "(%p)\tFreeing srb and completing\n", Irp));
942  context->InUse = FALSE;
943  status = context->FinalStatus; // allow failure to propagate
944  context = NULL;
945 
946  if(Irp->PendingReturned) {
948  }
949 
950  Irp->IoStatus.Status = status;
951  Irp->IoStatus.Information = 0;
952 
953  if (NT_SUCCESS(status)) {
954 
955  //
956  // Set the new power state
957  //
958 
959  fdoExtension->DevicePowerState =
960  currentStack->Parameters.Power.State.DeviceState;
961 
962  }
963 
964 
965  DebugPrint((1, "(%p)\tStarting next power irp\n", Irp));
966 
969  fdoExtension->PowerDownInProgress = FALSE;
970 
971  return status;
972  }
973 
975  NT_ASSERT(context->PowerChangeState.PowerDown2 != PowerDownDeviceInitial2);
976  break;
977  }
978  }
979 
981 } // end ClasspPowerDownCompletion()
#define SRB_FUNCTION_UNLOCK_QUEUE
Definition: srb.h:325
#define SRB_FLAGS_DISABLE_AUTOSENSE
Definition: srb.h:391
#define SCSI_SENSEQ_FORMAT_IN_PROGRESS
Definition: cdrw_hw.h:1316
UCHAR SenseKey
Definition: cdrw_hw.h:1167
VOID NTAPI RetryPowerRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PCLASS_POWER_CONTEXT Context)
Definition: power.c:1516
#define TRUE
Definition: types.h:120
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:6587
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:398
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
_In_ PIRP Irp
Definition: csq.h:116
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
struct _CDB::_SYNCHRONIZE_CACHE10 SYNCHRONIZE_CACHE10
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define SRB_STATUS(Status)
Definition: srb.h:381
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
IO_COMPLETION_ROUTINE ClasspPowerDownCompletion
Definition: power.c:36
_Unreferenced_parameter_ PVOID * CompletionContext
Definition: cdprocs.h:1130
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE
Definition: srb.h:402
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
struct _CDB::_START_STOP START_STOP
#define MAXIMUM_RETRIES
Definition: class2.h:14
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
PDEVICE_OBJECT DeviceObject
Definition: pci.h:42
#define FDO_HACK_NO_SYNC_CACHE
Definition: classp.h:55
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
BOOLEAN NTAPI ClassInterpretSenseInfo(IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status, OUT OPTIONAL ULONG *RetryInterval)
Definition: class.c:2994
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
#define IRP_MJ_POWER
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
Definition: srb.h:405
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
#define START_UNIT_TIMEOUT
Definition: class2.c:30
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
NTSTATUS NTAPI ClasspStartNextPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: power.c:1602
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
POWER_STATE NTAPI PoSetPowerState(IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State)
Definition: power.c:597
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
DEVICE_POWER_STATE DevicePowerState
Definition: classpnp.h:700
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

◆ ClasspPowerHandler()

NTSTATUS NTAPI ClasspPowerHandler ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN CLASS_POWER_OPTIONS  Options 
)

Definition at line 1007 of file power.c.

1012 {
1014  PDEVICE_OBJECT lowerDevice = commonExtension->LowerDeviceObject;
1016  PIO_STACK_LOCATION nextIrpStack;
1019 
1020  if (!commonExtension->IsFdo) {
1021 
1022  //
1023  // certain assumptions are made here,
1024  // particularly: having the fdoExtension
1025  //
1026 
1027  DebugPrint((0, "ClasspPowerHandler: Called for PDO %p???\n",
1028  DeviceObject));
1029  ASSERT(!"PDO using ClasspPowerHandler");
1030  return STATUS_NOT_SUPPORTED;
1031  }
1032 
1033  DebugPrint((1, "ClasspPowerHandler: Power irp %p to %s %p\n",
1034  Irp, (commonExtension->IsFdo ? "fdo" : "pdo"), DeviceObject));
1035 
1036  switch(irpStack->MinorFunction) {
1037 
1038  case IRP_MN_SET_POWER: {
1039  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
1040 
1041  DebugPrint((1, "(%p)\tIRP_MN_SET_POWER\n", Irp));
1042 
1043  DebugPrint((1, "(%p)\tSetting %s state to %d\n",
1044  Irp,
1045  (irpStack->Parameters.Power.Type == SystemPowerState ?
1046  "System" : "Device"),
1047  irpStack->Parameters.Power.State.SystemState));
1048 
1049  switch (irpStack->Parameters.Power.ShutdownType){
1050 
1051  case PowerActionSleep:
1052  case PowerActionHibernate:
1053  if (fdoData->HotplugInfo.MediaRemovable || fdoData->HotplugInfo.MediaHotplug){
1054  /*
1055  * We are suspending and this drive is either hot-pluggable
1056  * or contains removeable media.
1057  * Set the media dirty bit, since the media may change while
1058  * we are suspended.
1059  */
1061  }
1062  break;
1063  default:
1064  break;
1065  }
1066 
1067  break;
1068  }
1069 
1070  default: {
1071 
1072  DebugPrint((1, "(%p)\tIrp minor code = %#x\n",
1073  Irp, irpStack->MinorFunction));
1074  break;
1075  }
1076  }
1077 
1078  if (irpStack->Parameters.Power.Type != DevicePowerState ||
1079  irpStack->MinorFunction != IRP_MN_SET_POWER) {
1080 
1081  DebugPrint((1, "(%p)\tSending to lower device\n", Irp));
1082 
1083  goto ClasspPowerHandlerCleanup;
1084 
1085  }
1086 
1087  nextIrpStack = IoGetNextIrpStackLocation(Irp);
1088 
1089  //
1090  // already in exact same state, don't work to transition to it.
1091  //
1092 
1093  if(irpStack->Parameters.Power.State.DeviceState ==
1094  fdoExtension->DevicePowerState) {
1095 
1096  DebugPrint((1, "(%p)\tAlready in device state %x\n",
1097  Irp, fdoExtension->DevicePowerState));
1098  goto ClasspPowerHandlerCleanup;
1099 
1100  }
1101 
1102  //
1103  // or powering down from non-d0 state (device already stopped)
1104  // NOTE -- we're not sure whether this case can exist or not (the
1105  // power system may never send this sort of request) but it's trivial
1106  // to deal with.
1107  //
1108 
1109  if ((irpStack->Parameters.Power.State.DeviceState != PowerDeviceD0) &&
1110  (fdoExtension->DevicePowerState != PowerDeviceD0)) {
1111  DebugPrint((1, "(%p)\tAlready powered down to %x???\n",
1112  Irp, fdoExtension->DevicePowerState));
1113  fdoExtension->DevicePowerState =
1114  irpStack->Parameters.Power.State.DeviceState;
1115  goto ClasspPowerHandlerCleanup;
1116  }
1117 
1118  //
1119  // or going into a hibernation state when we're in the hibernation path.
1120  // If the device is spinning then we should leave it spinning - if it's not
1121  // then the dump driver will start it up for us.
1122  //
1123 
1124  if((irpStack->Parameters.Power.State.DeviceState == PowerDeviceD3) &&
1125  (irpStack->Parameters.Power.ShutdownType == PowerActionHibernate) &&
1126  (commonExtension->HibernationPathCount != 0)) {
1127 
1128  DebugPrint((1, "(%p)\tdoing nothing for hibernation request for "
1129  "state %x???\n",
1130  Irp, fdoExtension->DevicePowerState));
1131  fdoExtension->DevicePowerState =
1132  irpStack->Parameters.Power.State.DeviceState;
1133  goto ClasspPowerHandlerCleanup;
1134  }
1135  //
1136  // or when not handling powering up and are powering up
1137  //
1138 
1139  if ((!Options.HandleSpinUp) &&
1140  (irpStack->Parameters.Power.State.DeviceState == PowerDeviceD0)) {
1141 
1142  DebugPrint((2, "(%p)\tNot handling spinup to state %x\n",
1143  Irp, fdoExtension->DevicePowerState));
1144  fdoExtension->DevicePowerState =
1145  irpStack->Parameters.Power.State.DeviceState;
1146  goto ClasspPowerHandlerCleanup;
1147 
1148  }
1149 
1150  //
1151  // or when not handling powering down and are powering down
1152  //
1153 
1154  if ((!Options.HandleSpinDown) &&
1155  (irpStack->Parameters.Power.State.DeviceState != PowerDeviceD0)) {
1156 
1157  DebugPrint((2, "(%p)\tNot handling spindown to state %x\n",
1158  Irp, fdoExtension->DevicePowerState));
1159  fdoExtension->DevicePowerState =
1160  irpStack->Parameters.Power.State.DeviceState;
1161  goto ClasspPowerHandlerCleanup;
1162 
1163  }
1164 
1165  context = &(fdoExtension->PowerContext);
1166 
1167 #if DBG
1168  //
1169  // Mark the context as in use. We should be synchronizing this but
1170  // since it's just for debugging purposes we don't worry too much.
1171  //
1172 
1173  ASSERT(context->InUse == FALSE);
1174 #endif
1175 
1177  context->InUse = TRUE;
1178 
1179  nextIrpStack->Parameters.Scsi.Srb = &(context->Srb);
1180  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
1181 
1182  context->FinalStatus = STATUS_SUCCESS;
1183 
1184  context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
1185  context->Srb.OriginalRequest = Irp;
1186  context->Srb.SrbFlags |= SRB_FLAGS_BYPASS_LOCKED_QUEUE
1188  context->Srb.Function = SRB_FUNCTION_LOCK_QUEUE;
1189 
1190  context->Srb.SenseInfoBuffer =
1191  commonExtension->PartitionZeroExtension->SenseData;
1192  context->Srb.SenseInfoBufferLength = SENSE_BUFFER_SIZE;
1193  context->RetryCount = MAXIMUM_RETRIES;
1194 
1195  context->Options = Options;
1196  context->DeviceObject = DeviceObject;
1197  context->Irp = Irp;
1198 
1199  if(irpStack->Parameters.Power.State.DeviceState == PowerDeviceD0) {
1200 
1201  ASSERT(Options.HandleSpinUp);
1202 
1203  DebugPrint((2, "(%p)\tpower up - locking queue\n", Irp));
1204 
1205  //
1206  // We need to issue a queue lock request so that we
1207  // can spin the drive back up after the power is restored
1208  // but before any requests are processed.
1209  //
1210 
1211  context->Options.PowerDown = FALSE;
1212  context->PowerChangeState.PowerUp = PowerUpDeviceInitial;
1213  context->CompletionRoutine = ClasspPowerUpCompletion;
1214 
1215  } else {
1216 
1217  ASSERT(Options.HandleSpinDown);
1218 
1219  fdoExtension->PowerDownInProgress = TRUE;
1220 
1221  DebugPrint((2, "(%p)\tPowering down - locking queue\n", Irp));
1222 
1224  irpStack->Parameters.Power.Type,
1225  irpStack->Parameters.Power.State);
1226 
1227  context->Options.PowerDown = TRUE;
1228  context->PowerChangeState.PowerDown2 = PowerDownDeviceInitial2;
1229  context->CompletionRoutine = ClasspPowerDownCompletion;
1230 
1231  }
1232 
1233  //
1234  // we are not dealing with port-allocated sense in these routines.
1235  //
1236 
1239 
1240  //
1241  // we are always returning STATUS_PENDING, so we need to always
1242  // set the irp as pending.
1243  //
1244 
1246 
1247  if(Options.LockQueue) {
1248 
1249  //
1250  // Send the lock irp down.
1251  //
1252 
1254  context->CompletionRoutine,
1255  context,
1256  TRUE,
1257  TRUE,
1258  TRUE);
1259 
1260  IoCallDriver(lowerDevice, Irp);
1261 
1262  } else {
1263 
1264  //
1265  // Call the completion routine directly. It won't care what the
1266  // status of the "lock" was - it will just go and do the next
1267  // step of the operation.
1268  //
1269 
1270  context->CompletionRoutine(DeviceObject, Irp, context);
1271  }
1272 
1273  return STATUS_PENDING;
1274 
1275 ClasspPowerHandlerCleanup:
1276 
1278 
1279  DebugPrint((1, "(%p)\tStarting next power irp\n", Irp));
1283  NULL,
1284  TRUE,
1285  TRUE,
1286  TRUE);
1287  return PoCallDriver(lowerDevice, Irp);
1288 } // end ClasspPowerHandler()
#define TRUE
Definition: types.h:120
Definition: http.c:6587
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:398
_In_ PIRP Irp
Definition: csq.h:116
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
IO_COMPLETION_ROUTINE ClasspPowerUpCompletion
Definition: power.c:38
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:575
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
enum OPTION_FLAGS Options
Definition: stats.c:44
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
STORAGE_HOTPLUG_INFO HotplugInfo
Definition: classp.h:403
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
BOOLEAN MediaHotplug
Definition: imports.h:247
IO_COMPLETION_ROUTINE ClasspPowerDownCompletion
Definition: power.c:36
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE
Definition: srb.h:402
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define MAXIMUM_RETRIES
Definition: class2.h:14
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
CLASS_POWER_CONTEXT PowerContext
Definition: classpnp.h:744
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define IRP_MN_SET_POWER
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
Definition: srb.h:405
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
NTSTATUS NTAPI ClasspStartNextPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: power.c:1602
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
POWER_STATE NTAPI PoSetPowerState(IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State)
Definition: power.c:597
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
BOOLEAN MediaRemovable
Definition: imports.h:246
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)
#define SRB_FUNCTION_LOCK_QUEUE
Definition: srb.h:324
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
DEVICE_POWER_STATE DevicePowerState
Definition: classpnp.h:700

Referenced by ClassSpinDownPowerHandler().

◆ ClasspPowerUpCompletion()

NTSTATUS NTAPI ClasspPowerUpCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  CompletionContext 
)

Definition at line 144 of file power.c.

149 {
153 
156 
157 
159 
160  DebugPrint((1, "ClasspPowerUpCompletion: Device Object %p, Irp %p, "
161  "Context %p\n",
163 
166  ASSERT(context->Options.PowerDown == FALSE);
167  ASSERT(context->Options.HandleSpinUp);
168 
169  if(Irp->PendingReturned) {
171  }
172 
173  context->PowerChangeState.PowerUp++;
174 
175  switch(context->PowerChangeState.PowerUp) {
176 
177  case PowerUpDeviceLocked: {
178 
179  DebugPrint((1, "(%p)\tPreviously sent power lock\n", Irp));
180 
181  //
182  // Issue the actual power request to the lower driver.
183  //
184 
186 
187  //
188  // If the lock wasn't successful then just bail out on the power
189  // request unless we can ignore failed locks
190  //
191 
192  if ((context->Options.LockQueue != FALSE) &&
193  (!NT_SUCCESS(Irp->IoStatus.Status))) {
194 
195  DebugPrint((1, "(%p)\tIrp status was %lx\n",
196  Irp, Irp->IoStatus.Status));
197  DebugPrint((1, "(%p)\tSrb status was %lx\n",
198  Irp, context->Srb.SrbStatus));
199 
200  //
201  // Lock was not successful - throw down the power IRP
202  // by itself and don't try to spin up the drive or unlock
203  // the queue.
204  //
205 
206  context->InUse = FALSE;
207  context = NULL;
208 
209  //
210  // Set the new power state
211  //
212 
213  fdoExtension->DevicePowerState =
214  currentStack->Parameters.Power.State.DeviceState;
215 
216  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
217 
219 
222  NULL,
223  TRUE,
224  TRUE,
225  TRUE);
226 
227  //
228  // Indicate to Po that we've been successfully powered up so
229  // it can do it's notification stuff.
230  //
231 
233  currentStack->Parameters.Power.Type,
234  currentStack->Parameters.Power.State);
235 
236  PoCallDriver(commonExtension->LowerDeviceObject, Irp);
237 
238  ClassReleaseRemoveLock(commonExtension->DeviceObject,
239  Irp);
240 
242 
243  } else {
244  context->QueueLocked = (UCHAR) context->Options.LockQueue;
245  }
246 
247  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
248 
249  context->PowerChangeState.PowerUp = PowerUpDeviceLocked;
250 
253  context,
254  TRUE,
255  TRUE,
256  TRUE);
257 
258  status = PoCallDriver(commonExtension->LowerDeviceObject, Irp);
259 
260  DebugPrint((2, "(%p)\tPoCallDriver returned %lx\n", Irp, status));
261  break;
262  }
263 
264  case PowerUpDeviceOn: {
265 
266  PCDB cdb;
267 
268  if(NT_SUCCESS(Irp->IoStatus.Status)) {
269 
270  DebugPrint((1, "(%p)\tSending start unit to device\n", Irp));
271 
272  //
273  // Issue the start unit command to the device.
274  //
275 
276  context->Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
277  context->Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
278 
279  context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
280  context->Srb.DataTransferLength = 0;
281 
282  context->Srb.TimeOutValue = START_UNIT_TIMEOUT;
283 
284  context->Srb.SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
288 
289  if(context->Options.LockQueue) {
291  }
292 
293  context->Srb.CdbLength = 6;
294 
295  cdb = (PCDB) (context->Srb.Cdb);
296  RtlZeroMemory(cdb, sizeof(CDB));
297 
298 
299  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
300  cdb->START_STOP.Start = 1;
301 
302  context->PowerChangeState.PowerUp = PowerUpDeviceOn;
303 
306  context,
307  TRUE,
308  TRUE,
309  TRUE);
310 
311  nextStack->Parameters.Scsi.Srb = &(context->Srb);
312  nextStack->MajorFunction = IRP_MJ_SCSI;
313 
314  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
315 
316  DebugPrint((2, "(%p)\tIoCallDriver returned %lx\n", Irp, status));
317 
318  } else {
319 
320  //
321  // we're done.
322  //
323 
324  context->FinalStatus = Irp->IoStatus.Status;
325  goto ClasspPowerUpCompletionFailure;
326  }
327 
328  break;
329  }
330 
331  case PowerUpDeviceStarted: { // 3
332 
333  //
334  // First deal with an error if one occurred.
335  //
336 
337  if(SRB_STATUS(context->Srb.SrbStatus) != SRB_STATUS_SUCCESS) {
338 
339  BOOLEAN retry;
340 
341  DebugPrint((1, "%p\tError occured when issuing START_UNIT "
342  "command to device. Srb %p, Status %x\n",
343  Irp,
344  &context->Srb,
345  context->Srb.SrbStatus));
346 
347  ASSERT(!(TEST_FLAG(context->Srb.SrbStatus,
349  ASSERT(context->Srb.Function == SRB_FUNCTION_EXECUTE_SCSI);
350 
351  context->RetryInterval = 0;
352 
353  retry = ClassInterpretSenseInfo(
354  commonExtension->DeviceObject,
355  &context->Srb,
356  IRP_MJ_SCSI,
357  IRP_MJ_POWER,
358  MAXIMUM_RETRIES - context->RetryCount,
359  &status,
360  &context->RetryInterval);
361 
362  if ((retry != FALSE) && (context->RetryCount-- != 0)) {
363 
364  DebugPrint((1, "(%p)\tRetrying failed request\n", Irp));
365 
366  //
367  // Decrement the state so we come back through here the
368  // next time.
369  //
370 
371  context->PowerChangeState.PowerUp--;
372 
373  RetryPowerRequest(commonExtension->DeviceObject,
374  Irp,
375  context);
376 
377  break;
378 
379  }
380 
381  // reset retries
382  context->RetryCount = MAXIMUM_RETRIES;
383 
384  }
385 
386 ClasspPowerUpCompletionFailure:
387 
388  DebugPrint((1, "(%p)\tPreviously spun device up\n", Irp));
389 
390  if (context->QueueLocked) {
391  DebugPrint((1, "(%p)\tUnlocking queue\n", Irp));
392 
393  context->Srb.Function = SRB_FUNCTION_UNLOCK_QUEUE;
394  context->Srb.SrbFlags = SRB_FLAGS_BYPASS_LOCKED_QUEUE;
395  context->Srb.SrbStatus = context->Srb.ScsiStatus = 0;
396  context->Srb.DataTransferLength = 0;
397 
398  nextStack->Parameters.Scsi.Srb = &(context->Srb);
399  nextStack->MajorFunction = IRP_MJ_SCSI;
400 
401  context->PowerChangeState.PowerUp = PowerUpDeviceStarted;
402 
405  context,
406  TRUE,
407  TRUE,
408  TRUE);
409 
410  status = IoCallDriver(commonExtension->LowerDeviceObject, Irp);
411  DebugPrint((1, "(%p)\tIoCallDriver returned %lx\n",
412  Irp, status));
413  break;
414  }
415 
416  // Fall-through to next case...
417 
418  }
419 
420  case PowerUpDeviceUnlocked: {
421 
422  //
423  // This is the end of the dance. Free the srb and complete the
424  // request finally. We're ignoring possible intermediate
425  // error conditions ....
426  //
427 
428  if (context->QueueLocked) {
429  DebugPrint((1, "(%p)\tPreviously unlocked queue\n", Irp));
430  ASSERT(NT_SUCCESS(Irp->IoStatus.Status));
431  ASSERT(context->Srb.SrbStatus == SRB_STATUS_SUCCESS);
432  } else {
433  DebugPrint((1, "(%p)\tFall-through (queue not locked)\n", Irp));
434  }
435 
436  DebugPrint((1, "(%p)\tFreeing srb and completing\n", Irp));
437  context->InUse = FALSE;
438 
439  status = context->FinalStatus;
440  Irp->IoStatus.Status = status;
441 
442  context = NULL;
443 
444  //
445  // Set the new power state
446  //
447 
448  if(NT_SUCCESS(status)) {
449  fdoExtension->DevicePowerState =
450  currentStack->Parameters.Power.State.DeviceState;
451  }
452 
453  //
454  // Indicate to Po that we've been successfully powered up so
455  // it can do it's notification stuff.
456  //
457 
459  currentStack->Parameters.Power.Type,
460  currentStack->Parameters.Power.State);
461 
462  DebugPrint((1, "(%p)\tStarting next power irp\n", Irp));
465 
466  return status;
467  }
468 
469  case PowerUpDeviceInitial: {
470  NT_ASSERT(context->PowerChangeState.PowerUp != PowerUpDeviceInitial);
471  break;
472  }
473  }
474 
476 } // end ClasspPowerUpCompletion()
#define SRB_FUNCTION_UNLOCK_QUEUE
Definition: srb.h:325
#define SRB_FLAGS_DISABLE_AUTOSENSE
Definition: srb.h:391
VOID NTAPI RetryPowerRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PCLASS_POWER_CONTEXT Context)
Definition: power.c:1516
#define TRUE
Definition: types.h:120
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:6587
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:398
_In_ PIRP Irp
Definition: csq.h:116
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
IO_COMPLETION_ROUTINE ClasspPowerUpCompletion
Definition: power.c:38
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_STATUS(Status)
Definition: srb.h:381
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
_Unreferenced_parameter_ PVOID * CompletionContext
Definition: cdprocs.h:1130
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE
Definition: srb.h:402
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
struct _CDB::_START_STOP START_STOP
#define MAXIMUM_RETRIES
Definition: class2.h:14
PDEVICE_OBJECT DeviceObject
Definition: pci.h:42
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
BOOLEAN NTAPI ClassInterpretSenseInfo(IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status, OUT OPTIONAL ULONG *RetryInterval)
Definition: class.c:2994
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
#define IRP_MJ_POWER
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
Definition: srb.h:405
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
#define START_UNIT_TIMEOUT
Definition: class2.c:30
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
NTSTATUS NTAPI ClasspStartNextPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: power.c:1602
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
POWER_STATE NTAPI PoSetPowerState(IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State)
Definition: power.c:597
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
DEVICE_POWER_STATE DevicePowerState
Definition: classpnp.h:700
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

◆ ClasspStartNextPowerIrpCompletion()

NTSTATUS NTAPI ClasspStartNextPowerIrpCompletion ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 1602 of file power.c.

1607 {
1608  if(Irp->PendingReturned) {
1610  }
1611 
1613  return STATUS_SUCCESS;
1614 } // end ClasspStartNextPowerIrpCompletion()
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
return STATUS_SUCCESS
Definition: btrfs.c:2938
IoMarkIrpPending(Irp)

Referenced by ClasspPowerDownCompletion(), ClasspPowerHandler(), and ClasspPowerUpCompletion().

◆ ClassSpinDownPowerHandler()

NTSTATUS NTAPI ClassSpinDownPowerHandler ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 1398 of file power.c.

1402 {
1403  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
1405 
1407 
1408  //
1409  // this will set all options to FALSE
1410  //
1411 
1413 
1414  //
1415  // check the flags to see what options we need to worry about
1416  //
1417 
1418  if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
1420  options.HandleSpinDown = TRUE;
1421  }
1422 
1423  if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
1425  options.HandleSpinUp = TRUE;
1426  }
1427 
1428  if (!TEST_FLAG(fdoExtension->ScanForSpecialFlags,
1430  options.LockQueue = TRUE;
1431  }
1432 
1433  DebugPrint((3, "ClasspPowerHandler: Devobj %p\n"
1434  "\t%shandling spin down\n"
1435  "\t%shandling spin up\n"
1436  "\t%slocking queue\n",
1437  DeviceObject,
1438  (options.HandleSpinDown ? "" : "not "),
1439  (options.HandleSpinUp ? "" : "not "),
1440  (options.LockQueue ? "" : "not ")
1441  ));
1442 
1443  //
1444  // do all the dirty work
1445  //
1446 
1448 } // end ClassSpinDownPowerHandler()
#define TRUE
Definition: types.h:120
#define CLASS_SPECIAL_NO_QUEUE_LOCK
Definition: classpnp.h:164
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
_In_ PIRP Irp
Definition: csq.h:116
#define CLASS_SPECIAL_DISABLE_SPIN_DOWN
Definition: classpnp.h:162
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
NTSTATUS NTAPI ClasspPowerHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CLASS_POWER_OPTIONS Options)
Definition: power.c:1007
PVOID DeviceExtension
Definition: env_spec_w32.h:418
int options
Definition: main.c:106
#define CLASS_SPECIAL_DISABLE_SPIN_UP
Definition: classpnp.h:163
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

Referenced by ClassStopUnitPowerHandler(), and DriverEntry().

◆ ClassStopUnitPowerHandler()

NTSTATUS NTAPI ClassStopUnitPowerHandler ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 1466 of file power.c.

1470 {
1471  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
1472 
1473  DebugPrint((0, "ClassStopUnitPowerHandler - Devobj %p using outdated call\n"
1474  "Drivers should set the following flags in ScanForSpecialFlags "
1475  " in the FDO extension:\n"
1476  "\tCLASS_SPECIAL_DISABLE_SPIN_UP\n"
1477  "\tCLASS_SPECIAL_NO_QUEUE_LOCK\n"
1478  "This will provide equivalent functionality if the power "
1479  "routine is then set to ClassSpinDownPowerHandler\n\n",
1480  DeviceObject));
1481 
1483 
1484  SET_FLAG(fdoExtension->ScanForSpecialFlags,
1486  SET_FLAG(fdoExtension->ScanForSpecialFlags,
1488 
1490 } // end ClassStopUnitPowerHandler()
#define CLASS_SPECIAL_NO_QUEUE_LOCK
Definition: classpnp.h:164
_In_ PIRP Irp
Definition: csq.h:116
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define CLASS_SPECIAL_DISABLE_SPIN_UP
Definition: classpnp.h:163
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
NTSTATUS NTAPI ClassSpinDownPowerHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: power.c:1398

◆ RetryPowerRequest()

VOID NTAPI RetryPowerRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PCLASS_POWER_CONTEXT  Context 
)

Definition at line 1516 of file power.c.

1521 {
1523  PSCSI_REQUEST_BLOCK srb = &(Context->Srb);
1524  LARGE_INTEGER dueTime;
1525 
1526  DebugPrint((1, "(%p)\tDelaying retry by queueing DPC\n", Irp));
1527 
1528  ASSERT(Context->Irp == Irp);
1529  ASSERT(Context->DeviceObject == DeviceObject);
1532 
1533  //
1534  // reset the retry interval
1535  //
1536 
1537  Context->RetryInterval = 0;
1538 
1539  //
1540  // Reset byte count of transfer in SRB Extension.
1541  //
1542 
1543  srb->DataTransferLength = 0;
1544 
1545  //
1546  // Zero SRB statuses.
1547  //
1548 
1549  srb->SrbStatus = srb->ScsiStatus = 0;
1550 
1551  //
1552  // Set up major SCSI function.
1553  //
1554 
1555  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
1556 
1557  //
1558  // Save SRB address in next stack for port driver.
1559  //
1560 
1561  nextIrpStack->Parameters.Scsi.Srb = srb;
1562 
1563  //
1564  // Set the completion routine up again.
1565  //
1566 
1567  IoSetCompletionRoutine(Irp, Context->CompletionRoutine, Context,
1568  TRUE, TRUE, TRUE);
1569 
1570 
1571  if (Context->RetryInterval == 0) {
1572 
1573  DebugPrint((2, "(%p)\tDelaying minimum time (.2 sec)\n", Irp));
1574  dueTime.QuadPart = (LONGLONG)1000000 * 2;
1575 
1576  } else {
1577 
1578  DebugPrint((2, "(%p)\tDelaying %x seconds\n",
1579  Irp, Context->RetryInterval));
1580  dueTime.QuadPart = (LONGLONG)1000000 * 10 * Context->RetryInterval;
1581 
1582  }
1583 
1584  ClassRetryRequest(DeviceObject, Irp, dueTime);
1585 
1586  return;
1587 
1588 } // end RetryRequest()
#define TRUE
Definition: types.h:120
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:398
_In_ PIRP Irp
Definition: csq.h:116
ULONG DataTransferLength
Definition: srb.h:253
UCHAR SrbStatus
Definition: srb.h:243
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
UCHAR ScsiStatus
Definition: srb.h:244
int64_t LONGLONG
Definition: typedefs.h:66
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
Definition: srb.h:405
VOID NTAPI ClassRetryRequest(IN PDEVICE_OBJECT SelfDeviceObject, IN PIRP Irp, IN LARGE_INTEGER TimeDelta100ns)
Definition: class.c:8780
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by ClasspPowerDownCompletion(), and ClasspPowerUpCompletion().

Variable Documentation

◆ ClasspPowerDownCompletion

IO_COMPLETION_ROUTINE ClasspPowerDownCompletion

Definition at line 36 of file power.c.

Referenced by ClasspPowerDownCompletion(), and ClasspPowerHandler().

◆ ClasspPowerUpCompletion

IO_COMPLETION_ROUTINE ClasspPowerUpCompletion

Definition at line 38 of file power.c.

Referenced by ClasspPowerHandler(), and ClasspPowerUpCompletion().