ReactOS  0.4.13-dev-73-gcfe54aa
power.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1991 - 1999
4 
5 Module Name:
6 
7  class.c
8 
9 Abstract:
10 
11  SCSI class driver routines
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19 
20 Revision History:
21 
22 --*/
23 
24 #include "classp.h"
25 
26 #define CLASS_TAG_POWER 'WLcS'
27 
29 NTAPI
32  IN PIRP Irp,
34  );
35 
36 IO_COMPLETION_ROUTINE ClasspPowerDownCompletion;
37 
38 IO_COMPLETION_ROUTINE ClasspPowerUpCompletion;
39 
40 VOID
41 NTAPI
44  PIRP Irp,
46  );
47 
49 NTAPI
52  IN PIRP Irp,
54  );
55 
56 
57 /*++////////////////////////////////////////////////////////////////////////////
58 
59 ClassDispatchPower()
60 
61 Routine Description:
62 
63  This routine acquires the removelock for the irp and then calls the
64  appropriate power callback.
65 
66 Arguments:
67 
68  DeviceObject -
69  Irp -
70 
71 Return Value:
72 
73 --*/
75 NTAPI
78  IN PIRP Irp
79  )
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()
102 
103 /*++////////////////////////////////////////////////////////////////////////////
104 
105 ClasspPowerUpCompletion()
106 
107 Routine Description:
108 
109  This routine is used for intermediate completion of a power up request.
110  PowerUp requires four requests to be sent to the lower driver in sequence.
111 
112  * The queue is "power locked" to ensure that the class driver power-up
113  work can be done before request processing resumes.
114 
115  * The power irp is sent down the stack for any filter drivers and the
116  port driver to return power and resume command processing for the
117  device. Since the queue is locked, no queued irps will be sent
118  immediately.
119 
120  * A start unit command is issued to the device with appropriate flags
121  to override the "power locked" queue.
122 
123  * The queue is "power unlocked" to start processing requests again.
124 
125  This routine uses the function in the srb which just completed to determine
126  which state it is in.
127 
128 Arguments:
129 
130  DeviceObject - the device object being powered up
131 
132  Irp - the IO_REQUEST_PACKET containing the power request
133 
134  Srb - the SRB used to perform port/class operations.
135 
136 Return Value:
137 
138  STATUS_MORE_PROCESSING_REQUIRED or
139  STATUS_SUCCESS
140 
141 --*/
142 NTSTATUS
143 NTAPI
146  IN PIRP Irp,
148  )
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()
477 
478 /*++////////////////////////////////////////////////////////////////////////////
479 
480 ClasspPowerDownCompletion()
481 
482 Routine Description:
483 
484  This routine is used for intermediate completion of a power up request.
485  PowerUp requires four requests to be sent to the lower driver in sequence.
486 
487  * The queue is "power locked" to ensure that the class driver power-up
488  work can be done before request processing resumes.
489 
490  * The power irp is sent down the stack for any filter drivers and the
491  port driver to return power and resume command processing for the
492  device. Since the queue is locked, no queued irps will be sent
493  immediately.
494 
495  * A start unit command is issued to the device with appropriate flags
496  to override the "power locked" queue.
497 
498  * The queue is "power unlocked" to start processing requests again.
499 
500  This routine uses the function in the srb which just completed to determine
501  which state it is in.
502 
503 Arguments:
504 
505  DeviceObject - the device object being powered up
506 
507  Irp - the IO_REQUEST_PACKET containing the power request
508 
509  Srb - the SRB used to perform port/class operations.
510 
511 Return Value:
512 
513  STATUS_MORE_PROCESSING_REQUIRED or
514  STATUS_SUCCESS
515 
516 --*/
517 NTSTATUS
518 NTAPI
521  IN PIRP Irp,
523  )
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()
982 
983 /*++////////////////////////////////////////////////////////////////////////////
984 
985 ClasspPowerHandler()
986 
987 Routine Description:
988 
989  This routine reduces the number of useless spinups and spindown requests
990  sent to a given device by ignoring transitions to power states we are
991  currently in.
992 
993  ISSUE-2000/02/20-henrygab - by ignoring spin-up requests, we may be
994  allowing the drive
995 
996 Arguments:
997 
998  DeviceObject - the device object which is transitioning power states
999  Irp - the power irp
1000  Options - a set of flags indicating what the device handles
1001 
1002 Return Value:
1003 
1004 --*/
1005 NTSTATUS
1006 NTAPI
1009  IN PIRP Irp,
1010  IN CLASS_POWER_OPTIONS Options // ISSUE-2000/02/20-henrygab - pass pointer, not whole struct
1011  )
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()
1289 
1290 /*++////////////////////////////////////////////////////////////////////////////
1291 
1292 ClassMinimalPowerHandler()
1293 
1294 Routine Description:
1295 
1296  This routine is the minimum power handler for a storage driver. It does
1297  the least amount of work possible.
1298 
1299 --*/
1300 NTSTATUS
1301 NTAPI
1304  IN PIRP Irp
1305  )
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()
1369 
1370 /*++////////////////////////////////////////////////////////////////////////////
1371 
1372 ClassSpinDownPowerHandler()
1373 
1374 Routine Description:
1375 
1376  This routine is a callback for disks and other things which require both
1377  a start and a stop to be sent to the device. (actually the starts are
1378  almost always optional, since most device power themselves on to process
1379  commands, but i digress).
1380 
1381  Determines proper use of spinup, spindown, and queue locking based upon
1382  ScanForSpecialFlags in the FdoExtension. This is the most common power
1383  handler passed into classpnp.sys
1384 
1385 Arguments:
1386 
1387  DeviceObject - Supplies the functional device object
1388 
1389  Irp - Supplies the request to be retried.
1390 
1391 Return Value:
1392 
1393  None
1394 
1395 --*/
1396 NTSTATUS
1397 NTAPI
1400  IN PIRP Irp
1401  )
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()
1449 
1450 /*++////////////////////////////////////////////////////////////////////////////
1451 
1452 ClassStopUnitPowerHandler()
1453 
1454 Routine Description:
1455 
1456  This routine is an outdated call. To achieve equivalent functionality,
1457  the driver should set the following flags in ScanForSpecialFlags in the
1458  FdoExtension:
1459 
1460  CLASS_SPECIAL_DISABLE_SPIN_UP
1461  CLASS_SPECIAL_NO_QUEUE_LOCK
1462 
1463 --*/
1464 NTSTATUS
1465 NTAPI
1468  IN PIRP Irp
1469  )
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()
1491 
1492 /*++////////////////////////////////////////////////////////////////////////////
1493 
1494 RetryPowerRequest()
1495 
1496 Routine Description:
1497 
1498  This routine reinitializes the necessary fields, and sends the request
1499  to the lower driver.
1500 
1501 Arguments:
1502 
1503  DeviceObject - Supplies the device object associated with this request.
1504 
1505  Irp - Supplies the request to be retried.
1506 
1507  Context - Supplies a pointer to the power up context for this request.
1508 
1509 Return Value:
1510 
1511  None
1512 
1513 --*/
1514 VOID
1515 NTAPI
1518  PIRP Irp,
1520  )
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()
1589 
1590 /*++////////////////////////////////////////////////////////////////////////////
1591 
1592 ClasspStartNextPowerIrpCompletion()
1593 
1594 Routine Description:
1595 
1596  This routine guarantees that the next power irp (power up or down) is not
1597  sent until the previous one has fully completed.
1598 
1599 --*/
1600 NTSTATUS
1601 NTAPI
1604  IN PIRP Irp,
1605  IN PVOID Context
1606  )
1607 {
1608  if(Irp->PendingReturned) {
1610  }
1611 
1613  return STATUS_SUCCESS;
1614 } // end ClasspStartNextPowerIrpCompletion()
#define SRB_FUNCTION_UNLOCK_QUEUE
Definition: srb.h:325
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
#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
#define IN
Definition: typedefs.h:38
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 ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
USHORT Flags
Definition: iotypes.h:169
#define CLASS_SPECIAL_NO_QUEUE_LOCK
Definition: classpnp.h:164
#define IRP_MN_QUERY_POWER
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
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
IO_COMPLETION_ROUTINE ClasspPowerUpCompletion
Definition: power.c:38
ULONG DataTransferLength
Definition: srb.h:253
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:575
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
struct _CDB::_SYNCHRONIZE_CACHE10 SYNCHRONIZE_CACHE10
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
NTSTATUS NTAPI ClassMinimalPowerHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: power.c:1302
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define CLASS_SPECIAL_DISABLE_SPIN_DOWN
Definition: classpnp.h:162
enum OPTION_FLAGS Options
Definition: stats.c:44
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
IO_COMPLETION_ROUTINE ClasspPowerDownCompletion
Definition: power.c:36
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
UCHAR ScsiStatus
Definition: srb.h:244
_Unreferenced_parameter_ PVOID * CompletionContext
Definition: cdprocs.h:1130
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE
Definition: srb.h:402
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
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ClassStopUnitPowerHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: power.c:1466
union _CDB * PCDB
struct _CDB::_START_STOP START_STOP
#define MAXIMUM_RETRIES
Definition: class2.h:14
int options
Definition: main.c:106
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
int64_t LONGLONG
Definition: typedefs.h:66
PDEVICE_OBJECT DeviceObject
Definition: pci.h:42
#define FDO_HACK_NO_SYNC_CACHE
Definition: classp.h:55
PCLASS_POWER_DEVICE ClassPowerDevice
Definition: classpnp.h:512
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define CLASS_SPECIAL_DISABLE_SPIN_UP
Definition: classpnp.h:163
#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
PVPB NTAPI ClassGetVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: class.c:8048
NTSTATUS NTAPI ClassDispatchPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: power.c:76
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:693
CLASS_POWER_CONTEXT PowerContext
Definition: classpnp.h:744
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
#define IRP_MN_SET_POWER
#define NOTHING
Definition: env_spec_w32.h:461
__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 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
#define START_UNIT_TIMEOUT
Definition: class2.c:34
#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
VOID NTAPI ClassRetryRequest(IN PDEVICE_OBJECT SelfDeviceObject, IN PIRP Irp, IN LARGE_INTEGER TimeDelta100ns)
Definition: class.c:8780
Definition: iotypes.h:166
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#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:2771
BOOLEAN MediaRemovable
Definition: imports.h:246
return STATUS_SUCCESS
Definition: btrfs.c:2725
IoMarkIrpPending(Irp)
NTSTATUS NTAPI ClassSpinDownPowerHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: power.c:1398
#define VPB_MOUNTED
Definition: iotypes.h:1763
static SERVICE_STATUS status
Definition: service.c:31
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define SRB_FUNCTION_LOCK_QUEUE
Definition: srb.h:324
LONGLONG QuadPart
Definition: typedefs.h:112
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