Virtual Scsi Miniport Question

Peter,

ESI has Null in it. Does that tell you anything other than the obvious?

Joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
Sent: Friday, October 25, 2002 12:48 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

some notes:

    • this will freeze the queue for the current LUN, not the current
      target. very important distinction here. scsiport doesn’t do anything
      to track targets except as part of the bus address of the LUNs.

the code below looks okay from a quick scan, but obviously something’s
wrong with it so that “is this all correct” question is tough to answer
:slight_smile:

at the point that you crashed, ESI contains the pointer to the SRB
scsiport is processing. If you log all SRB pointers as they enter and
leave your driver you should be able to compare ESI against that log to
find out which SRB it is. Simply dumping the SRB probably won’t help
since it’s very likely been reused as a new SRB (or some other memory
allocation) by that point.

-p

-----Original Message-----
From: Joe Moriarty [mailto:xxxxx@east.sun.com]
Sent: Friday, October 25, 2002 9:11 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

Peter,

I am 100% sure you are correct. The only problem I have now is
determining which SRB I am completing twice. I have checked each and
everyone of the requests to make sure everything is correct. The only
question I have now is if I am handling the case when passing the
request down to a lower level driver.

So here is the sequence of events.

  1. SRB_FUNCTION_EXECUTE_SCSI requests comes in to my StartIo.
  2. I notify a worker thread to pass the request down to the lower level
    driver. pointer to the SRB is passed to the worker thread.
  3. I do the following before returning from my StartIo routine.
    //Adapter ready for next request.
    ScsiPortNotification(NextRequest, pAdapterExt, NULL);

I do not mark the current SRB I was working on in my StartIo as
completed, busy, etc. My guess was that this would freeze
the queue for this particular target ID. I verified this in the
debugger.

  1. Worker thread starts up and passes the SRB down to the lower level
    driver and waits on completion.
  2. Upon completion of the SRB I create the following IRP to pass to the
    SCSIPORT driver. The code is below.

PPDO_SCSI_MINIPORT_EXTENSION pPdoScsiMiniportExt;
PEMDISK_CONTROLLER_EXTENSION pEmDiskCntrlExt;
PDEVICE_EXT_HDR pPdoDevExtHdr;
PSCSI_REQUEST_BLOCK pCurrentSrb;
KEVENT kEvent;
IO_SRB_CONTROL_STRUCTURE IoCntrlStrct;
PIRP pIrp;
LARGE_INTEGER liStartingOffset;
IO_STATUS_BLOCK IoStatusBlock;
SCSI_REQUEST_BLOCK Srb;
PIO_STACK_LOCATION pIrpSp;
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;

pPdoScsiMiniportExt =
(PPDO_SCSI_MINIPORT_EXTENSION)pAdapterExt->pPdoScsiMiniport;
pEmDiskCntrlExt =
pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.pEmDiskCntrlExt;
pPdoDevExtHdr =
&pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.DeviceExtHdr;
pCurrentSrb = pAdapterExt->pCurrentSrb;

KeInitializeEvent(&kEvent, NotificationEvent, FALSE);

//
// Setup Data structure
//
RtlZeroMemory(&IoCntrlStrct, sizeof(IO_SRB_CONTROL_STRUCTURE));
IoCntrlStrct.IoSrbCntrl.HeaderLength = sizeof(SRB_IO_CONTROL);
strcpy(IoCntrlStrct.IoSrbCntrl.Signature, VER_INTERNALNAME_STR);
IoCntrlStrct.IoSrbCntrl.Timeout = FOUR_SECONDS;
IoCntrlStrct.IoSrbCntrl.ControlCode = DIO_SUNPCI_INTERMEDIATE_IO;
IoCntrlStrct.IoSrbCntrl.Length = sizeof(PSCSI_REQUEST_BLOCK);
IoCntrlStrct.pCurSrb = pCurrentSrb;

liStartingOffset.QuadPart = 1;// SCSIPORT does this, no idea why…
pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_SCSI,
(PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj,
&IoCntrlStrct,
sizeof(IO_SRB_CONTROL_STRUCTURE),
&liStartingOffset, &kEvent,
&IoStatusBlock);
if(pIrp)
{
//
// Setup Irp Request Data
//
RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
Srb.PathId = pCurrentSrb->PathId;
Srb.TargetId = pCurrentSrb->TargetId;
Srb.Lun = pCurrentSrb->Lun;

Srb.Function = SRB_FUNCTION_IO_CONTROL;
Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE |
SRB_FLAGS_BYPASS_FROZEN_QUEUE;
Srb.DataBuffer = &IoCntrlStrct;
Srb.DataTransferLength = sizeof(IO_SRB_CONTROL_STRUCTURE);

pIrpSp = IoGetNextIrpStackLocation(pIrp);
pIrpSp->MajorFunction = IRP_MJ_SCSI;
pIrpSp->MinorFunction = 1;
pIrpSp->Parameters.Scsi.Srb = &Srb;

IoCallDriver((PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj, pIrp);
KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE,
NULL);
Status = IoStatusBlock.Status;
}
6) My StartIo routine is hit with the above IRP. I figure out that the
IRP came from my worker thread trying to complete the SRB he was working
on. I complete the request for the worker thread. I then complete the
request for worker thread IRP he sent to complete the SRB. Below is the
code that does this.

