Hello,
We are facing some issues when trying to use the MPC8313e DMA peripheral. When we start a DMA transaction our system freezes so we must reset it. We are trying several buffer configurations (dynamical and static) and various transfer sizes but the same problem keeps on happening, the systems stops responding. There is also an important thing that may help you to find the cause. Sometimes the system freezes at the first transaction, but sometimes it happens later.
Below you can find the piece of code that fails. This code works without DMA (using a write loop). Could you please help us identifying the wrong part?
Thanks in advance.
DMA: memory to PCI (4byte, direct mode, snooping).
Memory buffer from kmalloc
1000 bytes
// pointer to the kmalloc'd area, rounded up to a page boundary
static char *buffer_area;
// original pointer for kmalloc'd area as returned by kmalloc
static void *buffer_ptr;
initmodule
{
....
// Allocate a memory area with kmalloc. Will be rounded up to a page boundary
buffer_ptr = kmalloc((NPAGES + 2) * PAGE_SIZE, GFP_KERNEL);
if ( buffer_ptr == NULL)
{
printk ( KERN_ALERT "\n\tERROR: kmalloc\n");
return -ENOMEM;
}
// round it up to the page bondary
buffer_area = (int *)((((unsigned long)buffer_ptr) + PAGE_SIZE - 1) & PAGE_MASK);
printk ("\n\tkmalloc buffer (0x%.8x@%lu)...", buffer_area,(NPAGES + 2) * PAGE_SIZE);
.....
}
fileoperation_write(buff,count_c)
{
int *buffer=(int *)buffer_area;
printk("pci_writeMA buffer %.8x v - %.8x p - %.8x b\n",
buffer, virt_to_phys(buffer), virt_to_bus(buffer));
copy_from_user((void *)buffer,(void *)buf,count_c);
*dmadar1=swapbyte(PCI_ADDR); //Dest Address
*dmasar1=swapbyte(virt_to_phys (buffer)); //Source Address
....
*dmabcr1=swapbyte(wr); //Byte count
*dmamr1=DMAMR_WR; //Config Mode
printk("DMA_WR: Before START\n");
print_config_DMA();
*dmamr1=DMAMR_WR_S; //Start DMA
printk("DMA_WR: After START\n");
print_config_DMA();
....
}
Console output:
(init)
kmalloc buffer (0xc0998000@28672)...
(fo_write)
pci_writeMA buffer c7fb0000 v - 07fb0000 p - 07fb0000 b
DMA_WR: Before START
Config DMA
MODE STATUS DESC ACT SOURCE DEST COUNT NEXT DESC
(1) 04801200 00000000 00000000 00009c00 004000e3 e8030000 00000000
DMA_WR: After START
Config DMA
MODE STATUS DESC ACT SOURCE DEST COUNT NEXT DESC
(1) Here is where the system stops. There should be written the same as in the previous example
Thanks,
Medina