DMA Problem

Hello,

I am facing a problem while writing a WDM DMA driver for a PCI chipset PLX 9080. I have to use the DMA chaining mode of PLX 9080. The descripor list for DMA chaining has to be on the PCI host.

I have carried out the following steps so far.
(1) In the start device got access to the DMA Adapter object by using "IoGetDmaAdapter"
(2) Then used the Adpater object pointer to allocate 33 buffers using "AllocateCommonBuffer". The physical and the virtual addresses of these buffers are stored. All the 33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining transfer are stored in these allocated buffers.
(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO (METHOD_OUT_DIRECT), I get the Mdl for the output buffer for the DMA transfer.
(4) The following set of operations are used to get the physical addresses of the buffer referred to by the Mdl.
(a) Mdl = Irp->MdlAddress
(b) MmProbeAndLockPages()
(c) MmGetMdlByteCount ()
(d) MmGetMdlVirtualAddress ()
(e) MmGetMdlByteOffset()
(5) Determine the number of map registers required by using ADDRESS_AND_SIZE_TO_SPAN_PAGES
(6) Then determine howmany times the GetScatterGatherList needs to be called by dividing the above result with the no of map registers allocated.
(7) If a scatter gather list alreday exists, clear it by calling PutScatterGatherList.
(8) Next Call ScatterGatherList with an adapter control routine.
(9) Mark the IRP Pending

Adapter Control routine

(10) Uses the elements of the scatter gather lsit to fill in the descriptors allocated using the AllocatecommonBuffer.
(11) Once the descriptors are filled with the physical addresses obtained, we next assign the DMA channel 0 descritor register wuth the address of the first PCI descriptor by giving the physicall address of the first buffer obtained via AllocateCommonBuffer API.
(3) Finally the DMA registers are filled to reflect chaining mode and the transferis started.
(4) the device physical address that I gave is the address at which the device has mapped the memory. This address is not the address that I see in Windows in the resources tab for the driver.
(5) I complete the IRP in the DPC.

Observation:

(1) I tried for a small size of 0x3c bytes and found the device to freeze.
(2) I suspect address given for DMA transfer. Are the PCI and device physical addresses provided correct?
(3) To get the device back to normal operation, I have to restart the system.
(4) I get no interrupt so IRP remains pending.

Where does the problem lie? Can u guide me?

Regards,
Purvi

Hello,

One more input...

In the resources tab for the driver of the device, windows does not show any DMA resouce type. I hope this is OK as it is to be seen only for ISA DMA devices and this is a PCI plx 9080 chipset. Is this understanding OK?

Regards,
Purvi
----- Original Message -----
From: Purvi Thakkar
To: xxxxx@lists.osr.com
Sent: Wednesday, October 20, 2004 5:45 PM
Subject: DMA Problem

Hello,

I am facing a problem while writing a WDM DMA driver for a PCI chipset PLX 9080. I have to use the DMA chaining mode of PLX 9080. The descripor list for DMA chaining has to be on the PCI host.

I have carried out the following steps so far.
(1) In the start device got access to the DMA Adapter object by using "IoGetDmaAdapter"
(2) Then used the Adpater object pointer to allocate 33 buffers using "AllocateCommonBuffer". The physical and the virtual addresses of these buffers are stored. All the 33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining transfer are stored in these allocated buffers.
(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO (METHOD_OUT_DIRECT), I get the Mdl for the output buffer for the DMA transfer.
(4) The following set of operations are used to get the physical addresses of the buffer referred to by the Mdl.
(a) Mdl = Irp->MdlAddress
(b) MmProbeAndLockPages()
(c) MmGetMdlByteCount ()
(d) MmGetMdlVirtualAddress ()
(e) MmGetMdlByteOffset()
(5) Determine the number of map registers required by using ADDRESS_AND_SIZE_TO_SPAN_PAGES
(6) Then determine howmany times the GetScatterGatherList needs to be called by dividing the above result with the no of map registers allocated.
(7) If a scatter gather list alreday exists, clear it by calling PutScatterGatherList.
(8) Next Call ScatterGatherList with an adapter control routine.
(9) Mark the IRP Pending

Adapter Control routine

(10) Uses the elements of the scatter gather lsit to fill in the descriptors allocated using the AllocatecommonBuffer.
(11) Once the descriptors are filled with the physical addresses obtained, we next assign the DMA channel 0 descritor register wuth the address of the first PCI descriptor by giving the physicall address of the first buffer obtained via AllocateCommonBuffer API.
(3) Finally the DMA registers are filled to reflect chaining mode and the transferis started.
(4) the device physical address that I gave is the address at which the device has mapped the memory. This address is not the address that I see in Windows in the resources tab for the driver.
(5) I complete the IRP in the DPC.

Observation:

(1) I tried for a small size of 0x3c bytes and found the device to freeze.
(2) I suspect address given for DMA transfer. Are the PCI and device physical addresses provided correct?
(3) To get the device back to normal operation, I have to restart the system.
(4) I get no interrupt so IRP remains pending.

Where does the problem lie? Can u guide me?

Regards,
Purvi

Yes, I think that’s correct. DMA resources are only used by ISA cards[1].

PCI definitely expects the hardware to know how to read/write memory
through it’s own bus, rather than relying on an external DMA circuit, so
there should be no DMA channel used by the PCI express.

[1] It’s perfectly possible to build intelligent “bus mastering” devices
for the ISA bus too. The DMA system is really there for use with quite old
devices that do not have the logic to read/write memory directly, but would
output data to be transferred by the DMA unit. This is an ANCIENT design,
and most ISA Ethernet devices for instance, will do direct memory accesses
from the ISA board itself.


Mats

xxxxx@lists.osr.com wrote on 10/20/2004 01:47:12 PM:

Hello,

One more input…

In the resources tab for the driver of the device, windows does not
show any DMA resouce type. I hope this is OK as it is to be seen
only for ISA DMA devices and this is a PCI plx 9080 chipset. Is this
understanding OK?

Regards,
Purvi
----- Original Message -----
From: Purvi Thakkar
To: xxxxx@lists.osr.com
Sent: Wednesday, October 20, 2004 5:45 PM
Subject: DMA Problem

Hello,

I am facing a problem while writing a WDM DMA driver for a PCI
chipset PLX 9080. I have to use the DMA chaining mode of PLX 9080.
The descripor list for DMA chaining has to be on the PCI host.

I have carried out the following steps so far.
(1) In the start device got access to the DMA Adapter object by
using “IoGetDmaAdapter”
(2) Then used the Adpater object pointer to allocate 33 buffers
using “AllocateCommonBuffer”. The physical and the virtual addresses
of these buffers are stored. All the 33 buffers are of PAGE_SIZE.
Next, the PCI descriptors for the DMA chaining transfer are stored
in these allocated buffers.
(3) When a IOCTL write is fired to the DMA device object with
DIRECT_IO (METHOD_OUT_DIRECT), I get the Mdl for the output buffer
for the DMA transfer.
(4) The following set of operations are used to get the physical
addresses of the buffer referred to by the Mdl.
(a) Mdl = Irp->MdlAddress
(b) MmProbeAndLockPages()
(c) MmGetMdlByteCount ()
(d) MmGetMdlVirtualAddress ()
(e) MmGetMdlByteOffset()
(5) Determine the number of map registers required by using
ADDRESS_AND_SIZE_TO_SPAN_PAGES
(6) Then determine howmany times the GetScatterGatherList needs to
be called by dividing the above result with the no of map registers
allocated.
(7) If a scatter gather list alreday exists, clear it by calling
PutScatterGatherList.
(8) Next Call ScatterGatherList with an adapter control routine.
(9) Mark the IRP Pending

Adapter Control routine

(10) Uses the elements of the scatter gather lsit to fill in the
descriptors allocated using the AllocatecommonBuffer.
(11) Once the descriptors are filled with the physical addresses
obtained, we next assign the DMA channel 0 descritor register wuth
the address of the first PCI descriptor by giving the physicall
address of the first buffer obtained via AllocateCommonBuffer API.
(3) Finally the DMA registers are filled to reflect chaining mode
and the transferis started.
(4) the device physical address that I gave is the address at which
the device has mapped the memory. This address is not the address
that I see in Windows in the resources tab for the driver.
(5) I complete the IRP in the DPC.

Observation:

(1) I tried for a small size of 0x3c bytes and found the device to
freeze.
(2) I suspect address given for DMA transfer. Are the PCI and device
physical addresses provided correct?
(3) To get the device back to normal operation, I have to restart the
system.
(4) I get no interrupt so IRP remains pending.

Where does the problem lie? Can u guide me?

Regards,
Purvi


Questions? First check the Kernel Driver FAQ at http://www.
osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com
ForwardSourceID:NT00005BB2

Well I do not known PLX9080 bridge.
Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
(read in the datasheet) that DMA descriptor MUST be aligned on a 16 byte
address.
And AllocateCommonBuffer does not returns aligned data.
So I modify the allocation of DMA descriptors to something like this:

//
// Requesting one extra entry so that we can align on 16 byte boundary
//
pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);

//
// AllocateCommonBuffer allocates memory and maps it so that it is simultaneously

// accessible from both the processor and a device for DMA operations.
// AllocateCommonBuffer returns the base virtual address of the allocated
range.
// If the buffer cannot be allocated, it returns NULL.
//
pDmaChannel->pvPlxSGListUnaligned = (*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,

KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned virtual
= 0x%X physical = 0x%X\n",
pDmaChannel->pvPlxSGListUnaligned, pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
));

//
// Align on 16 byte boundary as required by PLX device
//
pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor> (((ULONG)pDmaChannel->pvPlxSGListUnaligned
+ 0xF) & 0xFFFFFFF0);
pDmaChannel->ulPlxSGListPhysical = ((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
+ 0xF) & 0xFFFFFFF0;

KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned virtual
= 0x%X physical = 0x%X\n",
(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));

Hope this can help,
PaoloC

>– Messaggio originale –
>From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 17:45:17 +0530
>Reply-To: “Windows System Software Devs Interest List”
>
>
>Hello,
>
>I am facing a problem while writing a WDM DMA driver for a PCI chipset
PLX
>9080. I have to use the DMA chaining mode of PLX 9080. The descripor list
>for DMA chaining has to be on the PCI host.
>
>I have carried out the following steps so far.
>(1) In the start device got access to the DMA Adapter object by using “IoGetDmaAdapter”
>(2) Then used the Adpater object pointer to allocate 33 buffers using “AllocateCommonBuffer”.
>The physical and the virtual addresses of these buffers are stored. All
the
>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining
>transfer are stored in these allocated buffers.
>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
(METHOD_OUT_DIRECT),
>I get the Mdl for the output buffer for the DMA transfer.
>(4) The following set of operations are used to get the physical addresses
>of the buffer referred to by the Mdl.
> (a) Mdl = Irp->MdlAddress
> (b) MmProbeAndLockPages()
> (c) MmGetMdlByteCount ()
> (d) MmGetMdlVirtualAddress ()
> (e) MmGetMdlByteOffset()
>(5) Determine the number of map registers required by using ADDRESS_AND_SIZE_TO_SPAN_PAGES
>(6) Then determine howmany times the GetScatterGatherList needs to be called
>by dividing the above result with the no of map registers allocated.
>(7) If a scatter gather list alreday exists, clear it by calling PutScatterGatherList.
>(8) Next Call ScatterGatherList with an adapter control routine.
>(9) Mark the IRP Pending
>
>Adapter Control routine
>----------------------------------
>(10) Uses the elements of the scatter gather lsit to fill in the descriptors
>allocated using the AllocatecommonBuffer.
>(11) Once the descriptors are filled with the physical addresses obtained,
>we next assign the DMA channel 0 descritor register wuth the address of
the
>first PCI descriptor by giving the physicall address of the first buffer
>obtained via AllocateCommonBuffer API.
>(3) Finally the DMA registers are filled to reflect chaining mode and the
>transferis started.
>(4) the device physical address that I gave is the address at which the
device
>has mapped the memory. This address is not the address that I see in Windows
>in the resources tab for the driver.
>(5) I complete the IRP in the DPC.
>
>Observation:
>----------------------
>(1) I tried for a small size of 0x3c bytes and found the device to freeze.
>(2) I suspect address given for DMA transfer. Are the PCI and device physical
>addresses provided correct?
>(3) To get the device back to normal operation, I have to restart the system.
>(4) I get no interrupt so IRP remains pending.
>
>Where does the problem lie? Can u guide me?
>
>Regards,
>Purvi
>
>
>—
>Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

Hello PaoloC,

This was indeed a good piece of information. But I have taken care of this
by calling AllocateCommonBuffer 33 times each time requesting a page of
memory i.e. 4096 bytes thereby taking care of the alignment issue. I even
checked the physical and virtual addresses obtained and they are also
aligned to a 16 byte boundary. This 16 byte boundary alignment is also a
requirement for PLX 9080.

I am not sure of the pci and local addresses that are entered into the
descriptor. Could u throw some light on it. They are physical addresses but
with respect to PCI host space, local address space or something else. What
did u do when programing for DMA chaining.

Thanks and Best Regards,
Purvi
----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Wednesday, October 20, 2004 4:33 PM
Subject: RE: [ntdev] DMA Problem

Well I do not known PLX9080 bridge.
Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
(read in the datasheet) that DMA descriptor MUST be aligned on a 16 byte
address.
And AllocateCommonBuffer does not returns aligned data.
So I modify the allocation of DMA descriptors to something like this:

//
// Requesting one extra entry so that we can align on 16 byte boundary
//
pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);

//
// AllocateCommonBuffer allocates memory and maps it so that it is
simultaneously

// accessible from both the processor and a device for DMA operations.
// AllocateCommonBuffer returns the base virtual address of the allocated
range.
// If the buffer cannot be allocated, it returns NULL.
//
pDmaChannel->pvPlxSGListUnaligned =
(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,



KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned virtual
= 0x%X physical = 0x%X\n",
pDmaChannel->pvPlxSGListUnaligned,
pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
));

//
// Align on 16 byte boundary as required by PLX device
//
pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
(((ULONG)pDmaChannel->pvPlxSGListUnaligned
+ 0xF) & 0xFFFFFFF0);
pDmaChannel->ulPlxSGListPhysical =
((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
+ 0xF) & 0xFFFFFFF0;

KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned virtual
= 0x%X physical = 0x%X\n",
(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));

Hope this can help,
PaoloC

>– Messaggio originale –
>From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 17:45:17 +0530
>Reply-To: “Windows System Software Devs Interest List”

