| Home | Forums | Reviews | Articles | Register |
![]() |
| Thread Tools | Rate Thread |
|
|
|
| |
|
Tim Roberts
Guest
Posts: n/a
|
"Leon Huang" <(E-Mail Removed)> 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, (E-Mail Removed) Providenza & Boekelheide, Inc. |
|
||
|
||||
|
Leon Huang
Guest
Posts: n/a
|
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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > "Leon Huang" <(E-Mail Removed)> 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, (E-Mail Removed) > Providenza & Boekelheide, Inc. > |
|
||
|
||||
|
Peter Wieland [MSFT]
Guest
Posts: n/a
|
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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > 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 > |
|
||
|
||||
|
Leon Huang
Guest
Posts: n/a
|
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]" <(E-Mail Removed)> wrote in message news:2CDEB7E5-2864-4093-8D92-(E-Mail Removed)... > 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" <(E-Mail Removed)> wrote in message > news:(E-Mail Removed)... >> 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 >> > |
|
||
|
||||
|
Maxim S. Shatskih
Guest
Posts: n/a
|
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 (E-Mail Removed) http://www.storagecraft.com "Leon Huang" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > 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]" <(E-Mail Removed)> wrote in message > news:2CDEB7E5-2864-4093-8D92-(E-Mail Removed)... > > 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" <(E-Mail Removed)> wrote in message > > news:(E-Mail Removed)... > >> 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 > >> > > > > |
|
||
|
||||
|
Peter Wieland [MSFT]
Guest
Posts: n/a
|
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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > 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]" <(E-Mail Removed)> wrote in message > news:2CDEB7E5-2864-4093-8D92-(E-Mail Removed)... >> 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" <(E-Mail Removed)> wrote in message >> news:(E-Mail Removed)... >>> 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 >>> >> > > |
|
||
|
||||
|
Leon Huang
Guest
Posts: n/a
|
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]" <(E-Mail Removed)> wrote in message news:319AAC57-8881-4D99-AD22-(E-Mail Removed)... > 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" <(E-Mail Removed)> wrote in message > news:(E-Mail Removed)... >> 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]" <(E-Mail Removed)> wrote in message >> news:2CDEB7E5-2864-4093-8D92-(E-Mail Removed)... >>> 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" <(E-Mail Removed)> wrote in message >>> news:(E-Mail Removed)... >>>> 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 >>>> >>> >> >> > |
|
||
|
||||
|
Peter Wieland [MSFT]
Guest
Posts: n/a
|
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" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)... > 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]" <(E-Mail Removed)> wrote in message > news:319AAC57-8881-4D99-AD22-(E-Mail Removed)... >> 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" <(E-Mail Removed)> wrote in message >> news:(E-Mail Removed)... >>> 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]" <(E-Mail Removed)> wrote in message >>> news:2CDEB7E5-2864-4093-8D92-(E-Mail Removed)... >>>> 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" <(E-Mail Removed)> wrote in message >>>> news:(E-Mail Removed)... >>>>> 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 >>>>> >>>> >>> >>> >> > > |
|
||
|
||||
|
Leon Huang
Guest
Posts: n/a
|
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]" <(E-Mail Removed)> wrote in message news:1B050791-7C01-4C87-8189-(E-Mail Removed)... > 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" <(E-Mail Removed)> wrote in message > news:(E-Mail Removed)... >> 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]" <(E-Mail Removed)> wrote in message >> news:319AAC57-8881-4D99-AD22-(E-Mail Removed)... >>> 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" <(E-Mail Removed)> wrote in message >>> news:(E-Mail Removed)... >>>> 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]" <(E-Mail Removed)> wrote in message >>>> news:2CDEB7E5-2864-4093-8D92-(E-Mail Removed)... >>>>> 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" <(E-Mail Removed)> wrote in message >>>>> news:(E-Mail Removed)... >>>>>> 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 >>>>>> >>>>> >>>> >>>> >>> >> >> |
|
||
|
||||
|
|
|
| |
![]() |
| Thread Tools | |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Windows doesn't load device driver | robh | Windows XP General | 1 | 15th Jan 2009 10:38 AM |
| Vista doesn't plug and play device driver's not found | =?Utf-8?B?RQ==?= | Windows Vista Hardware | 3 | 16th Dec 2007 09:52 AM |
| Bluetooth ISSC USB Device doesn't work in vista beta2 | =?Utf-8?B?aGFuc2ltYW4=?= | Windows Vista Hardware | 3 | 29th May 2006 12:11 AM |
| USB doesn't work on other platform? | Nikolai Vorontsov | Windows XP Embedded | 2 | 15th Jun 2005 02:04 PM |
| UNinstall a driver for a device that doesn't exists | Po | Windows XP Drivers | 0 | 31st Oct 2003 10:17 AM |
Powered by vBulletin®. Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2010, Crawlability, Inc. |




