Microsoft Windows Vista Community Forums - Vistaheads
Recommended Download



Welcome to the Microsoft Windows Vista Community Forums - Vistaheads, YOUR Largest Resource for Windows Vista related information.

You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so , join our community today!

If you have any problems with the registration process or your account login, please contact us.

Driver Scanner

a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!

microsoft.public.windows.vista hardware devices






Speedup My PC
Reply
  #1 (permalink)  
Old 10-30-2007
Leon Huang
 

Posts: n/a
a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
Hi
I writed a BDA driver for a PCI TV card device,I found that my driver can
work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on Vista x64
+ less than 4G RAM, but can't work on Vista x64 + 4G RAM, this problem make
me confused. I guess that this problem maybe result from the DMA addressing
in Vista x64, or MS change the DMA addressing in Vista x64 after XP
x64,so,the DMA configuration of my driver doesn't compatible with Vista x64.
the following codes is config DMA.

#if defined(_AMD64_)||defined(_IA64_)
if (Mm64BitPhysicalAddress) //if system support 64-bit physical addressing
{
desc.Dma64BitAddresses = TRUE;
desc.Dma32BitAddresses = FALSE;
KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
}
else
{
desc.Dma32BitAddresses = TRUE;
desc.Dma64BitAddresses = FALSE;
KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
}
#else
desc.Dma64BitAddresses = FALSE;
desc.Dma32BitAddresses = TRUE;
#endif
desc.AutoInitialize = FALSE;
desc.MaximumLength = (ULONG) -1;
m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
&desc,
&m_MaxMapRegisters);
m_MaxMapRegisters=(TABLE_SIZE)/8;
KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
if(!m_pDMAObject)
{
KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
CleanUpResources();
return STATUS_INSUFFICIENT_RESOURCES;
}
////Allocate DMA Table memory!
for(index=0;index<DMA_INT_CNT;index++)
{
m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
AllocateCommonBuffer(m_pDMAObject,
TABLE_SIZE,
&m_DMAPara[index].KsDMA_Table_PA,
FALSE);
if(!m_DMAPara[index].KsDMA_Table_VA)
{
KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
CleanUpResources();
return STATUS_INSUFFICIENT_RESOURCES;
}
m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
}

can you give me a idea?

thanks

best regards

Leon Huang


Reply With Quote
Sponsored Links
  #2 (permalink)  
Old 10-31-2007
Tim Roberts
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
"Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote:
>
>Hi
> I writed a BDA driver for a PCI TV card device,I found that my driver can
>work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on Vista x64
>+ less than 4G RAM, but can't work on Vista x64 + 4G RAM, this problem make
>me confused. I guess that this problem maybe result from the DMA addressing
>in Vista x64, or MS change the DMA addressing in Vista x64 after XP
>x64,so,the DMA configuration of my driver doesn't compatible with Vista x64.
> the following codes is config DMA.
>
>#if defined(_AMD64_)||defined(_IA64_)
> if (Mm64BitPhysicalAddress) //if system support 64-bit physical addressing
> {
> desc.Dma64BitAddresses = TRUE;
> desc.Dma32BitAddresses = FALSE;
> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
> }
> else
> {
> desc.Dma32BitAddresses = TRUE;
> desc.Dma64BitAddresses = FALSE;
> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
> }
>#else
> desc.Dma64BitAddresses = FALSE;
> desc.Dma32BitAddresses = TRUE;
>#endif


This code is completely wrong, as the documentation makes clear. The
setting of Dma32BitAddresses and Dma64BitAddresses have ABSOLUTELY NOTHING
to do with the operating system. They are not software-related settings in
any way at all. They should never be wrapped in any #ifdefs.

You are describing YOUR DEVICE here. If your hardware can handle 64-bit
addresses when bus mastering, then you set Dma64BitAddresses to TRUE and
Dma32Bitaddresses to FALSE. If not, you set Dma64BitAddresses to FALSE,
and Dma32BitAddresses to TRUE. It's just that simple. Your hardware
doesn't change based on the operating system, so you will use the same
settings on every system.

My guess is that your device does NOT support 64-bit addressing, but on an
AMD64 system with more that 4G of RAM, you are saying that it does. That's
a recipe for disaster.
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
Reply With Quote
  #3 (permalink)  
Old 10-31-2007
Leon Huang
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
Hi Tim
Thanks for your reply.
My driver works well under Windows XP x64 operating system and 4G RAM
hardware platform, moreover, it works well under Windows Vista x64 operating
system and less than 4G RAM hardware platform, but can not work under
Windows Vista x64 operating system and 4G RAM hardware platform, the
hardware platform is the same.
In the case of Vista x64 operating system and 4G RAM, the driver succeed
to allocate DMA resource, but it can not receive the DMA interrupt.That is
make me confused.

Regards


"Tim Roberts" <timr@probo.com> wrote in message
news:146gi3t9hm9ssaf4fu4lgbk73l6q28ia84@4ax.com...
> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote:
>>
>>Hi
>> I writed a BDA driver for a PCI TV card device,I found that my driver
>> can
>>work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on Vista
>>x64
>>+ less than 4G RAM, but can't work on Vista x64 + 4G RAM, this problem
>>make
>>me confused. I guess that this problem maybe result from the DMA
>>addressing
>>in Vista x64, or MS change the DMA addressing in Vista x64 after XP
>>x64,so,the DMA configuration of my driver doesn't compatible with Vista
>>x64.
>> the following codes is config DMA.
>>
>>#if defined(_AMD64_)||defined(_IA64_)
>> if (Mm64BitPhysicalAddress) //if system support 64-bit physical
>> addressing
>> {
>> desc.Dma64BitAddresses = TRUE;
>> desc.Dma32BitAddresses = FALSE;
>> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
>> }
>> else
>> {
>> desc.Dma32BitAddresses = TRUE;
>> desc.Dma64BitAddresses = FALSE;
>> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
>> }
>>#else
>> desc.Dma64BitAddresses = FALSE;
>> desc.Dma32BitAddresses = TRUE;
>>#endif

>
> This code is completely wrong, as the documentation makes clear. The
> setting of Dma32BitAddresses and Dma64BitAddresses have ABSOLUTELY NOTHING
> to do with the operating system. They are not software-related settings
> in
> any way at all. They should never be wrapped in any #ifdefs.
>
> You are describing YOUR DEVICE here. If your hardware can handle 64-bit
> addresses when bus mastering, then you set Dma64BitAddresses to TRUE and
> Dma32Bitaddresses to FALSE. If not, you set Dma64BitAddresses to FALSE,
> and Dma32BitAddresses to TRUE. It's just that simple. Your hardware
> doesn't change based on the operating system, so you will use the same
> settings on every system.
>
> My guess is that your device does NOT support 64-bit addressing, but on an
> AMD64 system with more that 4G of RAM, you are saying that it does.
> That's
> a recipe for disaster.
> --
> Tim Roberts, timr@probo.com
> Providenza & Boekelheide, Inc.
>



Reply With Quote
  #4 (permalink)  
Old 11-02-2007
Peter Wieland [MSFT]
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
The first thing that I find odd is that you only support 64 bit addresses if
the system supports them. Why is that? Does your card change to only
supporting 32-bit addressing if it's running on an X86 machine? Do you not
support an x86 machine with > 4GB of memory?

What error are you seeing and where are you seeing it come from?

-p

--
This posting is provided "AS IS" with no warranties, and confers no rights.


"Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
news:uEszmypGIHA.936@TK2MSFTNGP06.phx.gbl...
> Hi
> I writed a BDA driver for a PCI TV card device,I found that my driver can
> work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on Vista
> x64 + less than 4G RAM, but can't work on Vista x64 + 4G RAM, this problem
> make me confused. I guess that this problem maybe result from the DMA
> addressing in Vista x64, or MS change the DMA addressing in Vista x64
> after XP x64,so,the DMA configuration of my driver doesn't compatible with
> Vista x64.
> the following codes is config DMA.
>
> #if defined(_AMD64_)||defined(_IA64_)
> if (Mm64BitPhysicalAddress) //if system support 64-bit physical addressing
> {
> desc.Dma64BitAddresses = TRUE;
> desc.Dma32BitAddresses = FALSE;
> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
> }
> else
> {
> desc.Dma32BitAddresses = TRUE;
> desc.Dma64BitAddresses = FALSE;
> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
> }
> #else
> desc.Dma64BitAddresses = FALSE;
> desc.Dma32BitAddresses = TRUE;
> #endif
> desc.AutoInitialize = FALSE;
> desc.MaximumLength = (ULONG) -1;
> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
> &desc,
> &m_MaxMapRegisters);
> m_MaxMapRegisters=(TABLE_SIZE)/8;
> KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
> if(!m_pDMAObject)
> {
> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
> CleanUpResources();
> return STATUS_INSUFFICIENT_RESOURCES;
> }
> ////Allocate DMA Table memory!
> for(index=0;index<DMA_INT_CNT;index++)
> {
> m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
> AllocateCommonBuffer(m_pDMAObject,
> TABLE_SIZE,
> &m_DMAPara[index].KsDMA_Table_PA,
> FALSE);
> if(!m_DMAPara[index].KsDMA_Table_VA)
> {
> KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
> CleanUpResources();
> return STATUS_INSUFFICIENT_RESOURCES;
> }
> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
> }
>
> can you give me a idea?
>
> thanks
>
> best regards
>
> Leon Huang
>

Reply With Quote
  #5 (permalink)  
Old 11-05-2007
Leon Huang
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
Hi Peter
I remove the #ifdef, as the following

desc.Dma64BitAddresses = FALSE;

desc.Dma32BitAddresses = TRUE;

The driver can receive the DMA interrupt, but the DMA buffer the driver
received is not the correct data.

The ASIC team analyzed the DMA transfer processing via logic analyzer on
Vista x64 and 4G RAM platform, they proved that the DMA chipsets transferred
correct package by the physical address and length which the driver wrote
into the DMA controller registers.

This modified driver(remove the #ifdef) can work well on Vista x64 and
less than 4G RAM platform, also work well on Windows XP x64 and 4G platform.


It looks as if this problem results from the driver, but I don't know the
difference of DMA transfer between Vista x64 and XP x64.

The following codes are about initializing DMA transfer.

//allocate DMA resource
#define TABLE_SIZE 0x8000

StartDevice()
{
...
...
DEVICE_DESCRIPTION desc;

RtlZeroMemory(&desc, sizeof(DEVICE_DESCRIPTION));

desc.Version = DEVICE_DESCRIPTION_VERSION;

desc.DmaChannel = ((ULONG) ~0);

desc.InterfaceType = PCIBus;

desc.DmaWidth = Width32Bits;

desc.DmaSpeed = Compatible;

desc.ScatterGather = TRUE;

desc.Master = TRUE;

desc.Dma64BitAddresses = FALSE;

desc.Dma32BitAddresses = TRUE;

desc.AutoInitialize = FALSE;

desc.MaximumLength = (ULONG) -1;

m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;

m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,

&desc,


&m_MaxMapRegisters);

m_MaxMapRegisters=(TABLE_SIZE)/8;

if (m_pDMAObject == NULL)

{

KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));

CleanUpResources();

return STATUS_INSUFFICIENT_RESOURCES;

}

////Allocate DMA Table memory!

For (index = 0; index < DMA_INT_CNT; index++)

{

m_DMAPara[index].KsDMA_Table_VA =
(PULONG)(m_pDMAObject->DmaOperations)->

AllocateCommonBuffer(m_pDMAObject,

TABLE_SIZE,


&m_DMAPara[index].KsDMA_Table_PA,

FALSE);

if(m_DMAPara[index].KsDMA_Table_VA == NULL)

{

KdPrint(("@@@Allocate DMA%d Table
Fail!\n",index));

CleanUpResources();

return STATUS_INSUFFICIENT_RESOURCES;

}

m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;

}

..

..

}



NTSTATUS KS_InitDMA ()

{

m_DMAPara[index].KspDMABuf = (PBYTE)ExAllocatePoolWithTag(

NonPagedPool,

m_DMAPara[index].KsdwDMABufSize,

'MpaM');

if(m_DMAPara[index].KspDMABuf == NULL)

{

KdPrint(("@@@KS_InitDMA%d List:Allocate DMA buffer memory
Fail!\n",index));

return STATUS_INSUFFICIENT_RESOURCES;;

}

//Allocate an MDL

m_DMAPara[index].KspMDL = IoAllocateMdl(

m_DMAPara[index].KspDMABuf,

m_DMAPara[index].KsdwDMABufSize,

FALSE,

FALSE,

NULL);

if(m_DMAPara[index].KspMDL == NULL)

{

ExFreePool(m_DMAPara[index].KspDMABuf);

m_DMAPara[index].KspDMABuf=NULL;

KdPrint(("@@@KS_InitDMA%d List:Allocate MDL
Fail!\n",index));

return STATUS_INSUFFICIENT_RESOURCES;

}

//Build the MDL to describe the memory pages

MmBuildMdlForNonPagedPool(m_DMAPara[index].KspMDL);

//scathergather list

return KS_DmaProgramTransfer(index);

}



NTSTATUS KS_DmaProgramTransfer(int index)

{

NTSTATUS ntStatus=STATUS_SUCCESS;

KIRQL oldIrql;

KdPrint(("KS_DmaProgramTransfer: DMA%d!\n",index));

//KeFlushIoBuffers(m_DMAPara[index].KspMDL, TRUE, TRUE);

//Get ScatterGather resource!

m_KsDmaCallContext.pKSDevice=m_pKSDevice;

m_KsDmaCallContext.index=index;

KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);

ntStatus=m_pDMAObject->DmaOperations->GetScatterGatherList(

m_pDMAObject,

m_pKSDevice->FunctionalDeviceObject,

m_DMAPara[index].KspMDL,

m_DMAPara[index].KspDMABuf,

m_DMAPara[index].KsdwDMABufSize,

KS_DmaCallBack,

&m_KsDmaCallContext,

FALSE

);

KdPrint(("GetScatterGatherList Status = 0x%X \n", ntStatus));

//ntStatus = STATUS_INSUFFICIENT_RESOURCES;

KeLowerIrql(oldIrql);

////////////////////////////////////////////

return ntStatus;

}



KS_DmaCallBack()

{

m_DMAPara[index].ScatterGatherList=ScatterGatherList;

ULONG TotalPages=ScatterGatherList->NumberOfElements;

if(TotalPages>m_MaxMapRegisters)

{

TotalPages=m_MaxMapRegisters;

KdPrint(("@@@Error: The DMA buffer PageCnt is too
large>m_MaxMapRegisters!\n"));

}

KdPrint(("TotalPages=%d\n",TotalPages));

for(unsigned long i=0;i<TotalPages;++i)

{

m_DMAPara[index].KsDMA_Table_VA[2*i]=

ScatterGatherList->Elements[i].Address.LowPart;

m_DMAPara[index].KsDMA_Table_VA[2*i+1]=

(ScatterGatherList->Elements[i].Length >> 2);

KdPrint(("ScatterGatherList->Elements[%d].Address 0x%X
\n",

i,
ScatterGatherList->Elements[i].Address.LowPart));

KdPrint(("ScatterGatherList->Elements[i].Length 0x%X \n",


i, ScatterGatherList->Elements[i].Length));

}

m_DMAPara[index].KsTotalEntry=TotalPages;

m_DMAPara[index].KsdwCurDMAUsed=0;

}

calling GetScatterGatherList failed, return STATUS_INSUFFICIENT_RESOURCES.

Thanks
Regards

Leon

"Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
news:2CDEB7E5-2864-4093-8D92-C106AB81EBE6@microsoft.com...
> The first thing that I find odd is that you only support 64 bit addresses
> if the system supports them. Why is that? Does your card change to only
> supporting 32-bit addressing if it's running on an X86 machine? Do you
> not support an x86 machine with > 4GB of memory?
>
> What error are you seeing and where are you seeing it come from?
>
> -p
>
> --
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
>
> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
> news:uEszmypGIHA.936@TK2MSFTNGP06.phx.gbl...
>> Hi
>> I writed a BDA driver for a PCI TV card device,I found that my driver
>> can work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on
>> Vista x64 + less than 4G RAM, but can't work on Vista x64 + 4G RAM, this
>> problem make me confused. I guess that this problem maybe result from the
>> DMA addressing in Vista x64, or MS change the DMA addressing in Vista x64
>> after XP x64,so,the DMA configuration of my driver doesn't compatible
>> with Vista x64.
>> the following codes is config DMA.
>>
>> #if defined(_AMD64_)||defined(_IA64_)
>> if (Mm64BitPhysicalAddress) //if system support 64-bit physical
>> addressing
>> {
>> desc.Dma64BitAddresses = TRUE;
>> desc.Dma32BitAddresses = FALSE;
>> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
>> }
>> else
>> {
>> desc.Dma32BitAddresses = TRUE;
>> desc.Dma64BitAddresses = FALSE;
>> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
>> }
>> #else
>> desc.Dma64BitAddresses = FALSE;
>> desc.Dma32BitAddresses = TRUE;
>> #endif
>> desc.AutoInitialize = FALSE;
>> desc.MaximumLength = (ULONG) -1;
>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>> &desc,
>> &m_MaxMapRegisters);
>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>> KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
>> if(!m_pDMAObject)
>> {
>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>> CleanUpResources();
>> return STATUS_INSUFFICIENT_RESOURCES;
>> }
>> ////Allocate DMA Table memory!
>> for(index=0;index<DMA_INT_CNT;index++)
>> {
>> m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
>> AllocateCommonBuffer(m_pDMAObject,
>> TABLE_SIZE,
>> &m_DMAPara[index].KsDMA_Table_PA,
>> FALSE);
>> if(!m_DMAPara[index].KsDMA_Table_VA)
>> {
>> KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
>> CleanUpResources();
>> return STATUS_INSUFFICIENT_RESOURCES;
>> }
>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>> }
>>
>> can you give me a idea?
>>
>> thanks
>>
>> best regards
>>
>> Leon Huang
>>

>



Reply With Quote
  #6 (permalink)  
Old 11-05-2007
Maxim S. Shatskih
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
There is no such thing as "DMA interrupt".

DMA is one thing, interrupt is another, and the association between them is
only logical and not hardwired in any CPU/motherboard chip, nor coded in
kernel/HAL.

So, look at your interrupt code in the driver and the interrupt logic in
the hardware, DMA is OK.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com

"Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
news:udjaEA3HIHA.1316@TK2MSFTNGP02.phx.gbl...
> Hi Peter
> I remove the #ifdef, as the following
>
> desc.Dma64BitAddresses = FALSE;
>
> desc.Dma32BitAddresses = TRUE;
>
> The driver can receive the DMA interrupt, but the DMA buffer the driver
> received is not the correct data.
>
> The ASIC team analyzed the DMA transfer processing via logic analyzer on
> Vista x64 and 4G RAM platform, they proved that the DMA chipsets transferred
> correct package by the physical address and length which the driver wrote
> into the DMA controller registers.
>
> This modified driver(remove the #ifdef) can work well on Vista x64 and
> less than 4G RAM platform, also work well on Windows XP x64 and 4G platform.
>
>
> It looks as if this problem results from the driver, but I don't know the
> difference of DMA transfer between Vista x64 and XP x64.
>
> The following codes are about initializing DMA transfer.
>
> //allocate DMA resource
> #define TABLE_SIZE 0x8000
>
> StartDevice()
> {
> ...
> ...
> DEVICE_DESCRIPTION desc;
>
> RtlZeroMemory(&desc, sizeof(DEVICE_DESCRIPTION));
>
> desc.Version = DEVICE_DESCRIPTION_VERSION;
>
> desc.DmaChannel = ((ULONG) ~0);
>
> desc.InterfaceType = PCIBus;
>
> desc.DmaWidth = Width32Bits;
>
> desc.DmaSpeed = Compatible;
>
> desc.ScatterGather = TRUE;
>
> desc.Master = TRUE;
>
> desc.Dma64BitAddresses = FALSE;
>
> desc.Dma32BitAddresses = TRUE;
>
> desc.AutoInitialize = FALSE;
>
> desc.MaximumLength = (ULONG) -1;
>
> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>
> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>
> &desc,
>
>
> &m_MaxMapRegisters);
>
> m_MaxMapRegisters=(TABLE_SIZE)/8;
>
> if (m_pDMAObject == NULL)
>
> {
>
> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>
> CleanUpResources();
>
> return STATUS_INSUFFICIENT_RESOURCES;
>
> }
>
> ////Allocate DMA Table memory!
>
> For (index = 0; index < DMA_INT_CNT; index++)
>
> {
>
> m_DMAPara[index].KsDMA_Table_VA =
> (PULONG)(m_pDMAObject->DmaOperations)->
>
> AllocateCommonBuffer(m_pDMAObject,
>
> TABLE_SIZE,
>
>
> &m_DMAPara[index].KsDMA_Table_PA,
>
> FALSE);
>
> if(m_DMAPara[index].KsDMA_Table_VA == NULL)
>
> {
>
> KdPrint(("@@@Allocate DMA%d Table
> Fail!\n",index));
>
> CleanUpResources();
>
> return STATUS_INSUFFICIENT_RESOURCES;
>
> }
>
> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>
> }
>
> ..
>
> ..
>
> }
>
>
>
> NTSTATUS KS_InitDMA ()
>
> {
>
> m_DMAPara[index].KspDMABuf = (PBYTE)ExAllocatePoolWithTag(
>
> NonPagedPool,
>
> m_DMAPara[index].KsdwDMABufSize,
>
> 'MpaM');
>
> if(m_DMAPara[index].KspDMABuf == NULL)
>
> {
>
> KdPrint(("@@@KS_InitDMA%d List:Allocate DMA buffer memory
> Fail!\n",index));
>
> return STATUS_INSUFFICIENT_RESOURCES;;
>
> }
>
> //Allocate an MDL
>
> m_DMAPara[index].KspMDL = IoAllocateMdl(
>
> m_DMAPara[index].KspDMABuf,
>
> m_DMAPara[index].KsdwDMABufSize,
>
> FALSE,
>
> FALSE,
>
> NULL);
>
> if(m_DMAPara[index].KspMDL == NULL)
>
> {
>
> ExFreePool(m_DMAPara[index].KspDMABuf);
>
> m_DMAPara[index].KspDMABuf=NULL;
>
> KdPrint(("@@@KS_InitDMA%d List:Allocate MDL
> Fail!\n",index));
>
> return STATUS_INSUFFICIENT_RESOURCES;
>
> }
>
> //Build the MDL to describe the memory pages
>
> MmBuildMdlForNonPagedPool(m_DMAPara[index].KspMDL);
>
> //scathergather list
>
> return KS_DmaProgramTransfer(index);
>
> }
>
>
>
> NTSTATUS KS_DmaProgramTransfer(int index)
>
> {
>
> NTSTATUS ntStatus=STATUS_SUCCESS;
>
> KIRQL oldIrql;
>
> KdPrint(("KS_DmaProgramTransfer: DMA%d!\n",index));
>
> //KeFlushIoBuffers(m_DMAPara[index].KspMDL, TRUE, TRUE);
>
> //Get ScatterGather resource!
>
> m_KsDmaCallContext.pKSDevice=m_pKSDevice;
>
> m_KsDmaCallContext.index=index;
>
> KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
>
> ntStatus=m_pDMAObject->DmaOperations->GetScatterGatherList(
>
> m_pDMAObject,
>
> m_pKSDevice->FunctionalDeviceObject,
>
> m_DMAPara[index].KspMDL,
>
> m_DMAPara[index].KspDMABuf,
>
> m_DMAPara[index].KsdwDMABufSize,
>
> KS_DmaCallBack,
>
> &m_KsDmaCallContext,
>
> FALSE
>
> );
>
> KdPrint(("GetScatterGatherList Status = 0x%X \n", ntStatus));
>
> //ntStatus = STATUS_INSUFFICIENT_RESOURCES;
>
> KeLowerIrql(oldIrql);
>
> ////////////////////////////////////////////
>
> return ntStatus;
>
> }
>
>
>
> KS_DmaCallBack()
>
> {
>
> m_DMAPara[index].ScatterGatherList=ScatterGatherList;
>
> ULONG TotalPages=ScatterGatherList->NumberOfElements;
>
> if(TotalPages>m_MaxMapRegisters)
>
> {
>
> TotalPages=m_MaxMapRegisters;
>
> KdPrint(("@@@Error: The DMA buffer PageCnt is too
> large>m_MaxMapRegisters!\n"));
>
> }
>
> KdPrint(("TotalPages=%d\n",TotalPages));
>
> for(unsigned long i=0;i<TotalPages;++i)
>
> {
>
> m_DMAPara[index].KsDMA_Table_VA[2*i]=
>
> ScatterGatherList->Elements[i].Address.LowPart;
>
> m_DMAPara[index].KsDMA_Table_VA[2*i+1]=
>
> (ScatterGatherList->Elements[i].Length >> 2);
>
> KdPrint(("ScatterGatherList->Elements[%d].Address 0x%X
> \n",
>
> i,
> ScatterGatherList->Elements[i].Address.LowPart));
>
> KdPrint(("ScatterGatherList->Elements[i].Length 0x%X \n",
>
>
> i, ScatterGatherList->Elements[i].Length));
>
> }
>
> m_DMAPara[index].KsTotalEntry=TotalPages;
>
> m_DMAPara[index].KsdwCurDMAUsed=0;
>
> }
>
> calling GetScatterGatherList failed, return STATUS_INSUFFICIENT_RESOURCES.
>
> Thanks
> Regards
>
> Leon
>
> "Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
> news:2CDEB7E5-2864-4093-8D92-C106AB81EBE6@microsoft.com...
> > The first thing that I find odd is that you only support 64 bit addresses
> > if the system supports them. Why is that? Does your card change to only
> > supporting 32-bit addressing if it's running on an X86 machine? Do you
> > not support an x86 machine with > 4GB of memory?
> >
> > What error are you seeing and where are you seeing it come from?
> >
> > -p
> >
> > --
> > This posting is provided "AS IS" with no warranties, and confers no
> > rights.
> >
> >
> > "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
> > news:uEszmypGIHA.936@TK2MSFTNGP06.phx.gbl...
> >> Hi
> >> I writed a BDA driver for a PCI TV card device,I found that my driver
> >> can work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on
> >> Vista x64 + less than 4G RAM, but can't work on Vista x64 + 4G RAM, this
> >> problem make me confused. I guess that this problem maybe result from the
> >> DMA addressing in Vista x64, or MS change the DMA addressing in Vista x64
> >> after XP x64,so,the DMA configuration of my driver doesn't compatible
> >> with Vista x64.
> >> the following codes is config DMA.
> >>
> >> #if defined(_AMD64_)||defined(_IA64_)
> >> if (Mm64BitPhysicalAddress) //if system support 64-bit physical
> >> addressing
> >> {
> >> desc.Dma64BitAddresses = TRUE;
> >> desc.Dma32BitAddresses = FALSE;
> >> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
> >> }
> >> else
> >> {
> >> desc.Dma32BitAddresses = TRUE;
> >> desc.Dma64BitAddresses = FALSE;
> >> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
> >> }
> >> #else
> >> desc.Dma64BitAddresses = FALSE;
> >> desc.Dma32BitAddresses = TRUE;
> >> #endif
> >> desc.AutoInitialize = FALSE;
> >> desc.MaximumLength = (ULONG) -1;
> >> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
> >> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
> >> &desc,
> >> &m_MaxMapRegisters);
> >> m_MaxMapRegisters=(TABLE_SIZE)/8;
> >> KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
> >> if(!m_pDMAObject)
> >> {
> >> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
> >> CleanUpResources();
> >> return STATUS_INSUFFICIENT_RESOURCES;
> >> }
> >> ////Allocate DMA Table memory!
> >> for(index=0;index<DMA_INT_CNT;index++)
> >> {
> >> m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
> >> AllocateCommonBuffer(m_pDMAObject,
> >> TABLE_SIZE,
> >> &m_DMAPara[index].KsDMA_Table_PA,
> >> FALSE);
> >> if(!m_DMAPara[index].KsDMA_Table_VA)
> >> {
> >> KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
> >> CleanUpResources();
> >> return STATUS_INSUFFICIENT_RESOURCES;
> >> }
> >> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
> >> }
> >>
> >> can you give me a idea?
> >>
> >> thanks
> >>
> >> best regards
> >>
> >> Leon Huang
> >>

> >

>
>


Reply With Quote
  #7 (permalink)  
Old 11-06-2007
Peter Wieland [MSFT]
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
My concern was that I would think your driver should ALWAYS say that it can
do 64-bit DMA since your hardware can apparently handle it.

If you say that you do 32-bit DMA on a 64-bit system then you'll be double
buffering. In that case you won't see the right data for the DMA transfer
show up in KspDMABuf until after you call PutScatterGatherList at the end of
the transfer. Did you wait until after calling PutScatterGatherList (after
the completion of the DMA transfer) before checking to see if you had the
right data?

GetScatterGatherList would return that error if you ask it to map more pages
than the number of map registers you got back from GetDmaAdapter. I notice
you don't bother to check that number until after the GetScatterGatherList
callback ... how many map registers are you getting and how does it compare
to the size of your buffer?

There should not be that significant of a difference between DMA in Server
2003 (or XP 64 bit) and Vista.

--
This posting is provided "AS IS" with no warranties, and confers no rights.


"Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
news:udjaEA3HIHA.1316@TK2MSFTNGP02.phx.gbl...
> Hi Peter
> I remove the #ifdef, as the following
>
> desc.Dma64BitAddresses = FALSE;
>
> desc.Dma32BitAddresses = TRUE;
>
> The driver can receive the DMA interrupt, but the DMA buffer the driver
> received is not the correct data.
>
> The ASIC team analyzed the DMA transfer processing via logic analyzer on
> Vista x64 and 4G RAM platform, they proved that the DMA chipsets
> transferred correct package by the physical address and length which the
> driver wrote into the DMA controller registers.
>
> This modified driver(remove the #ifdef) can work well on Vista x64 and
> less than 4G RAM platform, also work well on Windows XP x64 and 4G
> platform.
>
>
> It looks as if this problem results from the driver, but I don't know the
> difference of DMA transfer between Vista x64 and XP x64.
>
> The following codes are about initializing DMA transfer.
>
> //allocate DMA resource
> #define TABLE_SIZE 0x8000
>
> StartDevice()
> {
> ...
> ...
> DEVICE_DESCRIPTION desc;
>
> RtlZeroMemory(&desc, sizeof(DEVICE_DESCRIPTION));
>
> desc.Version = DEVICE_DESCRIPTION_VERSION;
>
> desc.DmaChannel = ((ULONG) ~0);
>
> desc.InterfaceType = PCIBus;
>
> desc.DmaWidth = Width32Bits;
>
> desc.DmaSpeed = Compatible;
>
> desc.ScatterGather = TRUE;
>
> desc.Master = TRUE;
>
> desc.Dma64BitAddresses = FALSE;
>
> desc.Dma32BitAddresses = TRUE;
>
> desc.AutoInitialize = FALSE;
>
> desc.MaximumLength = (ULONG) -1;
>
> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>
> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>
> &desc,
>
>
> &m_MaxMapRegisters);
>
> m_MaxMapRegisters=(TABLE_SIZE)/8;
>
> if (m_pDMAObject == NULL)
>
> {
>
> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>
> CleanUpResources();
>
> return STATUS_INSUFFICIENT_RESOURCES;
>
> }
>
> ////Allocate DMA Table memory!
>
> For (index = 0; index < DMA_INT_CNT; index++)
>
> {
>
> m_DMAPara[index].KsDMA_Table_VA =
> (PULONG)(m_pDMAObject->DmaOperations)->
>
> AllocateCommonBuffer(m_pDMAObject,
>
> TABLE_SIZE,
>
>
> &m_DMAPara[index].KsDMA_Table_PA,
>
> FALSE);
>
> if(m_DMAPara[index].KsDMA_Table_VA == NULL)
>
> {
>
> KdPrint(("@@@Allocate DMA%d Table
> Fail!\n",index));
>
> CleanUpResources();
>
> return STATUS_INSUFFICIENT_RESOURCES;
>
> }
>
> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>
> }
>
> ..
>
> ..
>
> }
>
>
>
> NTSTATUS KS_InitDMA ()
>
> {
>
> m_DMAPara[index].KspDMABuf = (PBYTE)ExAllocatePoolWithTag(
>
> NonPagedPool,
>
> m_DMAPara[index].KsdwDMABufSize,
>
> 'MpaM');
>
> if(m_DMAPara[index].KspDMABuf == NULL)
>
> {
>
> KdPrint(("@@@KS_InitDMA%d List:Allocate DMA buffer
> memory Fail!\n",index));
>
> return STATUS_INSUFFICIENT_RESOURCES;;
>
> }
>
> //Allocate an MDL
>
> m_DMAPara[index].KspMDL = IoAllocateMdl(
>
> m_DMAPara[index].KspDMABuf,
>
> m_DMAPara[index].KsdwDMABufSize,
>
> FALSE,
>
> FALSE,
>
> NULL);
>
> if(m_DMAPara[index].KspMDL == NULL)
>
> {
>
> ExFreePool(m_DMAPara[index].KspDMABuf);
>
> m_DMAPara[index].KspDMABuf=NULL;
>
> KdPrint(("@@@KS_InitDMA%d List:Allocate MDL
> Fail!\n",index));
>
> return STATUS_INSUFFICIENT_RESOURCES;
>
> }
>
> //Build the MDL to describe the memory pages
>
> MmBuildMdlForNonPagedPool(m_DMAPara[index].KspMDL);
>
> //scathergather list
>
> return KS_DmaProgramTransfer(index);
>
> }
>
>
>
> NTSTATUS KS_DmaProgramTransfer(int index)
>
> {
>
> NTSTATUS ntStatus=STATUS_SUCCESS;
>
> KIRQL oldIrql;
>
> KdPrint(("KS_DmaProgramTransfer: DMA%d!\n",index));
>
> //KeFlushIoBuffers(m_DMAPara[index].KspMDL, TRUE, TRUE);
>
> //Get ScatterGather resource!
>
> m_KsDmaCallContext.pKSDevice=m_pKSDevice;
>
> m_KsDmaCallContext.index=index;
>
> KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
>
> ntStatus=m_pDMAObject->DmaOperations->GetScatterGatherList(
>
> m_pDMAObject,
>
> m_pKSDevice->FunctionalDeviceObject,
>
> m_DMAPara[index].KspMDL,
>
> m_DMAPara[index].KspDMABuf,
>
> m_DMAPara[index].KsdwDMABufSize,
>
> KS_DmaCallBack,
>
> &m_KsDmaCallContext,
>
> FALSE
>
> );
>
> KdPrint(("GetScatterGatherList Status = 0x%X \n", ntStatus));
>
> //ntStatus = STATUS_INSUFFICIENT_RESOURCES;
>
> KeLowerIrql(oldIrql);
>
> ////////////////////////////////////////////
>
> return ntStatus;
>
> }
>
>
>
> KS_DmaCallBack()
>
> {
>
> m_DMAPara[index].ScatterGatherList=ScatterGatherList;
>
> ULONG TotalPages=ScatterGatherList->NumberOfElements;
>
> if(TotalPages>m_MaxMapRegisters)
>
> {
>
> TotalPages=m_MaxMapRegisters;
>
> KdPrint(("@@@Error: The DMA buffer PageCnt is too
> large>m_MaxMapRegisters!\n"));
>
> }
>
> KdPrint(("TotalPages=%d\n",TotalPages));
>
> for(unsigned long i=0;i<TotalPages;++i)
>
> {
>
> m_DMAPara[index].KsDMA_Table_VA[2*i]=
>
> ScatterGatherList->Elements[i].Address.LowPart;
>
> m_DMAPara[index].KsDMA_Table_VA[2*i+1]=
>
> (ScatterGatherList->Elements[i].Length >> 2);
>
> KdPrint(("ScatterGatherList->Elements[%d].Address 0x%X
> \n",
>
> i,
> ScatterGatherList->Elements[i].Address.LowPart));
>
> KdPrint(("ScatterGatherList->Elements[i].Length 0x%X
> \n",
>
>
> i, ScatterGatherList->Elements[i].Length));
>
> }
>
> m_DMAPara[index].KsTotalEntry=TotalPages;
>
> m_DMAPara[index].KsdwCurDMAUsed=0;
>
> }
>
> calling GetScatterGatherList failed, return STATUS_INSUFFICIENT_RESOURCES.
>
> Thanks
> Regards
>
> Leon
>
> "Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
> news:2CDEB7E5-2864-4093-8D92-C106AB81EBE6@microsoft.com...
>> The first thing that I find odd is that you only support 64 bit addresses
>> if the system supports them. Why is that? Does your card change to only
>> supporting 32-bit addressing if it's running on an X86 machine? Do you
>> not support an x86 machine with > 4GB of memory?
>>
>> What error are you seeing and where are you seeing it come from?
>>
>> -p
>>
>> --
>> This posting is provided "AS IS" with no warranties, and confers no
>> rights.
>>
>>
>> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
>> news:uEszmypGIHA.936@TK2MSFTNGP06.phx.gbl...
>>> Hi
>>> I writed a BDA driver for a PCI TV card device,I found that my driver
>>> can work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on
>>> Vista x64 + less than 4G RAM, but can't work on Vista x64 + 4G RAM, this
>>> problem make me confused. I guess that this problem maybe result from
>>> the DMA addressing in Vista x64, or MS change the DMA addressing in
>>> Vista x64 after XP x64,so,the DMA configuration of my driver doesn't
>>> compatible with Vista x64.
>>> the following codes is config DMA.
>>>
>>> #if defined(_AMD64_)||defined(_IA64_)
>>> if (Mm64BitPhysicalAddress) //if system support 64-bit physical
>>> addressing
>>> {
>>> desc.Dma64BitAddresses = TRUE;
>>> desc.Dma32BitAddresses = FALSE;
>>> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
>>> }
>>> else
>>> {
>>> desc.Dma32BitAddresses = TRUE;
>>> desc.Dma64BitAddresses = FALSE;
>>> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
>>> }
>>> #else
>>> desc.Dma64BitAddresses = FALSE;
>>> desc.Dma32BitAddresses = TRUE;
>>> #endif
>>> desc.AutoInitialize = FALSE;
>>> desc.MaximumLength = (ULONG) -1;
>>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>>> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>>> &desc,
>>> &m_MaxMapRegisters);
>>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>>> KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
>>> if(!m_pDMAObject)
>>> {
>>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>>> CleanUpResources();
>>> return STATUS_INSUFFICIENT_RESOURCES;
>>> }
>>> ////Allocate DMA Table memory!
>>> for(index=0;index<DMA_INT_CNT;index++)
>>> {
>>> m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
>>> AllocateCommonBuffer(m_pDMAObject,
>>> TABLE_SIZE,
>>> &m_DMAPara[index].KsDMA_Table_PA,
>>> FALSE);
>>> if(!m_DMAPara[index].KsDMA_Table_VA)
>>> {
>>> KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
>>> CleanUpResources();
>>> return STATUS_INSUFFICIENT_RESOURCES;
>>> }
>>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>>> }
>>>
>>> can you give me a idea?
>>>
>>> thanks
>>>
>>> best regards
>>>
>>> Leon Huang
>>>

>>

>
>

Reply With Quote
  #8 (permalink)  
Old 11-08-2007
Leon Huang
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
Hi
my PCI DMA device only support 32bit addressing, so, the
Dma64BitAddresses must be FALSE.
On Vista x64 + 4G RAM platform, The DMA call GetScatterGatherList, the
ScatterGatherList->Elements[].Length is
0x1000(4 KB), all elements length are not more than 4 KB, but on Vista x64
+ 3G RAM platform, the ScatterGatherList->Elements[].Length is much large,
and the element is only one. Why is that?
I don't know how to handle double buffer 32bit DMA on Vista x64 OS.

Thanks
Regards
Leon
"Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
news:319AAC57-8881-4D99-AD22-B239B48FC458@microsoft.com...
> My concern was that I would think your driver should ALWAYS say that it
> can do 64-bit DMA since your hardware can apparently handle it.
>
> If you say that you do 32-bit DMA on a 64-bit system then you'll be double
> buffering. In that case you won't see the right data for the DMA transfer
> show up in KspDMABuf until after you call PutScatterGatherList at the end
> of the transfer. Did you wait until after calling PutScatterGatherList
> (after the completion of the DMA transfer) before checking to see if you
> had the right data?
>
> GetScatterGatherList would return that error if you ask it to map more
> pages than the number of map registers you got back from GetDmaAdapter. I
> notice you don't bother to check that number until after the
> GetScatterGatherList callback ... how many map registers are you getting
> and how does it compare to the size of your buffer?
>
> There should not be that significant of a difference between DMA in Server
> 2003 (or XP 64 bit) and Vista.
>
> --
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
>
> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
> news:udjaEA3HIHA.1316@TK2MSFTNGP02.phx.gbl...
>> Hi Peter
>> I remove the #ifdef, as the following
>>
>> desc.Dma64BitAddresses = FALSE;
>>
>> desc.Dma32BitAddresses = TRUE;
>>
>> The driver can receive the DMA interrupt, but the DMA buffer the driver
>> received is not the correct data.
>>
>> The ASIC team analyzed the DMA transfer processing via logic analyzer on
>> Vista x64 and 4G RAM platform, they proved that the DMA chipsets
>> transferred correct package by the physical address and length which the
>> driver wrote into the DMA controller registers.
>>
>> This modified driver(remove the #ifdef) can work well on Vista x64 and
>> less than 4G RAM platform, also work well on Windows XP x64 and 4G
>> platform.
>>
>>
>> It looks as if this problem results from the driver, but I don't know the
>> difference of DMA transfer between Vista x64 and XP x64.
>>
>> The following codes are about initializing DMA transfer.
>>
>> //allocate DMA resource
>> #define TABLE_SIZE 0x8000
>>
>> StartDevice()
>> {
>> ...
>> ...
>> DEVICE_DESCRIPTION desc;
>>
>> RtlZeroMemory(&desc, sizeof(DEVICE_DESCRIPTION));
>>
>> desc.Version = DEVICE_DESCRIPTION_VERSION;
>>
>> desc.DmaChannel = ((ULONG) ~0);
>>
>> desc.InterfaceType = PCIBus;
>>
>> desc.DmaWidth = Width32Bits;
>>
>> desc.DmaSpeed = Compatible;
>>
>> desc.ScatterGather = TRUE;
>>
>> desc.Master = TRUE;
>>
>> desc.Dma64BitAddresses = FALSE;
>>
>> desc.Dma32BitAddresses = TRUE;
>>
>> desc.AutoInitialize = FALSE;
>>
>> desc.MaximumLength = (ULONG) -1;
>>
>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>>
>> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>>
>> &desc,
>>
>>
>> &m_MaxMapRegisters);
>>
>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>>
>> if (m_pDMAObject == NULL)
>>
>> {
>>
>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>>
>> CleanUpResources();
>>
>> return STATUS_INSUFFICIENT_RESOURCES;
>>
>> }
>>
>> ////Allocate DMA Table memory!
>>
>> For (index = 0; index < DMA_INT_CNT; index++)
>>
>> {
>>
>> m_DMAPara[index].KsDMA_Table_VA =
>> (PULONG)(m_pDMAObject->DmaOperations)->
>>
>> AllocateCommonBuffer(m_pDMAObject,
>>
>> TABLE_SIZE,
>>
>>
>> &m_DMAPara[index].KsDMA_Table_PA,
>>
>> FALSE);
>>
>> if(m_DMAPara[index].KsDMA_Table_VA == NULL)
>>
>> {
>>
>> KdPrint(("@@@Allocate DMA%d Table
>> Fail!\n",index));
>>
>> CleanUpResources();
>>
>> return STATUS_INSUFFICIENT_RESOURCES;
>>
>> }
>>
>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>>
>> }
>>
>> ..
>>
>> ..
>>
>> }
>>
>>
>>
>> NTSTATUS KS_InitDMA ()
>>
>> {
>>
>> m_DMAPara[index].KspDMABuf = (PBYTE)ExAllocatePoolWithTag(
>>
>> NonPagedPool,
>>
>> m_DMAPara[index].KsdwDMABufSize,
>>
>> 'MpaM');
>>
>> if(m_DMAPara[index].KspDMABuf == NULL)
>>
>> {
>>
>> KdPrint(("@@@KS_InitDMA%d List:Allocate DMA buffer
>> memory Fail!\n",index));
>>
>> return STATUS_INSUFFICIENT_RESOURCES;;
>>
>> }
>>
>> //Allocate an MDL
>>
>> m_DMAPara[index].KspMDL = IoAllocateMdl(
>>
>> m_DMAPara[index].KspDMABuf,
>>
>> m_DMAPara[index].KsdwDMABufSize,
>>
>> FALSE,
>>
>> FALSE,
>>
>> NULL);
>>
>> if(m_DMAPara[index].KspMDL == NULL)
>>
>> {
>>
>> ExFreePool(m_DMAPara[index].KspDMABuf);
>>
>> m_DMAPara[index].KspDMABuf=NULL;
>>
>> KdPrint(("@@@KS_InitDMA%d List:Allocate MDL
>> Fail!\n",index));
>>
>> return STATUS_INSUFFICIENT_RESOURCES;
>>
>> }
>>
>> //Build the MDL to describe the memory pages
>>
>> MmBuildMdlForNonPagedPool(m_DMAPara[index].KspMDL);
>>
>> //scathergather list
>>
>> return KS_DmaProgramTransfer(index);
>>
>> }
>>
>>
>>
>> NTSTATUS KS_DmaProgramTransfer(int index)
>>
>> {
>>
>> NTSTATUS ntStatus=STATUS_SUCCESS;
>>
>> KIRQL oldIrql;
>>
>> KdPrint(("KS_DmaProgramTransfer: DMA%d!\n",index));
>>
>> //KeFlushIoBuffers(m_DMAPara[index].KspMDL, TRUE, TRUE);
>>
>> //Get ScatterGather resource!
>>
>> m_KsDmaCallContext.pKSDevice=m_pKSDevice;
>>
>> m_KsDmaCallContext.index=index;
>>
>> KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
>>
>> ntStatus=m_pDMAObject->DmaOperations->GetScatterGatherList(
>>
>> m_pDMAObject,
>>
>> m_pKSDevice->FunctionalDeviceObject,
>>
>> m_DMAPara[index].KspMDL,
>>
>> m_DMAPara[index].KspDMABuf,
>>
>> m_DMAPara[index].KsdwDMABufSize,
>>
>> KS_DmaCallBack,
>>
>> &m_KsDmaCallContext,
>>
>> FALSE
>>
>> );
>>
>> KdPrint(("GetScatterGatherList Status = 0x%X \n", ntStatus));
>>
>> //ntStatus = STATUS_INSUFFICIENT_RESOURCES;
>>
>> KeLowerIrql(oldIrql);
>>
>> ////////////////////////////////////////////
>>
>> return ntStatus;
>>
>> }
>>
>>
>>
>> KS_DmaCallBack()
>>
>> {
>>
>> m_DMAPara[index].ScatterGatherList=ScatterGatherList;
>>
>> ULONG TotalPages=ScatterGatherList->NumberOfElements;
>>
>> if(TotalPages>m_MaxMapRegisters)
>>
>> {
>>
>> TotalPages=m_MaxMapRegisters;
>>
>> KdPrint(("@@@Error: The DMA buffer PageCnt is too
>> large>m_MaxMapRegisters!\n"));
>>
>> }
>>
>> KdPrint(("TotalPages=%d\n",TotalPages));
>>
>> for(unsigned long i=0;i<TotalPages;++i)
>>
>> {
>>
>> m_DMAPara[index].KsDMA_Table_VA[2*i]=
>>
>>
>> ScatterGatherList->Elements[i].Address.LowPart;
>>
>> m_DMAPara[index].KsDMA_Table_VA[2*i+1]=
>>
>> (ScatterGatherList->Elements[i].Length >> 2);
>>
>> KdPrint(("ScatterGatherList->Elements[%d].Address 0x%X
>> \n",
>>
>> i,
>> ScatterGatherList->Elements[i].Address.LowPart));
>>
>> KdPrint(("ScatterGatherList->Elements[i].Length 0x%X
>> \n",
>>
>>
>> i,
>> ScatterGatherList->Elements[i].Length));
>>
>> }
>>
>> m_DMAPara[index].KsTotalEntry=TotalPages;
>>
>> m_DMAPara[index].KsdwCurDMAUsed=0;
>>
>> }
>>
>> calling GetScatterGatherList failed, return
>> STATUS_INSUFFICIENT_RESOURCES.
>>
>> Thanks
>> Regards
>>
>> Leon
>>
>> "Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
>> news:2CDEB7E5-2864-4093-8D92-C106AB81EBE6@microsoft.com...
>>> The first thing that I find odd is that you only support 64 bit
>>> addresses if the system supports them. Why is that? Does your card
>>> change to only supporting 32-bit addressing if it's running on an X86
>>> machine? Do you not support an x86 machine with > 4GB of memory?
>>>
>>> What error are you seeing and where are you seeing it come from?
>>>
>>> -p
>>>
>>> --
>>> This posting is provided "AS IS" with no warranties, and confers no
>>> rights.
>>>
>>>
>>> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
>>> news:uEszmypGIHA.936@TK2MSFTNGP06.phx.gbl...
>>>> Hi
>>>> I writed a BDA driver for a PCI TV card device,I found that my driver
>>>> can work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on
>>>> Vista x64 + less than 4G RAM, but can't work on Vista x64 + 4G RAM,
>>>> this problem make me confused. I guess that this problem maybe result
>>>> from the DMA addressing in Vista x64, or MS change the DMA addressing
>>>> in Vista x64 after XP x64,so,the DMA configuration of my driver doesn't
>>>> compatible with Vista x64.
>>>> the following codes is config DMA.
>>>>
>>>> #if defined(_AMD64_)||defined(_IA64_)
>>>> if (Mm64BitPhysicalAddress) //if system support 64-bit physical
>>>> addressing
>>>> {
>>>> desc.Dma64BitAddresses = TRUE;
>>>> desc.Dma32BitAddresses = FALSE;
>>>> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
>>>> }
>>>> else
>>>> {
>>>> desc.Dma32BitAddresses = TRUE;
>>>> desc.Dma64BitAddresses = FALSE;
>>>> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
>>>> }
>>>> #else
>>>> desc.Dma64BitAddresses = FALSE;
>>>> desc.Dma32BitAddresses = TRUE;
>>>> #endif
>>>> desc.AutoInitialize = FALSE;
>>>> desc.MaximumLength = (ULONG) -1;
>>>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>>>> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>>>> &desc,
>>>> &m_MaxMapRegisters);
>>>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>>>> KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
>>>> if(!m_pDMAObject)
>>>> {
>>>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>>>> CleanUpResources();
>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>> }
>>>> ////Allocate DMA Table memory!
>>>> for(index=0;index<DMA_INT_CNT;index++)
>>>> {
>>>>
>>>> m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
>>>> AllocateCommonBuffer(m_pDMAObject,
>>>> TABLE_SIZE,
>>>> &m_DMAPara[index].KsDMA_Table_PA,
>>>> FALSE);
>>>> if(!m_DMAPara[index].KsDMA_Table_VA)
>>>> {
>>>> KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
>>>> CleanUpResources();
>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>> }
>>>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>>>> }
>>>>
>>>> can you give me a idea?
>>>>
>>>> thanks
>>>>
>>>> best regards
>>>>
>>>> Leon Huang
>>>>
>>>

>>
>>

>



Reply With Quote
  #9 (permalink)  
Old 11-08-2007
Peter Wieland [MSFT]
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
Ah. I assumed way down below that you were setting Dma64BitAddresses
because your device supported them. If your device does not support them
then you should not set that flag. You will have to deal with double
buffering.

You see one large SG entry on the 64-bit OS because the OS is double
buffering your request into a single contiguous buffer. The original buffer
very likely included one or more physical addresses that were not
addressable by your controller.

If the double buffering provided by the OS results in requests that are too
small you could allocate some common buffer and double buffer the requests
yourself. Then you could control how large they were and how many to do at
one time.

Or update your device.

-p

--
This posting is provided "AS IS" with no warranties, and confers no rights.


"Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
news:uJn206eIIHA.748@TK2MSFTNGP04.phx.gbl...
> Hi
> my PCI DMA device only support 32bit addressing, so, the
> Dma64BitAddresses must be FALSE.
> On Vista x64 + 4G RAM platform, The DMA call GetScatterGatherList, the
> ScatterGatherList->Elements[].Length is
> 0x1000(4 KB), all elements length are not more than 4 KB, but on Vista
> x64 + 3G RAM platform, the ScatterGatherList->Elements[].Length is much
> large, and the element is only one. Why is that?
> I don't know how to handle double buffer 32bit DMA on Vista x64 OS.
>
> Thanks
> Regards
> Leon
> "Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
> news:319AAC57-8881-4D99-AD22-B239B48FC458@microsoft.com...
>> My concern was that I would think your driver should ALWAYS say that it
>> can do 64-bit DMA since your hardware can apparently handle it.
>>
>> If you say that you do 32-bit DMA on a 64-bit system then you'll be
>> double buffering. In that case you won't see the right data for the DMA
>> transfer show up in KspDMABuf until after you call PutScatterGatherList
>> at the end of the transfer. Did you wait until after calling
>> PutScatterGatherList (after the completion of the DMA transfer) before
>> checking to see if you had the right data?
>>
>> GetScatterGatherList would return that error if you ask it to map more
>> pages than the number of map registers you got back from GetDmaAdapter.
>> I notice you don't bother to check that number until after the
>> GetScatterGatherList callback ... how many map registers are you getting
>> and how does it compare to the size of your buffer?
>>
>> There should not be that significant of a difference between DMA in
>> Server 2003 (or XP 64 bit) and Vista.
>>
>> --
>> This posting is provided "AS IS" with no warranties, and confers no
>> rights.
>>
>>
>> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
>> news:udjaEA3HIHA.1316@TK2MSFTNGP02.phx.gbl...
>>> Hi Peter
>>> I remove the #ifdef, as the following
>>>
>>> desc.Dma64BitAddresses = FALSE;
>>>
>>> desc.Dma32BitAddresses = TRUE;
>>>
>>> The driver can receive the DMA interrupt, but the DMA buffer the driver
>>> received is not the correct data.
>>>
>>> The ASIC team analyzed the DMA transfer processing via logic analyzer on
>>> Vista x64 and 4G RAM platform, they proved that the DMA chipsets
>>> transferred correct package by the physical address and length which the
>>> driver wrote into the DMA controller registers.
>>>
>>> This modified driver(remove the #ifdef) can work well on Vista x64
>>> and less than 4G RAM platform, also work well on Windows XP x64 and 4G
>>> platform.
>>>
>>>
>>> It looks as if this problem results from the driver, but I don't know
>>> the difference of DMA transfer between Vista x64 and XP x64.
>>>
>>> The following codes are about initializing DMA transfer.
>>>
>>> //allocate DMA resource
>>> #define TABLE_SIZE 0x8000
>>>
>>> StartDevice()
>>> {
>>> ...
>>> ...
>>> DEVICE_DESCRIPTION desc;
>>>
>>> RtlZeroMemory(&desc, sizeof(DEVICE_DESCRIPTION));
>>>
>>> desc.Version = DEVICE_DESCRIPTION_VERSION;
>>>
>>> desc.DmaChannel = ((ULONG) ~0);
>>>
>>> desc.InterfaceType = PCIBus;
>>>
>>> desc.DmaWidth = Width32Bits;
>>>
>>> desc.DmaSpeed = Compatible;
>>>
>>> desc.ScatterGather = TRUE;
>>>
>>> desc.Master = TRUE;
>>>
>>> desc.Dma64BitAddresses = FALSE;
>>>
>>> desc.Dma32BitAddresses = TRUE;
>>>
>>> desc.AutoInitialize = FALSE;
>>>
>>> desc.MaximumLength = (ULONG) -1;
>>>
>>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>>>
>>> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>>>
>>> &desc,
>>>
>>>
>>> &m_MaxMapRegisters);
>>>
>>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>>>
>>> if (m_pDMAObject == NULL)
>>>
>>> {
>>>
>>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>>>
>>> CleanUpResources();
>>>
>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>
>>> }
>>>
>>> ////Allocate DMA Table memory!
>>>
>>> For (index = 0; index < DMA_INT_CNT; index++)
>>>
>>> {
>>>
>>> m_DMAPara[index].KsDMA_Table_VA =
>>> (PULONG)(m_pDMAObject->DmaOperations)->
>>>
>>> AllocateCommonBuffer(m_pDMAObject,
>>>
>>> TABLE_SIZE,
>>>
>>>
>>> &m_DMAPara[index].KsDMA_Table_PA,
>>>
>>> FALSE);
>>>
>>> if(m_DMAPara[index].KsDMA_Table_VA == NULL)
>>>
>>> {
>>>
>>> KdPrint(("@@@Allocate DMA%d Table
>>> Fail!\n",index));
>>>
>>> CleanUpResources();
>>>
>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>
>>> }
>>>
>>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>>>
>>> }
>>>
>>> ..
>>>
>>> ..
>>>
>>> }
>>>
>>>
>>>
>>> NTSTATUS KS_InitDMA ()
>>>
>>> {
>>>
>>> m_DMAPara[index].KspDMABuf = (PBYTE)ExAllocatePoolWithTag(
>>>
>>> NonPagedPool,
>>>
>>> m_DMAPara[index].KsdwDMABufSize,
>>>
>>> 'MpaM');
>>>
>>> if(m_DMAPara[index].KspDMABuf == NULL)
>>>
>>> {
>>>
>>> KdPrint(("@@@KS_InitDMA%d List:Allocate DMA buffer
>>> memory Fail!\n",index));
>>>
>>> return STATUS_INSUFFICIENT_RESOURCES;;
>>>
>>> }
>>>
>>> //Allocate an MDL
>>>
>>> m_DMAPara[index].KspMDL = IoAllocateMdl(
>>>
>>> m_DMAPara[index].KspDMABuf,
>>>
>>> m_DMAPara[index].KsdwDMABufSize,
>>>
>>> FALSE,
>>>
>>> FALSE,
>>>
>>> NULL);
>>>
>>> if(m_DMAPara[index].KspMDL == NULL)
>>>
>>> {
>>>
>>> ExFreePool(m_DMAPara[index].KspDMABuf);
>>>
>>> m_DMAPara[index].KspDMABuf=NULL;
>>>
>>> KdPrint(("@@@KS_InitDMA%d List:Allocate MDL
>>> Fail!\n",index));
>>>
>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>
>>> }
>>>
>>> //Build the MDL to describe the memory pages
>>>
>>> MmBuildMdlForNonPagedPool(m_DMAPara[index].KspMDL);
>>>
>>> //scathergather list
>>>
>>> return KS_DmaProgramTransfer(index);
>>>
>>> }
>>>
>>>
>>>
>>> NTSTATUS KS_DmaProgramTransfer(int index)
>>>
>>> {
>>>
>>> NTSTATUS ntStatus=STATUS_SUCCESS;
>>>
>>> KIRQL oldIrql;
>>>
>>> KdPrint(("KS_DmaProgramTransfer: DMA%d!\n",index));
>>>
>>> //KeFlushIoBuffers(m_DMAPara[index].KspMDL, TRUE, TRUE);
>>>
>>> //Get ScatterGather resource!
>>>
>>> m_KsDmaCallContext.pKSDevice=m_pKSDevice;
>>>
>>> m_KsDmaCallContext.index=index;
>>>
>>> KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
>>>
>>> ntStatus=m_pDMAObject->DmaOperations->GetScatterGatherList(
>>>
>>> m_pDMAObject,
>>>
>>> m_pKSDevice->FunctionalDeviceObject,
>>>
>>> m_DMAPara[index].KspMDL,
>>>
>>> m_DMAPara[index].KspDMABuf,
>>>
>>> m_DMAPara[index].KsdwDMABufSize,
>>>
>>> KS_DmaCallBack,
>>>
>>> &m_KsDmaCallContext,
>>>
>>> FALSE
>>>
>>> );
>>>
>>> KdPrint(("GetScatterGatherList Status = 0x%X \n", ntStatus));
>>>
>>> //ntStatus = STATUS_INSUFFICIENT_RESOURCES;
>>>
>>> KeLowerIrql(oldIrql);
>>>
>>> ////////////////////////////////////////////
>>>
>>> return ntStatus;
>>>
>>> }
>>>
>>>
>>>
>>> KS_DmaCallBack()
>>>
>>> {
>>>
>>> m_DMAPara[index].ScatterGatherList=ScatterGatherList;
>>>
>>> ULONG TotalPages=ScatterGatherList->NumberOfElements;
>>>
>>> if(TotalPages>m_MaxMapRegisters)
>>>
>>> {
>>>
>>> TotalPages=m_MaxMapRegisters;
>>>
>>> KdPrint(("@@@Error: The DMA buffer PageCnt is too
>>> large>m_MaxMapRegisters!\n"));
>>>
>>> }
>>>
>>> KdPrint(("TotalPages=%d\n",TotalPages));
>>>
>>> for(unsigned long i=0;i<TotalPages;++i)
>>>
>>> {
>>>
>>> m_DMAPara[index].KsDMA_Table_VA[2*i]=
>>>
>>>
>>> ScatterGatherList->Elements[i].Address.LowPart;
>>>
>>> m_DMAPara[index].KsDMA_Table_VA[2*i+1]=
>>>
>>> (ScatterGatherList->Elements[i].Length >> 2);
>>>
>>> KdPrint(("ScatterGatherList->Elements[%d].Address 0x%X
>>> \n",
>>>
>>> i,
>>> ScatterGatherList->Elements[i].Address.LowPart));
>>>
>>> KdPrint(("ScatterGatherList->Elements[i].Length 0x%X
>>> \n",
>>>
>>>
>>> i,
>>> ScatterGatherList->Elements[i].Length));
>>>
>>> }
>>>
>>> m_DMAPara[index].KsTotalEntry=TotalPages;
>>>
>>> m_DMAPara[index].KsdwCurDMAUsed=0;
>>>
>>> }
>>>
>>> calling GetScatterGatherList failed, return
>>> STATUS_INSUFFICIENT_RESOURCES.
>>>
>>> Thanks
>>> Regards
>>>
>>> Leon
>>>
>>> "Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
>>> news:2CDEB7E5-2864-4093-8D92-C106AB81EBE6@microsoft.com...
>>>> The first thing that I find odd is that you only support 64 bit
>>>> addresses if the system supports them. Why is that? Does your card
>>>> change to only supporting 32-bit addressing if it's running on an X86
>>>> machine? Do you not support an x86 machine with > 4GB of memory?
>>>>
>>>> What error are you seeing and where are you seeing it come from?
>>>>
>>>> -p
>>>>
>>>> --
>>>> This posting is provided "AS IS" with no warranties, and confers no
>>>> rights.
>>>>
>>>>
>>>> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
>>>> news:uEszmypGIHA.936@TK2MSFTNGP06.phx.gbl...
>>>>> Hi
>>>>> I writed a BDA driver for a PCI TV card device,I found that my driver
>>>>> can work well on Vista32/XP32/XPx64 + 4GRAM platform, and work well on
>>>>> Vista x64 + less than 4G RAM, but can't work on Vista x64 + 4G RAM,
>>>>> this problem make me confused. I guess that this problem maybe result
>>>>> from the DMA addressing in Vista x64, or MS change the DMA addressing
>>>>> in Vista x64 after XP x64,so,the DMA configuration of my driver
>>>>> doesn't compatible with Vista x64.
>>>>> the following codes is config DMA.
>>>>>
>>>>> #if defined(_AMD64_)||defined(_IA64_)
>>>>> if (Mm64BitPhysicalAddress) //if system support 64-bit physical
>>>>> addressing
>>>>> {
>>>>> desc.Dma64BitAddresses = TRUE;
>>>>> desc.Dma32BitAddresses = FALSE;
>>>>> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
>>>>> }
>>>>> else
>>>>> {
>>>>> desc.Dma32BitAddresses = TRUE;
>>>>> desc.Dma64BitAddresses = FALSE;
>>>>> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
>>>>> }
>>>>> #else
>>>>> desc.Dma64BitAddresses = FALSE;
>>>>> desc.Dma32BitAddresses = TRUE;
>>>>> #endif
>>>>> desc.AutoInitialize = FALSE;
>>>>> desc.MaximumLength = (ULONG) -1;
>>>>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>>>>> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>>>>> &desc,
>>>>> &m_MaxMapRegisters);
>>>>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>>>>> KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
>>>>> if(!m_pDMAObject)
>>>>> {
>>>>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>>>>> CleanUpResources();
>>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>>> }
>>>>> ////Allocate DMA Table memory!
>>>>> for(index=0;index<DMA_INT_CNT;index++)
>>>>> {
>>>>>
>>>>> m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
>>>>> AllocateCommonBuffer(m_pDMAObject,
>>>>> TABLE_SIZE,
>>>>> &m_DMAPara[index].KsDMA_Table_PA,
>>>>> FALSE);
>>>>> if(!m_DMAPara[index].KsDMA_Table_VA)
>>>>> {
>>>>> KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
>>>>> CleanUpResources();
>>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>>> }
>>>>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>>>>> }
>>>>>
>>>>> can you give me a idea?
>>>>>
>>>>> thanks
>>>>>
>>>>> best regards
>>>>>
>>>>> Leon Huang
>>>>>
>>>>
>>>
>>>

>>

>
>

Reply With Quote
  #10 (permalink)  
Old 11-14-2007
Leon Huang
 

Posts: n/a
Re: a DMA PCI Device Driver doesn't work in Vista x64 + more 4GRAM platform!!
Hi Peter
If the driver call AllocateCommonBuffer to allocate a continuous
physical memory, the driver use this block physical buffer for receiving the
data from DMA device, in this case, the driver work well on Vista x64 + 4G
(or more than) platform. However, the driver doesn't work via scatter/gather
way. I think this may be resulted from that, the DMA device is 32 bits
addressing, the Dma64BitAddresses flag is FALSE, when calling
GetScatterGatherList, the system may allocate physical memory beyond 4G
space, so, the system may use double buffer for supporting it.
if the driver is in Scatter/Gather way, how can make Scatter/Gather
work well on Vista x64 + 4G platform.

Thanks
Regards


"Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
news:1B050791-7C01-4C87-8189-ABB52E07D7F0@microsoft.com...
> Ah. I assumed way down below that you were setting Dma64BitAddresses
> because your device supported them. If your device does not support them
> then you should not set that flag. You will have to deal with double
> buffering.
>
> You see one large SG entry on the 64-bit OS because the OS is double
> buffering your request into a single contiguous buffer. The original
> buffer very likely included one or more physical addresses that were not
> addressable by your controller.
>
> If the double buffering provided by the OS results in requests that are
> too small you could allocate some common buffer and double buffer the
> requests yourself. Then you could control how large they were and how
> many to do at one time.
>
> Or update your device.
>
> -p
>
> --
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
>
> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
> news:uJn206eIIHA.748@TK2MSFTNGP04.phx.gbl...
>> Hi
>> my PCI DMA device only support 32bit addressing, so, the
>> Dma64BitAddresses must be FALSE.
>> On Vista x64 + 4G RAM platform, The DMA call GetScatterGatherList, the
>> ScatterGatherList->Elements[].Length is
>> 0x1000(4 KB), all elements length are not more than 4 KB, but on Vista
>> x64 + 3G RAM platform, the ScatterGatherList->Elements[].Length is much
>> large, and the element is only one. Why is that?
>> I don't know how to handle double buffer 32bit DMA on Vista x64 OS.
>>
>> Thanks
>> Regards
>> Leon
>> "Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
>> news:319AAC57-8881-4D99-AD22-B239B48FC458@microsoft.com...
>>> My concern was that I would think your driver should ALWAYS say that it
>>> can do 64-bit DMA since your hardware can apparently handle it.
>>>
>>> If you say that you do 32-bit DMA on a 64-bit system then you'll be
>>> double buffering. In that case you won't see the right data for the DMA
>>> transfer show up in KspDMABuf until after you call PutScatterGatherList
>>> at the end of the transfer. Did you wait until after calling
>>> PutScatterGatherList (after the completion of the DMA transfer) before
>>> checking to see if you had the right data?
>>>
>>> GetScatterGatherList would return that error if you ask it to map more
>>> pages than the number of map registers you got back from GetDmaAdapter.
>>> I notice you don't bother to check that number until after the
>>> GetScatterGatherList callback ... how many map registers are you getting
>>> and how does it compare to the size of your buffer?
>>>
>>> There should not be that significant of a difference between DMA in
>>> Server 2003 (or XP 64 bit) and Vista.
>>>
>>> --
>>> This posting is provided "AS IS" with no warranties, and confers no
>>> rights.
>>>
>>>
>>> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
>>> news:udjaEA3HIHA.1316@TK2MSFTNGP02.phx.gbl...
>>>> Hi Peter
>>>> I remove the #ifdef, as the following
>>>>
>>>> desc.Dma64BitAddresses = FALSE;
>>>>
>>>> desc.Dma32BitAddresses = TRUE;
>>>>
>>>> The driver can receive the DMA interrupt, but the DMA buffer the driver
>>>> received is not the correct data.
>>>>
>>>> The ASIC team analyzed the DMA transfer processing via logic analyzer
>>>> on Vista x64 and 4G RAM platform, they proved that the DMA chipsets
>>>> transferred correct package by the physical address and length which
>>>> the driver wrote into the DMA controller registers.
>>>>
>>>> This modified driver(remove the #ifdef) can work well on Vista x64
>>>> and less than 4G RAM platform, also work well on Windows XP x64 and 4G
>>>> platform.
>>>>
>>>>
>>>> It looks as if this problem results from the driver, but I don't know
>>>> the difference of DMA transfer between Vista x64 and XP x64.
>>>>
>>>> The following codes are about initializing DMA transfer.
>>>>
>>>> //allocate DMA resource
>>>> #define TABLE_SIZE 0x8000
>>>>
>>>> StartDevice()
>>>> {
>>>> ...
>>>> ...
>>>> DEVICE_DESCRIPTION desc;
>>>>
>>>> RtlZeroMemory(&desc, sizeof(DEVICE_DESCRIPTION));
>>>>
>>>> desc.Version = DEVICE_DESCRIPTION_VERSION;
>>>>
>>>> desc.DmaChannel = ((ULONG) ~0);
>>>>
>>>> desc.InterfaceType = PCIBus;
>>>>
>>>> desc.DmaWidth = Width32Bits;
>>>>
>>>> desc.DmaSpeed = Compatible;
>>>>
>>>> desc.ScatterGather = TRUE;
>>>>
>>>> desc.Master = TRUE;
>>>>
>>>> desc.Dma64BitAddresses = FALSE;
>>>>
>>>> desc.Dma32BitAddresses = TRUE;
>>>>
>>>> desc.AutoInitialize = FALSE;
>>>>
>>>> desc.MaximumLength = (ULONG) -1;
>>>>
>>>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>>>>
>>>> m_pDMAObject = IoGetDmaAdapter(
>>>> pKSDevice->PhysicalDeviceObject,
>>>>
>>>> &desc,
>>>>
>>>>
>>>> &m_MaxMapRegisters);
>>>>
>>>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>>>>
>>>> if (m_pDMAObject == NULL)
>>>>
>>>> {
>>>>
>>>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>>>>
>>>> CleanUpResources();
>>>>
>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>>
>>>> }
>>>>
>>>> ////Allocate DMA Table memory!
>>>>
>>>> For (index = 0; index < DMA_INT_CNT; index++)
>>>>
>>>> {
>>>>
>>>> m_DMAPara[index].KsDMA_Table_VA =
>>>> (PULONG)(m_pDMAObject->DmaOperations)->
>>>>
>>>> AllocateCommonBuffer(m_pDMAObject,
>>>>
>>>>
>>>> TABLE_SIZE,
>>>>
>>>>
>>>> &m_DMAPara[index].KsDMA_Table_PA,
>>>>
>>>> FALSE);
>>>>
>>>> if(m_DMAPara[index].KsDMA_Table_VA == NULL)
>>>>
>>>> {
>>>>
>>>> KdPrint(("@@@Allocate DMA%d Table
>>>> Fail!\n",index));
>>>>
>>>> CleanUpResources();
>>>>
>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>>
>>>> }
>>>>
>>>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>>>>
>>>> }
>>>>
>>>> ..
>>>>
>>>> ..
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> NTSTATUS KS_InitDMA ()
>>>>
>>>> {
>>>>
>>>> m_DMAPara[index].KspDMABuf = (PBYTE)ExAllocatePoolWithTag(
>>>>
>>>> NonPagedPool,
>>>>
>>>> m_DMAPara[index].KsdwDMABufSize,
>>>>
>>>> 'MpaM');
>>>>
>>>> if(m_DMAPara[index].KspDMABuf == NULL)
>>>>
>>>> {
>>>>
>>>> KdPrint(("@@@KS_InitDMA%d List:Allocate DMA buffer
>>>> memory Fail!\n",index));
>>>>
>>>> return STATUS_INSUFFICIENT_RESOURCES;;
>>>>
>>>> }
>>>>
>>>> //Allocate an MDL
>>>>
>>>> m_DMAPara[index].KspMDL = IoAllocateMdl(
>>>>
>>>> m_DMAPara[index].KspDMABuf,
>>>>
>>>> m_DMAPara[index].KsdwDMABufSize,
>>>>
>>>> FALSE,
>>>>
>>>> FALSE,
>>>>
>>>> NULL);
>>>>
>>>> if(m_DMAPara[index].KspMDL == NULL)
>>>>
>>>> {
>>>>
>>>> ExFreePool(m_DMAPara[index].KspDMABuf);
>>>>
>>>> m_DMAPara[index].KspDMABuf=NULL;
>>>>
>>>> KdPrint(("@@@KS_InitDMA%d List:Allocate MDL
>>>> Fail!\n",index));
>>>>
>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>>
>>>> }
>>>>
>>>> //Build the MDL to describe the memory pages
>>>>
>>>> MmBuildMdlForNonPagedPool(m_DMAPara[index].KspMDL);
>>>>
>>>> //scathergather list
>>>>
>>>> return KS_DmaProgramTransfer(index);
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> NTSTATUS KS_DmaProgramTransfer(int index)
>>>>
>>>> {
>>>>
>>>> NTSTATUS ntStatus=STATUS_SUCCESS;
>>>>
>>>> KIRQL oldIrql;
>>>>
>>>> KdPrint(("KS_DmaProgramTransfer: DMA%d!\n",index));
>>>>
>>>> //KeFlushIoBuffers(m_DMAPara[index].KspMDL, TRUE, TRUE);
>>>>
>>>> //Get ScatterGather resource!
>>>>
>>>> m_KsDmaCallContext.pKSDevice=m_pKSDevice;
>>>>
>>>> m_KsDmaCallContext.index=index;
>>>>
>>>> KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
>>>>
>>>> ntStatus=m_pDMAObject->DmaOperations->GetScatterGatherList(
>>>>
>>>> m_pDMAObject,
>>>>
>>>> m_pKSDevice->FunctionalDeviceObject,
>>>>
>>>> m_DMAPara[index].KspMDL,
>>>>
>>>> m_DMAPara[index].KspDMABuf,
>>>>
>>>> m_DMAPara[index].KsdwDMABufSize,
>>>>
>>>> KS_DmaCallBack,
>>>>
>>>> &m_KsDmaCallContext,
>>>>
>>>> FALSE
>>>>
>>>> );
>>>>
>>>> KdPrint(("GetScatterGatherList Status = 0x%X \n", ntStatus));
>>>>
>>>> //ntStatus = STATUS_INSUFFICIENT_RESOURCES;
>>>>
>>>> KeLowerIrql(oldIrql);
>>>>
>>>> ////////////////////////////////////////////
>>>>
>>>> return ntStatus;
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> KS_DmaCallBack()
>>>>
>>>> {
>>>>
>>>> m_DMAPara[index].ScatterGatherList=ScatterGatherList;
>>>>
>>>> ULONG TotalPages=ScatterGatherList->NumberOfElements;
>>>>
>>>> if(TotalPages>m_MaxMapRegisters)
>>>>
>>>> {
>>>>
>>>> TotalPages=m_MaxMapRegisters;
>>>>
>>>> KdPrint(("@@@Error: The DMA buffer PageCnt is too
>>>> large>m_MaxMapRegisters!\n"));
>>>>
>>>> }
>>>>
>>>> KdPrint(("TotalPages=%d\n",TotalPages));
>>>>
>>>> for(unsigned long i=0;i<TotalPages;++i)
>>>>
>>>> {
>>>>
>>>> m_DMAPara[index].KsDMA_Table_VA[2*i]=
>>>>
>>>>
>>>> ScatterGatherList->Elements[i].Address.LowPart;
>>>>
>>>> m_DMAPara[index].KsDMA_Table_VA[2*i+1]=
>>>>
>>>> (ScatterGatherList->Elements[i].Length >>
>>>> 2);
>>>>
>>>> KdPrint(("ScatterGatherList->Elements[%d].Address
>>>> 0x%X \n",
>>>>
>>>> i,
>>>> ScatterGatherList->Elements[i].Address.LowPart));
>>>>
>>>> KdPrint(("ScatterGatherList->Elements[i].Length 0x%X
>>>> \n",
>>>>
>>>>
>>>> i,
>>>> ScatterGatherList->Elements[i].Length));
>>>>
>>>> }
>>>>
>>>> m_DMAPara[index].KsTotalEntry=TotalPages;
>>>>
>>>> m_DMAPara[index].KsdwCurDMAUsed=0;
>>>>
>>>> }
>>>>
>>>> calling GetScatterGatherList failed, return
>>>> STATUS_INSUFFICIENT_RESOURCES.
>>>>
>>>> Thanks
>>>> Regards
>>>>
>>>> Leon
>>>>
>>>> "Peter Wieland [MSFT]" <peterwie@online.microsoft.com> wrote in message
>>>> news:2CDEB7E5-2864-4093-8D92-C106AB81EBE6@microsoft.com...
>>>>> The first thing that I find odd is that you only support 64 bit
>>>>> addresses if the system supports them. Why is that? Does your card
>>>>> change to only supporting 32-bit addressing if it's running on an X86
>>>>> machine? Do you not support an x86 machine with > 4GB of memory?
>>>>>
>>>>> What error are you seeing and where are you seeing it come from?
>>>>>
>>>>> -p
>>>>>
>>>>> --
>>>>> This posting is provided "AS IS" with no warranties, and confers no
>>>>> rights.
>>>>>
>>>>>
>>>>> "Leon Huang" <huangxiaomeng@auvitek.com.cn> wrote in message
>>>>> news:uEszmypGIHA.936@TK2MSFTNGP06.phx.gbl...
>>>>>> Hi
>>>>>> I writed a BDA driver for a PCI TV card device,I found that my
>>>>>> driver can work well on Vista32/XP32/XPx64 + 4GRAM platform, and work
>>>>>> well on Vista x64 + less than 4G RAM, but can't work on Vista x64 +
>>>>>> 4G RAM, this problem make me confused. I guess that this problem
>>>>>> maybe result from the DMA addressing in Vista x64, or MS change the
>>>>>> DMA addressing in Vista x64 after XP x64,so,the DMA configuration of
>>>>>> my driver doesn't compatible with Vista x64.
>>>>>> the following codes is config DMA.
>>>>>>
>>>>>> #if defined(_AMD64_)||defined(_IA64_)
>>>>>> if (Mm64BitPhysicalAddress) //if system support 64-bit physical
>>>>>> addressing
>>>>>> {
>>>>>> desc.Dma64BitAddresses = TRUE;
>>>>>> desc.Dma32BitAddresses = FALSE;
>>>>>> KdPrint(("Mm64BitPhysicalAddress is TRUE \n"));
>>>>>> }
>>>>>> else
>>>>>> {
>>>>>> desc.Dma32BitAddresses = TRUE;
>>>>>> desc.Dma64BitAddresses = FALSE;
>>>>>> KdPrint(("Mm64BitPhysicalAddress is FALSE \n"));
>>>>>> }
>>>>>> #else
>>>>>> desc.Dma64BitAddresses = FALSE;
>>>>>> desc.Dma32BitAddresses = TRUE;
>>>>>> #endif
>>>>>> desc.AutoInitialize = FALSE;
>>>>>> desc.MaximumLength = (ULONG) -1;
>>>>>> m_MaxMapRegisters = (desc.MaximumLength / PAGE_SIZE) + 1;
>>>>>> m_pDMAObject = IoGetDmaAdapter( pKSDevice->PhysicalDeviceObject,
>>>>>> &desc,
>>>>>> &m_MaxMapRegisters);
>>>>>> m_MaxMapRegisters=(TABLE_SIZE)/8;
>>>>>> KdPrint(("DMA MaxMap Cnt=%d\n",m_MaxMapRegisters));
>>>>>> if(!m_pDMAObject)
>>>>>> {
>>>>>> KdPrint(("@@@Couldn't GetDMA adapter resource!\n"));
>>>>>> CleanUpResources();
>>>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>>>> }
>>>>>> ////Allocate DMA Table memory!
>>>>>> for(index=0;index<DMA_INT_CNT;index++)
>>>>>> {
>>>>>>
>>>>>> m_DMAPara[index].KsDMA_Table_VA=(PULONG)(m_pDMAObject->DmaOperations)->
>>>>>> AllocateCommonBuffer(m_pDMAObject,
>>>>>> TABLE_SIZE,
>>>>>> &m_DMAPara[index].KsDMA_Table_PA,
>>>>>> FALSE);
>>>>>> if(!m_DMAPara[index].KsDMA_Table_VA)
>>>>>> {
>>>>>> KdPrint(("@@@Allocate DMA%d Table Fail!\n",index));
>>>>>> CleanUpResources();
>>>>>> return STATUS_INSUFFICIENT_RESOURCES;
>>>>>> }
>>>>>> m_DMAPara[index].KsdwDMATableSize=TABLE_SIZE;
>>>>>> }
>>>>>>
>>>>>> can you give me a idea?
>>>>>>
>>>>>> thanks
>>>>>>
>>>>>> best regards
>>>>>>
>>>>>> Leon Huang
>>>>>>
>>>>>
>>>>
>>>>
>>>

>>
>>



Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Article ID: 929550 When you connect a PCI ExpressCard device to a portable Windows Vista-based computer, the device may not work correctly KBArticles English 0 10-22-2007 20:00
Article ID: 933442 A USB composite device does not work after you disable and then enable the device in Device Manager on a computer that is running Windows Vista KBArticles English 0 10-22-2007 20:00
Article ID: 933578 An Ultra DMA Mode 5 device may perform only at the speed of an Ultra DMA Mode 2 device after you swap devices in Windows Vista KBArticles English 0 10-22-2007 20:00
Article ID: 934543 Device Manager displays an exclamation point next to a device that is connected to a PCI multiport serial adapter on a Windows Vista-based computer KBArticles English 0 10-22-2007 20:00
4 monitors,1 pci express and pci vga card - can it work? jjkkll microsoft.public.windows.vista.installation setup 0 04-04-2007 12:42




All times are GMT +1. The time now is 11:19.




Driver Scanner - Free Scan Now

Vistaheads.com is part of the Heads Network. See also XPHeads.com , Win7Heads.com and Win8Heads.com.


Design by Vjacheslav Trushkin for phpBBStyles.com.
Powered by vBulletin® Version 3.6.7
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.6.0 RC 2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120