Windows 8 32 bit not allocating enough map registers for my PCIE DMA transfer

Hello Guys,
I have a slight problem. We designed a PCIE driver on windows 7 and for windows XP. The device supports 64 bit addressing and also scatter gather. The way the device driver is designed is that it requests for map registers for a particular transfer size(2.5 MB or so). If we dont get the full size then the driver unfortunately bails out. We ask for around 2 MB worth of registers and it always worked on windows 7 64 and 32 bit and even on XP 32. It for some reason doesn’t work on windows 8 32 bit. 64 does just fine.
Is the only solution for me, breaking up of the dma transfer into manageable chunks or the initial design of the driver be still used.
Why is that windows 8 doesn’t give me the map registers? I would just like to know the reason.

I am also confused about common buffers. If I dont get the full mapping can I resort to common buffer and create an SGL for the common buffer and feed it to the device?

I am a novice when it comes to DMA. So any help would be appreciated.

Because 32-bit Windows has at most a 2MB kernel address space, so you
can’t grab all of it plus half a megabyte for your device. Either fix
your device to work with smaller size DMA or accept the device will only
support 64-bit Windows (and even then not well).

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@yahoo.com” wrote in message
news:xxxxx@ntdev:

> Hello Guys,
> I have a slight problem. We designed a PCIE driver on windows 7 and for windows XP. The device supports 64 bit addressing and also scatter gather. The way the device driver is designed is that it requests for map registers for a particular transfer size(2.5 MB or so). If we dont get the full size then the driver unfortunately bails out. We ask for around 2 MB worth of registers and it always worked on windows 7 64 and 32 bit and even on XP 32. It for some reason doesn’t work on windows 8 32 bit. 64 does just fine.
> Is the only solution for me, breaking up of the dma transfer into manageable chunks or the initial design of the driver be still used.
> Why is that windows 8 doesn’t give me the map registers? I would just like to know the reason.
>
> I am also confused about common buffers. If I dont get the full mapping can I resort to common buffer and create an SGL for the common buffer and feed it to the device?
>
> I am a novice when it comes to DMA. So any help would be appreciated.

2 mb kernel space?! Why does it work on windows 7 32 bit? I am not averse to changing the drivers and that is my next step. I am just wondering why does windows 8 not allow that much amount and what is the least that I can expect from the OS.

Would you like to retract this whole post, Don? Not one of your better ones.

OP, you say “The way the device driver is designed is that it requests for map registers for a particular transfer size(2.5 MB or so)”. How does your driver do that?

Here’s a helpful blog post by someone who knows of what he writes.
http://blogs.msdn.com/b/peterwie/archive/2006/03/02/542517.aspx

You might want to read his whole series on “What is DMA?”

Phil
Not speaking for LogRhythm

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Don Burn
Sent: Friday, December 21, 2012 11:04 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Windows 8 32 bit not allocating enough map registers for my PCIE DMA transfer

Because 32-bit Windows has at most a 2MB kernel address space, so you
can’t grab all of it plus half a megabyte for your device. Either fix
your device to work with smaller size DMA or accept the device will only
support 64-bit Windows (and even then not well).

Don Burn
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

xxxxx@yahoo.com” wrote in message
news:xxxxx@ntdev:

> Hello Guys,
> I have a slight problem. We designed a PCIE driver on windows 7 and for windows XP. The device supports 64 bit addressing and also scatter gather. The way the device driver is designed is that it requests for map registers for a particular transfer size(2.5 MB or so). If we dont get the full size then the driver unfortunately bails out. We ask for around 2 MB worth of registers and it always worked on windows 7 64 and 32 bit and even on XP 32. It for some reason doesn’t work on windows 8 32 bit. 64 does just fine.
> Is the only solution for me, breaking up of the dma transfer into manageable chunks or the initial design of the driver be still used.
> Why is that windows 8 doesn’t give me the map registers? I would just like to know the reason.
>
> I am also confused about common buffers. If I dont get the full mapping can I resort to common buffer and create an SGL for the common buffer and feed it to the device?
>
> I am a novice when it comes to DMA. So any help would be appreciated.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Don meant to say 2GB.

I figured out as much about the 2 MB limit :|. I do a WdfDmaTransactionInitialize and then in my EvtProgramDma I go through the SG list and find out the length of each fragment of SCATTER_GATHER_LIST. If I don’t get what I asked for then I abort. This is a design which I inherited and I intend to change that.