pSrbIoCntrl = (PSRB_IO_CONTROL)pSrb->DataBuffer;
if(RtlCompareMemory(pSrbIoCntrl->Signature, VER_INTERNALNAME_STR,
sizeof(pSrbIoCntrl->Signature)) ==
sizeof(pSrbIoCntrl->Signature))
{
switch(pSrbIoCntrl->ControlCode)
{
case DIO_SUNPCI_INTERMEDIATE_IO:
{
PIO_SRB_CONTROL_STRUCTURE pIoSrbCntrlStrct;

pIoSrbCntrlStrct =
(PIO_SRB_CONTROL_STRUCTURE)pSrb->DataBuffer;
pCompletedSrb = pIoSrbCntrlStrct->pCurSrb;
if(pCompletedSrb)
{
// Complete the original SRB request.
ScsiPortNotification(RequestComplete, pAdapterExt,
pCompletedSrb);
}

// Set the status for the Intermediate SRB
pSrb->ScsiStatus = SCSISTAT_GOOD;
pSrb->SrbStatus = SRB_STATUS_SUCCESS;

// Complete the Intermediate SRB request.
ScsiPortNotification(RequestComplete, pAdapterExt, pSrb);
break;
}

Is this all correct?

Joe

> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
> Sent: Thursday, October 24, 2002 2:43 PM
> To: NT Developers Interest List
> Subject: [ntdev] RE: Virtual SCSI miniport question
>
>
> SpGetInterruptState takes all the data squirreled away while the
> miniport was running inside the ‘interupt spinlock’ (in your case it’s

> just a normal spinlock and we synch at DPC level) and makes it safely
> accessible by the completion DPC. If it’s faulting in that routine
> it’s likely that something squirreled away is no longer valid - for
> example you might have completed an SRB which had already been
> completed earlier.
>
> given that the SrbStatus is a one byte field at offset 3 in the SRB,
> that SpGetInterruptState checks the SRB statuses while processing
> them, and that the faulting address below is attempting to read a one
> byte value at offset 3 from esi, I’d suspect that’s the case.
>
> -p
>
> -----Original Message-----
> From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> Sent: Thursday, October 24, 2002 10:28 AM
> To: NT Developers Interest List
> Subject: [ntdev] Virtual SCSI miniport question
>
>
> I have a virtual SCSI miniport driver that works fine except for when
> the user issues a SHUTDOWN/RESET under Win2K. I get to the “Windows
> is shutting down …” and then boom. The dump is below. It doesn’t
> happen all the time. I would say that in 50% of the shutdowns this
> will occur. The question I have is why is the SCSIPORT driver trying
> to acquire the interrupt state from the HBA? I have set the
> HwInterrupt routine to NULL in my DriverEntry routine. BTW, this is a

> PNP virtual SCSI miniport. The system thinks it’s on a ISA bus. I
> have created a bus driver that enumerates a virtual SCSI miniport
> device. The SCSIPORT driver loads on top of this stack and then calls

> my virtual SCSI miniport driver.
>
> Thanks In Advance,
> Joe
>
> **********************************************************************
> **
> ****
> ***
> *
> *
> * Bugcheck Analysis
> *
> *
> *
>
************************************************************************
> ****
> ***
>
> DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> An attempt was made to access a pagable (or completely invalid)
> address at an interrupt request level (IRQL) that is too high. This
> is usually caused by drivers using improper addresses. If kernel
> debugger is available get stack backtrace.
> Arguments:
> Arg1: 00000003, memory referenced
> Arg2: 00000002, IRQL
> Arg3: 00000000, value 0 = read operation, 1 = write operation
> Arg4: bff3a6a6, address which referenced memory
>
> Debugging Details:
> ------------------
>
>
> READ_ADDRESS: 00000003 Unknown
>
> CURRENT_IRQL: 2
>
> FAULTING_IP:
> SCSIPORT!SpGetInterruptState+6e
> bff3a6a6 8a5603 mov dl,[esi+0x3]
>
> DEFAULT_BUCKET_ID: DRIVER_FAULT
>
> BUGCHECK_STR: D1
>
> LAST_CONTROL_TRANSFER: from 8042bcb9 to 80452e70
>
> STACK_TEXT:
> f441fb0c 8042bcb9 00000003 f441fb54 00000003
> nt!RtlpBreakWithStatusInstruction f441fb3c 8042c068 00000003 00000003
> bff3a6a6 nt!KiBugCheckDebugBreak+0x31 f441fec4 80464b1f 00000000
> 00000003 00000002 nt!KeBugCheckEx+0x37b f441fec4 bff3a6a6 00000000
> 00000003 00000002 nt!KiTrap0E+0x27c f441ff5c bff3b636 f441ffd0
> 818881e4 818880e8 SCSIPORT!SpGetInterruptState+0x6e f441ff70 bff39971
> 818880e8 bff3a638 f441ffd0 SCSIPORT!SpSynchronizeExecution+0x1e
> f441ffe0 80460bd4 818880a4 81888030 00000000
> SCSIPORT!ScsiPortCompletionDpc+0x3b
> f441fff4 80403a82 f4473b9c 00000000 00000000 nt!KiRetireDpcList+0x30
>
>
> FOLLOWUP_IP:
> SCSIPORT!SpGetInterruptState+6e
> bff3a6a6 8a5603 mov dl,[esi+0x3]
>
> FOLLOWUP_NAME: MachineOwner
>
> SYMBOL_NAME: SCSIPORT!SpGetInterruptState+6e
>
> MODULE_NAME: SCSIPORT
>
> IMAGE_NAME: SCSIPORT
>
> STACK_COMMAND: kb
>
> BUCKET_ID: 0xD1_SCSIPORT!SpGetInterruptState+6e
>
> Followup: MachineOwner
> ---------
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@microsoft.com To
> unsubscribe send a blank email to %%email.unsub%%
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@east.sun.com To

> unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@east.sun.com
To unsubscribe send a blank email to %%email.unsub%%

Pete,

Here’s some more information. Did I forget to mention thanks for helping me
out here :).

register dump

eax=00000003 ebx=000000d1 ecx=ffffffff edx=00000000 esi=00000003
edi=ee01fb54
eip=80452e70 esp=ee01fb10 ebp=ee01fb3c iopl=0 nv up ei pl zr na po
nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
efl=00000246
nt!RtlpBreakWithStatusInstruction:
80452e70 cc int 3

stack dump

SCSIPORT!SpGetInterruptState:
bff3a638 53 push ebx
bff3a639 8b5c2408 mov ebx,[esp+0x8]
bff3a63d 8b03 mov eax,[ebx]
bff3a63f f680e001000004 test byte ptr [eax+0x1e0],0x4
bff3a646 8d90e0010000 lea edx,[eax+0x1e0]
bff3a64c 7507 jnz SCSIPORT!SpGetInterruptState+0x1d
(bff3a655)
bff3a64e 32c0 xor al,al
bff3a650 e90e010000 jmp SCSIPORT!SpGetInterruptState+0x12b
(bff3a763)
bff3a655 57 push edi
bff3a656 8b7b04 mov edi,[ebx+0x4]
bff3a659 56 push esi
bff3a65a 6a10 push 0x10
bff3a65c 59 pop ecx
bff3a65d 8bf2 mov esi,edx
bff3a65f f3a5 rep movsd
bff3a661 812280410800 and dword ptr [edx],0x84180
bff3a667 33ff xor edi,edi
bff3a669 ba00000200 mov edx,0x20000
bff3a66e 8d88e0000000 lea ecx,[eax+0xe0]
bff3a674 89b8e4010000 mov [eax+0x1e4],edi
bff3a67a 89b80c020000 mov [eax+0x20c],edi
bff3a680 89b810020000 mov [eax+0x210],edi
bff3a686 89b81c020000 mov [eax+0x21c],edi
bff3a68c ff1530daf3bf call dword ptr [SCSIPORT!imp (bff3da30)]
bff3a692 8b4304 mov eax,[ebx+0x4]
bff3a695 8b4804 mov ecx,[eax+0x4]
bff3a698 3bcf cmp ecx,edi
bff3a69a 0f84bf000000 je SCSIPORT!SpGetInterruptState+0x127
(bff3a75f)
bff3a6a0 8b711c mov esi,[ecx+0x1c]
bff3a6a3 8b4114 mov eax,[ecx+0x14]
bff3a6a6 8a5603 mov dl,[esi+0x3] <- BREAKPOINT: Here’s where
the crash is
bff3a6a9 80fa01 cmp dl,0x1
bff3a6ac 7460 jz SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a6ae 807e0402 cmp byte ptr [esi+0x4],0x2
bff3a6b2 7530 jnz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6b4 f6c280 test dl,0x80
bff3a6b7 752b jnz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6b9 397e1c cmp [esi+0x1c],edi
bff3a6bc 7426 jz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6be 807e0b00 cmp byte ptr [esi+0xb],0x0
bff3a6c2 7420 jz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6c4 8b90b0000000 mov edx,[eax+0xb0]
bff3a6ca 8d98b0000000 lea ebx,[eax+0xb0]
bff3a6d0 f6c204 test dl,0x4
bff3a6d3 740a jz SCSIPORT!SpGetInterruptState+0xa7
(bff3a6df)
bff3a6d5 80660400 and byte ptr [esi+0x4],0x0
bff3a6d9 c6460310 mov byte ptr [esi+0x3],0x10
bff3a6dd eb05 jmp SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6df 83ca04 or edx,0x4
bff3a6e2 8913 mov [ebx],edx
bff3a6e4 807e0428 cmp byte ptr [esi+0x4],0x28
bff3a6e8 7524 jnz SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a6ea 8a9005010000 mov dl,[eax+0x105]
bff3a6f0 8388b000000010 or dword ptr [eax+0xb0],0x10
bff3a6f7 3a9004010000 cmp dl,[eax+0x104]
bff3a6fd 8d9804010000 lea ebx,[eax+0x104]
bff3a703 7309 jnb SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a705 80fa02 cmp dl,0x2
bff3a708 7604 jbe SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a70a feca dec dl
bff3a70c 8813 mov [ebx],dl
bff3a70e 807e08ff cmp byte ptr [esi+0x8],0xff
bff3a712 7504 jnz SCSIPORT!SpGetInterruptState+0xe0
(bff3a718)
bff3a714 b301 mov bl,0x1
bff3a716 eb16 jmp SCSIPORT!SpGetInterruptState+0xf6
(bff3a72e)
bff3a718 8b5110 mov edx,[ecx+0x10]
bff3a71b 8d710c lea esi,[ecx+0xc]
bff3a71e 39b0f0000000 cmp [eax+0xf0],esi
bff3a724 8b36 mov esi,[esi]
bff3a726 8932 mov [edx],esi

Thanks,
Joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Joe Moriarty
Sent: Friday, October 25, 2002 2:11 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

Peter,

ESI has Null in it. Does that tell you anything other than the obvious?

Joe

> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
> Sent: Friday, October 25, 2002 12:48 PM
> To: NT Developers Interest List
> Subject: [ntdev] RE: Virtual SCSI miniport question
>
>
> some notes:
>
> 3) - this will freeze the queue for the current LUN, not the current
> target. very important distinction here. scsiport doesn’t do anything
> to track targets except as part of the bus address of the LUNs.
>
> the code below looks okay from a quick scan, but obviously something’s
> wrong with it so that “is this all correct” question is tough to answer
> :slight_smile:
>
> at the point that you crashed, ESI contains the pointer to the SRB
> scsiport is processing. If you log all SRB pointers as they enter and
> leave your driver you should be able to compare ESI against that log to
> find out which SRB it is. Simply dumping the SRB probably won’t help
> since it’s very likely been reused as a new SRB (or some other memory
> allocation) by that point.
>
> -p
>
> -----Original Message-----
> From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> Sent: Friday, October 25, 2002 9:11 AM
> To: NT Developers Interest List
> Subject: [ntdev] RE: Virtual SCSI miniport question
>
>
> Peter,
>
> I am 100% sure you are correct. The only problem I have now is
> determining which SRB I am completing twice. I have checked each and
> everyone of the requests to make sure everything is correct. The only
> question I have now is if I am handling the case when passing the
> request down to a lower level driver.
>
> So here is the sequence of events.
>
> 1) SRB_FUNCTION_EXECUTE_SCSI requests comes in to my StartIo.
> 2) I notify a worker thread to pass the request down to the lower level
> driver. pointer to the SRB is passed to the worker thread.
> 3) I do the following before returning from my StartIo routine.
> //Adapter ready for next request.
> ScsiPortNotification(NextRequest, pAdapterExt, NULL);
>
> I do not mark the current SRB I was working on in my StartIo as
> completed, busy, etc. My guess was that this would freeze
> the queue for this particular target ID. I verified this in the
> debugger.
>
> 4) Worker thread starts up and passes the SRB down to the lower level
> driver and waits on completion.
> 5) Upon completion of the SRB I create the following IRP to pass to the
> SCSIPORT driver. The code is below.
>
> PPDO_SCSI_MINIPORT_EXTENSION pPdoScsiMiniportExt;
> PEMDISK_CONTROLLER_EXTENSION pEmDiskCntrlExt;
> PDEVICE_EXT_HDR pPdoDevExtHdr;
> PSCSI_REQUEST_BLOCK pCurrentSrb;
> KEVENT kEvent;
> IO_SRB_CONTROL_STRUCTURE IoCntrlStrct;
> PIRP pIrp;
> LARGE_INTEGER liStartingOffset;
> IO_STATUS_BLOCK IoStatusBlock;
> SCSI_REQUEST_BLOCK Srb;
> PIO_STACK_LOCATION pIrpSp;
> NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
>
> pPdoScsiMiniportExt =
> (PPDO_SCSI_MINIPORT_EXTENSION)pAdapterExt->pPdoScsiMiniport;
> pEmDiskCntrlExt =
> pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.pEmDiskCntrlExt;
> pPdoDevExtHdr =
> &pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.DeviceExtHdr;
> pCurrentSrb = pAdapterExt->pCurrentSrb;
>
> KeInitializeEvent(&kEvent, NotificationEvent, FALSE);
>
> //
> // Setup Data structure
> //
> RtlZeroMemory(&IoCntrlStrct, sizeof(IO_SRB_CONTROL_STRUCTURE));
> IoCntrlStrct.IoSrbCntrl.HeaderLength = sizeof(SRB_IO_CONTROL);
> strcpy(IoCntrlStrct.IoSrbCntrl.Signature, VER_INTERNALNAME_STR);
> IoCntrlStrct.IoSrbCntrl.Timeout = FOUR_SECONDS;
> IoCntrlStrct.IoSrbCntrl.ControlCode = DIO_SUNPCI_INTERMEDIATE_IO;
> IoCntrlStrct.IoSrbCntrl.Length = sizeof(PSCSI_REQUEST_BLOCK);
> IoCntrlStrct.pCurSrb = pCurrentSrb;
>
> liStartingOffset.QuadPart = 1;// SCSIPORT does this, no idea why…
> pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_SCSI,
> (PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj,
> &IoCntrlStrct,
> sizeof(IO_SRB_CONTROL_STRUCTURE),
> &liStartingOffset, &kEvent,
> &IoStatusBlock);
> if(pIrp)
> {
> //
> // Setup Irp Request Data
> //
> RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
> Srb.PathId = pCurrentSrb->PathId;
> Srb.TargetId = pCurrentSrb->TargetId;
> Srb.Lun = pCurrentSrb->Lun;
>
> Srb.Function = SRB_FUNCTION_IO_CONTROL;
> Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
> Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE |
> SRB_FLAGS_BYPASS_FROZEN_QUEUE;
> Srb.DataBuffer = &IoCntrlStrct;
> Srb.DataTransferLength = sizeof(IO_SRB_CONTROL_STRUCTURE);
>
> pIrpSp = IoGetNextIrpStackLocation(pIrp);
> pIrpSp->MajorFunction = IRP_MJ_SCSI;
> pIrpSp->MinorFunction = 1;
> pIrpSp->Parameters.Scsi.Srb = &Srb;
>
> IoCallDriver((PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj, pIrp);
> KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE,
> NULL);
> Status = IoStatusBlock.Status;
> }
> 6) My StartIo routine is hit with the above IRP. I figure out that the
> IRP came from my worker thread trying to complete the SRB he was working
> on. I complete the request for the worker thread. I then complete the
> request for worker thread IRP he sent to complete the SRB. Below is the
> code that does this.
>
> pSrbIoCntrl = (PSRB_IO_CONTROL)pSrb->DataBuffer;
> if(RtlCompareMemory(pSrbIoCntrl->Signature, VER_INTERNALNAME_STR,
> sizeof(pSrbIoCntrl->Signature)) ==
> sizeof(pSrbIoCntrl->Signature))
> {
> switch(pSrbIoCntrl->ControlCode)
> {
> case DIO_SUNPCI_INTERMEDIATE_IO:
> {
> PIO_SRB_CONTROL_STRUCTURE pIoSrbCntrlStrct;
>
> pIoSrbCntrlStrct =
> (PIO_SRB_CONTROL_STRUCTURE)pSrb->DataBuffer;
> pCompletedSrb = pIoSrbCntrlStrct->pCurSrb;
> if(pCompletedSrb)
> {
> // Complete the original SRB request.
> ScsiPortNotification(RequestComplete, pAdapterExt,
> pCompletedSrb);
> }
>
> // Set the status for the Intermediate SRB
> pSrb->ScsiStatus = SCSISTAT_GOOD;
> pSrb->SrbStatus = SRB_STATUS_SUCCESS;
>
> // Complete the Intermediate SRB request.
> ScsiPortNotification(RequestComplete, pAdapterExt, pSrb);
> break;
> }
>
> Is this all correct?
>
> Joe
>
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
> > Sent: Thursday, October 24, 2002 2:43 PM
> > To: NT Developers Interest List
> > Subject: [ntdev] RE: Virtual SCSI miniport question
> >
> >
> > SpGetInterruptState takes all the data squirreled away while the
> > miniport was running inside the ‘interupt spinlock’ (in your case it’s
>
> > just a normal spinlock and we synch at DPC level) and makes it safely
> > accessible by the completion DPC. If it’s faulting in that routine
> > it’s likely that something squirreled away is no longer valid - for
> > example you might have completed an SRB which had already been
> > completed earlier.
> >
> > given that the SrbStatus is a one byte field at offset 3 in the SRB,
> > that SpGetInterruptState checks the SRB statuses while processing
> > them, and that the faulting address below is attempting to read a one
> > byte value at offset 3 from esi, I’d suspect that’s the case.
> >
> > -p
> >
> > -----Original Message-----
> > From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> > Sent: Thursday, October 24, 2002 10:28 AM
> > To: NT Developers Interest List
> > Subject: [ntdev] Virtual SCSI miniport question
> >
> >
> > I have a virtual SCSI miniport driver that works fine except for when
> > the user issues a SHUTDOWN/RESET under Win2K. I get to the “Windows
> > is shutting down …” and then boom. The dump is below. It doesn’t
> > happen all the time. I would say that in 50% of the shutdowns this
> > will occur. The question I have is why is the SCSIPORT driver trying
> > to acquire the interrupt state from the HBA? I have set the
> > HwInterrupt routine to NULL in my DriverEntry routine. BTW, this is a
>
> > PNP virtual SCSI miniport. The system thinks it’s on a ISA bus. I
> > have created a bus driver that enumerates a virtual SCSI miniport
> > device. The SCSIPORT driver loads on top of this stack and then calls
>
> > my virtual SCSI miniport driver.
> >
> > Thanks In Advance,
> > Joe
> >
> > **********************************************************************
> > **
> > ****
> > ***
> > *
> > *
> > * Bugcheck Analysis
> > *
> > *
> > *
> >
> ************************************************************************
> > ****
> > ***
> >
> > DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> > An attempt was made to access a pagable (or completely invalid)
> > address at an interrupt request level (IRQL) that is too high. This
> > is usually caused by drivers using improper addresses. If kernel
> > debugger is available get stack backtrace.
> > Arguments:
> > Arg1: 00000003, memory referenced
> > Arg2: 00000002, IRQL
> > Arg3: 00000000, value 0 = read operation, 1 = write operation
> > Arg4: bff3a6a6, address which referenced memory
> >
> > Debugging Details:
> > ------------------
> >
> >
> > READ_ADDRESS: 00000003 Unknown
> >
> > CURRENT_IRQL: 2
> >
> > FAULTING_IP:
> > SCSIPORT!SpGetInterruptState+6e
> > bff3a6a6 8a5603 mov dl,[esi+0x3]
> >
> > DEFAULT_BUCKET_ID: DRIVER_FAULT
> >
> > BUGCHECK_STR: D1
> >
> > LAST_CONTROL_TRANSFER: from 8042bcb9 to 80452e70
> >
> > STACK_TEXT:
> > f441fb0c 8042bcb9 00000003 f441fb54 00000003
> > nt!RtlpBreakWithStatusInstruction f441fb3c 8042c068 00000003 00000003
> > bff3a6a6 nt!KiBugCheckDebugBreak+0x31 f441fec4 80464b1f 00000000
> > 00000003 00000002 nt!KeBugCheckEx+0x37b f441fec4 bff3a6a6 00000000
> > 00000003 00000002 nt!KiTrap0E+0x27c f441ff5c bff3b636 f441ffd0
> > 818881e4 818880e8 SCSIPORT!SpGetInterruptState+0x6e f441ff70 bff39971
> > 818880e8 bff3a638 f441ffd0 SCSIPORT!SpSynchronizeExecution+0x1e
> > f441ffe0 80460bd4 818880a4 81888030 00000000
> > SCSIPORT!ScsiPortCompletionDpc+0x3b
> > f441fff4 80403a82 f4473b9c 00000000 00000000 nt!KiRetireDpcList+0x30
> >
> >
> > FOLLOWUP_IP:
> > SCSIPORT!SpGetInterruptState+6e
> > bff3a6a6 8a5603 mov dl,[esi+0x3]
> >
> > FOLLOWUP_NAME: MachineOwner
> >
> > SYMBOL_NAME: SCSIPORT!SpGetInterruptState+6e
> >
> > MODULE_NAME: SCSIPORT
> >
> > IMAGE_NAME: SCSIPORT
> >
> > STACK_COMMAND: kb
> >
> > BUCKET_ID: 0xD1_SCSIPORT!SpGetInterruptState+6e
> >
> > Followup: MachineOwner
> > ---------
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@microsoft.com To
> > unsubscribe send a blank email to %%email.unsub%%
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@east.sun.com To
>
> > unsubscribe send a blank email to %%email.unsub%%
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@microsoft.com To
> unsubscribe send a blank email to %%email.unsub%%
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@east.sun.com
> To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@east.sun.com
To unsubscribe send a blank email to %%email.unsub%%

Peter,

I just went through the entire list of SRBs from system power on to the
crash and all the SRBs are accounted for (A New SRB address matched up with
a completed SRB address). Here is a sampling of the data I collected
through windbg.

New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (f96d5ab0)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (f96d5ab0)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (f96d5b48)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (f96d5b48)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (811624c8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (811624c8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (811624c8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (811624c8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (811624c8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (811624c8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8173fa68)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8173fa68)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (8173fa68)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8173fa68)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (814c7c08)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (814c7c08)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)
New Srb = (814c7c08)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (814c7c08)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)

Joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Joe Moriarty
Sent: Friday, October 25, 2002 2:24 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

Pete,

Here’s some more information. Did I forget to mention thanks for
helping me
out here :).

register dump

eax=00000003 ebx=000000d1 ecx=ffffffff edx=00000000 esi=00000003
edi=ee01fb54
eip=80452e70 esp=ee01fb10 ebp=ee01fb3c iopl=0 nv up ei pl zr na po
nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000
efl=00000246
nt!RtlpBreakWithStatusInstruction:
80452e70 cc int 3

stack dump

SCSIPORT!SpGetInterruptState:
bff3a638 53 push ebx
bff3a639 8b5c2408 mov ebx,[esp+0x8]
bff3a63d 8b03 mov eax,[ebx]
bff3a63f f680e001000004 test byte ptr [eax+0x1e0],0x4
bff3a646 8d90e0010000 lea edx,[eax+0x1e0]
bff3a64c 7507 jnz SCSIPORT!SpGetInterruptState+0x1d
(bff3a655)
bff3a64e 32c0 xor al,al
bff3a650 e90e010000 jmp SCSIPORT!SpGetInterruptState+0x12b
(bff3a763)
bff3a655 57 push edi
bff3a656 8b7b04 mov edi,[ebx+0x4]
bff3a659 56 push esi
bff3a65a 6a10 push 0x10
bff3a65c 59 pop ecx
bff3a65d 8bf2 mov esi,edx
bff3a65f f3a5 rep movsd
bff3a661 812280410800 and dword ptr [edx],0x84180
bff3a667 33ff xor edi,edi
bff3a669 ba00000200 mov edx,0x20000
bff3a66e 8d88e0000000 lea ecx,[eax+0xe0]
bff3a674 89b8e4010000 mov [eax+0x1e4],edi
bff3a67a 89b80c020000 mov [eax+0x20c],edi
bff3a680 89b810020000 mov [eax+0x210],edi
bff3a686 89b81c020000 mov [eax+0x21c],edi
bff3a68c ff1530daf3bf call dword ptr [SCSIPORT!imp (bff3da30)]
bff3a692 8b4304 mov eax,[ebx+0x4]
bff3a695 8b4804 mov ecx,[eax+0x4]
bff3a698 3bcf cmp ecx,edi
bff3a69a 0f84bf000000 je SCSIPORT!SpGetInterruptState+0x127
(bff3a75f)
bff3a6a0 8b711c mov esi,[ecx+0x1c]
bff3a6a3 8b4114 mov eax,[ecx+0x14]
bff3a6a6 8a5603 mov dl,[esi+0x3] <- BREAKPOINT:
Here’s where
the crash is
bff3a6a9 80fa01 cmp dl,0x1
bff3a6ac 7460 jz SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a6ae 807e0402 cmp byte ptr [esi+0x4],0x2
bff3a6b2 7530 jnz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6b4 f6c280 test dl,0x80
bff3a6b7 752b jnz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6b9 397e1c cmp [esi+0x1c],edi
bff3a6bc 7426 jz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6be 807e0b00 cmp byte ptr [esi+0xb],0x0
bff3a6c2 7420 jz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6c4 8b90b0000000 mov edx,[eax+0xb0]
bff3a6ca 8d98b0000000 lea ebx,[eax+0xb0]
bff3a6d0 f6c204 test dl,0x4
bff3a6d3 740a jz SCSIPORT!SpGetInterruptState+0xa7
(bff3a6df)
bff3a6d5 80660400 and byte ptr [esi+0x4],0x0
bff3a6d9 c6460310 mov byte ptr [esi+0x3],0x10
bff3a6dd eb05 jmp SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6df 83ca04 or edx,0x4
bff3a6e2 8913 mov [ebx],edx
bff3a6e4 807e0428 cmp byte ptr [esi+0x4],0x28
bff3a6e8 7524 jnz SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a6ea 8a9005010000 mov dl,[eax+0x105]
bff3a6f0 8388b000000010 or dword ptr [eax+0xb0],0x10
bff3a6f7 3a9004010000 cmp dl,[eax+0x104]
bff3a6fd 8d9804010000 lea ebx,[eax+0x104]
bff3a703 7309 jnb SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a705 80fa02 cmp dl,0x2
bff3a708 7604 jbe SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a70a feca dec dl
bff3a70c 8813 mov [ebx],dl
bff3a70e 807e08ff cmp byte ptr [esi+0x8],0xff
bff3a712 7504 jnz SCSIPORT!SpGetInterruptState+0xe0
(bff3a718)
bff3a714 b301 mov bl,0x1
bff3a716 eb16 jmp SCSIPORT!SpGetInterruptState+0xf6
(bff3a72e)
bff3a718 8b5110 mov edx,[ecx+0x10]
bff3a71b 8d710c lea esi,[ecx+0xc]
bff3a71e 39b0f0000000 cmp [eax+0xf0],esi
bff3a724 8b36 mov esi,[esi]
bff3a726 8932 mov [edx],esi

Thanks,
Joe

> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Joe Moriarty
> Sent: Friday, October 25, 2002 2:11 PM
> To: NT Developers Interest List
> Subject: [ntdev] RE: Virtual SCSI miniport question
>
>
> Peter,
>
> ESI has Null in it. Does that tell you anything other than the obvious?
>
> Joe
>
>
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
> > Sent: Friday, October 25, 2002 12:48 PM
> > To: NT Developers Interest List
> > Subject: [ntdev] RE: Virtual SCSI miniport question
> >
> >
> > some notes:
> >
> > 3) - this will freeze the queue for the current LUN, not the current
> > target. very important distinction here. scsiport doesn’t
do anything
> > to track targets except as part of the bus address of the LUNs.
> >
> > the code below looks okay from a quick scan, but obviously something’s
> > wrong with it so that “is this all correct” question is tough
to answer
> > :slight_smile:
> >
> > at the point that you crashed, ESI contains the pointer to the SRB
> > scsiport is processing. If you log all SRB pointers as they enter and
> > leave your driver you should be able to compare ESI against
that log to
> > find out which SRB it is. Simply dumping the SRB probably won’t help
> > since it’s very likely been reused as a new SRB (or some other memory
> > allocation) by that point.
> >
> > -p
> >
> > -----Original Message-----
> > From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> > Sent: Friday, October 25, 2002 9:11 AM
> > To: NT Developers Interest List
> > Subject: [ntdev] RE: Virtual SCSI miniport question
> >
> >
> > Peter,
> >
> > I am 100% sure you are correct. The only problem I have now is
> > determining which SRB I am completing twice. I have checked each and
> > everyone of the requests to make sure everything is correct. The only
> > question I have now is if I am handling the case when passing the
> > request down to a lower level driver.
> >
> > So here is the sequence of events.
> >
> > 1) SRB_FUNCTION_EXECUTE_SCSI requests comes in to my StartIo.
> > 2) I notify a worker thread to pass the request down to the
lower level
> > driver. pointer to the SRB is passed to the worker thread.
> > 3) I do the following before returning from my StartIo routine.
> > //Adapter ready for next request.
> > ScsiPortNotification(NextRequest, pAdapterExt, NULL);
> >
> > I do not mark the current SRB I was working on in my StartIo as
> > completed, busy, etc. My guess was that this would freeze
> > the queue for this particular target ID. I verified this in the
> > debugger.
> >
> > 4) Worker thread starts up and passes the SRB down to the lower level
> > driver and waits on completion.
> > 5) Upon completion of the SRB I create the following IRP to
pass to the
> > SCSIPORT driver. The code is below.
> >
> > PPDO_SCSI_MINIPORT_EXTENSION pPdoScsiMiniportExt;
> > PEMDISK_CONTROLLER_EXTENSION pEmDiskCntrlExt;
> > PDEVICE_EXT_HDR pPdoDevExtHdr;
> > PSCSI_REQUEST_BLOCK pCurrentSrb;
> > KEVENT kEvent;
> > IO_SRB_CONTROL_STRUCTURE IoCntrlStrct;
> > PIRP pIrp;
> > LARGE_INTEGER liStartingOffset;
> > IO_STATUS_BLOCK IoStatusBlock;
> > SCSI_REQUEST_BLOCK Srb;
> > PIO_STACK_LOCATION pIrpSp;
> > NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
> >
> > pPdoScsiMiniportExt =
> > (PPDO_SCSI_MINIPORT_EXTENSION)pAdapterExt->pPdoScsiMiniport;
> > pEmDiskCntrlExt =
> > pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.pEmDiskCntrlExt;
> > pPdoDevExtHdr =
> > &pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.DeviceExtHdr;
> > pCurrentSrb = pAdapterExt->pCurrentSrb;
> >
> > KeInitializeEvent(&kEvent, NotificationEvent, FALSE);
> >
> > //
> > // Setup Data structure
> > //
> > RtlZeroMemory(&IoCntrlStrct, sizeof(IO_SRB_CONTROL_STRUCTURE));
> > IoCntrlStrct.IoSrbCntrl.HeaderLength = sizeof(SRB_IO_CONTROL);
> > strcpy(IoCntrlStrct.IoSrbCntrl.Signature, VER_INTERNALNAME_STR);
> > IoCntrlStrct.IoSrbCntrl.Timeout = FOUR_SECONDS;
> > IoCntrlStrct.IoSrbCntrl.ControlCode = DIO_SUNPCI_INTERMEDIATE_IO;
> > IoCntrlStrct.IoSrbCntrl.Length = sizeof(PSCSI_REQUEST_BLOCK);
> > IoCntrlStrct.pCurSrb = pCurrentSrb;
> >
> > liStartingOffset.QuadPart = 1;// SCSIPORT does this, no idea why…
> > pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_SCSI,
> > (PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj,
> > &IoCntrlStrct,
> > sizeof(IO_SRB_CONTROL_STRUCTURE),
> > &liStartingOffset, &kEvent,
> > &IoStatusBlock);
> > if(pIrp)
> > {
> > //
> > // Setup Irp Request Data
> > //
> > RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
> > Srb.PathId = pCurrentSrb->PathId;
> > Srb.TargetId = pCurrentSrb->TargetId;
> > Srb.Lun = pCurrentSrb->Lun;
> >
> > Srb.Function = SRB_FUNCTION_IO_CONTROL;
> > Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
> > Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE |
> > SRB_FLAGS_BYPASS_FROZEN_QUEUE;
> > Srb.DataBuffer = &IoCntrlStrct;
> > Srb.DataTransferLength = sizeof(IO_SRB_CONTROL_STRUCTURE);
> >
> > pIrpSp = IoGetNextIrpStackLocation(pIrp);
> > pIrpSp->MajorFunction = IRP_MJ_SCSI;
> > pIrpSp->MinorFunction = 1;
> > pIrpSp->Parameters.Scsi.Srb = &Srb;
> >
> >
IoCallDriver((PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj, pIrp);
> > KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE,
> > NULL);
> > Status = IoStatusBlock.Status;
> > }
> > 6) My StartIo routine is hit with the above IRP. I figure
out that the
> > IRP came from my worker thread trying to complete the SRB he
was working
> > on. I complete the request for the worker thread. I then
complete the
> > request for worker thread IRP he sent to complete the SRB.
Below is the
> > code that does this.
> >
> > pSrbIoCntrl = (PSRB_IO_CONTROL)pSrb->DataBuffer;
> > if(RtlCompareMemory(pSrbIoCntrl->Signature, VER_INTERNALNAME_STR,
> > sizeof(pSrbIoCntrl->Signature)) ==
> > sizeof(pSrbIoCntrl->Signature))
> > {
> > switch(pSrbIoCntrl->ControlCode)
> > {
> > case DIO_SUNPCI_INTERMEDIATE_IO:
> > {
> > PIO_SRB_CONTROL_STRUCTURE pIoSrbCntrlStrct;
> >
> > pIoSrbCntrlStrct =
> > (PIO_SRB_CONTROL_STRUCTURE)pSrb->DataBuffer;
> > pCompletedSrb = pIoSrbCntrlStrct->pCurSrb;
> > if(pCompletedSrb)
> > {
> > // Complete the original SRB request.
> > ScsiPortNotification(RequestComplete, pAdapterExt,
> > pCompletedSrb);
> > }
> >
> > // Set the status for the Intermediate SRB
> > pSrb->ScsiStatus = SCSISTAT_GOOD;
> > pSrb->SrbStatus = SRB_STATUS_SUCCESS;
> >
> > // Complete the Intermediate SRB request.
> > ScsiPortNotification(RequestComplete, pAdapterExt, pSrb);
> > break;
> > }
> >
> > Is this all correct?
> >
> > Joe
> >
> >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
> > > Sent: Thursday, October 24, 2002 2:43 PM
> > > To: NT Developers Interest List
> > > Subject: [ntdev] RE: Virtual SCSI miniport question
> > >
> > >
> > > SpGetInterruptState takes all the data squirreled away while the
> > > miniport was running inside the ‘interupt spinlock’ (in
your case it’s
> >
> > > just a normal spinlock and we synch at DPC level) and makes
it safely
> > > accessible by the completion DPC. If it’s faulting in that routine
> > > it’s likely that something squirreled away is no longer valid - for
> > > example you might have completed an SRB which had already been
> > > completed earlier.
> > >
> > > given that the SrbStatus is a one byte field at offset 3 in the SRB,
> > > that SpGetInterruptState checks the SRB statuses while processing
> > > them, and that the faulting address below is attempting to
read a one
> > > byte value at offset 3 from esi, I’d suspect that’s the case.
> > >
> > > -p
> > >
> > > -----Original Message-----
> > > From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> > > Sent: Thursday, October 24, 2002 10:28 AM
> > > To: NT Developers Interest List
> > > Subject: [ntdev] Virtual SCSI miniport question
> > >
> > >
> > > I have a virtual SCSI miniport driver that works fine
except for when
> > > the user issues a SHUTDOWN/RESET under Win2K. I get to the “Windows
> > > is shutting down …” and then boom. The dump is below. It doesn’t
> > > happen all the time. I would say that in 50% of the shutdowns this
> > > will occur. The question I have is why is the SCSIPORT driver trying
> > > to acquire the interrupt state from the HBA? I have set the
> > > HwInterrupt routine to NULL in my DriverEntry routine.
BTW, this is a
> >
> > > PNP virtual SCSI miniport. The system thinks it’s on a ISA bus. I
> > > have created a bus driver that enumerates a virtual SCSI miniport
> > > device. The SCSIPORT driver loads on top of this stack and
then calls
> >
> > > my virtual SCSI miniport driver.
> > >
> > > Thanks In Advance,
> > > Joe
> > >
> > >
**********************************************************************
> > > **
> > > ****
> > > ***
> > > *
> > > *
> > > * Bugcheck Analysis
> > > *
> > > *
> > > *
> > >
> >
************************************************************************
> > > ****
> > > ***
> > >
> > > DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> > > An attempt was made to access a pagable (or completely invalid)
> > > address at an interrupt request level (IRQL) that is too high. This
> > > is usually caused by drivers using improper addresses. If kernel
> > > debugger is available get stack backtrace.
> > > Arguments:
> > > Arg1: 00000003, memory referenced
> > > Arg2: 00000002, IRQL
> > > Arg3: 00000000, value 0 = read operation, 1 = write operation
> > > Arg4: bff3a6a6, address which referenced memory
> > >
> > > Debugging Details:
> > > ------------------
> > >
> > >
> > > READ_ADDRESS: 00000003 Unknown
> > >
> > > CURRENT_IRQL: 2
> > >
> > > FAULTING_IP:
> > > SCSIPORT!SpGetInterruptState+6e
> > > bff3a6a6 8a5603 mov dl,[esi+0x3]
> > >
> > > DEFAULT_BUCKET_ID: DRIVER_FAULT
> > >
> > > BUGCHECK_STR: D1
> > >
> > > LAST_CONTROL_TRANSFER: from 8042bcb9 to 80452e70
> > >
> > > STACK_TEXT:
> > > f441fb0c 8042bcb9 00000003 f441fb54 00000003
> > > nt!RtlpBreakWithStatusInstruction f441fb3c 8042c068
00000003 00000003
> > > bff3a6a6 nt!KiBugCheckDebugBreak+0x31 f441fec4 80464b1f 00000000
> > > 00000003 00000002 nt!KeBugCheckEx+0x37b f441fec4 bff3a6a6 00000000
> > > 00000003 00000002 nt!KiTrap0E+0x27c f441ff5c bff3b636 f441ffd0
> > > 818881e4 818880e8 SCSIPORT!SpGetInterruptState+0x6e
f441ff70 bff39971
> > > 818880e8 bff3a638 f441ffd0 SCSIPORT!SpSynchronizeExecution+0x1e
> > > f441ffe0 80460bd4 818880a4 81888030 00000000
> > > SCSIPORT!ScsiPortCompletionDpc+0x3b
> > > f441fff4 80403a82 f4473b9c 00000000 00000000 nt!KiRetireDpcList+0x30
> > >
> > >
> > > FOLLOWUP_IP:
> > > SCSIPORT!SpGetInterruptState+6e
> > > bff3a6a6 8a5603 mov dl,[esi+0x3]
> > >
> > > FOLLOWUP_NAME: MachineOwner
> > >
> > > SYMBOL_NAME: SCSIPORT!SpGetInterruptState+6e
> > >
> > > MODULE_NAME: SCSIPORT
> > >
> > > IMAGE_NAME: SCSIPORT
> > >
> > > STACK_COMMAND: kb
> > >
> > > BUCKET_ID: 0xD1_SCSIPORT!SpGetInterruptState+6e
> > >
> > > Followup: MachineOwner
> > > ---------
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@microsoft.com To
> > > unsubscribe send a blank email to %%email.unsub%%
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as:
xxxxx@east.sun.com To
> >
> > > unsubscribe send a blank email to %%email.unsub%%
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@microsoft.com To
> > unsubscribe send a blank email to %%email.unsub%%
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@east.sun.com
> > To unsubscribe send a blank email to %%email.unsub%%
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@east.sun.com
> To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@east.sun.com
To unsubscribe send a blank email to %%email.unsub%%

unfortunately no.

does this same problem happen with XP? You could try enabling the
scsiport verifier in XP and see if that can better pinpoint the problem.

-p

-----Original Message-----
From: Joe Moriarty [mailto:xxxxx@east.sun.com]
Sent: Friday, October 25, 2002 11:11 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

Peter,

ESI has Null in it. Does that tell you anything other than the obvious?

Joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
Sent: Friday, October 25, 2002 12:48 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

some notes:

    • this will freeze the queue for the current LUN, not the current
      target. very important distinction here. scsiport doesn’t do
      anything to track targets except as part of the bus address of the
      LUNs.

the code below looks okay from a quick scan, but obviously something’s

wrong with it so that “is this all correct” question is tough to
answer
:slight_smile:

at the point that you crashed, ESI contains the pointer to the SRB
scsiport is processing. If you log all SRB pointers as they enter and

leave your driver you should be able to compare ESI against that log
to find out which SRB it is. Simply dumping the SRB probably won’t
help since it’s very likely been reused as a new SRB (or some other
memory
allocation) by that point.

-p

-----Original Message-----
From: Joe Moriarty [mailto:xxxxx@east.sun.com]
Sent: Friday, October 25, 2002 9:11 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

Peter,

I am 100% sure you are correct. The only problem I have now is
determining which SRB I am completing twice. I have checked each and
everyone of the requests to make sure everything is correct. The only

question I have now is if I am handling the case when passing the
request down to a lower level driver.

So here is the sequence of events.

  1. SRB_FUNCTION_EXECUTE_SCSI requests comes in to my StartIo.
  2. I notify a worker thread to pass the request down to the lower
    level driver. pointer to the SRB is passed to the worker thread.
  3. I do the following before returning from my StartIo routine.
    //Adapter ready for next request.
    ScsiPortNotification(NextRequest, pAdapterExt, NULL);

I do not mark the current SRB I was working on in my StartIo as
completed, busy, etc. My guess was that this would freeze
the queue for this particular target ID. I verified this in the
debugger.

  1. Worker thread starts up and passes the SRB down to the lower level
    driver and waits on completion.
  2. Upon completion of the SRB I create the following IRP to pass to
    the SCSIPORT driver. The code is below.

PPDO_SCSI_MINIPORT_EXTENSION pPdoScsiMiniportExt;
PEMDISK_CONTROLLER_EXTENSION pEmDiskCntrlExt;
PDEVICE_EXT_HDR pPdoDevExtHdr;
PSCSI_REQUEST_BLOCK pCurrentSrb;
KEVENT kEvent;
IO_SRB_CONTROL_STRUCTURE IoCntrlStrct;
PIRP pIrp;
LARGE_INTEGER liStartingOffset;
IO_STATUS_BLOCK IoStatusBlock;
SCSI_REQUEST_BLOCK Srb;
PIO_STACK_LOCATION pIrpSp;
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;

pPdoScsiMiniportExt =
(PPDO_SCSI_MINIPORT_EXTENSION)pAdapterExt->pPdoScsiMiniport;
pEmDiskCntrlExt =
pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.pEmDiskCntrlExt;
pPdoDevExtHdr =
&pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.DeviceExtHdr;
pCurrentSrb = pAdapterExt->pCurrentSrb;

KeInitializeEvent(&kEvent, NotificationEvent, FALSE);

//
// Setup Data structure
//
RtlZeroMemory(&IoCntrlStrct, sizeof(IO_SRB_CONTROL_STRUCTURE));
IoCntrlStrct.IoSrbCntrl.HeaderLength = sizeof(SRB_IO_CONTROL);
strcpy(IoCntrlStrct.IoSrbCntrl.Signature, VER_INTERNALNAME_STR);
IoCntrlStrct.IoSrbCntrl.Timeout = FOUR_SECONDS;
IoCntrlStrct.IoSrbCntrl.ControlCode = DIO_SUNPCI_INTERMEDIATE_IO;
IoCntrlStrct.IoSrbCntrl.Length = sizeof(PSCSI_REQUEST_BLOCK);
IoCntrlStrct.pCurSrb = pCurrentSrb;

liStartingOffset.QuadPart = 1;// SCSIPORT does this, no idea why…
pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_SCSI,
(PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj,
&IoCntrlStrct,
sizeof(IO_SRB_CONTROL_STRUCTURE),
&liStartingOffset, &kEvent,
&IoStatusBlock);
if(pIrp)
{
//
// Setup Irp Request Data
//
RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
Srb.PathId = pCurrentSrb->PathId;
Srb.TargetId = pCurrentSrb->TargetId;
Srb.Lun = pCurrentSrb->Lun;

Srb.Function = SRB_FUNCTION_IO_CONTROL;
Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE |
SRB_FLAGS_BYPASS_FROZEN_QUEUE;
Srb.DataBuffer = &IoCntrlStrct;
Srb.DataTransferLength = sizeof(IO_SRB_CONTROL_STRUCTURE);

pIrpSp = IoGetNextIrpStackLocation(pIrp);
pIrpSp->MajorFunction = IRP_MJ_SCSI;
pIrpSp->MinorFunction = 1;
pIrpSp->Parameters.Scsi.Srb = &Srb;

IoCallDriver((PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj,
pIrp);
KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE,
NULL);
Status = IoStatusBlock.Status;
}
6) My StartIo routine is hit with the above IRP. I figure out that
the IRP came from my worker thread trying to complete the SRB he was
working on. I complete the request for the worker thread. I then
complete the request for worker thread IRP he sent to complete the
SRB. Below is the code that does this.

pSrbIoCntrl = (PSRB_IO_CONTROL)pSrb->DataBuffer;
if(RtlCompareMemory(pSrbIoCntrl->Signature, VER_INTERNALNAME_STR,
sizeof(pSrbIoCntrl->Signature)) ==
sizeof(pSrbIoCntrl->Signature))
{
switch(pSrbIoCntrl->ControlCode)
{
case DIO_SUNPCI_INTERMEDIATE_IO:
{
PIO_SRB_CONTROL_STRUCTURE pIoSrbCntrlStrct;

pIoSrbCntrlStrct =
(PIO_SRB_CONTROL_STRUCTURE)pSrb->DataBuffer;
pCompletedSrb = pIoSrbCntrlStrct->pCurSrb;
if(pCompletedSrb)
{
// Complete the original SRB request.
ScsiPortNotification(RequestComplete, pAdapterExt,
pCompletedSrb);
}

// Set the status for the Intermediate SRB
pSrb->ScsiStatus = SCSISTAT_GOOD;
pSrb->SrbStatus = SRB_STATUS_SUCCESS;

// Complete the Intermediate SRB request.
ScsiPortNotification(RequestComplete, pAdapterExt, pSrb);
break;
}

Is this all correct?

Joe

> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
> Sent: Thursday, October 24, 2002 2:43 PM
> To: NT Developers Interest List
> Subject: [ntdev] RE: Virtual SCSI miniport question
>
>
> SpGetInterruptState takes all the data squirreled away while the
> miniport was running inside the ‘interupt spinlock’ (in your case
it’s

> just a normal spinlock and we synch at DPC level) and makes it
> safely
> accessible by the completion DPC. If it’s faulting in that routine
> it’s likely that something squirreled away is no longer valid - for
> example you might have completed an SRB which had already been
> completed earlier.
>
> given that the SrbStatus is a one byte field at offset 3 in the SRB,
> that SpGetInterruptState checks the SRB statuses while processing
> them, and that the faulting address below is attempting to read a
one
> byte value at offset 3 from esi, I’d suspect that’s the case.
>
> -p
>
> -----Original Message-----
> From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> Sent: Thursday, October 24, 2002 10:28 AM
> To: NT Developers Interest List
> Subject: [ntdev] Virtual SCSI miniport question
>
>
> I have a virtual SCSI miniport driver that works fine except for
> when
> the user issues a SHUTDOWN/RESET under Win2K. I get to the "Windows

> is shutting down …" and then boom. The dump is below. It doesn’t

> happen all the time. I would say that in 50% of the shutdowns this
> will occur. The question I have is why is the SCSIPORT driver trying

> to acquire the interrupt state from the HBA? I have set the
> HwInterrupt routine to NULL in my DriverEntry routine. BTW, this is
a

> PNP virtual SCSI miniport. The system thinks it’s on a ISA bus. I
> have created a bus driver that enumerates a virtual SCSI miniport
> device. The SCSIPORT driver loads on top of this stack and then
calls

> my virtual SCSI miniport driver.
>
> Thanks In Advance,
> Joe
>
> ********************************************************************
> **
> **
> ****
> ***
> *
> *
> * Bugcheck Analysis
> *
> *
> *
>
**********************************************************************
**
> ****
> ***
>
> DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> An attempt was made to access a pagable (or completely invalid)
> address at an interrupt request level (IRQL) that is too high. This

> is usually caused by drivers using improper addresses. If kernel
> debugger is available get stack backtrace.
> Arguments:
> Arg1: 00000003, memory referenced
> Arg2: 00000002, IRQL
> Arg3: 00000000, value 0 = read operation, 1 = write operation
> Arg4: bff3a6a6, address which referenced memory
>
> Debugging Details:
> ------------------
>
>
> READ_ADDRESS: 00000003 Unknown
>
> CURRENT_IRQL: 2
>
> FAULTING_IP:
> SCSIPORT!SpGetInterruptState+6e
> bff3a6a6 8a5603 mov dl,[esi+0x3]
>
> DEFAULT_BUCKET_ID: DRIVER_FAULT
>
> BUGCHECK_STR: D1
>
> LAST_CONTROL_TRANSFER: from 8042bcb9 to 80452e70
>
> STACK_TEXT:
> f441fb0c 8042bcb9 00000003 f441fb54 00000003
> nt!RtlpBreakWithStatusInstruction f441fb3c 8042c068 00000003
00000003
> bff3a6a6 nt!KiBugCheckDebugBreak+0x31 f441fec4 80464b1f 00000000
> 00000003 00000002 nt!KeBugCheckEx+0x37b f441fec4 bff3a6a6 00000000
> 00000003 00000002 nt!KiTrap0E+0x27c f441ff5c bff3b636 f441ffd0
> 818881e4 818880e8 SCSIPORT!SpGetInterruptState+0x6e f441ff70
bff39971
> 818880e8 bff3a638 f441ffd0 SCSIPORT!SpSynchronizeExecution+0x1e
> f441ffe0 80460bd4 818880a4 81888030 00000000
> SCSIPORT!ScsiPortCompletionDpc+0x3b
> f441fff4 80403a82 f4473b9c 00000000 00000000 nt!KiRetireDpcList+0x30
>
>
> FOLLOWUP_IP:
> SCSIPORT!SpGetInterruptState+6e
> bff3a6a6 8a5603 mov dl,[esi+0x3]
>
> FOLLOWUP_NAME: MachineOwner
>
> SYMBOL_NAME: SCSIPORT!SpGetInterruptState+6e
>
> MODULE_NAME: SCSIPORT
>
> IMAGE_NAME: SCSIPORT
>
> STACK_COMMAND: kb
>
> BUCKET_ID: 0xD1_SCSIPORT!SpGetInterruptState+6e
>
> Followup: MachineOwner
> ---------
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@microsoft.com To
> unsubscribe send a blank email to %%email.unsub%%
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@east.sun.com
> To

> unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@east.sun.com To

unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%

what happens with a checked build? There’s an assertion just earlier on
in SpGetInterruptState which checks for cycles in the completed request
list, but that’s only enabled for checked builds. You might try one and
see if you hit that.

-p

-----Original Message-----
From: Joe Moriarty [mailto:xxxxx@east.sun.com]
Sent: Friday, October 25, 2002 11:42 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

Peter,

I just went through the entire list of SRBs from system power on to the
crash and all the SRBs are accounted for (A New SRB address matched up
with a completed SRB address). Here is a sampling of the data I
collected through windbg.

New Srb = (8115eaa8)
New Srb = (ee073ce4)
Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8) Completing
SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (8115eaa8) New Srb =
(ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (f96d5ab0)
New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb =
(f96d5ab0) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb =
(f96d5b48) New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO
Srb = (f96d5b48) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New
Srb = (811624c8) New Srb = (ee073ce4) Completing
DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8) Completing
SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (811624c8) New Srb =
(ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (8115eaa8)
New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb =
(8115eaa8) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb =
(8115eaa8) New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO
Srb = (8115eaa8) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New
Srb = (8115eaa8) New Srb = (ee073ce4) Completing
DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8) Completing
SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (811624c8) New Srb =
(ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (811624c8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (811624c8)
New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb =
(811624c8) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb =
(811624c8) New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO
Srb = (811624c8) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New
Srb = (8115eaa8) New Srb = (ee073ce4) Completing
DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8) Completing
SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (8115eaa8) New Srb =
(ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8115eaa8)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (8115eaa8)
New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb =
(8115eaa8) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb =
(811624c8) New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO
Srb = (811624c8) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New
Srb = (8173fa68) New Srb = (ee073ce4) Completing
DIO_SUNPCI_INTERMEDIATE_IO Srb = (8173fa68) Completing
SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (8173fa68) New Srb =
(ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb = (8173fa68)
Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb = (814c7c08)
New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO Srb =
(814c7c08) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4) New Srb =
(814c7c08) New Srb = (ee073ce4) Completing DIO_SUNPCI_INTERMEDIATE_IO
Srb = (814c7c08) Completing SRB_FUNCTION_IO_CONTROL Srb = (ee073ce4)

Joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Joe Moriarty
Sent: Friday, October 25, 2002 2:24 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Virtual SCSI miniport question

Pete,

Here’s some more information. Did I forget to mention thanks for
helping me out here :).

register dump

eax=00000003 ebx=000000d1 ecx=ffffffff edx=00000000 esi=00000003
edi=ee01fb54
eip=80452e70 esp=ee01fb10 ebp=ee01fb3c iopl=0 nv up ei pl zr
na po
nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
nt!RtlpBreakWithStatusInstruction:
80452e70 cc int 3

stack dump

SCSIPORT!SpGetInterruptState:
bff3a638 53 push ebx
bff3a639 8b5c2408 mov ebx,[esp+0x8]
bff3a63d 8b03 mov eax,[ebx]
bff3a63f f680e001000004 test byte ptr [eax+0x1e0],0x4
bff3a646 8d90e0010000 lea edx,[eax+0x1e0]
bff3a64c 7507 jnz SCSIPORT!SpGetInterruptState+0x1d
(bff3a655)
bff3a64e 32c0 xor al,al
bff3a650 e90e010000 jmp SCSIPORT!SpGetInterruptState+0x12b
(bff3a763)
bff3a655 57 push edi
bff3a656 8b7b04 mov edi,[ebx+0x4]
bff3a659 56 push esi
bff3a65a 6a10 push 0x10
bff3a65c 59 pop ecx
bff3a65d 8bf2 mov esi,edx
bff3a65f f3a5 rep movsd
bff3a661 812280410800 and dword ptr [edx],0x84180
bff3a667 33ff xor edi,edi
bff3a669 ba00000200 mov edx,0x20000
bff3a66e 8d88e0000000 lea ecx,[eax+0xe0]
bff3a674 89b8e4010000 mov [eax+0x1e4],edi
bff3a67a 89b80c020000 mov [eax+0x20c],edi
bff3a680 89b810020000 mov [eax+0x210],edi
bff3a686 89b81c020000 mov [eax+0x21c],edi
bff3a68c ff1530daf3bf call dword ptr [SCSIPORT!imp
(bff3da30)]
bff3a692 8b4304 mov eax,[ebx+0x4]
bff3a695 8b4804 mov ecx,[eax+0x4]
bff3a698 3bcf cmp ecx,edi
bff3a69a 0f84bf000000 je SCSIPORT!SpGetInterruptState+0x127
(bff3a75f)
bff3a6a0 8b711c mov esi,[ecx+0x1c]
bff3a6a3 8b4114 mov eax,[ecx+0x14]
bff3a6a6 8a5603 mov dl,[esi+0x3] <- BREAKPOINT:
Here’s where
the crash is
bff3a6a9 80fa01 cmp dl,0x1
bff3a6ac 7460 jz SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a6ae 807e0402 cmp byte ptr [esi+0x4],0x2
bff3a6b2 7530 jnz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6b4 f6c280 test dl,0x80
bff3a6b7 752b jnz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6b9 397e1c cmp [esi+0x1c],edi
bff3a6bc 7426 jz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6be 807e0b00 cmp byte ptr [esi+0xb],0x0
bff3a6c2 7420 jz SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6c4 8b90b0000000 mov edx,[eax+0xb0]
bff3a6ca 8d98b0000000 lea ebx,[eax+0xb0]
bff3a6d0 f6c204 test dl,0x4
bff3a6d3 740a jz SCSIPORT!SpGetInterruptState+0xa7
(bff3a6df)
bff3a6d5 80660400 and byte ptr [esi+0x4],0x0
bff3a6d9 c6460310 mov byte ptr [esi+0x3],0x10
bff3a6dd eb05 jmp SCSIPORT!SpGetInterruptState+0xac
(bff3a6e4)
bff3a6df 83ca04 or edx,0x4
bff3a6e2 8913 mov [ebx],edx
bff3a6e4 807e0428 cmp byte ptr [esi+0x4],0x28
bff3a6e8 7524 jnz SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a6ea 8a9005010000 mov dl,[eax+0x105]
bff3a6f0 8388b000000010 or dword ptr [eax+0xb0],0x10
bff3a6f7 3a9004010000 cmp dl,[eax+0x104]
bff3a6fd 8d9804010000 lea ebx,[eax+0x104]
bff3a703 7309 jnb SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a705 80fa02 cmp dl,0x2
bff3a708 7604 jbe SCSIPORT!SpGetInterruptState+0xd6
(bff3a70e)
bff3a70a feca dec dl
bff3a70c 8813 mov [ebx],dl
bff3a70e 807e08ff cmp byte ptr [esi+0x8],0xff
bff3a712 7504 jnz SCSIPORT!SpGetInterruptState+0xe0
(bff3a718)
bff3a714 b301 mov bl,0x1
bff3a716 eb16 jmp SCSIPORT!SpGetInterruptState+0xf6
(bff3a72e)
bff3a718 8b5110 mov edx,[ecx+0x10]
bff3a71b 8d710c lea esi,[ecx+0xc]
bff3a71e 39b0f0000000 cmp [eax+0xf0],esi
bff3a724 8b36 mov esi,[esi]
bff3a726 8932 mov [edx],esi

Thanks,
Joe

> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Joe Moriarty
> Sent: Friday, October 25, 2002 2:11 PM
> To: NT Developers Interest List
> Subject: [ntdev] RE: Virtual SCSI miniport question
>
>
> Peter,
>
> ESI has Null in it. Does that tell you anything other than the
> obvious?
>
> Joe
>
>
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com]On Behalf Of Peter Wieland
> > Sent: Friday, October 25, 2002 12:48 PM
> > To: NT Developers Interest List
> > Subject: [ntdev] RE: Virtual SCSI miniport question
> >
> >
> > some notes:
> >
> > 3) - this will freeze the queue for the current LUN, not the
> > current target. very important distinction here. scsiport
> > doesn’t
do anything
> > to track targets except as part of the bus address of the LUNs.
> >
> > the code below looks okay from a quick scan, but obviously
> > something’s wrong with it so that “is this all correct” question
> > is tough
to answer
> > :slight_smile:
> >
> > at the point that you crashed, ESI contains the pointer to the SRB

> > scsiport is processing. If you log all SRB pointers as they enter

> > and leave your driver you should be able to compare ESI against
that log to
> > find out which SRB it is. Simply dumping the SRB probably won’t
> > help since it’s very likely been reused as a new SRB (or some
> > other memory
> > allocation) by that point.
> >
> > -p
> >
> > -----Original Message-----
> > From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> > Sent: Friday, October 25, 2002 9:11 AM
> > To: NT Developers Interest List
> > Subject: [ntdev] RE: Virtual SCSI miniport question
> >
> >
> > Peter,
> >
> > I am 100% sure you are correct. The only problem I have now is
> > determining which SRB I am completing twice. I have checked each
> > and everyone of the requests to make sure everything is correct.
> > The only question I have now is if I am handling the case when
> > passing the request down to a lower level driver.
> >
> > So here is the sequence of events.
> >
> > 1) SRB_FUNCTION_EXECUTE_SCSI requests comes in to my StartIo.
> > 2) I notify a worker thread to pass the request down to the
lower level
> > driver. pointer to the SRB is passed to the worker thread.
> > 3) I do the following before returning from my StartIo routine.
> > //Adapter ready for next request.
> > ScsiPortNotification(NextRequest, pAdapterExt, NULL);
> >
> > I do not mark the current SRB I was working on in my StartIo as

> > completed, busy, etc. My guess was that this would freeze
> > the queue for this particular target ID. I verified this in
> > the debugger.
> >
> > 4) Worker thread starts up and passes the SRB down to the lower
> > level driver and waits on completion.
> > 5) Upon completion of the SRB I create the following IRP to
pass to the
> > SCSIPORT driver. The code is below.
> >
> > PPDO_SCSI_MINIPORT_EXTENSION pPdoScsiMiniportExt;
> > PEMDISK_CONTROLLER_EXTENSION pEmDiskCntrlExt;
> > PDEVICE_EXT_HDR pPdoDevExtHdr;
> > PSCSI_REQUEST_BLOCK pCurrentSrb;
> > KEVENT kEvent;
> > IO_SRB_CONTROL_STRUCTURE IoCntrlStrct;
> > PIRP pIrp;
> > LARGE_INTEGER liStartingOffset;
> > IO_STATUS_BLOCK IoStatusBlock;
> > SCSI_REQUEST_BLOCK Srb;
> > PIO_STACK_LOCATION pIrpSp;
> > NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
> >
> > pPdoScsiMiniportExt =
> > (PPDO_SCSI_MINIPORT_EXTENSION)pAdapterExt->pPdoScsiMiniport;
> > pEmDiskCntrlExt =
> > pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.pEmDiskCntrlE
> > pPdoScsiMiniportExt->xt;
> > pPdoDevExtHdr =
> >
&pPdoScsiMiniportExt->PdoDskCntrlComExt.DeviceDataExt.DeviceExtHdr;
> > pCurrentSrb = pAdapterExt->pCurrentSrb;
> >
> > KeInitializeEvent(&kEvent, NotificationEvent, FALSE);
> >
> > //
> > // Setup Data structure
> > //
> > RtlZeroMemory(&IoCntrlStrct, sizeof(IO_SRB_CONTROL_STRUCTURE));
> > IoCntrlStrct.IoSrbCntrl.HeaderLength = sizeof(SRB_IO_CONTROL);
> > strcpy(IoCntrlStrct.IoSrbCntrl.Signature,
VER_INTERNALNAME_STR);
> > IoCntrlStrct.IoSrbCntrl.Timeout = FOUR_SECONDS;
> > IoCntrlStrct.IoSrbCntrl.ControlCode =
DIO_SUNPCI_INTERMEDIATE_IO;
> > IoCntrlStrct.IoSrbCntrl.Length = sizeof(PSCSI_REQUEST_BLOCK);
> > IoCntrlStrct.pCurSrb = pCurrentSrb;
> >
> > liStartingOffset.QuadPart = 1;// SCSIPORT does this, no idea
why…
> > pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_SCSI,
> > (PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj,
> > &IoCntrlStrct,
> > sizeof(IO_SRB_CONTROL_STRUCTURE),
> > &liStartingOffset, &kEvent,

> > &IoStatusBlock);
> > if(pIrp)
> > {
> > //
> > // Setup Irp Request Data
> > //
> > RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK));
> > Srb.PathId = pCurrentSrb->PathId;
> > Srb.TargetId = pCurrentSrb->TargetId;
> > Srb.Lun = pCurrentSrb->Lun;
> >
> > Srb.Function = SRB_FUNCTION_IO_CONTROL;
> > Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
> > Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_NO_QUEUE_FREEZE
|
> > SRB_FLAGS_BYPASS_FROZEN_QUEUE;
> > Srb.DataBuffer = &IoCntrlStrct;
> > Srb.DataTransferLength = sizeof(IO_SRB_CONTROL_STRUCTURE);
> >
> > pIrpSp = IoGetNextIrpStackLocation(pIrp);
> > pIrpSp->MajorFunction = IRP_MJ_SCSI;
> > pIrpSp->MinorFunction = 1;
> > pIrpSp->Parameters.Scsi.Srb = &Srb;
> >
> >
IoCallDriver((PDEVICE_OBJECT)pAdapterExt->pScsiPortDevObj, pIrp);
> > KeWaitForSingleObject(&kEvent, Executive, KernelMode, FALSE,

> > NULL);
> > Status = IoStatusBlock.Status;
> > }
> > 6) My StartIo routine is hit with the above IRP. I figure
out that the
> > IRP came from my worker thread trying to complete the SRB he
was working
> > on. I complete the request for the worker thread. I then
complete the
> > request for worker thread IRP he sent to complete the SRB.
Below is the
> > code that does this.
> >
> > pSrbIoCntrl = (PSRB_IO_CONTROL)pSrb->DataBuffer;
> > if(RtlCompareMemory(pSrbIoCntrl->Signature,
> > VER_INTERNALNAME_STR,
> > sizeof(pSrbIoCntrl->Signature)) ==
> > sizeof(pSrbIoCntrl->Signature))
> > {
> > switch(pSrbIoCntrl->ControlCode)
> > {
> > case DIO_SUNPCI_INTERMEDIATE_IO:
> > {
> > PIO_SRB_CONTROL_STRUCTURE pIoSrbCntrlStrct;
> >
> > pIoSrbCntrlStrct =
> > (PIO_SRB_CONTROL_STRUCTURE)pSrb->DataBuffer;
> > pCompletedSrb = pIoSrbCntrlStrct->pCurSrb;
> > if(pCompletedSrb)
> > {
> > // Complete the original SRB request.
> > ScsiPortNotification(RequestComplete, pAdapterExt,
> > pCompletedSrb);
> > }
> >
> > // Set the status for the Intermediate SRB
> > pSrb->ScsiStatus = SCSISTAT_GOOD;
> > pSrb->SrbStatus = SRB_STATUS_SUCCESS;
> >
> > // Complete the Intermediate SRB request.
> > ScsiPortNotification(RequestComplete, pAdapterExt,
pSrb);
> > break;
> > }
> >
> > Is this all correct?
> >
> > Joe
> >
> >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com]On Behalf Of Peter
> > > Wieland
> > > Sent: Thursday, October 24, 2002 2:43 PM
> > > To: NT Developers Interest List
> > > Subject: [ntdev] RE: Virtual SCSI miniport question
> > >
> > >
> > > SpGetInterruptState takes all the data squirreled away while the

> > > miniport was running inside the ‘interupt spinlock’ (in
your case it’s
> >
> > > just a normal spinlock and we synch at DPC level) and makes
it safely
> > > accessible by the completion DPC. If it’s faulting in that
> > > routine it’s likely that something squirreled away is no longer
> > > valid - for example you might have completed an SRB which had
> > > already been completed earlier.
> > >
> > > given that the SrbStatus is a one byte field at offset 3 in the
> > > SRB, that SpGetInterruptState checks the SRB statuses while
> > > processing them, and that the faulting address below is
> > > attempting to
read a one
> > > byte value at offset 3 from esi, I’d suspect that’s the case.
> > >
> > > -p
> > >
> > > -----Original Message-----
> > > From: Joe Moriarty [mailto:xxxxx@east.sun.com]
> > > Sent: Thursday, October 24, 2002 10:28 AM
> > > To: NT Developers Interest List
> > > Subject: [ntdev] Virtual SCSI miniport question
> > >
> > >
> > > I have a virtual SCSI miniport driver that works fine
except for when
> > > the user issues a SHUTDOWN/RESET under Win2K. I get to the
> > > “Windows is shutting down …” and then boom. The dump is
> > > below. It doesn’t happen all the time. I would say that in 50%

> > > of the shutdowns this will occur. The question I have is why is
> > > the SCSIPORT driver trying to acquire the interrupt state from
> > > the HBA? I have set the HwInterrupt routine to NULL in my
> > > DriverEntry routine.
BTW, this is a
> >
> > > PNP virtual SCSI miniport. The system thinks it’s on a ISA bus.

> > > I have created a bus driver that enumerates a virtual SCSI
> > > miniport device. The SCSIPORT driver loads on top of this stack

> > > and
then calls
> >
> > > my virtual SCSI miniport driver.
> > >
> > > Thanks In Advance,
> > > Joe
> > >
> > >
**********************************************************************
> > > **
> > > ****
> > > ***
> > > *
> > > *
> > > * Bugcheck Analysis
> > > *
> > > *
> > > *
> > >
> >
**********************************************************************
**
> > > ****
> > > ***
> > >
> > > DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
> > > An attempt was made to access a pagable (or completely invalid)
> > > address at an interrupt request level (IRQL) that is too high.
> > > This is usually caused by drivers using improper addresses. If
> > > kernel debugger is available get stack backtrace.
> > > Arguments:
> > > Arg1: 00000003, memory referenced
> > > Arg2: 00000002, IRQL
> > > Arg3: 00000000, value 0 = read operation, 1 = write operation
> > > Arg4: bff3a6a6, address which referenced memory
> > >
> > > Debugging Details:
> > > ------------------
> > >
> > >
> > > READ_ADDRESS: 00000003 Unknown
> > >
> > > CURRENT_IRQL: 2
> > >
> > > FAULTING_IP:
> > > SCSIPORT!SpGetInterruptState+6e
> > > bff3a6a6 8a5603 mov dl,[esi+0x3]
> > >
> > > DEFAULT_BUCKET_ID: DRIVER_FAULT
> > >
> > > BUGCHECK_STR: D1
> > >
> > > LAST_CONTROL_TRANSFER: from 8042bcb9 to 80452e70
> > >
> > > STACK_TEXT:
> > > f441fb0c 8042bcb9 00000003 f441fb54 00000003
> > > nt!RtlpBreakWithStatusInstruction f441fb3c 8042c068
00000003 00000003
> > > bff3a6a6 nt!KiBugCheckDebugBreak+0x31 f441fec4 80464b1f 00000000

> > > 00000003 00000002 nt!KeBugCheckEx+0x37b f441fec4 bff3a6a6
> > > 00000000 00000003 00000002 nt!KiTrap0E+0x27c f441ff5c bff3b636
> > > f441ffd0 818881e4 818880e8 SCSIPORT!SpGetInterruptState+0x6e
f441ff70 bff39971
> > > 818880e8 bff3a638 f441ffd0 SCSIPORT!SpSynchronizeExecution+0x1e
> > > f441ffe0 80460bd4 818880a4 81888030 00000000
> > > SCSIPORT!ScsiPortCompletionDpc+0x3b
> > > f441fff4 80403a82 f4473b9c 00000000 00000000
> > > nt!KiRetireDpcList+0x30
> > >
> > >
> > > FOLLOWUP_IP:
> > > SCSIPORT!SpGetInterruptState+6e
> > > bff3a6a6 8a5603 mov dl,[esi+0x3]
> > >
> > > FOLLOWUP_NAME: MachineOwner
> > >
> > > SYMBOL_NAME: SCSIPORT!SpGetInterruptState+6e
> > >
> > > MODULE_NAME: SCSIPORT
> > >
> > > IMAGE_NAME: SCSIPORT
> > >
> > > STACK_COMMAND: kb
> > >
> > > BUCKET_ID: 0xD1_SCSIPORT!SpGetInterruptState+6e
> > >
> > > Followup: MachineOwner
> > > ---------
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@microsoft.com

> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as:
xxxxx@east.sun.com To
> >
> > > unsubscribe send a blank email to %%email.unsub%%
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@microsoft.com
> > To unsubscribe send a blank email to %%email.unsub%%
> >
> >
> > —
> > You are currently subscribed to ntdev as:
> > xxxxx@east.sun.com To unsubscribe send a blank email to
> > %%email.unsub%%
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@east.sun.com
> To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@east.sun.com To

unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@microsoft.com To
unsubscribe send a blank email to %%email.unsub%%