Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
4.7 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1990 - 1999
  3. Module Name:
  4. stop.c
  5. Abstract:
  6. This is the NT SCSI port driver. This file contains the initialization
  7. code.
  8. Authors:
  9. Mike Glass
  10. Jeff Havens
  11. Environment:
  12. kernel mode only
  13. Notes:
  14. This module is a driver dll for scsi miniports.
  15. Revision History:
  16. --*/
  17. #include "port.h"
  18. typedef struct _SP_STOP_DEVICE_CONTEXT {
  19. OUT NTSTATUS Status;
  20. IN KEVENT Event;
  21. } SP_STOP_DEVICE_CONTEXT, *PSP_STOP_DEVICE_CONTEXT;
  22. VOID
  23. SpCallHwStopAdapter(
  24. IN PDEVICE_OBJECT Adapter
  25. );
  26. BOOLEAN
  27. SpCallHwStopAdapterSynchronized(
  28. IN PADAPTER_EXTENSION AdapterExtension
  29. );
  30. VOID
  31. SpDeviceStoppedCompletion(
  32. IN PDEVICE_OBJECT DeviceObject,
  33. IN NTSTATUS Status,
  34. IN PSP_STOP_DEVICE_CONTEXT Context
  35. );
  36. #ifdef ALLOC_PRAGMA
  37. #pragma alloc_text(PAGE, ScsiPortStopLogicalUnit)
  38. #pragma alloc_text(PAGE, ScsiPortStopAdapter)
  39. #endif
  40. NTSTATUS
  41. ScsiPortStopLogicalUnit(
  42. IN PLOGICAL_UNIT_EXTENSION LogicalUnit
  43. )
  44. /*++
  45. Routine Description:
  46. This routine will lock the queue for the given logical unit to make sure
  47. that all request processing for this device is stopped. It will clear
  48. the IsStarted flag once the queue has been locked successfully. This will
  49. keep any other requests from being processed until a start has been
  50. received.
  51. Arguments:
  52. LogicalUnit - the logical unit to be started.
  53. Irp - the stop request
  54. Return Value:
  55. status
  56. --*/
  57. {
  58. SP_STOP_DEVICE_CONTEXT context;
  59. NTSTATUS status = STATUS_SUCCESS;
  60. PAGED_CODE();
  61. if(LogicalUnit->CommonExtension.CurrentPnpState == IRP_MN_STOP_DEVICE) {
  62. return STATUS_SUCCESS;
  63. }
  64. KeInitializeEvent(&(context.Event), SynchronizationEvent, FALSE);
  65. status = SpEnableDisableLogicalUnit(LogicalUnit,
  66. FALSE,
  67. SpDeviceStoppedCompletion,
  68. &context);
  69. KeWaitForSingleObject(&(context.Event),
  70. Executive,
  71. KernelMode,
  72. FALSE,
  73. NULL);
  74. return context.Status;
  75. }
  76. VOID
  77. SpDeviceStoppedCompletion(
  78. IN PDEVICE_OBJECT DeviceObject,
  79. IN NTSTATUS Status,
  80. IN PSP_STOP_DEVICE_CONTEXT Context
  81. )
  82. {
  83. Context->Status = Status;
  84. KeSetEvent(&(Context->Event), IO_NO_INCREMENT, FALSE);
  85. return;
  86. }
  87. NTSTATUS
  88. ScsiPortStopAdapter(
  89. IN PDEVICE_OBJECT Adapter,
  90. IN PIRP StopRequest
  91. )
  92. /*++
  93. Routine Description:
  94. This routine will stop an adapter and release it's io and interrupt
  95. resources. Pool allocations will not be freed, nor will the various
  96. miniport extensions.
  97. Arguments:
  98. Adapter - the device object for the adapter.
  99. Return Value:
  100. status
  101. --*/
  102. {
  103. PADAPTER_EXTENSION adapterExtension = Adapter->DeviceExtension;
  104. PCOMMON_EXTENSION commonExtension = Adapter->DeviceExtension;
  105. KEVENT event;
  106. ULONG bin;
  107. PAGED_CODE();
  108. ASSERT(adapterExtension->IsPnp);
  109. //
  110. // If we're not started and we weren't started then there's no reason
  111. // to do any work when stopping.
  112. //
  113. if((commonExtension->CurrentPnpState != IRP_MN_START_DEVICE) &&
  114. (commonExtension->PreviousPnpState != IRP_MN_START_DEVICE)) {
  115. return STATUS_SUCCESS;
  116. }
  117. //
  118. // Since all the children are stopped no requests can get through to the
  119. // adapter.
  120. //
  121. //
  122. // Send a request through the start-io routine to shut it down so that we
  123. // can start it back up later.
  124. //
  125. KeInitializeEvent(&event, SynchronizationEvent, FALSE);
  126. StopRequest->IoStatus.Information = (ULONG_PTR) &event;
  127. IoStartPacket(Adapter, StopRequest, 0, NULL);
  128. KeWaitForSingleObject(&event,
  129. Executive,
  130. KernelMode,
  131. FALSE,
  132. NULL);
  133. //
  134. // Call the miniport and get it to shut the adapter down.
  135. //
  136. SpEnableDisableAdapter(adapterExtension, FALSE);
  137. SpReleaseAdapterResources(adapterExtension, TRUE, FALSE);
  138. //
  139. // Zero out all the logical unit extensions.
  140. //
  141. for(bin = 0; bin < NUMBER_LOGICAL_UNIT_BINS; bin++) {
  142. PLOGICAL_UNIT_EXTENSION lun;
  143. for(lun = adapterExtension->LogicalUnitList[bin].List;
  144. lun != NULL;
  145. lun = lun->NextLogicalUnit) {
  146. RtlZeroMemory(lun->HwLogicalUnitExtension,
  147. adapterExtension->HwLogicalUnitExtensionSize);
  148. }
  149. }
  150. return STATUS_SUCCESS;
  151. }