请教linux&2440下DMA驱动问题
想写一个linux下DMA驱动,主要功能是将一个固定地址端口的数据传入内存
写的时候仿照内核中uda1341的驱动中的s3c2410iis_dma_in部分编写
问题出现在s3c2410_dma_enqueue中,在read()中调用了s3c2410_dma_enqueue函数,如下:
static ssize_t ad_read(struct file *file, char *buffer, size_t count, loff_t *offset)
{
const char *buffer0 = buffer;
ad_stream_t *s = &ad_stream;
unsigned long flags;
//int chunksize, ret = 0;
printk("ad_read: count=%d\n", count);
if ( !s->buffers )
{
if ( ad_setup_buf ( s ) )
return -ENOMEM;
ad_buf_t *b = s->buf;
down ( &b->sem );
printk("it is ok until here!1\n" );
s3c2410_dma_enqueue ( s->dma_ch, ( void * ) b, b->dma_addr, s->fragsize );
printk( "it is ok until here!3\n" );
}
return 0;
}
程序执行到s3c2410_dma_enqueue后停止,出现:
s3c2410_dma_start is at end !
the curr_tc is 107a40
s3c2410_dma_irq is running!
BUG: soft lockup - CPU#0 stuck for 61s! [ad_dma:923]
Modules linked in: ad_dma
Pid: 923, comm: ad_dma
CPU: 0 Not tainted (2.6.28.7 #355)
PC is at handle_IRQ_event+0x34/0x80
LR is at handle_edge_irq+0x104/0x144
pc : [<c006b3d8>] lr : [<c006cc18>] psr: 60000013
跟踪到plat-s3c24xx\dma.c,发现程序在s3c2410_dma_enqueue()的最后执行了local_irq_restore(flags)后停止(此时DMA的计数器不为0),随后进入中断(此时DMA计数器应该为0了),程序出error
感觉在local_irq_restore(flags)执行后,程序应该是继续向下执行直到DMA计数器为0产生中断,但是这里给人的感觉是local_irq_restore(flags)执行完了系统死锁了,不向下执行了,但是又能进中断,不知道怎么把程序调通……
在这个地方徘徊了N多天了,盼望牛人拯救啊!!!!