When you call IoGetDmaAdapter, you specify your maximum transfer length. Also, you MUST set ScatterGather to TRUE, and Dma64BitAddress to TRUE.

When you need to do a transfer, you DON’T call MapTransfer for a PCIe SG-capable device.

You call GetScatterGatherList function. You can also use BuildScatterGatherList function, if you have a pre-allocated buffer big enough.

When the transfer is complete, you call PutScatterGatherList (whether you obtained it by Get or Build).

I am using kmdf. Should I try WDM to check if it’s kmdf which is restricting me on windows 8?

>I am using kmdf. Should I try WDM to check if it’s kmdf which is restricting me on windows 8?

Most likely you’re using wrong parameters to call WdfDmaEnablerCreate and related functions. Post the code.

Kmdf is not restricting you here

d


From: xxxxx@yahoo.commailto:xxxxx
Sent: ?12/?21/?2012 3:01 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Windows 8 32 bit not allocating enough map registers for my PCIE DMA transfer

I am using kmdf. Should I try WDM to check if it’s kmdf which is restricting me on windows 8?


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

#ifdef AMD64
WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
WdfDmaProfileScatterGather64Duplex,
maximumLength);
#else
WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
WdfDmaProfileScatterGatherDuplex,
maximumLength);
#endif

status = WdfDmaEnablerCreate( DeviceExtension->WdfDevice,
&dmaConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&DeviceExtension->WdfDmaEnabler );

Could this be a problem ,the WdfDmaProfileScatterGather64Duplex and WdfDmaProfileScatterGatherDuplex in 32 bit compilation. Also the maximum length is 2 tb. I did change it to smaller lengths without any difference.

Go and read this http://www.microsoft.com/whdc/driver/kernel/dma.mspx

It has answer to your all queries…Don’t start coding without
understanding the system!

Thanks,
APP

On Sat, Dec 22, 2012 at 6:36 AM, wrote:

> #ifdef AMD64
> WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
> WdfDmaProfileScatterGather64Duplex,
> maximumLength);
> #else
> WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig,
> WdfDmaProfileScatterGatherDuplex,
> maximumLength);
> #endif
>
> status = WdfDmaEnablerCreate( DeviceExtension->WdfDevice,
> &dmaConfig,
> WDF_NO_OBJECT_ATTRIBUTES,
> &DeviceExtension->WdfDmaEnabler );
>
> Could this be a problem ,the WdfDmaProfileScatterGather64Duplex and
> WdfDmaProfileScatterGatherDuplex in 32 bit compilation. Also the maximum
> length is 2 tb. I did change it to smaller lengths without any difference.
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

You should use WdfDmaProfileScatterGather64Duplex for both x86 and x64.

Otherwise the transfer size will be limited by size of a reserved bounce buffer.

YUCK!

What you’re saying by the above is that on 32-bit Windows systems, your *device hardware* is only capable of doing transfers to device bus logical addresses (just think “physical addresses”) less than 4GB. This is clearly not what you mean. I hope.

Here’s a hint: ANY time you see a conditional compilation in the code portion of a Windows driver, if that’s not a conditional on DBG, it is immediately suspect. Seriously. Windows isn’t like other OSes where drivers are conditionalized all over them based on the target platform. We have the HAL and the Kernel, which are both processor architecture specific, that handle most of the variations for us. Sure, there ARE legitimate use of conditional compilation (such as target OS version), but it’s not common.

Bingo. Mr. Grig once AGAIN has diagnosed and pinpointed the exact problem. Well done, Mr. Grig.

Peter
OSR

Thanks everyone. I will confirm this after the vacations. I inherited an incomplete driver with the hardware/ firmware code almost complete. This code is a part of what I got. I had quite a few problems that I am still attempting to solve.
Mr Purkar, I don’t think you quite understand the concept of a forum. I suggest you google it and also read properly what I posted. My question was simply why would one OS(flavor i.e. Windows 8 32 bit vs Windows 7 32 bit) behave differently than the other on the same hardware.

That fixed it. The conditional compilation was indeed the culprit and removing that fixed it. Thanks Alex and Everyone else.

Why is this implemented as bounce buffer? When the data was copied to the low 32 bit range via DMA it may as well stay there. No copy needed, the developer does not have to handle map registers, and the transfer size is not limited to 256 map registers (1MB).

>Why is this implemented as bounce buffer?

The bounce buffer has to be allocated anyway if you declare you cannot handle 64 bit address, no matter what happens in the future and whether it will ever be used.