Tech Support > Microsoft Windows > Drivers > IRQL He11
IRQL He11
Posted by Slide-O-Mix on August 2nd, 2006


I am currently modifying a driver we use internally that interfaces with a
PCI board. We are adding a DMA capability to the board where we can DMA data
to and from specific memory regions, that is working correctly and I get
interrupts and get into my DpcForIsr, etc, BUT what I need to do when I get
data from the DMA is write it out to a file. Now, I know that in my Dpc I
can't call ZwWriteFile to write out to my file that I opened previously, so I
wrote code to setup a work item to do it for me. I am trying to copy the data
from the NonPagedPool physical memory that the DMA is going into to another
buffer that the work item can use to write to the file. I am having major
issues because obviously RtlCopyMemory can't be called in the Dpc either
because the IRQL is wrong. I tried getting an MDL and locking the pages in
memory so they are resident before calling RtlCopyMemory, but I am having a
heck of a time. If anyone can help out I would appreciate it greatly, below
is the portion of the code that I am having problems with, it is contained in
a DpcForIsr.

// allocate a work item context
pWriteCtx = (PWRITECTX_INFO) ExAllocatePoolWithTag(
NonPagedPool,
sizeof(WRITECTX_INFO),
'xtcW'
);

// assign file handle
pWriteCtx->hFile = pDmaStream->hFile;

pWriteCtx->pBuffer = (U32*)ExAllocatePoolWithTag(
NonPagedPool,
pBuffer->Size,
'Wmem'
);

if(pWriteCtx->pBuffer == NULL)
{
DebugPrintf((
"Insufficient resources to allocate work queue buffer\n"
));

ExFreePool(pWriteCtx);
}
else
{
try
{
RtlZeroMemory(pWriteCtx->pBuffer, pBuffer->Size);
pWriteCtx->bufferSize = pBuffer->Size;

pMdl = IoAllocateMdl(
pWriteCtx->pBuffer,
pBuffer->Size,
FALSE,
TRUE,
NULL
);

pMdlDma = IoAllocateMdl(
(PVOID)pBuffer->UserAddr,
pBuffer->Size,
FALSE,
TRUE,
NULL
);

MmBuildMdlForNonPagedPool(
pMdl
);

MmBuildMdlForNonPagedPool(
pMdlDma
);

MmProbeAndLockPages(
pMdl,
KernelMode,
IoWriteAccess
);

MmProbeAndLockPages(
pMdlDma,
KernelMode,
IoReadAccess
);

//
// Map the physical pages described by the MDL into system space.
// Note: double mapping the buffer this way causes lot of
// system overhead for large size buffers.
//

pTempBuf = MmGetSystemAddressForMdlSafe(
pMdl,
NormalPagePriority
);

pTempDmaBuf = MmGetSystemAddressForMdlSafe(
pMdlDma,
NormalPagePriority
);

// copy the data from the buffer into the work queue buffer
RtlCopyMemory(
(VOID*)pTempBuf,
(VOID*)pTempDmaBuf,
pBuffer->Size
);

// unlock the pages and free the MDL
MmUnlockPages(
pMdl
);

MmUnlockPages(
pMdlDma
);

IoFreeMdl(
pMdl
);

IoFreeMdl(
pMdlDma
);



pBuffer is the buffer that represents the DMA buffer where the data from the
DMA is located. My work item context structure looks like this:

typedef struct _WRITECTX_INFO
{
PIO_WORKITEM item;
DEVICE_EXTENSION *pdx;
U32* pBuffer;
U32 bufferSize;
HANDLE hFile;
} WRITECTX_INFO, *PWRITECTX_INFO;

I am very new to driver development, so I know I am doing something wrong
(obviously or it would be working). Thanks!




Posted by Don Burn on August 3rd, 2006


You can call RtlCopyMemory from any IRQL as long as both buffers are
non-paged. You should not be building a MDL for this, just allocate the
memory from NonPagedPool. Of course depending on the frequency of DMA
operations, you could also just queue a work item and have it write the data
from the DMA buffer.


--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply



"Slide-O-Mix" <SlideOMix@discussions.microsoft.com> wrote in message
news:AC6A0D46-DBAA-43C7-8D71-BE7C08DC6C97@microsoft.com...


Posted by Slide-O-Mix on August 3rd, 2006


Ok, that makes sense, I am allocating one of the buffers from the
NonPagedPool as can be seen from my code. The other is being allocated using
AllocateCommonBuffer on a DMA adapter, is there anything special I need to do
for that buffer? I think that might be where my BSOD's are coming from in
relation to the IRQL not less than or equal errors I am seeing.

"Don Burn" wrote:

Posted by Pavel A. on August 3rd, 2006


"Slide-O-Mix" wrote:
....................

Not sure that try & exception handlers work in a DPC for ISR...
--PA


Posted by Slide-O-Mix on August 3rd, 2006




"Pavel A." wrote:


You are correct, they don't

I did finally get this all working better, I looked through the code and
noticed that during the allocation of the common buffer for DMA it goes
through all the steps to create an Mdl Safe address, I just switched to using
that address during RtlCopyMemory and it works much better. Thanks all for
the help.


Similar Posts