MmGetMdlVirtualAddress & WdfDmaTransactionInitialize

Hi,

we are developing PCI express driver for VISTA OS and driver uses scatter gather DMA.
our aim is to read the data (1MB) from the device. Device splits this 1MB data in 4 packets. Device generate DMA demand interrupt for first packet and driver prepares the DMA for the transfer. Then device generate DMA End interrupt and driver completes the DMA. DMA demand interrupt & DMA End interrupt sequence is followed for each packets.

Implementation are as follows.

The following DPC is queued from ISR on DMA demand and DMA end interrupt.

In DPC routine, driver process as follows.

ReadDPC
{

status = WdfIoQueueRetrieveNextRequest(deviceContext->ReadQueue, &request);

if (DMA demand interrupt)
{
WdfRequestRetrieveOutputWdmMdl( request, &mdl);

deviceContext->CurrentVirtualAddress = MmGetMdlVirtualAddress( mdl );

(ULONG *)deviceContext->CurrentVirtualAddress += deviceContext
->TotalTransferredLength;

WdfDmaTransactionInitialize( deviceContext->DmaTransaction,
(PFN_WDF_PROGRAM_DMA) DmaCallback,
WdfDmaDirectionReadFromDevice, // DMA Direction
mdl, deviceContext->CurrentVirtualAddress,
readLength );

}

if (DMA end interrupt)
{
returnValue = WdfDmaTransactionDmaCompleted(deviceContext->DmaTransaction,
&status) ;
currentBytesTransferred = WdfDmaTransactionGetBytesTransferred(deviceContext
->DmaTransaction);

deviceContext->TotalTransferredLength += currentBytesTransferred;

WdfDmaTransactionRelease(deviceContext->DmaTransaction);

}

}

I am getting 4 packets from the driver. but data content are zero. all are invalid.
I have replaced MmGetMdlVirtualAddress with MmGetSystemAddressForMdlSafe as below. still packet content is zero.

Can you please give idea what problem is in this implementation.

Thanks & Regards,
Raphel

What does your DmaCallback routine do?

On Jan 8, 2008 7:02 AM, wrote:

> Hi,
>
> we are developing PCI express driver for VISTA OS and driver uses scatter
> gather DMA.
> our aim is to read the data (1MB) from the device. Device splits this 1MB
> data in 4 packets. Device generate DMA demand interrupt for first packet
> and driver prepares the DMA for the transfer. Then device generate DMA End
> interrupt and driver completes the DMA. DMA demand interrupt & DMA End
> interrupt sequence is followed for each packets.
>
> Implementation are as follows.
>
> The following DPC is queued from ISR on DMA demand and DMA end interrupt.
>
> In DPC routine, driver process as follows.
>
> ReadDPC
> {
>
> status = WdfIoQueueRetrieveNextRequest(deviceContext->ReadQueue,
> &request);
>
> if (DMA demand interrupt)
> {
> WdfRequestRetrieveOutputWdmMdl( request, &mdl);
>
> deviceContext->CurrentVirtualAddress = MmGetMdlVirtualAddress( mdl );
>
> (ULONG *)deviceContext->CurrentVirtualAddress += deviceContext
>
> ->TotalTransferredLength;
>
> WdfDmaTransactionInitialize( deviceContext->DmaTransaction,
> (PFN_WDF_PROGRAM_DMA) DmaCallback,
> WdfDmaDirectionReadFromDevice, // DMA Direction
> mdl,
> deviceContext->CurrentVirtualAddress,
> readLength );
>
> }
>
> if (DMA end interrupt)
> {
> returnValue =
> WdfDmaTransactionDmaCompleted(deviceContext->DmaTransaction,
> &status) ;
> currentBytesTransferred =
> WdfDmaTransactionGetBytesTransferred(deviceContext
> ->DmaTransaction);
>
> deviceContext->TotalTransferredLength += currentBytesTransferred;
>
> WdfDmaTransactionRelease(deviceContext->DmaTransaction);
>
> }
>
> }
>
> I am getting 4 packets from the driver. but data content are zero. all are
> invalid.
> I have replaced MmGetMdlVirtualAddress with MmGetSystemAddressForMdlSafe
> as below. still packet content is zero.
>
> Can you please give idea what problem is in this implementation.
>
>
> Thanks & Regards,
> Raphel
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Mark Roddy

Hi,

In Dma callback routine, we are doing as follows.

In PCIe board, we have descriptor SRAM. We have linked list of descriptor blocks.

Each descriptor block has source address and destination address. Since this is read,

Source address is device memory address and destination address is system memory address

(given by SgList in DmaCallback parameter).we are mapping system memory and device memory.

BOOLEAN DmaCallback(WDFDMATRANSACTION dmaTransaction, WDFDEVICE device, PVOID context, WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST SgList)

{

PDEVICE_CONTEXT deviceContext;

NTSTATUS status = STATUS_SUCCESS;

PHYSICAL_ADDRESS address;

ULONG length, elementCounter, descripterPosition, readValue;

/* Get a context to the device */

deviceContext = (PDEVICE_CONTEXT) context;

// Scatter/Gather

address = SgList->Elements[0].Address;

length = SgList->Elements[0].Length;

// Local Interrupt Input Enable, Local DMA Channel0 Interrupt Disable

SetConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x68), 0x00000800);

ResetConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x68), 0x00040000);

deviceContext->DmaLocalAddress = PCI_FIFO_ADDRESS ;

// Bus Width: 32bit(bit0,1) TA#/READY# Input : Enable(bit6) Local Burst: Enable(bit8) Scatter/Gather: Enable(bit9) DMA Done Intrrupt: Enable(bit10)

// DMA Channel0 Interrupt Select: routes the DMA Channel0 interrupts to the PCI Businterrupt(bit17)

// :When EOT is asserted, DMA transfer ends the current scatter gather transfer and continues with remaining transfers

SetConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x080), 0x000A0743);

// DMA Ch0 PCI Address

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x084), address.LowPart);

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x088), deviceContext->DmaLocalAddress);

// DMA Ch0 Transfer Byte Count

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x08C), length);

// Descriptor Start Address

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x090), 0x00040008); // Direction of transfer(bit3 1:transfer from the Local Bus to the PCI Bus)

// Descriptor

descripterPosition = 0x00040000;

// Descriptor

for(elementCounter = 0; elementCounter < SgList->NumberOfElements; ++elementCounter) {

address = SgList->Elements[elementCounter].Address;

length = SgList->Elements[elementCounter].Length;

//DMA Ch0 PCIB Address

WritePciSp0Register(deviceContext, descripterPosition + 0x00, address.LowPart);

WritePciSp0Register(deviceContext, descripterPosition + 0x04, deviceContext->DmaLocalAddress);

WritePciSp0Register(deviceContext, descripterPosition + 0x08, length);

if( descripterPosition >= 0x7FFFF){

length = 0;

}

if(( length <= 0 )||( (SgList->NumberOfElements-1) == elementCounter)){

// Set DMA Channel0 Descriptor Pointer Register to indicate end of list.

// Bit1 = TRUE( End-of Chain), Bit2 = TRUE( Interrupt After Terminal Count) Bit3 = TRUE ( Transfer direction - PCI to Local)

WritePciSp0Register(deviceContext, descripterPosition + 0x0C, (0x40000 | 0x000E));

}

else

{

WritePciSp0Register(deviceContext, descripterPosition + 0x0C, ((descripterPosition + SIZEOF_DESCRIPTER) | 0x08 ));

}

deviceContext->DmaLocalAddress = CalcNextStartAddress(deviceContext, length);

descripterPosition += SIZEOF_DESCRIPTER;

} // end- for loop

// DMA$BE>Aw3+;O(J

WriteConfigRegister ( deviceContext, ((PCI_CONFIG_SPACE)+0xA8), 0x0001); // DMA Channel0 Enable

WriteConfigRegister ( deviceContext, ((PCI_CONFIG_SPACE)+0xA8), 0x0003); // DMA Channel0 Start

return TRUE;

}

Thanks & Regards,

Raphel


From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Mark Roddy
Sent: Wednesday, January 09, 2008 12:01 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] MmGetMdlVirtualAddress & WdfDmaTransactionInitialize

What does your DmaCallback routine do?

On Jan 8, 2008 7:02 AM, wrote:

Hi,

we are developing PCI express driver for VISTA OS and driver uses scatter gather DMA.
our aim is to read the data (1MB) from the device. Device splits this 1MB data in 4 packets. Device generate DMA demand interrupt for first packet and driver prepares the DMA for the transfer. Then device generate DMA End interrupt and driver completes the DMA. DMA demand interrupt & DMA End interrupt sequence is followed for each packets.

Implementation are as follows.

The following DPC is queued from ISR on DMA demand and DMA end interrupt.

In DPC routine, driver process as follows.

ReadDPC
{

status = WdfIoQueueRetrieveNextRequest(deviceContext->ReadQueue, &request);

if (DMA demand interrupt)
{
WdfRequestRetrieveOutputWdmMdl( request, &mdl);

deviceContext->CurrentVirtualAddress = MmGetMdlVirtualAddress( mdl );

(ULONG *)deviceContext->CurrentVirtualAddress += deviceContext
->TotalTransferredLength;

WdfDmaTransactionInitialize( deviceContext->DmaTransaction,
(PFN_WDF_PROGRAM_DMA) DmaCallback,
WdfDmaDirectionReadFromDevice, // DMA Direction
mdl, deviceContext->CurrentVirtualAddress,
readLength );

}

if (DMA end interrupt)
{
returnValue = WdfDmaTransactionDmaCompleted(deviceContext->DmaTransaction,
&status) ;
currentBytesTransferred = WdfDmaTransactionGetBytesTransferred(deviceContext
->DmaTransaction);

deviceContext->TotalTransferredLength += currentBytesTransferred;

WdfDmaTransactionRelease(deviceContext->DmaTransaction);

}

}

I am getting 4 packets from the driver. but data content are zero. all are invalid.
I have replaced MmGetMdlVirtualAddress with MmGetSystemAddressForMdlSafe as below. still packet content is zero.

Can you please give idea what problem is in this implementation.

Thanks & Regards,
Raphel


NTDEV is sponsored by OSR

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

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


Mark Roddy — NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Actually, nevermind the callback routine, where is the call to
WdfDmaTransactionExecute?

On Jan 8, 2008 8:13 PM, wrote:

> Hi,
>
>
>
> In Dma callback routine, we are doing as follows.
>
>
>
> In PCIe board, we have descriptor SRAM. We have linked list of descriptor
> blocks.
>
> Each descriptor block has source address and destination address. Since
> this is read,
>
> Source address is device memory address and destination address is system
> memory address
>
> (given by SgList in DmaCallback parameter).we are mapping system memory
> and device memory.
>
>
>
>
>
> BOOLEAN DmaCallback(WDFDMATRANSACTION dmaTransaction, WDFDEVICE device,
> PVOID context, WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST SgList)
>
> {
>
> PDEVICE_CONTEXT deviceContext;
>
> NTSTATUS status =
> STATUS_SUCCESS;
>
> PHYSICAL_ADDRESS address;
>
> ULONG length,
> elementCounter, descripterPosition, readValue;
>
>
>
> /* Get a context to the device */
>
> deviceContext = (PDEVICE_CONTEXT) context;
>
>
>
> // Scatter/Gather
>
> address = SgList->Elements[0].Address;
>
> length = SgList->Elements[0].Length;
>
>
>
> // Local Interrupt Input Enable, Local DMA Channel0
> Interrupt Disable
>
> SetConfigRegister(deviceContext,
> ((PCI_CONFIG_SPACE)+0x68), 0x00000800);
>
> ResetConfigRegister(deviceContext,
> ((PCI_CONFIG_SPACE)+0x68), 0x00040000);
>
> deviceContext->DmaLocalAddress = PCI_FIFO_ADDRESS ;
>
>
>
> // Bus Width: 32bit(bit0,1) TA#/READY# Input :
> Enable(bit6) Local Burst: Enable(bit8) Scatter/Gather: Enable(bit9) DMA
> Done Intrrupt: Enable(bit10)
>
> // DMA Channel0 Interrupt Select: routes the DMA Channel0
> interrupts to the PCI Businterrupt(bit17)
>
> // :When EOT is asserted, DMA transfer ends the current
> scatter gather transfer and continues with remaining transfers
>
> SetConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x080),
> 0x000A0743);
>
>
>
> // DMA Ch0 PCI Address
>
> WriteConfigRegister(deviceContext,
> ((PCI_CONFIG_SPACE)+0x084), address.LowPart);
>
> WriteConfigRegister(deviceContext,
> ((PCI_CONFIG_SPACE)+0x088), deviceContext->DmaLocalAddress);
>
> // DMA Ch0 Transfer Byte Count
>
> WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x08C),
> length);
>
> // Descriptor Start Address
>
> WriteConfigRegister(deviceContext,
> ((PCI_CONFIG_SPACE)+0x090), 0x00040008); //
> Direction of transfer(bit3 1:transfer from the Local Bus to the PCI Bus)
>
>
>
> // Descriptor
>
> descripterPosition = 0x00040000;
>
>
>
> // Descriptor
>
> for(elementCounter = 0; elementCounter <
> SgList->NumberOfElements; ++elementCounter) {
>
> address =
> SgList->Elements[elementCounter].Address;
>
> length =
> SgList->Elements[elementCounter].Length;
>
>
>
> //DMA Ch0 PCIB Address
>
> WritePciSp0Register(deviceContext,
> descripterPosition + 0x00, address.LowPart);
>
> WritePciSp0Register(deviceContext,
> descripterPosition + 0x04, deviceContext->DmaLocalAddress);
>
> WritePciSp0Register(deviceContext,
> descripterPosition + 0x08, length);
>
>
>
> if( descripterPosition >= 0x7FFFF){
>
> length = 0;
>
> }
>
>
>
> if(( length <= 0 )||(
> (SgList->NumberOfElements-1) == elementCounter)){
>
> // Set DMA Channel0 Descriptor
> Pointer Register to indicate end of list.
>
> // Bit1 = TRUE( End-of Chain),
> Bit2 = TRUE( Interrupt After Terminal Count) Bit3 = TRUE ( Transfer
> direction - PCI to Local)
>
>
> WritePciSp0Register(deviceContext, descripterPosition + 0x0C, (0x40000 |
> 0x000E));
>
> }
>
> else
>
> {
>
>
> WritePciSp0Register(deviceContext, descripterPosition + 0x0C,
> ((descripterPosition + SIZEOF_DESCRIPTER) | 0x08 ));
>
> }
>
> deviceContext->DmaLocalAddress =
> CalcNextStartAddress(deviceContext, length);
>
> descripterPosition += SIZEOF_DESCRIPTER;
>
> } // end- for loop
>
>
>
> // DMA$BE>Aw3+;O(B
>
> WriteConfigRegister ( deviceContext,
> ((PCI_CONFIG_SPACE)+0xA8), 0x0001); // DMA Channel0 Enable
>
> WriteConfigRegister ( deviceContext,
> ((PCI_CONFIG_SPACE)+0xA8), 0x0003); // DMA Channel0 Start
>
> return TRUE;
>
> }
>
>
>
>
>
> Thanks & Regards,
>
> Raphel
>
>
>
>
> ------------------------------
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Mark Roddy
> Sent: Wednesday, January 09, 2008 12:01 AM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] MmGetMdlVirtualAddress &
> WdfDmaTransactionInitialize
>
>
>
> What does your DmaCallback routine do?
>
> On Jan 8, 2008 7:02 AM, wrote:
>
> Hi,
>
> we are developing PCI express driver for VISTA OS and driver uses scatter
> gather DMA.
> our aim is to read the data (1MB) from the device. Device splits this 1MB
> data in 4 packets. Device generate DMA demand interrupt for first packet
> and driver prepares the DMA for the transfer. Then device generate DMA End
> interrupt and driver completes the DMA. DMA demand interrupt & DMA End
> interrupt sequence is followed for each packets.
>
> Implementation are as follows.
>
> The following DPC is queued from ISR on DMA demand and DMA end interrupt.
>
> In DPC routine, driver process as follows.
>
> ReadDPC
> {
>
> status = WdfIoQueueRetrieveNextRequest(deviceContext->ReadQueue,
> &request);
>
> if (DMA demand interrupt)
> {
> WdfRequestRetrieveOutputWdmMdl( request, &mdl);
>
> deviceContext->CurrentVirtualAddress = MmGetMdlVirtualAddress( mdl );
>
> (ULONG *)deviceContext->CurrentVirtualAddress += deviceContext
>
> ->TotalTransferredLength;
>
> WdfDmaTransactionInitialize( deviceContext->DmaTransaction,
> (PFN_WDF_PROGRAM_DMA) DmaCallback,
> WdfDmaDirectionReadFromDevice, // DMA Direction
> mdl,
> deviceContext->CurrentVirtualAddress,
> readLength );
>
> }
>
> if (DMA end interrupt)
> {
> returnValue =
> WdfDmaTransactionDmaCompleted(deviceContext->DmaTransaction,
> &status) ;
> currentBytesTransferred =
> WdfDmaTransactionGetBytesTransferred(deviceContext
> ->DmaTransaction);
>
> deviceContext->TotalTransferredLength += currentBytesTransferred;
>
> WdfDmaTransactionRelease(deviceContext->DmaTransaction);
>
> }
>
> }
>
> I am getting 4 packets from the driver. but data content are zero. all are
> invalid.
> I have replaced MmGetMdlVirtualAddress with MmGetSystemAddressForMdlSafe
> as below. still packet content is zero.
>
> Can you please give idea what problem is in this implementation.
>
>
> Thanks & Regards,
> Raphel
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>
>
>
> –
> Mark Roddy — NTDEV is sponsored by OSR For our schedule of WDF, WDM,
> debugging and other seminars visit: http://www.osr.com/seminars To
> unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


Mark Roddy

Hi,

WdfDmaTransactionExecute is called after WdfDmaTransactionInitialize is called.

Thanks & Regards,

Raphel


From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Mark Roddy
Sent: Wednesday, January 09, 2008 1:02 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] MmGetMdlVirtualAddress & WdfDmaTransactionInitialize

Actually, nevermind the callback routine, where is the call to WdfDmaTransactionExecute?

On Jan 8, 2008 8:13 PM, wrote:

Hi,

In Dma callback routine, we are doing as follows.

In PCIe board, we have descriptor SRAM. We have linked list of descriptor blocks.

Each descriptor block has source address and destination address. Since this is read,

Source address is device memory address and destination address is system memory address

(given by SgList in DmaCallback parameter).we are mapping system memory and device memory.

BOOLEAN DmaCallback(WDFDMATRANSACTION dmaTransaction, WDFDEVICE device, PVOID context, WDF_DMA_DIRECTION direction, PSCATTER_GATHER_LIST SgList)

{

PDEVICE_CONTEXT deviceContext;

NTSTATUS status = STATUS_SUCCESS;

PHYSICAL_ADDRESS address;

ULONG length, elementCounter, descripterPosition, readValue;

/* Get a context to the device */

deviceContext = (PDEVICE_CONTEXT) context;

// Scatter/Gather

address = SgList->Elements[0].Address;

length = SgList->Elements[0].Length;

// Local Interrupt Input Enable, Local DMA Channel0 Interrupt Disable

SetConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x68), 0x00000800);

ResetConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x68), 0x00040000);

deviceContext->DmaLocalAddress = PCI_FIFO_ADDRESS ;

// Bus Width: 32bit(bit0,1) TA#/READY# Input : Enable(bit6) Local Burst: Enable(bit8) Scatter/Gather: Enable(bit9) DMA Done Intrrupt: Enable(bit10)

// DMA Channel0 Interrupt Select: routes the DMA Channel0 interrupts to the PCI Businterrupt(bit17)

// :When EOT is asserted, DMA transfer ends the current scatter gather transfer and continues with remaining transfers

SetConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x080), 0x000A0743);

// DMA Ch0 PCI Address

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x084), address.LowPart );

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x088), deviceContext->DmaLocalAddress);

// DMA Ch0 Transfer Byte Count

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x08C), length);

// Descriptor Start Address

WriteConfigRegister(deviceContext, ((PCI_CONFIG_SPACE)+0x090), 0x00040008); // Direction of transfer(bit3 1:transfer from the Local Bus to the PCI Bus)

// Descriptor

descripterPosition = 0x00040000;

// Descriptor

for(elementCounter = 0; elementCounter < SgList->NumberOfElements; ++elementCounter) {

address = SgList->Elements[elementCounter].Address;

length = SgList->Elements[elementCounter].Length;

//DMA Ch0 PCIB Address

WritePciSp0Register(deviceContext, descripterPosition + 0x00, address.LowPart );

WritePciSp0Register(deviceContext, descripterPosition + 0x04, deviceContext->DmaLocalAddress);

WritePciSp0Register(deviceContext, descripterPosition + 0x08, length);

if( descripterPosition >= 0x7FFFF){

length = 0;

}

if(( length <= 0 )||( (SgList->NumberOfElements-1) == elementCounter)){

// Set DMA Channel0 Descriptor Pointer Register to indicate end of list.

// Bit1 = TRUE( End-of Chain), Bit2 = TRUE( Interrupt After Terminal Count) Bit3 = TRUE ( Transfer direction - PCI to Local)

WritePciSp0Register(deviceContext, descripterPosition + 0x0C, (0x40000 | 0x000E));

}

else

{

WritePciSp0Register(deviceContext, descripterPosition + 0x0C, ((descripterPosition + SIZEOF_DESCRIPTER) | 0x08 ));

}

deviceContext->DmaLocalAddress = CalcNextStartAddress(deviceContext, length);

descripterPosition += SIZEOF_DESCRIPTER;

} // end- for loop

// DMA $BE>Aw3+;O(J

WriteConfigRegister ( deviceContext, ((PCI_CONFIG_SPACE)+0xA8), 0x0001); // DMA Channel0 Enable

WriteConfigRegister ( deviceContext, ((PCI_CONFIG_SPACE)+0xA8), 0x0003); // DMA Channel0 Start

return TRUE;

}

Thanks & Regards,

Raphel

________________________________

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Mark Roddy
Sent: Wednesday, January 09, 2008 12:01 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] MmGetMdlVirtualAddress & WdfDmaTransactionInitialize

What does your DmaCallback routine do?

On Jan 8, 2008 7:02 AM, wrote:

Hi,

we are developing PCI express driver for VISTA OS and driver uses scatter gather DMA.
our aim is to read the data (1MB) from the device. Device splits this 1MB data in 4 packets. Device generate DMA demand interrupt for first packet and driver prepares the DMA for the transfer. Then device generate DMA End interrupt and driver completes the DMA. DMA demand interrupt & DMA End interrupt sequence is followed for each packets.

Implementation are as follows.

The following DPC is queued from ISR on DMA demand and DMA end interrupt.

In DPC routine, driver process as follows.

ReadDPC
{

status = WdfIoQueueRetrieveNextRequest(deviceContext->ReadQueue, &request);

if (DMA demand interrupt)
{
WdfRequestRetrieveOutputWdmMdl( request, &mdl);

deviceContext->CurrentVirtualAddress = MmGetMdlVirtualAddress( mdl );

(ULONG *)deviceContext->CurrentVirtualAddress += deviceContext
->TotalTransferredLength;

WdfDmaTransactionInitialize( deviceContext->DmaTransaction,
(PFN_WDF_PROGRAM_DMA) DmaCallback,
WdfDmaDirectionReadFromDevice, // DMA Direction
mdl, deviceContext->CurrentVirtualAddress,
readLength );

}

if (DMA end interrupt)
{
returnValue = WdfDmaTransactionDmaCompleted(deviceContext->DmaTransaction,
&status) ;
currentBytesTransferred = WdfDmaTransactionGetBytesTransferred(deviceContext
->DmaTransaction);

deviceContext->TotalTransferredLength += currentBytesTransferred;

WdfDmaTransactionRelease(deviceContext->DmaTransaction);

}

}

I am getting 4 packets from the driver. but data content are zero. all are invalid.
I have replaced MmGetMdlVirtualAddress with MmGetSystemAddressForMdlSafe as below. still packet content is zero.

Can you please give idea what problem is in this implementation.

Thanks & Regards,
Raphel


NTDEV is sponsored by OSR

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

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


Mark Roddy — NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer



NTDEV is sponsored by OSR

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

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


Mark Roddy — NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer