https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fb155b4ea4f6e66231b17dcf5fc0938c1b0e9732
commit fb155b4ea4f6e66231b17dcf5fc0938c1b0e9732 Author: Victor Perevertkin <victor.perevert...@reactos.org> AuthorDate: Wed Oct 28 15:20:23 2020 +0300 Commit: Victor Perevertkin <victor.perevert...@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 */