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 questionsome 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
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 questionPeter,
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.
- SRB_FUNCTION_EXECUTE_SCSI requests comes in to my StartIo.
- 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.- 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.
- Worker thread starts up and passes the SRB down to the lower level
driver and waits on completion.- 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%%