阅读:5432回复:9
请教PCI9054驱动程序中断服务程序中如何区分DMA完成中断和LINT#?
小弟在写一个小的驱动程序,想以PCI本地中断来触发DMA传输。用的DS3.1开发环境,在中断服务例程中BOOLEAN PLX9054Device::Isr_Irq(void) 该如何判断驱动程序现在扑捉的中断是DMA传输完成中断 还是本地LINT#的引起的中断。
我的Isr_Irq(void) 例程中是想用 status=m_IoPortRange0.ind(INTCSR); ST=status & 0x208000; if(ST==0x200000) //判别为DMA传输中断 { } else if(ST==0x8000) //判别为LINT#中断 { } 来判别的,但是失败了,请教高手 DMA传输完成中断和LINT#中断 INTCSR此时的值分别应该是什么? 小弟用的是PCI9054芯片。 扑捉到LINT#中断以后,触发DMA传输,或着采用事件通知应用程序 是不是应该在延迟过程调用DpcFor_Irq();中设置? 我现在最大的问题是扑捉不到LINT#中断 ,但是能扑捉到DMA传输中断。还想请问一个问题,如果我用SOFTICE调试程序,我应该用什么命令去查看INTCSR寄存器的内容 ,谢谢!! 请高手指点一二,小弟感激不尽 另外还有一个困惑已久的问题,请各位师兄帮忙,设计寻址数据缓冲方式是DO_DIRECT_IO,那么DMA数据应该是直接传输以应用程序的数据缓冲区,请问应用程序的数据缓冲区是不是计算机的物理内存? 我对这个概念一直不是很清楚。。。谢谢指教! |
|
沙发#
发布于:2008-03-09 21:19
恩!本人也遇此现象,测试中发现,lint#发生后能进入Isr_Irq(void)函数,但是不能满足 if(ST==0x8000) 条件,也就是说intcsr[15]在此时并没有被置为1,不正常。而dma中断发生时能过进入Isr_Irq(void) 同时也满足if(ST==0x200000) 条件,属正常。也很困惑。如有结果还望留言相告!
另外,如果都正常时,可以在Isr_Irq(void)函数中调用m_DpcFor_Irq.Request(&m_IntFlag, NULL)进入DpcFor_Irq()函数,本人开发的例程如下: BOOLEAN PciDriverDevice::Isr_Irq(void) { t << "Entering PciDriverDevice::Isr_Irq zhanglb test 030708m--中断发生\n"; ULONG Reg68 = 0; UCHAR RegA8 = 0; ULONG status = 0; status = m_Bar1.ind(0x68); status = status & 0x208000; if(status == 0x200000 || status == 0x8000) { RegA8 = m_Bar1.inb(0xa8); if(RegA8 & 0x10 == 0x10) { RegA8 = RegA8; } if(status == 0x200000) //Dma Interrupt { m_Bar1.outd(0x68,0x0); m_Bar1.outb(0xa8,0x09); m_IntFlag = 2; t << " DMA中断发生 zhanglb test 030708m \n"; } else//status == 0x8000 local Interrupt { m_Bar1.outd(0x68,0x40180); //local int m_IntFlag = 1; t << " Local中断发生 zhanglb test 030708m \n"; } if (!m_DpcFor_Irq.Request(&m_IntFlag, NULL)) { t << " DpcFor_Irq 调用失败! zhanglb test 030708m \n"; } } else { t <<status<< "Isr_Irq 运行失败 zhanglb test 030708m\n"; } // Return TRUE to indicate that our device caused the interrupt return TRUE; } VOID PciDriverDevice::DpcFor_Irq(PVOID Arg1, PVOID Arg2) { t << "Entering PciDriverDevice::DpcFor_Irq zhanglb test 030708m--中断回调函数\n"; ULONG IntFlag = 0; IntFlag = *(PULONG)Arg1; switch(IntFlag) { case 1: //local int if(m_pEventToSignal != NULL) { m_Bar1.outd(0x68,0x00040180); m_pEventToSignal->Set(); } else { m_Bar1.outd(0x68,0x00000000); } break; case 2: if(m_pEventToDma != NULL) { m_Bar1.outd(0x68,0x00040980); m_pEventToDma->Set(); } else { m_Bar1.outd(0x68,0x00000000); } break; default: break; } UNREFERENCED_PARAMETER(Arg1); UNREFERENCED_PARAMETER(Arg2); } |
|
板凳#
发布于:2008-03-10 00:49
2楼的朋友 lint#发生后能进入Isr_Irq(void)函数后 你的INTCSR里面内容是什么?
|
|
地板#
发布于:2008-03-10 19:27
恩!我用 status = m_Bar1.ind(0x68); t <<status \n; 显示的INTCSR结果为 0x0f040980;
除了INTCSR[15]不是期望的状态,其余位应该都是正常情况的。 到现在没有搞明白原因,很是奇怪。 |
|
地下室#
发布于:2008-03-14 16:26
9054直接用武安河的例子就能用了
不过记得有几个地方写的不对,是地址 |
|
|
5楼#
发布于:2008-03-27 18:44
问题已解决,特意过来总结下。INTCSR[15]要local interrupt持续相当时间才能被9054设置为有效,原先 local interrupt 只持续7us,可能9054 还来不及设置INTCSR[15]=1,故检测不到
INTCSR[15]=1状态。 后来将local interrupt 持续的时间延长为70us,问题解决,能够检测到 INTCSR[15]=1状态。 具体应持续多长时间不好说,实践证明要求稍长一些! |
|
6楼#
发布于:2008-06-08 22:01
我也遇到相同的问题,也是把LINT时间延长,但是不同的电脑时间不相同,我大概是50us,想请教这个LINT的时间范围是多少,谢谢!!!
|
|
7楼#
发布于:2011-03-05 20:07
很受益,谢谢大家!
|
|
8楼#
发布于:2011-08-17 22:58
大有收获~~
|
|
9楼#
发布于:2013-01-13 12:06
LINT时间延长?这个怎么做?
|
|