>
>
>Hello,
>
>I am facing a problem while writing a WDM DMA driver for a PCI chipset
PLX
>9080. I have to use the DMA chaining mode of PLX 9080. The descripor list
>for DMA chaining has to be on the PCI host.
>
>I have carried out the following steps so far.
>(1) In the start device got access to the DMA Adapter object by using
“IoGetDmaAdapter”
>(2) Then used the Adpater object pointer to allocate 33 buffers using
“AllocateCommonBuffer”.
>The physical and the virtual addresses of these buffers are stored. All
the
>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining
>transfer are stored in these allocated buffers.
>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
(METHOD_OUT_DIRECT),
>I get the Mdl for the output buffer for the DMA transfer.
>(4) The following set of operations are used to get the physical addresses
>of the buffer referred to by the Mdl.
> (a) Mdl = Irp->MdlAddress
> (b) MmProbeAndLockPages()
> (c) MmGetMdlByteCount ()
> (d) MmGetMdlVirtualAddress ()
> (e) MmGetMdlByteOffset()
>(5) Determine the number of map registers required by using
ADDRESS_AND_SIZE_TO_SPAN_PAGES
>(6) Then determine howmany times the GetScatterGatherList needs to be
called
>by dividing the above result with the no of map registers allocated.
>(7) If a scatter gather list alreday exists, clear it by calling
PutScatterGatherList.
>(8) Next Call ScatterGatherList with an adapter control routine.
>(9) Mark the IRP Pending
>
>Adapter Control routine
>----------------------------------
>(10) Uses the elements of the scatter gather lsit to fill in the
descriptors
>allocated using the AllocatecommonBuffer.
>(11) Once the descriptors are filled with the physical addresses obtained,
>we next assign the DMA channel 0 descritor register wuth the address of
the
>first PCI descriptor by giving the physicall address of the first buffer
>obtained via AllocateCommonBuffer API.
>(3) Finally the DMA registers are filled to reflect chaining mode and the
>transferis started.
>(4) the device physical address that I gave is the address at which the
device
>has mapped the memory. This address is not the address that I see in
Windows
>in the resources tab for the driver.
>(5) I complete the IRP in the DPC.
>
>Observation:
>----------------------
>(1) I tried for a small size of 0x3c bytes and found the device to freeze.
>(2) I suspect address given for DMA transfer. Are the PCI and device
physical
>addresses provided correct?
>(3) To get the device back to normal operation, I have to restart the
system.
>(4) I get no interrupt so IRP remains pending.
>
>Where does the problem lie? Can u guide me?
>
>Regards,
>Purvi
>
>
>—
>Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

Hi Purvi,
I use both the virtual & physical addresses returned by AllocateCommonBuffer
after I have rounded those addresses to the nearest 16 byte align.
Virtual address is used to access the DMA descriptor list and physical address
is used to write the link between DMA descriptor entries, which will be
used by PLX device.
If you assume that my whole descriptor list is allocated in a single buffer
returned by AllocateCommonBuffer you can understand the following piece
of code I am using to build the descriptor list:

//

// Virtual address to traverse the descriptor list

//

PPLX_DMA_DESCRIPTOR pPlxDescr = pDmaChannel->pPlxSGList;

//

// Physical address of next DMA descriptor used by PLX to traverse the chain

//

ULONG ulPlxNextDescr = pDmaChannel->ulPlxSGListPhysical + sizeof( PLX_DMA_DESCRIPTOR
);

//

// Building the descriptor list

//

for (ULONG k = 0;

k < n;

i++, k++, pPlxDescr++, ulPlxNextDescr += sizeof( PLX_DMA_DESCRIPTOR ))

{

pPlxDescr->ulPciAddress = sglist->Elements[i].Address.LowPart;
pPlxDescr->ulLocalAddress = pDmaChannel->ulLocalAddress;
pPlxDescr->ulCount = sglist->Elements[i].Length;
pPlxDescr->bitPciAddressSpace = 1;

pPlxDescr->bitLocalToPciBus = pDmaChannel->bIsWrite ? 0 : 1;
pPlxDescr->bitEndOFChain = 0;
pPlxDescr->bitInterruptAfterTC = 0;

pPlxDescr->bmNextDescrAddress = (ulPlxNextDescr >> 4);

//

// Update the number of bytes transferred so far

//

pDmaChannel->nbytes += sglist->Elements[i].Length;

}

//

// Special processing for the last entry: end of list flag + generate interrupt

  • no next
    //

pPlxDescr–;

pPlxDescr->bitEndOFChain = 1;

pPlxDescr->bitInterruptAfterTC = 1;

Regards,
PaoloC

– Messaggio originale –
From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: Re: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 21:06:05 +0530
>Reply-To: “Windows System Software Devs Interest List”
>
>
>Hello PaoloC,
>
>This was indeed a good piece of information. But I have taken care of this
>by calling AllocateCommonBuffer 33 times each time requesting a page of
>memory i.e. 4096 bytes thereby taking care of the alignment issue. I even
>checked the physical and virtual addresses obtained and they are also
>aligned to a 16 byte boundary. This 16 byte boundary alignment is also
a
>requirement for PLX 9080.
>
>I am not sure of the pci and local addresses that are entered into the
>descriptor. Could u throw some light on it. They are physical addresses
but
>with respect to PCI host space, local address space or something else.
What
>did u do when programing for DMA chaining.
>
>Thanks and Best Regards,
>Purvi
>----- Original Message -----
>From:
>To: “Windows System Software Devs Interest List”
>Sent: Wednesday, October 20, 2004 4:33 PM
>Subject: RE: [ntdev] DMA Problem
>
>
>Well I do not known PLX9080 bridge.
>Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
>(read in the datasheet) that DMA descriptor MUST be aligned on a 16 byte
>address.
>And AllocateCommonBuffer does not returns aligned data.
>So I modify the allocation of DMA descriptors to something like this:
>
>//
>// Requesting one extra entry so that we can align on 16 byte boundary
>//
>pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);
>
>//
>// AllocateCommonBuffer allocates memory and maps it so that it is
>simultaneously
>
>// accessible from both the processor and a device for DMA operations.
>// AllocateCommonBuffer returns the base virtual address of the allocated
>range.
>// If the buffer cannot be allocated, it returns NULL.
>//
>pDmaChannel->pvPlxSGListUnaligned =
>(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
>(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,
>…
>…
>
>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned virtual
>= 0x%X physical = 0x%X\n",
>pDmaChannel->pvPlxSGListUnaligned,
>pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>));
>
>//
>// Align on 16 byte boundary as required by PLX device
>//
>pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
>(((ULONG)pDmaChannel->pvPlxSGListUnaligned
>+ 0xF) & 0xFFFFFFF0);
>pDmaChannel->ulPlxSGListPhysical =
>((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>+ 0xF) & 0xFFFFFFF0;
>
>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned virtual
>= 0x%X physical = 0x%X\n",
>(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));
>
>
>Hope this can help,
>PaoloC
>
>
>>– Messaggio originale –
>>From: “Purvi Thakkar”
>>To: “Windows System Software Devs Interest List”
>>Subject: [ntdev] DMA Problem
>>Date: Wed, 20 Oct 2004 17:45:17 +0530
>>Reply-To: “Windows System Software Devs Interest List”
>
>>
>>
>>Hello,
>>
>>I am facing a problem while writing a WDM DMA driver for a PCI chipset
>PLX
>>9080. I have to use the DMA chaining mode of PLX 9080. The descripor
list
>>for DMA chaining has to be on the PCI host.
>>
>>I have carried out the following steps so far.
>>(1) In the start device got access to the DMA Adapter object by using
>“IoGetDmaAdapter”
>>(2) Then used the Adpater object pointer to allocate 33 buffers using
>“AllocateCommonBuffer”.
>>The physical and the virtual addresses of these buffers are stored. All
>the
>>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining
>>transfer are stored in these allocated buffers.
>>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
>(METHOD_OUT_DIRECT),
>>I get the Mdl for the output buffer for the DMA transfer.
>>(4) The following set of operations are used to get the physical addresses
>>of the buffer referred to by the Mdl.
>> (a) Mdl = Irp->MdlAddress
>> (b) MmProbeAndLockPages()
>> (c) MmGetMdlByteCount ()
>> (d) MmGetMdlVirtualAddress ()
>> (e) MmGetMdlByteOffset()
>>(5) Determine the number of map registers required by using
>ADDRESS_AND_SIZE_TO_SPAN_PAGES
>>(6) Then determine howmany times the GetScatterGatherList needs to be
>called
>>by dividing the above result with the no of map registers allocated.
>>(7) If a scatter gather list alreday exists, clear it by calling
>PutScatterGatherList.
>>(8) Next Call ScatterGatherList with an adapter control routine.
>>(9) Mark the IRP Pending
>>
>>Adapter Control routine
>>----------------------------------
>>(10) Uses the elements of the scatter gather lsit to fill in the
>descriptors
>>allocated using the AllocatecommonBuffer.
>>(11) Once the descriptors are filled with the physical addresses obtained,
>>we next assign the DMA channel 0 descritor register wuth the address of
>the
>>first PCI descriptor by giving the physicall address of the first buffer
>>obtained via AllocateCommonBuffer API.
>>(3) Finally the DMA registers are filled to reflect chaining mode and
the
>>transferis started.
>>(4) the device physical address that I gave is the address at which the
>device
>>has mapped the memory. This address is not the address that I see in
>Windows
>>in the resources tab for the driver.
>>(5) I complete the IRP in the DPC.
>>
>>Observation:
>>----------------------
>>(1) I tried for a small size of 0x3c bytes and found the device to freeze.
>>(2) I suspect address given for DMA transfer. Are the PCI and device
>physical
>>addresses provided correct?
>>(3) To get the device back to normal operation, I have to restart the
>system.
>>(4) I get no interrupt so IRP remains pending.
>>
>>Where does the problem lie? Can u guide me?
>>
>>Regards,
>>Purvi
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>‘’
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@tin.it
>To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

Hi! PaoloC,

I have done the same thing but I am not sure of the local address value.

What value did u enter for " pDmaChannel->ulLocalAddress" and from where did
u get this value.

Thanks and Best Regards,
Purvi
----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Wednesday, October 20, 2004 6:09 PM
Subject: Re: [ntdev] DMA Problem

Hi Purvi,
I use both the virtual & physical addresses returned by AllocateCommonBuffer
after I have rounded those addresses to the nearest 16 byte align.
Virtual address is used to access the DMA descriptor list and physical
address
is used to write the link between DMA descriptor entries, which will be
used by PLX device.
If you assume that my whole descriptor list is allocated in a single buffer
returned by AllocateCommonBuffer you can understand the following piece
of code I am using to build the descriptor list:

//

// Virtual address to traverse the descriptor list

//

PPLX_DMA_DESCRIPTOR pPlxDescr = pDmaChannel->pPlxSGList;

//

// Physical address of next DMA descriptor used by PLX to traverse the chain

//

ULONG ulPlxNextDescr = pDmaChannel->ulPlxSGListPhysical + sizeof(
PLX_DMA_DESCRIPTOR
);

//

// Building the descriptor list

//

for (ULONG k = 0;

k < n;

i++, k++, pPlxDescr++, ulPlxNextDescr += sizeof( PLX_DMA_DESCRIPTOR ))

{

pPlxDescr->ulPciAddress = sglist->Elements[i].Address.LowPart;
pPlxDescr->ulLocalAddress = pDmaChannel->ulLocalAddress;
pPlxDescr->ulCount = sglist->Elements[i].Length;
pPlxDescr->bitPciAddressSpace = 1;

pPlxDescr->bitLocalToPciBus = pDmaChannel->bIsWrite ? 0 : 1;
pPlxDescr->bitEndOFChain = 0;
pPlxDescr->bitInterruptAfterTC = 0;

pPlxDescr->bmNextDescrAddress = (ulPlxNextDescr >> 4);

//

// Update the number of bytes transferred so far

//

pDmaChannel->nbytes += sglist->Elements[i].Length;

}

//

// Special processing for the last entry: end of list flag + generate
interrupt
+ no next
//

pPlxDescr–;

pPlxDescr->bitEndOFChain = 1;

pPlxDescr->bitInterruptAfterTC = 1;

Regards,
PaoloC

>– Messaggio originale –
>From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: Re: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 21:06:05 +0530
>Reply-To: “Windows System Software Devs Interest List”

>
>
>Hello PaoloC,
>
>This was indeed a good piece of information. But I have taken care of this
>by calling AllocateCommonBuffer 33 times each time requesting a page of
>memory i.e. 4096 bytes thereby taking care of the alignment issue. I even
>checked the physical and virtual addresses obtained and they are also
>aligned to a 16 byte boundary. This 16 byte boundary alignment is also
a
>requirement for PLX 9080.
>
>I am not sure of the pci and local addresses that are entered into the
>descriptor. Could u throw some light on it. They are physical addresses
but
>with respect to PCI host space, local address space or something else.
What
>did u do when programing for DMA chaining.
>
>Thanks and Best Regards,
>Purvi
>----- Original Message -----
>From:
>To: “Windows System Software Devs Interest List”
>Sent: Wednesday, October 20, 2004 4:33 PM
>Subject: RE: [ntdev] DMA Problem
>
>
>Well I do not known PLX9080 bridge.
>Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
>(read in the datasheet) that DMA descriptor MUST be aligned on a 16 byte
>address.
>And AllocateCommonBuffer does not returns aligned data.
>So I modify the allocation of DMA descriptors to something like this:
>
>//
>// Requesting one extra entry so that we can align on 16 byte boundary
>//
>pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);
>
>//
>// AllocateCommonBuffer allocates memory and maps it so that it is
>simultaneously
>
>// accessible from both the processor and a device for DMA operations.
>// AllocateCommonBuffer returns the base virtual address of the allocated
>range.
>// If the buffer cannot be allocated, it returns NULL.
>//
>pDmaChannel->pvPlxSGListUnaligned =
>(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
>(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,
>…
>…
>
>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned virtual
>= 0x%X physical = 0x%X\n",
>pDmaChannel->pvPlxSGListUnaligned,
>pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>));
>
>//
>// Align on 16 byte boundary as required by PLX device
>//
>pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
>(((ULONG)pDmaChannel->pvPlxSGListUnaligned
>+ 0xF) & 0xFFFFFFF0);
>pDmaChannel->ulPlxSGListPhysical =
>((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>+ 0xF) & 0xFFFFFFF0;
>
>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned virtual
>= 0x%X physical = 0x%X\n",
>(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));
>
>
>Hope this can help,
>PaoloC
>
>
>>– Messaggio originale –
>>From: “Purvi Thakkar”
>>To: “Windows System Software Devs Interest List”
>>Subject: [ntdev] DMA Problem
>>Date: Wed, 20 Oct 2004 17:45:17 +0530
>>Reply-To: “Windows System Software Devs Interest List”
>
>>
>>
>>Hello,
>>
>>I am facing a problem while writing a WDM DMA driver for a PCI chipset
>PLX
>>9080. I have to use the DMA chaining mode of PLX 9080. The descripor
list
>>for DMA chaining has to be on the PCI host.
>>
>>I have carried out the following steps so far.
>>(1) In the start device got access to the DMA Adapter object by using
>“IoGetDmaAdapter”
>>(2) Then used the Adpater object pointer to allocate 33 buffers using
>“AllocateCommonBuffer”.
>>The physical and the virtual addresses of these buffers are stored. All
>the
>>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA
chaining
>>transfer are stored in these allocated buffers.
>>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
>(METHOD_OUT_DIRECT),
>>I get the Mdl for the output buffer for the DMA transfer.
>>(4) The following set of operations are used to get the physical addresses
>>of the buffer referred to by the Mdl.
>> (a) Mdl = Irp->MdlAddress
>> (b) MmProbeAndLockPages()
>> (c) MmGetMdlByteCount ()
>> (d) MmGetMdlVirtualAddress ()
>> (e) MmGetMdlByteOffset()
>>(5) Determine the number of map registers required by using
>ADDRESS_AND_SIZE_TO_SPAN_PAGES
>>(6) Then determine howmany times the GetScatterGatherList needs to be
>called
>>by dividing the above result with the no of map registers allocated.
>>(7) If a scatter gather list alreday exists, clear it by calling
>PutScatterGatherList.
>>(8) Next Call ScatterGatherList with an adapter control routine.
>>(9) Mark the IRP Pending
>>
>>Adapter Control routine
>>----------------------------------
>>(10) Uses the elements of the scatter gather lsit to fill in the
>descriptors
>>allocated using the AllocatecommonBuffer.
>>(11) Once the descriptors are filled with the physical addresses obtained,
>>we next assign the DMA channel 0 descritor register wuth the address of
>the
>>first PCI descriptor by giving the physicall address of the first buffer
>>obtained via AllocateCommonBuffer API.
>>(3) Finally the DMA registers are filled to reflect chaining mode and
the
>>transferis started.
>>(4) the device physical address that I gave is the address at which the
>device
>>has mapped the memory. This address is not the address that I see in
>Windows
>>in the resources tab for the driver.
>>(5) I complete the IRP in the DPC.
>>
>>Observation:
>>----------------------
>>(1) I tried for a small size of 0x3c bytes and found the device to
freeze…
>>(2) I suspect address given for DMA transfer. Are the PCI and device
>physical
>>addresses provided correct?
>>(3) To get the device back to normal operation, I have to restart the
>system.
>>(4) I get no interrupt so IRP remains pending.
>>
>>Where does the problem lie? Can u guide me?
>>
>>Regards,
>>Purvi
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>‘’
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@tin.it
>To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

Hi Purvi,

my “local address” is initialized in the following way:

//
// Setup the LOCAL BUS address
//
pDmaChannel->ulLocalAddress = (iChannel == DMA_WRITE_CHANNEL) ? 0x50000028
: 0x50000030;

Above hardcoded values were defined by the hardware guy who designed the
board !
IIRC they are the addresses (virtual ?) on the PLX board bus where are
mapped the FIFOs I have to fill or to get data from with my driver DMA operations.

PaoloC

– Messaggio originale –
From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: Re: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 22:06:15 +0530
>Reply-To: “Windows System Software Devs Interest List”
>
>
>Hi! PaoloC,
>
>I have done the same thing but I am not sure of the local address value.
>
>What value did u enter for " pDmaChannel->ulLocalAddress" and from where
>did
>u get this value.
>
>Thanks and Best Regards,
>Purvi
>----- Original Message -----
>From:
>To: “Windows System Software Devs Interest List”
>Sent: Wednesday, October 20, 2004 6:09 PM
>Subject: Re: [ntdev] DMA Problem
>
>
>Hi Purvi,
>I use both the virtual & physical addresses returned by AllocateCommonBuffer
>after I have rounded those addresses to the nearest 16 byte align.
>Virtual address is used to access the DMA descriptor list and physical
>address
>is used to write the link between DMA descriptor entries, which will be
>used by PLX device.
>If you assume that my whole descriptor list is allocated in a single buffer
>returned by AllocateCommonBuffer you can understand the following piece
>of code I am using to build the descriptor list:
>
>
>
>//
>
>// Virtual address to traverse the descriptor list
>
>//
>
>PPLX_DMA_DESCRIPTOR pPlxDescr = pDmaChannel->pPlxSGList;
>
>
>
>//
>
>// Physical address of next DMA descriptor used by PLX to traverse the
chain
>
>//
>
>ULONG ulPlxNextDescr = pDmaChannel->ulPlxSGListPhysical + sizeof(
>PLX_DMA_DESCRIPTOR
>);
>
>
>//
>
>// Building the descriptor list
>
>//
>
>for (ULONG k = 0;
>
>k < n;
>
>i++, k++, pPlxDescr++, ulPlxNextDescr += sizeof( PLX_DMA_DESCRIPTOR ))
>
>{
>
>pPlxDescr->ulPciAddress = sglist->Elements[i].Address.LowPart;
>pPlxDescr->ulLocalAddress = pDmaChannel->ulLocalAddress;
>pPlxDescr->ulCount = sglist->Elements[i].Length;
>pPlxDescr->bitPciAddressSpace = 1;
>
>pPlxDescr->bitLocalToPciBus = pDmaChannel->bIsWrite ? 0 : 1;
>pPlxDescr->bitEndOFChain = 0;
>pPlxDescr->bitInterruptAfterTC = 0;
>
>pPlxDescr->bmNextDescrAddress = (ulPlxNextDescr >> 4);
>
>
>
>//
>
>// Update the number of bytes transferred so far
>
>//
>
>pDmaChannel->nbytes += sglist->Elements[i].Length;
>
>}
>
>
>
>//
>
>// Special processing for the last entry: end of list flag + generate
>interrupt
>+ no next
>//
>
>pPlxDescr–;
>
>pPlxDescr->bitEndOFChain = 1;
>
>pPlxDescr->bitInterruptAfterTC = 1;
>
>
>
>Regards,
>PaoloC
>
>
>>– Messaggio originale –
>>From: “Purvi Thakkar”
>>To: “Windows System Software Devs Interest List”
>>Subject: Re: [ntdev] DMA Problem
>>Date: Wed, 20 Oct 2004 21:06:05 +0530
>>Reply-To: “Windows System Software Devs Interest List”
>
>>
>>
>>Hello PaoloC,
>>
>>This was indeed a good piece of information. But I have taken care of
this
>>by calling AllocateCommonBuffer 33 times each time requesting a page of
>>memory i.e. 4096 bytes thereby taking care of the alignment issue. I even
>>checked the physical and virtual addresses obtained and they are also
>>aligned to a 16 byte boundary. This 16 byte boundary alignment is also
>a
>>requirement for PLX 9080.
>>
>>I am not sure of the pci and local addresses that are entered into the
>>descriptor. Could u throw some light on it. They are physical addresses
>but
>>with respect to PCI host space, local address space or something else.
>What
>>did u do when programing for DMA chaining.
>>
>>Thanks and Best Regards,
>>Purvi
>>----- Original Message -----
>>From:
>>To: “Windows System Software Devs Interest List”
>>Sent: Wednesday, October 20, 2004 4:33 PM
>>Subject: RE: [ntdev] DMA Problem
>>
>>
>>Well I do not known PLX9080 bridge.
>>Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
>>(read in the datasheet) that DMA descriptor MUST be aligned on a 16 byte
>>address.
>>And AllocateCommonBuffer does not returns aligned data.
>>So I modify the allocation of DMA descriptors to something like this:
>>
>>//
>>// Requesting one extra entry so that we can align on 16 byte boundary
>>//
>>pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);
>>
>>//
>>// AllocateCommonBuffer allocates memory and maps it so that it is
>>simultaneously
>>
>>// accessible from both the processor and a device for DMA operations.
>>// AllocateCommonBuffer returns the base virtual address of the allocated
>>range.
>>// If the buffer cannot be allocated, it returns NULL.
>>//
>>pDmaChannel->pvPlxSGListUnaligned =
>>(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
>>(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,
>>…
>>…
>>
>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned virtual
>>= 0x%X physical = 0x%X\n",
>>pDmaChannel->pvPlxSGListUnaligned,
>>pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>));
>>
>>//
>>// Align on 16 byte boundary as required by PLX device
>>//
>>pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
>>(((ULONG)pDmaChannel->pvPlxSGListUnaligned
>>+ 0xF) & 0xFFFFFFF0);
>>pDmaChannel->ulPlxSGListPhysical =
>>((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>+ 0xF) & 0xFFFFFFF0;
>>
>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned virtual
>>= 0x%X physical = 0x%X\n",
>>(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));
>>
>>
>>Hope this can help,
>>PaoloC
>>
>>
>>>– Messaggio originale –
>>>From: “Purvi Thakkar”
>>>To: “Windows System Software Devs Interest List”
>>>Subject: [ntdev] DMA Problem
>>>Date: Wed, 20 Oct 2004 17:45:17 +0530
>>>Reply-To: “Windows System Software Devs Interest List”
>>
>>>
>>>
>>>Hello,
>>>
>>>I am facing a problem while writing a WDM DMA driver for a PCI chipset
>>PLX
>>>9080. I have to use the DMA chaining mode of PLX 9080. The descripor
>list
>>>for DMA chaining has to be on the PCI host.
>>>
>>>I have carried out the following steps so far.
>>>(1) In the start device got access to the DMA Adapter object by using
>>“IoGetDmaAdapter”
>>>(2) Then used the Adpater object pointer to allocate 33 buffers using
>>“AllocateCommonBuffer”.
>>>The physical and the virtual addresses of these buffers are stored. All
>>the
>>>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA
>chaining
>>>transfer are stored in these allocated buffers.
>>>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
>>(METHOD_OUT_DIRECT),
>>>I get the Mdl for the output buffer for the DMA transfer.
>>>(4) The following set of operations are used to get the physical addresses
>>>of the buffer referred to by the Mdl.
>>> (a) Mdl = Irp->MdlAddress
>>> (b) MmProbeAndLockPages()
>>> (c) MmGetMdlByteCount ()
>>> (d) MmGetMdlVirtualAddress ()
>>> (e) MmGetMdlByteOffset()
>>>(5) Determine the number of map registers required by using
>>ADDRESS_AND_SIZE_TO_SPAN_PAGES
>>>(6) Then determine howmany times the GetScatterGatherList needs to be
>>called
>>>by dividing the above result with the no of map registers allocated.
>>>(7) If a scatter gather list alreday exists, clear it by calling
>>PutScatterGatherList.
>>>(8) Next Call ScatterGatherList with an adapter control routine.
>>>(9) Mark the IRP Pending
>>>
>>>Adapter Control routine
>>>----------------------------------
>>>(10) Uses the elements of the scatter gather lsit to fill in the
>>descriptors
>>>allocated using the AllocatecommonBuffer.
>>>(11) Once the descriptors are filled with the physical addresses obtained,
>>>we next assign the DMA channel 0 descritor register wuth the address
of
>>the
>>>first PCI descriptor by giving the physicall address of the first buffer
>>>obtained via AllocateCommonBuffer API.
>>>(3) Finally the DMA registers are filled to reflect chaining mode and
>the
>>>transferis started.
>>>(4) the device physical address that I gave is the address at which the
>>device
>>>has mapped the memory. This address is not the address that I see in
>>Windows
>>>in the resources tab for the driver.
>>>(5) I complete the IRP in the DPC.
>>>
>>>Observation:
>>>----------------------
>>>(1) I tried for a small size of 0x3c bytes and found the device to
>freeze…
>>>(2) I suspect address given for DMA transfer. Are the PCI and device
>>physical
>>>addresses provided correct?
>>>(3) To get the device back to normal operation, I have to restart the
>>system.
>>>(4) I get no interrupt so IRP remains pending.
>>>
>>>Where does the problem lie? Can u guide me?
>>>
>>>Regards,
>>>Purvi
>>>
>>>
>>>—
>>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>>
>>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>>‘’
>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>‘’
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: xxxxx@tin.it
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@tin.it
>To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

Hello PaoloC,

Thanks for the help. I am not sure of this address. While the rest of the
information matches with whatever u said. I will have to check up with the
hardware person then in this case. Do u have any idea if this address can be
obtained from any PLX register(in your case)?

As far as allocation of common buffer is concerned, my understanding is as
follows: Can u please confirm if my understanding is correct?
(1) For allocation less than 1 PAGE_SIZE, u have to ensure 16 byte
allignment for the descriptor table for PLX .
(2) For allocation = PAGE_SIZE, u always get a value alligned to page
boundary.
(3) For allocation greater than PAGE_SIZE, u have to do a one time
MapTransfer kind of operation after AllocateCommonBuffer by building Mdl to
get the physical addresses of the allocated common buffer that span across
various physical pages. May be we even have to do a 16 byte alignment for
the first physical address obtained for the 1st map register.

Best Regards,
Purvi

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Wednesday, October 20, 2004 7:07 PM
Subject: Re: [ntdev] DMA Problem

Hi Purvi,

my “local address” is initialized in the following way:

//
// Setup the LOCAL BUS address
//
pDmaChannel->ulLocalAddress = (iChannel == DMA_WRITE_CHANNEL) ? 0x50000028
: 0x50000030;

Above hardcoded values were defined by the hardware guy who designed the
board !
IIRC they are the addresses (virtual ?) on the PLX board bus where are
mapped the FIFOs I have to fill or to get data from with my driver DMA
operations.

PaoloC

>– Messaggio originale –
>From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: Re: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 22:06:15 +0530
>Reply-To: “Windows System Software Devs Interest List”

>
>
>Hi! PaoloC,
>
>I have done the same thing but I am not sure of the local address value.
>
>What value did u enter for " pDmaChannel->ulLocalAddress" and from where
>did
>u get this value.
>
>Thanks and Best Regards,
>Purvi
>----- Original Message -----
>From:
>To: “Windows System Software Devs Interest List”
>Sent: Wednesday, October 20, 2004 6:09 PM
>Subject: Re: [ntdev] DMA Problem
>
>
>Hi Purvi,
>I use both the virtual & physical addresses returned by
AllocateCommonBuffer
>after I have rounded those addresses to the nearest 16 byte align.
>Virtual address is used to access the DMA descriptor list and physical
>address
>is used to write the link between DMA descriptor entries, which will be
>used by PLX device.
>If you assume that my whole descriptor list is allocated in a single buffer
>returned by AllocateCommonBuffer you can understand the following piece
>of code I am using to build the descriptor list:
>
>
>
>//
>
>// Virtual address to traverse the descriptor list
>
>//
>
>PPLX_DMA_DESCRIPTOR pPlxDescr = pDmaChannel->pPlxSGList;
>
>
>
>//
>
>// Physical address of next DMA descriptor used by PLX to traverse the
chain
>
>//
>
>ULONG ulPlxNextDescr = pDmaChannel->ulPlxSGListPhysical + sizeof(
>PLX_DMA_DESCRIPTOR
>);
>
>
>//
>
>// Building the descriptor list
>
>//
>
>for (ULONG k = 0;
>
>k < n;
>
>i++, k++, pPlxDescr++, ulPlxNextDescr += sizeof( PLX_DMA_DESCRIPTOR ))
>
>{
>
>pPlxDescr->ulPciAddress = sglist->Elements[i].Address.LowPart;
>pPlxDescr->ulLocalAddress = pDmaChannel->ulLocalAddress;
>pPlxDescr->ulCount = sglist->Elements[i].Length;
>pPlxDescr->bitPciAddressSpace = 1;
>
>pPlxDescr->bitLocalToPciBus = pDmaChannel->bIsWrite ? 0 : 1;
>pPlxDescr->bitEndOFChain = 0;
>pPlxDescr->bitInterruptAfterTC = 0;
>
>pPlxDescr->bmNextDescrAddress = (ulPlxNextDescr >> 4);
>
>
>
>//
>
>// Update the number of bytes transferred so far
>
>//
>
>pDmaChannel->nbytes += sglist->Elements[i].Length;
>
>}
>
>
>
>//
>
>// Special processing for the last entry: end of list flag + generate
>interrupt
>+ no next
>//
>
>pPlxDescr–;
>
>pPlxDescr->bitEndOFChain = 1;
>
>pPlxDescr->bitInterruptAfterTC = 1;
>
>
>
>Regards,
>PaoloC
>
>
>>– Messaggio originale –
>>From: “Purvi Thakkar”
>>To: “Windows System Software Devs Interest List”
>>Subject: Re: [ntdev] DMA Problem
>>Date: Wed, 20 Oct 2004 21:06:05 +0530
>>Reply-To: “Windows System Software Devs Interest List”
>
>>
>>
>>Hello PaoloC,
>>
>>This was indeed a good piece of information. But I have taken care of
this
>>by calling AllocateCommonBuffer 33 times each time requesting a page of
>>memory i.e. 4096 bytes thereby taking care of the alignment issue. I even
>>checked the physical and virtual addresses obtained and they are also
>>aligned to a 16 byte boundary. This 16 byte boundary alignment is also
>a
>>requirement for PLX 9080.
>>
>>I am not sure of the pci and local addresses that are entered into the
>>descriptor. Could u throw some light on it. They are physical addresses
>but
>>with respect to PCI host space, local address space or something else.
>What
>>did u do when programing for DMA chaining.
>>
>>Thanks and Best Regards,
>>Purvi
>>----- Original Message -----
>>From:
>>To: “Windows System Software Devs Interest List”
>>Sent: Wednesday, October 20, 2004 4:33 PM
>>Subject: RE: [ntdev] DMA Problem
>>
>>
>>Well I do not known PLX9080 bridge.
>>Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
>>(read in the datasheet) that DMA descriptor MUST be aligned on a 16 byte
>>address.
>>And AllocateCommonBuffer does not returns aligned data.
>>So I modify the allocation of DMA descriptors to something like this:
>>
>>//
>>// Requesting one extra entry so that we can align on 16 byte boundary
>>//
>>pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);
>>
>>//
>>// AllocateCommonBuffer allocates memory and maps it so that it is
>>simultaneously
>>
>>// accessible from both the processor and a device for DMA operations.
>>// AllocateCommonBuffer returns the base virtual address of the allocated
>>range.
>>// If the buffer cannot be allocated, it returns NULL.
>>//
>>pDmaChannel->pvPlxSGListUnaligned =
>>(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
>>(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,
>>…
>>…
>>
>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned virtual
>>= 0x%X physical = 0x%X\n",
>>pDmaChannel->pvPlxSGListUnaligned,
>>pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>));
>>
>>//
>>// Align on 16 byte boundary as required by PLX device
>>//
>>pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
>>(((ULONG)pDmaChannel->pvPlxSGListUnaligned
>>+ 0xF) & 0xFFFFFFF0);
>>pDmaChannel->ulPlxSGListPhysical =
>>((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>+ 0xF) & 0xFFFFFFF0;
>>
>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned virtual
>>= 0x%X physical = 0x%X\n",
>>(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));
>>
>>
>>Hope this can help,
>>PaoloC
>>
>>
>>>– Messaggio originale –
>>>From: “Purvi Thakkar”
>>>To: “Windows System Software Devs Interest List”
>>>Subject: [ntdev] DMA Problem
>>>Date: Wed, 20 Oct 2004 17:45:17 +0530
>>>Reply-To: “Windows System Software Devs Interest List”
>>
>>>
>>>
>>>Hello,
>>>
>>>I am facing a problem while writing a WDM DMA driver for a PCI chipset
>>PLX
>>>9080. I have to use the DMA chaining mode of PLX 9080. The descripor
>list
>>>for DMA chaining has to be on the PCI host.
>>>
>>>I have carried out the following steps so far.
>>>(1) In the start device got access to the DMA Adapter object by using
>>“IoGetDmaAdapter”
>>>(2) Then used the Adpater object pointer to allocate 33 buffers using
>>“AllocateCommonBuffer”.
>>>The physical and the virtual addresses of these buffers are stored. All
>>the
>>>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA
>chaining
>>>transfer are stored in these allocated buffers.
>>>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
>>(METHOD_OUT_DIRECT),
>>>I get the Mdl for the output buffer for the DMA transfer.
>>>(4) The following set of operations are used to get the physical
addresses
>>>of the buffer referred to by the Mdl.
>>> (a) Mdl = Irp->MdlAddress
>>> (b) MmProbeAndLockPages()
>>> (c) MmGetMdlByteCount ()
>>> (d) MmGetMdlVirtualAddress ()
>>> (e) MmGetMdlByteOffset()
>>>(5) Determine the number of map registers required by using
>>ADDRESS_AND_SIZE_TO_SPAN_PAGES
>>>(6) Then determine howmany times the GetScatterGatherList needs to be
>>called
>>>by dividing the above result with the no of map registers allocated.
>>>(7) If a scatter gather list alreday exists, clear it by calling
>>PutScatterGatherList.
>>>(8) Next Call ScatterGatherList with an adapter control routine.
>>>(9) Mark the IRP Pending
>>>
>>>Adapter Control routine
>>>----------------------------------
>>>(10) Uses the elements of the scatter gather lsit to fill in the
>>descriptors
>>>allocated using the AllocatecommonBuffer.
>>>(11) Once the descriptors are filled with the physical addresses
obtained,
>>>we next assign the DMA channel 0 descritor register wuth the address
of
>>the
>>>first PCI descriptor by giving the physicall address of the first buffer
>>>obtained via AllocateCommonBuffer API.
>>>(3) Finally the DMA registers are filled to reflect chaining mode and
>the
>>>transferis started.
>>>(4) the device physical address that I gave is the address at which the
>>device
>>>has mapped the memory. This address is not the address that I see in
>>Windows
>>>in the resources tab for the driver.
>>>(5) I complete the IRP in the DPC.
>>>
>>>Observation:
>>>----------------------
>>>(1) I tried for a small size of 0x3c bytes and found the device to
>freeze…
>>>(2) I suspect address given for DMA transfer. Are the PCI and device
>>physical
>>>addresses provided correct?
>>>(3) To get the device back to normal operation, I have to restart the
>>system.
>>>(4) I get no interrupt so IRP remains pending.
>>>
>>>Where does the problem lie? Can u guide me?
>>>
>>>Regards,
>>>Purvi
>>>
>>>
>>>—
>>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>>
>>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>>‘’
>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>‘’
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: xxxxx@tin.it
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@tin.it
>To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

If you allocate anything that is greater than a page, it will be
page-aligned (and thus absolutely aligned to 16 bytes). Of course, the end
of the allocation may not be 16-byte aligned if the size isn’t a multiple
of 16 bytes.

So you should only have to align the address if the allocation is smaller
than 1 page.


Mats

xxxxx@lists.osr.com wrote on 10/20/2004 06:52:25 PM:

Hello PaoloC,

Thanks for the help. I am not sure of this address. While the rest of the
information matches with whatever u said. I will have to check up with
the
hardware person then in this case. Do u have any idea if this address can
be
obtained from any PLX register(in your case)?

As far as allocation of common buffer is concerned, my understanding is
as
follows: Can u please confirm if my understanding is correct?
(1) For allocation less than 1 PAGE_SIZE, u have to ensure 16 byte
allignment for the descriptor table for PLX .
(2) For allocation = PAGE_SIZE, u always get a value alligned to page
boundary.
(3) For allocation greater than PAGE_SIZE, u have to do a one time
MapTransfer kind of operation after AllocateCommonBuffer by building Mdl
to
get the physical addresses of the allocated common buffer that span
across
various physical pages. May be we even have to do a 16 byte alignment for
the first physical address obtained for the 1st map register.

Best Regards,
Purvi

----- Original Message -----
From:
> To: “Windows System Software Devs Interest List”
> Sent: Wednesday, October 20, 2004 7:07 PM
> Subject: Re: [ntdev] DMA Problem
>
>
> Hi Purvi,
>
> my “local address” is initialized in the following way:
>
> //
> // Setup the LOCAL BUS address
> //
> pDmaChannel->ulLocalAddress = (iChannel == DMA_WRITE_CHANNEL) ?
0x50000028
> : 0x50000030;
>
> Above hardcoded values were defined by the hardware guy who designed the
> board !
> IIRC they are the addresses (virtual ?) on the PLX board bus where are
> mapped the FIFOs I have to fill or to get data from with my driver DMA
> operations.
>
> PaoloC
>
> >– Messaggio originale –
> >From: “Purvi Thakkar”
> >To: “Windows System Software Devs Interest List”
> >Subject: Re: [ntdev] DMA Problem
> >Date: Wed, 20 Oct 2004 22:06:15 +0530
> >Reply-To: “Windows System Software Devs Interest List”
>
> >
> >
> >Hi! PaoloC,
> >
> >I have done the same thing but I am not sure of the local address value.
> >
> >What value did u enter for " pDmaChannel->ulLocalAddress" and from where
> >did
> >u get this value.
> >
> >Thanks and Best Regards,
> >Purvi
> >----- Original Message -----
> >From:
> >To: “Windows System Software Devs Interest List”
> >Sent: Wednesday, October 20, 2004 6:09 PM
> >Subject: Re: [ntdev] DMA Problem
> >
> >
> >Hi Purvi,
> >I use both the virtual & physical addresses returned by
> AllocateCommonBuffer
> >after I have rounded those addresses to the nearest 16 byte align.
> >Virtual address is used to access the DMA descriptor list and physical
> >address
> >is used to write the link between DMA descriptor entries, which will be
> >used by PLX device.
> >If you assume that my whole descriptor list is allocated in a single
buffer
> >returned by AllocateCommonBuffer you can understand the following piece
> >of code I am using to build the descriptor list:
> >
> >
> >
> >//
> >
> >// Virtual address to traverse the descriptor list
> >
> >//
> >
> >PPLX_DMA_DESCRIPTOR pPlxDescr = pDmaChannel->pPlxSGList;
> >
> >
> >
> >//
> >
> >// Physical address of next DMA descriptor used by PLX to traverse the
> chain
> >
> >//
> >
> >ULONG ulPlxNextDescr = pDmaChannel->ulPlxSGListPhysical + sizeof(
> >PLX_DMA_DESCRIPTOR
> >);
> >
> >
> >//
> >
> >// Building the descriptor list
> >
> >//
> >
> >for (ULONG k = 0;
> >
> >k < n;
> >
> >i++, k++, pPlxDescr++, ulPlxNextDescr += sizeof( PLX_DMA_DESCRIPTOR ))
> >
> >{
> >
> >pPlxDescr->ulPciAddress = sglist->Elements[i].Address.LowPart;
> >pPlxDescr->ulLocalAddress = pDmaChannel->ulLocalAddress;
> >pPlxDescr->ulCount = sglist->Elements[i].Length;
> >pPlxDescr->bitPciAddressSpace = 1;
> >
> >pPlxDescr->bitLocalToPciBus = pDmaChannel->bIsWrite ? 0 : 1;
> >pPlxDescr->bitEndOFChain = 0;
> >pPlxDescr->bitInterruptAfterTC = 0;
> >
> >pPlxDescr->bmNextDescrAddress = (ulPlxNextDescr >> 4);
> >
> >
> >
> >//
> >
> >// Update the number of bytes transferred so far
> >
> >//
> >
> >pDmaChannel->nbytes += sglist->Elements[i].Length;
> >
> >}
> >
> >
> >
> >//
> >
> >// Special processing for the last entry: end of list flag + generate
> >interrupt
> >+ no next
> >//
> >
> >pPlxDescr–;
> >
> >pPlxDescr->bitEndOFChain = 1;
> >
> >pPlxDescr->bitInterruptAfterTC = 1;
> >
> >
> >
> >Regards,
> >PaoloC
> >
> >
> >>– Messaggio originale –
> >>From: “Purvi Thakkar”
> >>To: “Windows System Software Devs Interest List”
> >>Subject: Re: [ntdev] DMA Problem
> >>Date: Wed, 20 Oct 2004 21:06:05 +0530
> >>Reply-To: “Windows System Software Devs Interest List”
> >
> >>
> >>
> >>Hello PaoloC,
> >>
> >>This was indeed a good piece of information. But I have taken care of
> this
> >>by calling AllocateCommonBuffer 33 times each time requesting a page of
> >>memory i.e. 4096 bytes thereby taking care of the alignment issue. I
even
> >>checked the physical and virtual addresses obtained and they are also
> >>aligned to a 16 byte boundary. This 16 byte boundary alignment is also
> >a
> >>requirement for PLX 9080.
> >>
> >>I am not sure of the pci and local addresses that are entered into the
> >>descriptor. Could u throw some light on it. They are physical addresses
> >but
> >>with respect to PCI host space, local address space or something else.
> >What
> >>did u do when programing for DMA chaining.
> >>
> >>Thanks and Best Regards,
> >>Purvi
> >>----- Original Message -----
> >>From:
> >>To: “Windows System Software Devs Interest List”
> >>Sent: Wednesday, October 20, 2004 4:33 PM
> >>Subject: RE: [ntdev] DMA Problem
> >>
> >>
> >>Well I do not known PLX9080 bridge.
> >>Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
> >>(read in the datasheet) that DMA descriptor MUST be aligned on a 16
byte
> >>address.
> >>And AllocateCommonBuffer does not returns aligned data.
> >>So I modify the allocation of DMA descriptors to something like this:
> >>
> >>//
> >>// Requesting one extra entry so that we can align on 16 byte boundary
> >>//
> >>pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);
> >>
> >>//
> >>// AllocateCommonBuffer allocates memory and maps it so that it is
> >>simultaneously
> >>
> >>// accessible from both the processor and a device for DMA operations.
> >>// AllocateCommonBuffer returns the base virtual address of the
allocated
> >>range.
> >>// If the buffer cannot be allocated, it returns NULL.
> >>//
> >>pDmaChannel->pvPlxSGListUnaligned =
> >>(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
> >>(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,
> >>…
> >>…
> >>
> >>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned
virtual
> >>= 0x%X physical = 0x%X\n",
> >>pDmaChannel->pvPlxSGListUnaligned,
> >>pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
> >>));
> >>
> >>//
> >>// Align on 16 byte boundary as required by PLX device
> >>//
> >>pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
> >>(((ULONG)pDmaChannel->pvPlxSGListUnaligned
> >>+ 0xF) & 0xFFFFFFF0);
> >>pDmaChannel->ulPlxSGListPhysical =
> >>((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
> >>+ 0xF) & 0xFFFFFFF0;
> >>
> >>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned
virtual
> >>= 0x%X physical = 0x%X\n",
> >>(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));
> >>
> >>
> >>Hope this can help,
> >>PaoloC
> >>
> >>
> >>>– Messaggio originale –
> >>>From: “Purvi Thakkar”
> >>>To: “Windows System Software Devs Interest List”
> >>>Subject: [ntdev] DMA Problem
> >>>Date: Wed, 20 Oct 2004 17:45:17 +0530
> >>>Reply-To: “Windows System Software Devs Interest List”
> >>
> >>>
> >>>
> >>>Hello,
> >>>
> >>>I am facing a problem while writing a WDM DMA driver for a PCI chipset
> >>PLX
> >>>9080. I have to use the DMA chaining mode of PLX 9080. The descripor
> >list
> >>>for DMA chaining has to be on the PCI host.
> >>>
> >>>I have carried out the following steps so far.
> >>>(1) In the start device got access to the DMA Adapter object by using
> >>“IoGetDmaAdapter”
> >>>(2) Then used the Adpater object pointer to allocate 33 buffers using
> >>“AllocateCommonBuffer”.
> >>>The physical and the virtual addresses of these buffers are stored.
All
> >>the
> >>>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA
> >chaining
> >>>transfer are stored in these allocated buffers.
> >>>(3) When a IOCTL write is fired to the DMA device object with
DIRECT_IO
> >>(METHOD_OUT_DIRECT),
> >>>I get the Mdl for the output buffer for the DMA transfer.
> >>>(4) The following set of operations are used to get the physical
> addresses
> >>>of the buffer referred to by the Mdl.
> >>> (a) Mdl = Irp->MdlAddress
> >>> (b) MmProbeAndLockPages()
> >>> (c) MmGetMdlByteCount ()
> >>> (d) MmGetMdlVirtualAddress ()
> >>> (e) MmGetMdlByteOffset()
> >>>(5) Determine the number of map registers required by using
> >>ADDRESS_AND_SIZE_TO_SPAN_PAGES
> >>>(6) Then determine howmany times the GetScatterGatherList needs to be
> >>called
> >>>by dividing the above result with the no of map registers allocated.
> >>>(7) If a scatter gather list alreday exists, clear it by calling
> >>PutScatterGatherList.
> >>>(8) Next Call ScatterGatherList with an adapter control routine.
> >>>(9) Mark the IRP Pending
> >>>
> >>>Adapter Control routine
> >>>----------------------------------
> >>>(10) Uses the elements of the scatter gather lsit to fill in the
> >>descriptors
> >>>allocated using the AllocatecommonBuffer.
> >>>(11) Once the descriptors are filled with the physical addresses
> obtained,
> >>>we next assign the DMA channel 0 descritor register wuth the address
> of
> >>the
> >>>first PCI descriptor by giving the physicall address of the first
buffer
> >>>obtained via AllocateCommonBuffer API.
> >>>(3) Finally the DMA registers are filled to reflect chaining mode and
> >the
> >>>transferis started.
> >>>(4) the device physical address that I gave is the address at which
the
> >>device
> >>>has mapped the memory. This address is not the address that I see in
> >>Windows
> >>>in the resources tab for the driver.
> >>>(5) I complete the IRP in the DPC.
> >>>
> >>>Observation:
> >>>----------------------
> >>>(1) I tried for a small size of 0x3c bytes and found the device to
> >freeze…
> >>>(2) I suspect address given for DMA transfer. Are the PCI and device
> >>physical
> >>>addresses provided correct?
> >>>(3) To get the device back to normal operation, I have to restart the
> >>system.
> >>>(4) I get no interrupt so IRP remains pending.
> >>>
> >>>Where does the problem lie? Can u guide me?
> >>>
> >>>Regards,
> >>>Purvi
> >>>
> >>>
> >>>—
> >>>Questions? First check the Kernel Driver FAQ at
> >>http://www.osronline.com/article.cfm?id=256
> >>>
> >>>You are currently subscribed to ntdev as: unknown lmsubst tag
argument:
> >>‘’
> >>>To unsubscribe send a blank email to xxxxx@lists.osr.com
> >>
> >>
> >>
> >>
> >>—
> >>Questions? First check the Kernel Driver FAQ at
> >>http://www.osronline.com/article.cfm?id=256
> >>
> >>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
> >‘’
> >>To unsubscribe send a blank email to xxxxx@lists.osr.com
> >>
> >>
> >>
> >>—
> >>Questions? First check the Kernel Driver FAQ at
> >http://www.osronline.com/article.cfm?id=256
> >>
> >>You are currently subscribed to ntdev as: xxxxx@tin.it
> >>To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
> >
> >
> >
> >—
> >Questions? First check the Kernel Driver FAQ at
> >http://www.osronline.com/article.cfm?id=256
> >
> >You are currently subscribed to ntdev as: unknown lmsubst tag argument:
> ‘’
> >To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
> >
> >
> >—
> >Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
> >
> >You are currently subscribed to ntdev as: xxxxx@tin.it
> >To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.
> osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@3dlabs.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

> ForwardSourceID:NT00005C56</pplx_dma_descriptor>

IIRC the “local address” is the address on the board bus where PLX DMA bridge
will write/read the data when performing a DMA data operation.
In my board this address refers at a FIFO so it is never incremented during
the DMA operation and it is the same in each eantry of DMA descriptor list.
I do not think it is coming from any PLX register since it is the board
bus address where you want to move to/get from data.
May be you have to use a direct slave operation to get this address from
some specific memory location/register of the board.
I am not an expert of AllocateCommonBuffer operation.
I just noticed that returned address for my needed size was not aligned
so I made a trick to allocate a bigger buffer and use the first address
aligned according to PLX need.

Regards,
PaoloC

– Messaggio originale –
From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: Re: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 23:22:25 +0530
>Reply-To: “Windows System Software Devs Interest List”
>
>
>Hello PaoloC,
>
>Thanks for the help. I am not sure of this address. While the rest of the
>information matches with whatever u said. I will have to check up with
the
>hardware person then in this case. Do u have any idea if this address can
>be
>obtained from any PLX register(in your case)?
>
>As far as allocation of common buffer is concerned, my understanding is
as
>follows: Can u please confirm if my understanding is correct?
>(1) For allocation less than 1 PAGE_SIZE, u have to ensure 16 byte
>allignment for the descriptor table for PLX .
>(2) For allocation = PAGE_SIZE, u always get a value alligned to page
>boundary.
>(3) For allocation greater than PAGE_SIZE, u have to do a one time
>MapTransfer kind of operation after AllocateCommonBuffer by building Mdl
>to
>get the physical addresses of the allocated common buffer that span across
>various physical pages. May be we even have to do a 16 byte alignment for
>the first physical address obtained for the 1st map register.
>
>Best Regards,
>Purvi
>
>----- Original Message -----
>From:
>To: “Windows System Software Devs Interest List”
>Sent: Wednesday, October 20, 2004 7:07 PM
>Subject: Re: [ntdev] DMA Problem
>
>
>Hi Purvi,
>
>my “local address” is initialized in the following way:
>
>//
>// Setup the LOCAL BUS address
>//
>pDmaChannel->ulLocalAddress = (iChannel == DMA_WRITE_CHANNEL) ? 0x50000028
>: 0x50000030;
>
>Above hardcoded values were defined by the hardware guy who designed the
>board !
>IIRC they are the addresses (virtual ?) on the PLX board bus where are
>mapped the FIFOs I have to fill or to get data from with my driver DMA
>operations.
>
>PaoloC
>
>>– Messaggio originale –
>>From: “Purvi Thakkar”
>>To: “Windows System Software Devs Interest List”
>>Subject: Re: [ntdev] DMA Problem
>>Date: Wed, 20 Oct 2004 22:06:15 +0530
>>Reply-To: “Windows System Software Devs Interest List”
>
>>
>>
>>Hi! PaoloC,
>>
>>I have done the same thing but I am not sure of the local address value.
>>
>>What value did u enter for " pDmaChannel->ulLocalAddress" and from where
>>did
>>u get this value.
>>
>>Thanks and Best Regards,
>>Purvi
>>----- Original Message -----
>>From:
>>To: “Windows System Software Devs Interest List”
>>Sent: Wednesday, October 20, 2004 6:09 PM
>>Subject: Re: [ntdev] DMA Problem
>>
>>
>>Hi Purvi,
>>I use both the virtual & physical addresses returned by
>AllocateCommonBuffer
>>after I have rounded those addresses to the nearest 16 byte align.
>>Virtual address is used to access the DMA descriptor list and physical
>>address
>>is used to write the link between DMA descriptor entries, which will be
>>used by PLX device.
>>If you assume that my whole descriptor list is allocated in a single buffer
>>returned by AllocateCommonBuffer you can understand the following piece
>>of code I am using to build the descriptor list:
>>
>>
>>
>>//
>>
>>// Virtual address to traverse the descriptor list
>>
>>//
>>
>>PPLX_DMA_DESCRIPTOR pPlxDescr = pDmaChannel->pPlxSGList;
>>
>>
>>
>>//
>>
>>// Physical address of next DMA descriptor used by PLX to traverse the
>chain
>>
>>//
>>
>>ULONG ulPlxNextDescr = pDmaChannel->ulPlxSGListPhysical + sizeof(
>>PLX_DMA_DESCRIPTOR
>>);
>>
>>
>>//
>>
>>// Building the descriptor list
>>
>>//
>>
>>for (ULONG k = 0;
>>
>>k < n;
>>
>>i++, k++, pPlxDescr++, ulPlxNextDescr += sizeof( PLX_DMA_DESCRIPTOR ))
>>
>>{
>>
>>pPlxDescr->ulPciAddress = sglist->Elements[i].Address.LowPart;
>>pPlxDescr->ulLocalAddress = pDmaChannel->ulLocalAddress;
>>pPlxDescr->ulCount = sglist->Elements[i].Length;
>>pPlxDescr->bitPciAddressSpace = 1;
>>
>>pPlxDescr->bitLocalToPciBus = pDmaChannel->bIsWrite ? 0 : 1;
>>pPlxDescr->bitEndOFChain = 0;
>>pPlxDescr->bitInterruptAfterTC = 0;
>>
>>pPlxDescr->bmNextDescrAddress = (ulPlxNextDescr >> 4);
>>
>>
>>
>>//
>>
>>// Update the number of bytes transferred so far
>>
>>//
>>
>>pDmaChannel->nbytes += sglist->Elements[i].Length;
>>
>>}
>>
>>
>>
>>//
>>
>>// Special processing for the last entry: end of list flag + generate
>>interrupt
>>+ no next
>>//
>>
>>pPlxDescr–;
>>
>>pPlxDescr->bitEndOFChain = 1;
>>
>>pPlxDescr->bitInterruptAfterTC = 1;
>>
>>
>>
>>Regards,
>>PaoloC
>>
>>
>>>– Messaggio originale –
>>>From: “Purvi Thakkar”
>>>To: “Windows System Software Devs Interest List”
>>>Subject: Re: [ntdev] DMA Problem
>>>Date: Wed, 20 Oct 2004 21:06:05 +0530
>>>Reply-To: “Windows System Software Devs Interest List”
>>
>>>
>>>
>>>Hello PaoloC,
>>>
>>>This was indeed a good piece of information. But I have taken care of
>this
>>>by calling AllocateCommonBuffer 33 times each time requesting a page
of
>>>memory i.e. 4096 bytes thereby taking care of the alignment issue. I
even
>>>checked the physical and virtual addresses obtained and they are also
>>>aligned to a 16 byte boundary. This 16 byte boundary alignment is also
>>a
>>>requirement for PLX 9080.
>>>
>>>I am not sure of the pci and local addresses that are entered into the
>>>descriptor. Could u throw some light on it. They are physical addresses
>>but
>>>with respect to PCI host space, local address space or something else.
>>What
>>>did u do when programing for DMA chaining.
>>>
>>>Thanks and Best Regards,
>>>Purvi
>>>----- Original Message -----
>>>From:
>>>To: “Windows System Software Devs Interest List”
>>>Sent: Wednesday, October 20, 2004 4:33 PM
>>>Subject: RE: [ntdev] DMA Problem
>>>
>>>
>>>Well I do not known PLX9080 bridge.
>>>Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
>>>(read in the datasheet) that DMA descriptor MUST be aligned on a 16
byte
>>>address.
>>>And AllocateCommonBuffer does not returns aligned data.
>>>So I modify the allocation of DMA descriptors to something like this:
>>>
>>>//
>>>// Requesting one extra entry so that we can align on 16 byte boundary
>>>//
>>>pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);
>>>
>>>//
>>>// AllocateCommonBuffer allocates memory and maps it so that it is
>>>simultaneously
>>>
>>>// accessible from both the processor and a device for DMA operations.
>>>// AllocateCommonBuffer returns the base virtual address of the allocated
>>>range.
>>>// If the buffer cannot be allocated, it returns NULL.
>>>//
>>>pDmaChannel->pvPlxSGListUnaligned =
>>>(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
>>>(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,
>>>…
>>>…
>>>
>>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned virtual
>>>= 0x%X physical = 0x%X\n",
>>>pDmaChannel->pvPlxSGListUnaligned,
>>>pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>>));
>>>
>>>//
>>>// Align on 16 byte boundary as required by PLX device
>>>//
>>>pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
>>>(((ULONG)pDmaChannel->pvPlxSGListUnaligned
>>>+ 0xF) & 0xFFFFFFF0);
>>>pDmaChannel->ulPlxSGListPhysical =
>>>((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>>+ 0xF) & 0xFFFFFFF0;
>>>
>>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned virtual
>>>= 0x%X physical = 0x%X\n",
>>>(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));
>>>
>>>
>>>Hope this can help,
>>>PaoloC
>>>
>>>
>>>>– Messaggio originale –
>>>>From: “Purvi Thakkar”
>>>>To: “Windows System Software Devs Interest List”
>>>>Subject: [ntdev] DMA Problem
>>>>Date: Wed, 20 Oct 2004 17:45:17 +0530
>>>>Reply-To: “Windows System Software Devs Interest List”
>>>
>>>>
>>>>
>>>>Hello,
>>>>
>>>>I am facing a problem while writing a WDM DMA driver for a PCI chipset
>>>PLX
>>>>9080. I have to use the DMA chaining mode of PLX 9080. The descripor
>>list
>>>>for DMA chaining has to be on the PCI host.
>>>>
>>>>I have carried out the following steps so far.
>>>>(1) In the start device got access to the DMA Adapter object by using
>>>“IoGetDmaAdapter”
>>>>(2) Then used the Adpater object pointer to allocate 33 buffers using
>>>“AllocateCommonBuffer”.
>>>>The physical and the virtual addresses of these buffers are stored.
All
>>>the
>>>>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA
>>chaining
>>>>transfer are stored in these allocated buffers.
>>>>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
>>>(METHOD_OUT_DIRECT),
>>>>I get the Mdl for the output buffer for the DMA transfer.
>>>>(4) The following set of operations are used to get the physical
>addresses
>>>>of the buffer referred to by the Mdl.
>>>> (a) Mdl = Irp->MdlAddress
>>>> (b) MmProbeAndLockPages()
>>>> (c) MmGetMdlByteCount ()
>>>> (d) MmGetMdlVirtualAddress ()
>>>> (e) MmGetMdlByteOffset()
>>>>(5) Determine the number of map registers required by using
>>>ADDRESS_AND_SIZE_TO_SPAN_PAGES
>>>>(6) Then determine howmany times the GetScatterGatherList needs to be
>>>called
>>>>by dividing the above result with the no of map registers allocated.
>>>>(7) If a scatter gather list alreday exists, clear it by calling
>>>PutScatterGatherList.
>>>>(8) Next Call ScatterGatherList with an adapter control routine.
>>>>(9) Mark the IRP Pending
>>>>
>>>>Adapter Control routine
>>>>----------------------------------
>>>>(10) Uses the elements of the scatter gather lsit to fill in the
>>>descriptors
>>>>allocated using the AllocatecommonBuffer.
>>>>(11) Once the descriptors are filled with the physical addresses
>obtained,
>>>>we next assign the DMA channel 0 descritor register wuth the address
>of
>>>the
>>>>first PCI descriptor by giving the physicall address of the first buffer
>>>>obtained via AllocateCommonBuffer API.
>>>>(3) Finally the DMA registers are filled to reflect chaining mode and
>>the
>>>>transferis started.
>>>>(4) the device physical address that I gave is the address at which
the
>>>device
>>>>has mapped the memory. This address is not the address that I see in
>>>Windows
>>>>in the resources tab for the driver.
>>>>(5) I complete the IRP in the DPC.
>>>>
>>>>Observation:
>>>>----------------------
>>>>(1) I tried for a small size of 0x3c bytes and found the device to
>>freeze…
>>>>(2) I suspect address given for DMA transfer. Are the PCI and device
>>>physical
>>>>addresses provided correct?
>>>>(3) To get the device back to normal operation, I have to restart the
>>>system.
>>>>(4) I get no interrupt so IRP remains pending.
>>>>
>>>>Where does the problem lie? Can u guide me?
>>>>
>>>>Regards,
>>>>Purvi
>>>>
>>>>
>>>>—
>>>>Questions? First check the Kernel Driver FAQ at
>>>http://www.osronline.com/article.cfm?id=256
>>>>
>>>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>>>‘’
>>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>
>>>
>>>
>>>
>>>—
>>>Questions? First check the Kernel Driver FAQ at
>>>http://www.osronline.com/article.cfm?id=256
>>>
>>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>>‘’
>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>
>>>
>>>
>>>—
>>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>>
>>>You are currently subscribed to ntdev as: xxxxx@tin.it
>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>‘’
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: xxxxx@tin.it
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@tin.it
>To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

Thanks PaoloC
Regards,
Purvi
----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Wednesday, October 20, 2004 8:09 PM
Subject: Re: [ntdev] DMA Problem

IIRC the “local address” is the address on the board bus where PLX DMA
bridge
will write/read the data when performing a DMA data operation.
In my board this address refers at a FIFO so it is never incremented during
the DMA operation and it is the same in each eantry of DMA descriptor list.
I do not think it is coming from any PLX register since it is the board
bus address where you want to move to/get from data.
May be you have to use a direct slave operation to get this address from
some specific memory location/register of the board.
I am not an expert of AllocateCommonBuffer operation.
I just noticed that returned address for my needed size was not aligned
so I made a trick to allocate a bigger buffer and use the first address
aligned according to PLX need.

Regards,
PaoloC
>– Messaggio originale –
>From: “Purvi Thakkar”
>To: “Windows System Software Devs Interest List”
>Subject: Re: [ntdev] DMA Problem
>Date: Wed, 20 Oct 2004 23:22:25 +0530
>Reply-To: “Windows System Software Devs Interest List”

>
>
>Hello PaoloC,
>
>Thanks for the help. I am not sure of this address. While the rest of the
>information matches with whatever u said. I will have to check up with
the
>hardware person then in this case. Do u have any idea if this address can
>be
>obtained from any PLX register(in your case)?
>
>As far as allocation of common buffer is concerned, my understanding is
as
>follows: Can u please confirm if my understanding is correct?
>(1) For allocation less than 1 PAGE_SIZE, u have to ensure 16 byte
>allignment for the descriptor table for PLX .
>(2) For allocation = PAGE_SIZE, u always get a value alligned to page
>boundary.
>(3) For allocation greater than PAGE_SIZE, u have to do a one time
>MapTransfer kind of operation after AllocateCommonBuffer by building Mdl
>to
>get the physical addresses of the allocated common buffer that span across
>various physical pages. May be we even have to do a 16 byte alignment for
>the first physical address obtained for the 1st map register.
>
>Best Regards,
>Purvi
>
>----- Original Message -----
>From:
>To: “Windows System Software Devs Interest List”
>Sent: Wednesday, October 20, 2004 7:07 PM
>Subject: Re: [ntdev] DMA Problem
>
>
>Hi Purvi,
>
>my “local address” is initialized in the following way:
>
>//
>// Setup the LOCAL BUS address
>//
>pDmaChannel->ulLocalAddress = (iChannel == DMA_WRITE_CHANNEL) ? 0x50000028
>: 0x50000030;
>
>Above hardcoded values were defined by the hardware guy who designed the
>board !
>IIRC they are the addresses (virtual ?) on the PLX board bus where are
>mapped the FIFOs I have to fill or to get data from with my driver DMA
>operations.
>
>PaoloC
>
>>– Messaggio originale –
>>From: “Purvi Thakkar”
>>To: “Windows System Software Devs Interest List”
>>Subject: Re: [ntdev] DMA Problem
>>Date: Wed, 20 Oct 2004 22:06:15 +0530
>>Reply-To: “Windows System Software Devs Interest List”
>
>>
>>
>>Hi! PaoloC,
>>
>>I have done the same thing but I am not sure of the local address value.
>>
>>What value did u enter for " pDmaChannel->ulLocalAddress" and from where
>>did
>>u get this value.
>>
>>Thanks and Best Regards,
>>Purvi
>>----- Original Message -----
>>From:
>>To: “Windows System Software Devs Interest List”
>>Sent: Wednesday, October 20, 2004 6:09 PM
>>Subject: Re: [ntdev] DMA Problem
>>
>>
>>Hi Purvi,
>>I use both the virtual & physical addresses returned by
>AllocateCommonBuffer
>>after I have rounded those addresses to the nearest 16 byte align.
>>Virtual address is used to access the DMA descriptor list and physical
>>address
>>is used to write the link between DMA descriptor entries, which will be
>>used by PLX device.
>>If you assume that my whole descriptor list is allocated in a single
buffer
>>returned by AllocateCommonBuffer you can understand the following piece
>>of code I am using to build the descriptor list:
>>
>>
>>
>>//
>>
>>// Virtual address to traverse the descriptor list
>>
>>//
>>
>>PPLX_DMA_DESCRIPTOR pPlxDescr = pDmaChannel->pPlxSGList;
>>
>>
>>
>>//
>>
>>// Physical address of next DMA descriptor used by PLX to traverse the
>chain
>>
>>//
>>
>>ULONG ulPlxNextDescr = pDmaChannel->ulPlxSGListPhysical + sizeof(
>>PLX_DMA_DESCRIPTOR
>>);
>>
>>
>>//
>>
>>// Building the descriptor list
>>
>>//
>>
>>for (ULONG k = 0;
>>
>>k < n;
>>
>>i++, k++, pPlxDescr++, ulPlxNextDescr += sizeof( PLX_DMA_DESCRIPTOR ))
>>
>>{
>>
>>pPlxDescr->ulPciAddress = sglist->Elements[i].Address.LowPart;
>>pPlxDescr->ulLocalAddress = pDmaChannel->ulLocalAddress;
>>pPlxDescr->ulCount = sglist->Elements[i].Length;
>>pPlxDescr->bitPciAddressSpace = 1;
>>
>>pPlxDescr->bitLocalToPciBus = pDmaChannel->bIsWrite ? 0 : 1;
>>pPlxDescr->bitEndOFChain = 0;
>>pPlxDescr->bitInterruptAfterTC = 0;
>>
>>pPlxDescr->bmNextDescrAddress = (ulPlxNextDescr >> 4);
>>
>>
>>
>>//
>>
>>// Update the number of bytes transferred so far
>>
>>//
>>
>>pDmaChannel->nbytes += sglist->Elements[i].Length;
>>
>>}
>>
>>
>>
>>//
>>
>>// Special processing for the last entry: end of list flag + generate
>>interrupt
>>+ no next
>>//
>>
>>pPlxDescr–;
>>
>>pPlxDescr->bitEndOFChain = 1;
>>
>>pPlxDescr->bitInterruptAfterTC = 1;
>>
>>
>>
>>Regards,
>>PaoloC
>>
>>
>>>– Messaggio originale –
>>>From: “Purvi Thakkar”
>>>To: “Windows System Software Devs Interest List”
>>>Subject: Re: [ntdev] DMA Problem
>>>Date: Wed, 20 Oct 2004 21:06:05 +0530
>>>Reply-To: “Windows System Software Devs Interest List”
>>
>>>
>>>
>>>Hello PaoloC,
>>>
>>>This was indeed a good piece of information. But I have taken care of
>this
>>>by calling AllocateCommonBuffer 33 times each time requesting a page
of
>>>memory i.e. 4096 bytes thereby taking care of the alignment issue. I
even
>>>checked the physical and virtual addresses obtained and they are also
>>>aligned to a 16 byte boundary. This 16 byte boundary alignment is also
>>a
>>>requirement for PLX 9080.
>>>
>>>I am not sure of the pci and local addresses that are entered into the
>>>descriptor. Could u throw some light on it. They are physical addresses
>>but
>>>with respect to PCI host space, local address space or something else.
>>What
>>>did u do when programing for DMA chaining.
>>>
>>>Thanks and Best Regards,
>>>Purvi
>>>----- Original Message -----
>>>From:
>>>To: “Windows System Software Devs Interest List”
>>>Sent: Wednesday, October 20, 2004 4:33 PM
>>>Subject: RE: [ntdev] DMA Problem
>>>
>>>
>>>Well I do not known PLX9080 bridge.
>>>Anyway in a driver I wrote for PLX9056 I was in trouble until I realize
>>>(read in the datasheet) that DMA descriptor MUST be aligned on a 16
byte
>>>address.
>>>And AllocateCommonBuffer does not returns aligned data.
>>>So I modify the allocation of DMA descriptors to something like this:
>>>
>>>//
>>>// Requesting one extra entry so that we can align on 16 byte boundary
>>>//
>>>pDmaChannel->ulSGListSize = sizeof(PLX_DMA_DESCRIPTOR) * (MAXSG + 1);
>>>
>>>//
>>>// AllocateCommonBuffer allocates memory and maps it so that it is
>>>simultaneously
>>>
>>>// accessible from both the processor and a device for DMA operations.
>>>// AllocateCommonBuffer returns the base virtual address of the allocated
>>>range.
>>>// If the buffer cannot be allocated, it returns NULL.
>>>//
>>>pDmaChannel->pvPlxSGListUnaligned =
>>>(*pDmaChannel->AdapterObject->DmaOperations->AllocateCommonBuffer)
>>>(pDmaChannel->AdapterObject, // IN PDMA_ADAPTER DmaAdapter,
>>>…
>>>…
>>>
>>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL unaligned
virtual
>>>= 0x%X physical = 0x%X\n",
>>>pDmaChannel->pvPlxSGListUnaligned,
>>>pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>>));
>>>
>>>//
>>>// Align on 16 byte boundary as required by PLX device
>>>//
>>>pDmaChannel->pPlxSGList = reinterpret_cast <pplx_dma_descriptor>
>>>(((ULONG)pDmaChannel->pvPlxSGListUnaligned
>>>+ 0xF) & 0xFFFFFFF0);
>>>pDmaChannel->ulPlxSGListPhysical =
>>>((ULONG)pDmaChannel->paPlxSGListPhysicalUnaligned.u.LowPart
>>>+ 0xF) & 0xFFFFFFF0;
>>>
>>>KdPrint((DRIVERNAME " - [PlxDeviceResourcesAllocate] SGL aligned
virtual
>>>= 0x%X physical = 0x%X\n",
>>>(ULONG) pDmaChannel->pPlxSGList, pDmaChannel->ulPlxSGListPhysical ));
>>>
>>>
>>>Hope this can help,
>>>PaoloC
>>>
>>>
>>>>– Messaggio originale –
>>>>From: “Purvi Thakkar”
>>>>To: “Windows System Software Devs Interest List”
>>>>Subject: [ntdev] DMA Problem
>>>>Date: Wed, 20 Oct 2004 17:45:17 +0530
>>>>Reply-To: “Windows System Software Devs Interest List”
>>>
>>>>
>>>>
>>>>Hello,
>>>>
>>>>I am facing a problem while writing a WDM DMA driver for a PCI chipset
>>>PLX
>>>>9080. I have to use the DMA chaining mode of PLX 9080. The descripor
>>list
>>>>for DMA chaining has to be on the PCI host.
>>>>
>>>>I have carried out the following steps so far.
>>>>(1) In the start device got access to the DMA Adapter object by using
>>>“IoGetDmaAdapter”
>>>>(2) Then used the Adpater object pointer to allocate 33 buffers using
>>>“AllocateCommonBuffer”.
>>>>The physical and the virtual addresses of these buffers are stored.
All
>>>the
>>>>33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA
>>chaining
>>>>transfer are stored in these allocated buffers.
>>>>(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
>>>(METHOD_OUT_DIRECT),
>>>>I get the Mdl for the output buffer for the DMA transfer.
>>>>(4) The following set of operations are used to get the physical
>addresses
>>>>of the buffer referred to by the Mdl.
>>>> (a) Mdl = Irp->MdlAddress
>>>> (b) MmProbeAndLockPages()
>>>> (c) MmGetMdlByteCount ()
>>>> (d) MmGetMdlVirtualAddress ()
>>>> (e) MmGetMdlByteOffset()
>>>>(5) Determine the number of map registers required by using
>>>ADDRESS_AND_SIZE_TO_SPAN_PAGES
>>>>(6) Then determine howmany times the GetScatterGatherList needs to be
>>>called
>>>>by dividing the above result with the no of map registers allocated.
>>>>(7) If a scatter gather list alreday exists, clear it by calling
>>>PutScatterGatherList.
>>>>(8) Next Call ScatterGatherList with an adapter control routine.
>>>>(9) Mark the IRP Pending
>>>>
>>>>Adapter Control routine
>>>>----------------------------------
>>>>(10) Uses the elements of the scatter gather lsit to fill in the
>>>descriptors
>>>>allocated using the AllocatecommonBuffer.
>>>>(11) Once the descriptors are filled with the physical addresses
>obtained,
>>>>we next assign the DMA channel 0 descritor register wuth the address
>of
>>>the
>>>>first PCI descriptor by giving the physicall address of the first buffer
>>>>obtained via AllocateCommonBuffer API.
>>>>(3) Finally the DMA registers are filled to reflect chaining mode and
>>the
>>>>transferis started.
>>>>(4) the device physical address that I gave is the address at which
the
>>>device
>>>>has mapped the memory. This address is not the address that I see in
>>>Windows
>>>>in the resources tab for the driver.
>>>>(5) I complete the IRP in the DPC.
>>>>
>>>>Observation:
>>>>----------------------
>>>>(1) I tried for a small size of 0x3c bytes and found the device to
>>freeze…
>>>>(2) I suspect address given for DMA transfer. Are the PCI and device
>>>physical
>>>>addresses provided correct?
>>>>(3) To get the device back to normal operation, I have to restart the
>>>system.
>>>>(4) I get no interrupt so IRP remains pending.
>>>>
>>>>Where does the problem lie? Can u guide me?
>>>>
>>>>Regards,
>>>>Purvi
>>>>
>>>>
>>>>—
>>>>Questions? First check the Kernel Driver FAQ at
>>>http://www.osronline.com/article.cfm?id=256
>>>>
>>>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>>>‘’
>>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>
>>>
>>>
>>>
>>>—
>>>Questions? First check the Kernel Driver FAQ at
>>>http://www.osronline.com/article.cfm?id=256
>>>
>>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>>‘’
>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>>
>>>
>>>
>>>—
>>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>>
>>>You are currently subscribed to ntdev as: xxxxx@tin.it
>>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
>‘’
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>>
>>
>>
>>—
>>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>>
>>You are currently subscribed to ntdev as: xxxxx@tin.it
>>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
>http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
>To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>
>
>—
>Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
>You are currently subscribed to ntdev as: xxxxx@tin.it
>To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</pplx_dma_descriptor>

Well, I think the key here is your last statement (observation
4)…

(4) I get
no interrupt so IRP remains pending.

You need to determine why the PCI card doesn’t generate an interrupt. It
could be that its DMA engine was not started properly, or the parameters
written to its registers were incorrect.

A PCI bus analyzer more than paid for itself when I was debugging our own
inhouse designed PCI card, especially regarding DMA.

As for our card, it doesn’t support scatter/gather, so I had to implement
the different chains in the driver (although I am discussing with the
hardware engineer about implementing it. Fortunately, we use a Xylinx
FPGA core so changes are simply a matter of flashing new FPGA code to the
card). I also use driverworks which made the code pretty
straightforward.

At 05:45 PM 10/20/2004 +0530, you wrote:

Hello,

 

I am facing a problem while writing a WDM DMA
driver for a PCI chipset PLX 9080. I have to use the DMA chaining
mode of PLX 9080. The descripor list for DMA chaining has to be on the
PCI host.

 

I have carried out the following steps so
far.

(1) In the start device got access to the DMA
Adapter object by using “IoGetDmaAdapter”

(2) Then used the Adpater object pointer to
allocate 33 buffers using “AllocateCommonBuffer”. The physical
and the virtual addresses of these buffers are stored. All the 33 buffers
are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining transfer
are stored in these allocated buffers.

(3) When a IOCTL write is fired to the DMA
device object with DIRECT_IO (METHOD_OUT_DIRECT), I get the Mdl for the
output buffer for the DMA transfer.

(4) The following set of operations are used to
get the physical addresses of the buffer referred to by the
Mdl.

(a) Mdl =
Irp->MdlAddress

(b)
MmProbeAndLockPages()

(c) MmGetMdlByteCount
()

(d) MmGetMdlVirtualAddress
()

(e)
MmGetMdlByteOffset()

(5) Determine the number of map registers
required by using ADDRESS_AND_SIZE_TO_SPAN_PAGES

(6) Then determine howmany times the
GetScatterGatherList needs to be called by dividing the above result with
the no of map registers allocated.

(7) If a scatter gather list alreday exists,
clear it by calling PutScatterGatherList.

(8) Next Call ScatterGatherList with an adapter
control routine.

(9) Mark the IRP Pending

 

Adapter Control routine

----------------------------------

(10) Uses the elements of the scatter gather
lsit to fill in the descriptors allocated using the
AllocatecommonBuffer.

(11) Once the descriptors are filled with the
physical addresses obtained, we next assign the DMA channel 0 descritor
register wuth the address of the first PCI descriptor by giving the
physicall address of the first buffer obtained via AllocateCommonBuffer
API.

(3) Finally the DMA registers are filled to
reflect chaining mode and the transferis started.

(4) the device physical address that I gave is
the address at which the device has mapped the memory. This address is
not the address that I see in Windows in the resources tab for the
driver.

(5) I complete the IRP in the DPC.

 

Observation:

----------------------

(1) I tried for a small size of 0x3c bytes and
found the device to freeze.

(2) I suspect address given for DMA transfer.
Are the PCI and device physical addresses provided correct?

(3) To get the device back to normal operation,
I have to restart the system.

(4) I get no interrupt so IRP remains
pending.

 

Where does the problem lie? Can u guide
me?

 

Regards,

Purvi

 


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’

To unsubscribe send a blank email to xxxxx@lists.osr.com


Russ Poffenberger

Credence Systems Corp.

xxxxx@credence.com

Hi,
several possible reasons for your problem:
a) worst one - you properly initialized DMA transfer, but there’s no
interrupt because of hardware problem.
b) more probable one - improper initialization.
First of all - is 9080 chip itself properly initialized ? What is in PCI
configuration register 0x4? BusMaster enabled? Memory Space enabled? What
is written to Local Bus Region configuration register (Local Configuration
Register 0x18)?
If all is fine, is your descriptor chain valid? Each descriptor contains of
4 32-bit values. PCI address, local address, data length count and address
of next descriptor. Lower 4 bits of next descriptor address are used for
service flags - transfer direction (bit 3), are descriptors stored in local
memory or on host (bit 1), is it end of chain (bit 2). Is end of chain bit
set in last descriptor?
And, of course, check once more how you are setting the DMA (What are you
writing to 0x80? Is doneIntEnable - bit 10 - set? Is address of first
descriptor written to 0x90? What are you writing to 0xA8? )

Regards,
Alex Krol

-----Original Message-----
From: Purvi Thakkar [mailto:xxxxx@patni.ecnet.jp]
Sent: Wednesday, October 20, 2004 2:47 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] DMA Problem

Hello,

One more input…

In the resources tab for the driver of the device, windows does not show any
DMA resouce type. I hope this is OK as it is to be seen only for ISA DMA
devices and this is a PCI plx 9080 chipset. Is this understanding OK?

Regards,
Purvi

----- Original Message -----
From: Purvi mailto:xxxxx Thakkar
To: xxxxx@lists.osr.com mailto:xxxxx
Sent: Wednesday, October 20, 2004 5:45 PM
Subject: DMA Problem

Hello,

I am facing a problem while writing a WDM DMA driver for a PCI chipset PLX
9080. I have to use the DMA chaining mode of PLX 9080. The descripor list
for DMA chaining has to be on the PCI host.

I have carried out the following steps so far.
(1) In the start device got access to the DMA Adapter object by using
“IoGetDmaAdapter”
(2) Then used the Adpater object pointer to allocate 33 buffers using
“AllocateCommonBuffer”. The physical and the virtual addresses of these
buffers are stored. All the 33 buffers are of PAGE_SIZE. Next, the PCI
descriptors for the DMA chaining transfer are stored in these allocated
buffers.
(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
(METHOD_OUT_DIRECT), I get the Mdl for the output buffer for the DMA
transfer.
(4) The following set of operations are used to get the physical addresses
of the buffer referred to by the Mdl.
(a) Mdl = Irp->MdlAddress
(b) MmProbeAndLockPages()
(c) MmGetMdlByteCount ()
(d) MmGetMdlVirtualAddress ()
(e) MmGetMdlByteOffset()
(5) Determine the number of map registers required by using
ADDRESS_AND_SIZE_TO_SPAN_PAGES
(6) Then determine howmany times the GetScatterGatherList needs to be called
by dividing the above result with the no of map registers allocated.
(7) If a scatter gather list alreday exists, clear it by calling
PutScatterGatherList.
(8) Next Call ScatterGatherList with an adapter control routine.
(9) Mark the IRP Pending

Adapter Control routine
----------------------------------
(10) Uses the elements of the scatter gather lsit to fill in the descriptors
allocated using the AllocatecommonBuffer.
(11) Once the descriptors are filled with the physical addresses obtained,
we next assign the DMA channel 0 descritor register wuth the address of the
first PCI descriptor by giving the physicall address of the first buffer
obtained via AllocateCommonBuffer API.
(3) Finally the DMA registers are filled to reflect chaining mode and the
transferis started.
(4) the device physical address that I gave is the address at which the
device has mapped the memory. This address is not the address that I see in
Windows in the resources tab for the driver.
(5) I complete the IRP in the DPC.

Observation:
----------------------
(1) I tried for a small size of 0x3c bytes and found the device to freeze.
(2) I suspect address given for DMA transfer. Are the PCI and device
physical addresses provided correct?
(3) To get the device back to normal operation, I have to restart the
system.
(4) I get no interrupt so IRP remains pending.

Where does the problem lie? Can u guide me?

Regards,
Purvi


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</mailto:xxxxx></mailto:xxxxx>

Correction: end of chain flag - bit 1, descriptor location flag - bit 0.

-----Original Message-----
From: Alexander Krol [mailto:xxxxx@creo.com]
Sent: Wednesday, October 20, 2004 5:53 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] DMA Problem

Hi,
several possible reasons for your problem:
a) worst one - you properly initialized DMA transfer, but there’s no
interrupt because of hardware problem.
b) more probable one - improper initialization.
First of all - is 9080 chip itself properly initialized ? What is in PCI
configuration register 0x4? BusMaster enabled? Memory Space enabled? What
is written to Local Bus Region configuration register (Local Configuration
Register 0x18)?
If all is fine, is your descriptor chain valid? Each descriptor contains of
4 32-bit values. PCI address, local address, data length count and address
of next descriptor. Lower 4 bits of next descriptor address are used for
service flags - transfer direction (bit 3), are descriptors stored in local
memory or on host (bit 1), is it end of chain (bit 2). Is end of chain bit
set in last descriptor?
And, of course, check once more how you are setting the DMA (What are you
writing to 0x80? Is doneIntEnable - bit 10 - set? Is address of first
descriptor written to 0x90? What are you writing to 0xA8? )

Regards,
Alex Krol

-----Original Message-----
From: Purvi Thakkar [mailto:xxxxx@patni.ecnet.jp]
Sent: Wednesday, October 20, 2004 2:47 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] DMA Problem

Hello,

One more input…

In the resources tab for the driver of the device, windows does not show any
DMA resouce type. I hope this is OK as it is to be seen only for ISA DMA
devices and this is a PCI plx 9080 chipset. Is this understanding OK?

Regards,
Purvi

----- Original Message -----
From: Purvi mailto:xxxxx Thakkar
To: xxxxx@lists.osr.com mailto:xxxxx
Sent: Wednesday, October 20, 2004 5:45 PM
Subject: DMA Problem

Hello,

I am facing a problem while writing a WDM DMA driver for a PCI chipset PLX
9080. I have to use the DMA chaining mode of PLX 9080. The descripor list
for DMA chaining has to be on the PCI host.

I have carried out the following steps so far.
(1) In the start device got access to the DMA Adapter object by using
“IoGetDmaAdapter”
(2) Then used the Adpater object pointer to allocate 33 buffers using
“AllocateCommonBuffer”. The physical and the virtual addresses of these
buffers are stored. All the 33 buffers are of PAGE_SIZE. Next, the PCI
descriptors for the DMA chaining transfer are stored in these allocated
buffers.
(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO
(METHOD_OUT_DIRECT), I get the Mdl for the output buffer for the DMA
transfer.
(4) The following set of operations are used to get the physical addresses
of the buffer referred to by the Mdl.
(a) Mdl = Irp->MdlAddress
(b) MmProbeAndLockPages()
(c) MmGetMdlByteCount ()
(d) MmGetMdlVirtualAddress ()
(e) MmGetMdlByteOffset()
(5) Determine the number of map registers required by using
ADDRESS_AND_SIZE_TO_SPAN_PAGES
(6) Then determine howmany times the GetScatterGatherList needs to be called
by dividing the above result with the no of map registers allocated.
(7) If a scatter gather list alreday exists, clear it by calling
PutScatterGatherList.
(8) Next Call ScatterGatherList with an adapter control routine.
(9) Mark the IRP Pending

Adapter Control routine
----------------------------------
(10) Uses the elements of the scatter gather lsit to fill in the descriptors
allocated using the AllocatecommonBuffer.
(11) Once the descriptors are filled with the physical addresses obtained,
we next assign the DMA channel 0 descritor register wuth the address of the
first PCI descriptor by giving the physicall address of the first buffer
obtained via AllocateCommonBuffer API.
(3) Finally the DMA registers are filled to reflect chaining mode and the
transferis started.
(4) the device physical address that I gave is the address at which the
device has mapped the memory. This address is not the address that I see in
Windows in the resources tab for the driver.
(5) I complete the IRP in the DPC.

Observation:
----------------------
(1) I tried for a small size of 0x3c bytes and found the device to freeze.
(2) I suspect address given for DMA transfer. Are the PCI and device
physical addresses provided correct?
(3) To get the device back to normal operation, I have to restart the
system.
(4) I get no interrupt so IRP remains pending.

Where does the problem lie? Can u guide me?

Regards,
Purvi


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@creo.com
To unsubscribe send a blank email to xxxxx@lists.osr.com</mailto:xxxxx></mailto:xxxxx>

Please allocate 1 common buffer of 33 pages in size. Allocating lots of common buffers is a very bad idea.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com

----- Original Message -----
From: Purvi Thakkar
To: Windows System Software Devs Interest List
Sent: Wednesday, October 20, 2004 4:15 PM
Subject: [ntdev] DMA Problem

Hello,

I am facing a problem while writing a WDM DMA driver for a PCI chipset PLX 9080. I have to use the DMA chaining mode of PLX 9080. The descripor list for DMA chaining has to be on the PCI host.

I have carried out the following steps so far.
(1) In the start device got access to the DMA Adapter object by using "IoGetDmaAdapter"
(2) Then used the Adpater object pointer to allocate 33 buffers using "AllocateCommonBuffer". The physical and the virtual addresses of these buffers are stored. All the 33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining transfer are stored in these allocated buffers.
(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO (METHOD_OUT_DIRECT), I get the Mdl for the output buffer for the DMA transfer.
(4) The following set of operations are used to get the physical addresses of the buffer referred to by the Mdl.
(a) Mdl = Irp->MdlAddress
(b) MmProbeAndLockPages()
(c) MmGetMdlByteCount ()
(d) MmGetMdlVirtualAddress ()
(e) MmGetMdlByteOffset()
(5) Determine the number of map registers required by using ADDRESS_AND_SIZE_TO_SPAN_PAGES
(6) Then determine howmany times the GetScatterGatherList needs to be called by dividing the above result with the no of map registers allocated.
(7) If a scatter gather list alreday exists, clear it by calling PutScatterGatherList.
(8) Next Call ScatterGatherList with an adapter control routine.
(9) Mark the IRP Pending

Adapter Control routine

(10) Uses the elements of the scatter gather lsit to fill in the descriptors allocated using the AllocatecommonBuffer.
(11) Once the descriptors are filled with the physical addresses obtained, we next assign the DMA channel 0 descritor register wuth the address of the first PCI descriptor by giving the physicall address of the first buffer obtained via AllocateCommonBuffer API.
(3) Finally the DMA registers are filled to reflect chaining mode and the transferis started.
(4) the device physical address that I gave is the address at which the device has mapped the memory. This address is not the address that I see in Windows in the resources tab for the driver.
(5) I complete the IRP in the DPC.

Observation:

(1) I tried for a small size of 0x3c bytes and found the device to freeze.
(2) I suspect address given for DMA transfer. Are the PCI and device physical addresses provided correct?
(3) To get the device back to normal operation, I have to restart the system.
(4) I get no interrupt so IRP remains pending.

Where does the problem lie? Can u guide me?

Regards,
Purvi


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@lists.osr.com

DMA resource type is for ISA only.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com

----- Original Message -----
From: Purvi Thakkar
To: Windows System Software Devs Interest List
Sent: Wednesday, October 20, 2004 4:47 PM
Subject: Re:[ntdev] DMA Problem

Hello,

One more input...

In the resources tab for the driver of the device, windows does not show any DMA resouce type. I hope this is OK as it is to be seen only for ISA DMA devices and this is a PCI plx 9080 chipset. Is this understanding OK?

Regards,
Purvi
----- Original Message -----
From: Purvi Thakkar
To: xxxxx@lists.osr.com
Sent: Wednesday, October 20, 2004 5:45 PM
Subject: DMA Problem

Hello,

I am facing a problem while writing a WDM DMA driver for a PCI chipset PLX 9080. I have to use the DMA chaining mode of PLX 9080. The descripor list for DMA chaining has to be on the PCI host.

I have carried out the following steps so far.
(1) In the start device got access to the DMA Adapter object by using "IoGetDmaAdapter"
(2) Then used the Adpater object pointer to allocate 33 buffers using "AllocateCommonBuffer". The physical and the virtual addresses of these buffers are stored. All the 33 buffers are of PAGE_SIZE. Next, the PCI descriptors for the DMA chaining transfer are stored in these allocated buffers.
(3) When a IOCTL write is fired to the DMA device object with DIRECT_IO (METHOD_OUT_DIRECT), I get the Mdl for the output buffer for the DMA transfer.
(4) The following set of operations are used to get the physical addresses of the buffer referred to by the Mdl.
(a) Mdl = Irp->MdlAddress
(b) MmProbeAndLockPages()
(c) MmGetMdlByteCount ()
(d) MmGetMdlVirtualAddress ()
(e) MmGetMdlByteOffset()
(5) Determine the number of map registers required by using ADDRESS_AND_SIZE_TO_SPAN_PAGES
(6) Then determine howmany times the GetScatterGatherList needs to be called by dividing the above result with the no of map registers allocated.
(7) If a scatter gather list alreday exists, clear it by calling PutScatterGatherList.
(8) Next Call ScatterGatherList with an adapter control routine.
(9) Mark the IRP Pending

Adapter Control routine

(10) Uses the elements of the scatter gather lsit to fill in the descriptors allocated using the AllocatecommonBuffer.
(11) Once the descriptors are filled with the physical addresses obtained, we next assign the DMA channel 0 descritor register wuth the address of the first PCI descriptor by giving the physicall address of the first buffer obtained via AllocateCommonBuffer API.
(3) Finally the DMA registers are filled to reflect chaining mode and the transferis started.
(4) the device physical address that I gave is the address at which the device has mapped the memory. This address is not the address that I see in Windows in the resources tab for the driver.
(5) I complete the IRP in the DPC.

Observation:

(1) I tried for a small size of 0x3c bytes and found the device to freeze.
(2) I suspect address given for DMA transfer. Are the PCI and device physical addresses provided correct?
(3) To get the device back to normal operation, I have to restart the system.
(4) I get no interrupt so IRP remains pending.

Where does the problem lie? Can u guide me?

Regards,
Purvi


Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ''
To unsubscribe send a blank email to xxxxx@lists.osr.com

IIRC ISA busmastering (MASTER# wire) was always very limited, and thus
never used except something very special.

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

----- Original Message -----
From: “Mats PETERSSON”
To: “Windows System Software Devs Interest List”
Sent: Wednesday, October 20, 2004 1:31 PM
Subject: Re:[ntdev] DMA Problem

>
>
>
>
>
> Yes, I think that’s correct. DMA resources are only used by ISA cards[1].
>
> PCI definitely expects the hardware to know how to read/write memory
> through it’s own bus, rather than relying on an external DMA circuit, so
> there should be no DMA channel used by the PCI express.
>
> [1] It’s perfectly possible to build intelligent “bus mastering” devices
> for the ISA bus too. The DMA system is really there for use with quite old
> devices that do not have the logic to read/write memory directly, but would
> output data to be transferred by the DMA unit. This is an ANCIENT design,
> and most ISA Ethernet devices for instance, will do direct memory accesses
> from the ISA board itself.
>
> –
> Mats
>
> xxxxx@lists.osr.com wrote on 10/20/2004 01:47:12 PM:
>
> > Hello,
> >
> > One more input…
> >
> > In the resources tab for the driver of the device, windows does not
> > show any DMA resouce type. I hope this is OK as it is to be seen
> > only for ISA DMA devices and this is a PCI plx 9080 chipset. Is this
> > understanding OK?
> >
> > Regards,
> > Purvi
> > ----- Original Message -----
> > From: Purvi Thakkar
> > To: xxxxx@lists.osr.com
> > Sent: Wednesday, October 20, 2004 5:45 PM
> > Subject: DMA Problem
> >
> > Hello,
> >
> > I am facing a problem while writing a WDM DMA driver for a PCI
> > chipset PLX 9080. I have to use the DMA chaining mode of PLX 9080.
> > The descripor list for DMA chaining has to be on the PCI host.
> >
> > I have carried out the following steps so far.
> > (1) In the start device got access to the DMA Adapter object by
> > using “IoGetDmaAdapter”
> > (2) Then used the Adpater object pointer to allocate 33 buffers
> > using “AllocateCommonBuffer”. The physical and the virtual addresses
> > of these buffers are stored. All the 33 buffers are of PAGE_SIZE.
> > Next, the PCI descriptors for the DMA chaining transfer are stored
> > in these allocated buffers.
> > (3) When a IOCTL write is fired to the DMA device object with
> > DIRECT_IO (METHOD_OUT_DIRECT), I get the Mdl for the output buffer
> > for the DMA transfer.
> > (4) The following set of operations are used to get the physical
> > addresses of the buffer referred to by the Mdl.
> > (a) Mdl = Irp->MdlAddress
> > (b) MmProbeAndLockPages()
> > (c) MmGetMdlByteCount ()
> > (d) MmGetMdlVirtualAddress ()
> > (e) MmGetMdlByteOffset()
> > (5) Determine the number of map registers required by using
> > ADDRESS_AND_SIZE_TO_SPAN_PAGES
> > (6) Then determine howmany times the GetScatterGatherList needs to
> > be called by dividing the above result with the no of map registers
> allocated.
> > (7) If a scatter gather list alreday exists, clear it by calling
> > PutScatterGatherList.
> > (8) Next Call ScatterGatherList with an adapter control routine.
> > (9) Mark the IRP Pending
> >
> > Adapter Control routine
> > ----------------------------------
> > (10) Uses the elements of the scatter gather lsit to fill in the
> > descriptors allocated using the AllocatecommonBuffer.
> > (11) Once the descriptors are filled with the physical addresses
> > obtained, we next assign the DMA channel 0 descritor register wuth
> > the address of the first PCI descriptor by giving the physicall
> > address of the first buffer obtained via AllocateCommonBuffer API.
> > (3) Finally the DMA registers are filled to reflect chaining mode
> > and the transferis started.
> > (4) the device physical address that I gave is the address at which
> > the device has mapped the memory. This address is not the address
> > that I see in Windows in the resources tab for the driver.
> > (5) I complete the IRP in the DPC.
> >
> > Observation:
> > ----------------------
> > (1) I tried for a small size of 0x3c bytes and found the device to
> freeze.
> > (2) I suspect address given for DMA transfer. Are the PCI and device
> > physical addresses provided correct?
> > (3) To get the device back to normal operation, I have to restart the
> system.
> > (4) I get no interrupt so IRP remains pending.
> >
> > Where does the problem lie? Can u guide me?
> >
> > Regards,
> > Purvi
> >
> > —
> > Questions? First check the Kernel Driver FAQ at http://www.
> > osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: unknown lmsubst tag argument:
> ‘’
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> > ForwardSourceID:NT00005BB2
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

The Windows 2000 DDK said:

If a driver needs several pages of common buffer space, but the pages need not be contiguous, the driver should make several one-page requests to AllocateCommonBuffer instead of one large request. This approach conserves contiguous memory.

Sounds like the reverse of what you’re saying?

Andreas

----- Original Message -----
From: Maxim S. Shatskih
To: Windows System Software Devs Interest List
Sent: Wednesday, October 20, 2004 9:59 PM
Subject: Re: [ntdev] DMA Problem

Please allocate 1 common buffer of 33 pages in size. Allocating lots of common buffers is a very bad idea.

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

I think that perhaps if you are a boot start unloadable driver the single
allocation is a good idea while if you are dynamically loadable and in
particular not a boot start driver then the 33-one page allocations might
have a better chance of success.

=====================
Mark Roddy


From: Andreas Hansson [mailto:xxxxx@briljant.se]
Sent: Monday, October 25, 2004 12:29 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] DMA Problem

The Windows 2000 DDK said:

If a driver needs several pages of common buffer space, but the pages need
not be contiguous, the driver should make several one-page requests to
AllocateCommonBuffer instead of one large request. This approach conserves
contiguous memory.

Sounds like the reverse of what you’re saying?

Andreas

----- Original Message -----
From: Maxim S. mailto:xxxxx Shatskih
To: Windows System Software Devs Interest mailto:xxxxx List

Sent: Wednesday, October 20, 2004 9:59 PM
Subject: Re: [ntdev] DMA Problem

Please allocate 1 common buffer of 33 pages in size. Allocating lots of
common buffers is a very bad idea.

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


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com</http:></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx>