https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fb155b4ea4f6e66231b17…
commit fb155b4ea4f6e66231b17dcf5fc0938c1b0e9732
Author: Victor Perevertkin <victor.perevertkin(a)reactos.org>
AuthorDate: Wed Oct 28 15:20:23 2020 +0300
Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org>
CommitDate: Sat Dec 5 22:28:54 2020 +0300
[SCSIPORT] Fix Sense request sending
- Pass all SRB flags which Windows scsiport passes
- Correctly reset the queue after completion
This fixes the bug when MS cdrom driver hangs after media ejection
---
drivers/storage/port/scsiport/scsi.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/storage/port/scsiport/scsi.c b/drivers/storage/port/scsiport/scsi.c
index 29b683d10c0..6cfd1ba29f3 100644
--- a/drivers/storage/port/scsiport/scsi.c
+++ b/drivers/storage/port/scsiport/scsi.c
@@ -445,6 +445,9 @@ SpiSenseCompletionRoutine(
_In_ PIRP Irp,
_In_opt_ PVOID Context)
{
+ PIO_STACK_LOCATION ioStack = IoGetNextIrpStackLocation(Irp);
+ PSCSI_PORT_LUN_EXTENSION lunExt = ioStack->DeviceObject->DeviceExtension;
+ PSCSI_PORT_DEVICE_EXTENSION portExt =
lunExt->Common.LowerDevice->DeviceExtension;
PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)Context;
PSCSI_REQUEST_BLOCK InitialSrb;
PIRP InitialIrp;
@@ -478,6 +481,26 @@ SpiSenseCompletionRoutine(
/* Make sure initial SRB's queue is frozen */
ASSERT(InitialSrb->SrbStatus & SRB_STATUS_QUEUE_FROZEN);
+ // The queue is frozen, but the SRB had a SRB_FLAGS_NO_QUEUE_FREEZE => unfreeze
the queue
+ if ((InitialSrb->SrbFlags & SRB_FLAGS_NO_QUEUE_FREEZE) &&
+ (InitialSrb->SrbStatus & SRB_STATUS_QUEUE_FROZEN))
+ {
+ KIRQL irql;
+
+ KeAcquireSpinLock(&portExt->SpinLock, &irql);
+
+ ASSERT(lunExt->Flags & LUNEX_FROZEN_QUEUE);
+
+ lunExt->Flags &= ~LUNEX_FROZEN_QUEUE;
+ lunExt->Flags &= ~LUNEX_NEED_REQUEST_SENSE;
+
+ // SpiGetNextRequestFromLun releases the lock
+ SpiGetNextRequestFromLun(portExt, lunExt);
+ KeLowerIrql(irql);
+
+ InitialSrb->SrbStatus &= ~SRB_STATUS_QUEUE_FROZEN;
+ }
+
/* Complete this request */
IoCompleteRequest(InitialIrp, IO_DISK_INCREMENT);
@@ -580,10 +603,16 @@ SpiSendRequestSense(
Srb->SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_BYPASS_FROZEN_QUEUE |
SRB_FLAGS_DISABLE_DISCONNECT;
- /* Transfer disable synch transfer flag */
+ // pass some InitialSrb flags
if (InitialSrb->SrbFlags & SRB_FLAGS_DISABLE_SYNCH_TRANSFER)
Srb->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
+ if (InitialSrb->SrbFlags & SRB_FLAGS_BYPASS_LOCKED_QUEUE)
+ Srb->SrbFlags |= SRB_FLAGS_BYPASS_LOCKED_QUEUE;
+
+ if (InitialSrb->SrbFlags & SRB_FLAGS_NO_QUEUE_FREEZE)
+ Srb->SrbFlags |= SRB_FLAGS_NO_QUEUE_FREEZE;
+
Srb->DataBuffer = InitialSrb->SenseInfoBuffer;
/* Fill the transfer length */