From: flyingfly on
Hi:
I'm working with a SCSI miniport driver, and I encountered a very strange
problem that I don't know how to handle. Plz help me figure it out, Thanks a
lot!

I'm trying to write a driver to present a ram disk. I have a FPGA based
PCI card, but the RTL in FPGA is unable to handle the DMA operations.
So I define a byte array in DEVICE_EXTENSION to present a 16MB RAM. All
the data transfers and DMA operations are between the array and system memory.

Question 1:

I've finished the driver and it works almost successfully, but during the
'format disk' process, a error occurred and the 'format disk' can not finish
successfully.

I use Bus Hound to capture the data during the 'format disk' process, and
find out that during some WRITE and READ commands, the data read from ram
disk is not the same as the data written!
This must be the reason of the failure.

So I use WinDbg to step to the location, it's 4 WRITE commands followed
by 4 READ commands, each command has a data transfer length of 4KB, and the
block address are 0x2a00,0x2a08,0x2a10,0x2a18.
All the WRITE commands are written 0s to ram disk, so all the READ
commands should send out 0s.

I use View Memory in WinDbg to watch the address at Srb->DataBuffer and
Call Stack to view the following function calls.
For the first READ command with block address 0x2a00 and transfer length
of 4KB, I step to the end of my StartIo routine and find that the data in the
memory are all 0s.
That means that I have send the correct data to memory, but why the OS
get a wrong data?

So I continue with Step Out and watch memory closely, and I find that
after SCSIPORT!ScsiPortFdoDispatch+0x270, the data in memory is been changed!

To find out the exact location in SCSIPORT!ScsiPortFdoDispatch, I use
Step Into for the next READ command, and the place where memory data been
changed is hal!KfLowerIrql+0x17!

The Call Stack in shown below:
00 ML505_miniport!ML505StartIo +0xaf0 (FPO: [Non-Fpo]) (CONV: stdcall)
01 SCSIPORT!SpStartIoSynchronized+0x14f (FPO: [Non-Fpo])
02 SCSIPORT!SpSynchronizeExecution+0x20 (FPO: [Non-Fpo])
03 SCSIPORT!SpBuildScatterGather+0x36b (FPO: [Non-Fpo])
04 hal!HalAllocateAdapterChannel+0x126 (FPO: [Non-Fpo])
05 nt!IoAllocateAdapterChannel+0x2a (FPO: [Non-Fpo])
06 SCSIPORT!ScsiPortStartIo+0x23f (FPO: [Non-Fpo])
07 nt!IoStartPacket+0x7d (FPO: [Non-Fpo])
08 SCSIPORT!ScsiPortFdoDispatch+0x270 (FPO: [Non-Fpo])
09 SCSIPORT!SpDispatchRequest+0x68 (FPO: [Non-Fpo])
0a SCSIPORT!ScsiPortPdoScsi+0xec (FPO: [Non-Fpo])
0b SCSIPORT!ScsiPortGlobalDispatch+0x1d (FPO: [Non-Fpo])
WARNING: Stack unwind information not available. Following frames may
be wrong.
0c bhound5+0x1435
0d bhound5+0x24e3
0e bhound5+0x1486
0f bhound5+0x14ad
10 CLASSPNP!ServiceTransferRequest+0xe4 (FPO: [Non-Fpo])
11 CLASSPNP!ClassReadWrite+0xff (FPO: [Non-Fpo])
12 bhound5+0x1435
13 nt!IopfCallDriver+0x31 (FPO: [0,0,0])
14 nt!RawReadWriteDeviceControl+0x60 (FPO: [Non-Fpo])
15 nt!RawDispatch+0x114 (FPO: [Non-Fpo])
16 nt!IopfCallDriver+0x31 (FPO: [0,0,0])
17 nt!IopSynchronousServiceTail+0x70 (FPO: [Non-Fpo])
18 nt!NtReadFile+0x55d (FPO: [Non-Fpo])
19 nt!KiFastCallEntry+0xfc (FPO: [0,0] TrapFrame @ bacefd64)

The commands are shown below:
ML505_miniport!ML505StartIo+0xaf0:
f7a75300 b001 mov al,1
1: kd> gu
SCSIPORT!SpStartIoSynchronized+0x14f:
f73c38eb 8ad8 mov bl,al
1: kd> gu
SCSIPORT!SpSynchronizeExecution+0x20:
f73c434e 8ad3 mov dl,bl
1: kd> gu
SCSIPORT!SpBuildScatterGather+0x36b:
f73c53f7 8bce mov ecx,esi
1: kd> gu
hal!HalAllocateAdapterChannel+0x126:
806ea6e8 83f802 cmp eax,2
1: kd> gu
nt!IoAllocateAdapterChannel+0x2a:
804efee2 5d pop ebp
1: kd> gu
SCSIPORT!ScsiPortStartIo+0x23f:
f73c564d 85c0 test eax,eax
1: kd> gu
nt!IoStartPacket+0x7d:
804f11fd eb22 jmp nt!IoStartPacket+0xa1 (804f1221)
1: kd> gu
SCSIPORT!ScsiPortFdoDispatch+0x270:
f73c4d04 8a4d0f mov cl,byte ptr [ebp+0Fh]
1: kd> t
SCSIPORT!ScsiPortFdoDispatch+0x273:
f73c4d07 ff1518903cf7 call dword ptr [SCSIPORT!_imp_KfLowerIrql
(f73c9018)]
1: kd> t
hal!KfLowerIrql:
806e7410 33c0 xor eax,eax
1: kd> t
hal!KfLowerIrql+0x2:
806e7412 8ac1 mov al,cl
1: kd> t
hal!KfLowerIrql+0x4:
806e7414 33c9 xor ecx,ecx
1: kd> t
hal!KfLowerIrql+0x6:
806e7416 8a8898736e80 mov cl,byte ptr hal!HalpIRQLtoTPR
(806e7398)[eax]
1: kd> t
hal!KfLowerIrql+0xc:
806e741c 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
1: kd> t
hal!KfLowerIrql+0x12:
806e7422 a18000feff mov eax,dword ptr ds:[FFFE0080h]
1: kd> t
hal!KfLowerIrql+0x17:
806e7427 c3 ret
1: kd> t
SCSIPORT!ScsiPortFdoDispatch+0x279:
f73c4d0d b803010000 mov eax,103h

After hal!KfLowerIrql+0x17, the data in memory is changed.

As can be seen from the Call Stack, Bus Hound start to work after
SCSIPORT!ScsiPortGlobalDispatch+0x1d.
So I can suspect that the OS is informed to get data from memory after
SCSIPORT!ScsiPortGlobalDispatch+0x1d, and it can only find wrong data there.

Who actually moved my cheese?
Is it SCSIPORT!ScsiPortFdoDispatch or hal!KfLowerIrql? Or maybe there
are still problems with my driver code?


Question 2:

Scatter/Gather is closed in my driver, and I think that for non
Scatter/Gather DMA operations, the host will give the data buffer a page
aligned physical address.
But I find it didn't work the way I expected, sometimes the physical
address are page aligned, but sometimes not.

For the READ operaion shown above in Question 1, the value of
Srb->DataBuffer is 0xf79ac208,
and the converted physical address using SCSIPortGetPhysicalAddress is
0x20208, which is not even WORD aligned!

Why this could happen? Is there and parameters I did not set correctly?



Thanks for your patience to read through such a long article, and if u
can share any idea about my issue, I'll be so grateful!!

Thanks again and much appreciate!
From: Satya on
>Is it SCSIPORT!ScsiPortFdoDispatch or hal!KfLowerIrql? Or maybe there
>are still problems with my driver code?

I would guess there are issues in the driver code. Perhaps the memory you
think you own is freed and claimed by someone else and they are scribbling in
the same area ?

Satya
http://www.winprogger.com

"flyingfly" wrote:

> Hi:
> I'm working with a SCSI miniport driver, and I encountered a very strange
> problem that I don't know how to handle. Plz help me figure it out, Thanks a
> lot!
>
> I'm trying to write a driver to present a ram disk. I have a FPGA based
> PCI card, but the RTL in FPGA is unable to handle the DMA operations.
> So I define a byte array in DEVICE_EXTENSION to present a 16MB RAM. All
> the data transfers and DMA operations are between the array and system memory.
>
> Question 1:
>
> I've finished the driver and it works almost successfully, but during the
> 'format disk' process, a error occurred and the 'format disk' can not finish
> successfully.
>
> I use Bus Hound to capture the data during the 'format disk' process, and
> find out that during some WRITE and READ commands, the data read from ram
> disk is not the same as the data written!
> This must be the reason of the failure.
>
> So I use WinDbg to step to the location, it's 4 WRITE commands followed
> by 4 READ commands, each command has a data transfer length of 4KB, and the
> block address are 0x2a00,0x2a08,0x2a10,0x2a18.
> All the WRITE commands are written 0s to ram disk, so all the READ
> commands should send out 0s.
>
> I use View Memory in WinDbg to watch the address at Srb->DataBuffer and
> Call Stack to view the following function calls.
> For the first READ command with block address 0x2a00 and transfer length
> of 4KB, I step to the end of my StartIo routine and find that the data in the
> memory are all 0s.
> That means that I have send the correct data to memory, but why the OS
> get a wrong data?
>
> So I continue with Step Out and watch memory closely, and I find that
> after SCSIPORT!ScsiPortFdoDispatch+0x270, the data in memory is been changed!
>
> To find out the exact location in SCSIPORT!ScsiPortFdoDispatch, I use
> Step Into for the next READ command, and the place where memory data been
> changed is hal!KfLowerIrql+0x17!
>
> The Call Stack in shown below:
> 00 ML505_miniport!ML505StartIo +0xaf0 (FPO: [Non-Fpo]) (CONV: stdcall)
> 01 SCSIPORT!SpStartIoSynchronized+0x14f (FPO: [Non-Fpo])
> 02 SCSIPORT!SpSynchronizeExecution+0x20 (FPO: [Non-Fpo])
> 03 SCSIPORT!SpBuildScatterGather+0x36b (FPO: [Non-Fpo])
> 04 hal!HalAllocateAdapterChannel+0x126 (FPO: [Non-Fpo])
> 05 nt!IoAllocateAdapterChannel+0x2a (FPO: [Non-Fpo])
> 06 SCSIPORT!ScsiPortStartIo+0x23f (FPO: [Non-Fpo])
> 07 nt!IoStartPacket+0x7d (FPO: [Non-Fpo])
> 08 SCSIPORT!ScsiPortFdoDispatch+0x270 (FPO: [Non-Fpo])
> 09 SCSIPORT!SpDispatchRequest+0x68 (FPO: [Non-Fpo])
> 0a SCSIPORT!ScsiPortPdoScsi+0xec (FPO: [Non-Fpo])
> 0b SCSIPORT!ScsiPortGlobalDispatch+0x1d (FPO: [Non-Fpo])
> WARNING: Stack unwind information not available. Following frames may
> be wrong.
> 0c bhound5+0x1435
> 0d bhound5+0x24e3
> 0e bhound5+0x1486
> 0f bhound5+0x14ad
> 10 CLASSPNP!ServiceTransferRequest+0xe4 (FPO: [Non-Fpo])
> 11 CLASSPNP!ClassReadWrite+0xff (FPO: [Non-Fpo])
> 12 bhound5+0x1435
> 13 nt!IopfCallDriver+0x31 (FPO: [0,0,0])
> 14 nt!RawReadWriteDeviceControl+0x60 (FPO: [Non-Fpo])
> 15 nt!RawDispatch+0x114 (FPO: [Non-Fpo])
> 16 nt!IopfCallDriver+0x31 (FPO: [0,0,0])
> 17 nt!IopSynchronousServiceTail+0x70 (FPO: [Non-Fpo])
> 18 nt!NtReadFile+0x55d (FPO: [Non-Fpo])
> 19 nt!KiFastCallEntry+0xfc (FPO: [0,0] TrapFrame @ bacefd64)
>
> The commands are shown below:
> ML505_miniport!ML505StartIo+0xaf0:
> f7a75300 b001 mov al,1
> 1: kd> gu
> SCSIPORT!SpStartIoSynchronized+0x14f:
> f73c38eb 8ad8 mov bl,al
> 1: kd> gu
> SCSIPORT!SpSynchronizeExecution+0x20:
> f73c434e 8ad3 mov dl,bl
> 1: kd> gu
> SCSIPORT!SpBuildScatterGather+0x36b:
> f73c53f7 8bce mov ecx,esi
> 1: kd> gu
> hal!HalAllocateAdapterChannel+0x126:
> 806ea6e8 83f802 cmp eax,2
> 1: kd> gu
> nt!IoAllocateAdapterChannel+0x2a:
> 804efee2 5d pop ebp
> 1: kd> gu
> SCSIPORT!ScsiPortStartIo+0x23f:
> f73c564d 85c0 test eax,eax
> 1: kd> gu
> nt!IoStartPacket+0x7d:
> 804f11fd eb22 jmp nt!IoStartPacket+0xa1 (804f1221)
> 1: kd> gu
> SCSIPORT!ScsiPortFdoDispatch+0x270:
> f73c4d04 8a4d0f mov cl,byte ptr [ebp+0Fh]
> 1: kd> t
> SCSIPORT!ScsiPortFdoDispatch+0x273:
> f73c4d07 ff1518903cf7 call dword ptr [SCSIPORT!_imp_KfLowerIrql
> (f73c9018)]
> 1: kd> t
> hal!KfLowerIrql:
> 806e7410 33c0 xor eax,eax
> 1: kd> t
> hal!KfLowerIrql+0x2:
> 806e7412 8ac1 mov al,cl
> 1: kd> t
> hal!KfLowerIrql+0x4:
> 806e7414 33c9 xor ecx,ecx
> 1: kd> t
> hal!KfLowerIrql+0x6:
> 806e7416 8a8898736e80 mov cl,byte ptr hal!HalpIRQLtoTPR
> (806e7398)[eax]
> 1: kd> t
> hal!KfLowerIrql+0xc:
> 806e741c 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
> 1: kd> t
> hal!KfLowerIrql+0x12:
> 806e7422 a18000feff mov eax,dword ptr ds:[FFFE0080h]
> 1: kd> t
> hal!KfLowerIrql+0x17:
> 806e7427 c3 ret
> 1: kd> t
> SCSIPORT!ScsiPortFdoDispatch+0x279:
> f73c4d0d b803010000 mov eax,103h
>
> After hal!KfLowerIrql+0x17, the data in memory is changed.
>
> As can be seen from the Call Stack, Bus Hound start to work after
> SCSIPORT!ScsiPortGlobalDispatch+0x1d.
> So I can suspect that the OS is informed to get data from memory after
> SCSIPORT!ScsiPortGlobalDispatch+0x1d, and it can only find wrong data there.
>
> Who actually moved my cheese?
> Is it SCSIPORT!ScsiPortFdoDispatch or hal!KfLowerIrql? Or maybe there
> are still problems with my driver code?
>
>
> Question 2:
>
> Scatter/Gather is closed in my driver, and I think that for non
> Scatter/Gather DMA operations, the host will give the data buffer a page
> aligned physical address.
> But I find it didn't work the way I expected, sometimes the physical
> address are page aligned, but sometimes not.
>
> For the READ operaion shown above in Question 1, the value of
> Srb->DataBuffer is 0xf79ac208,
> and the converted physical address using SCSIPortGetPhysicalAddress is
> 0x20208, which is not even WORD aligned!
>
> Why this could happen? Is there and parameters I did not set correctly?
>
>
>
> Thanks for your patience to read through such a long article, and if u
> can share any idea about my issue, I'll be so grateful!!
>
> Thanks again and much appreciate!