maryea
驱动牛犊
驱动牛犊
  • 注册日期2006-04-11
  • 最后登录2008-03-17
  • 粉丝0
  • 关注0
  • 积分130分
  • 威望14点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
阅读:5432回复:9

请教PCI9054驱动程序中断服务程序中如何区分DMA完成中断和LINT#?

楼主#
更多 发布于:2008-03-09 17:59
     小弟在写一个小的驱动程序,想以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数据应该是直接传输以应用程序的数据缓冲区,请问应用程序的数据缓冲区是不是计算机的物理内存?  我对这个概念一直不是很清楚。。。谢谢指教!
zlbabc
驱动牛犊
驱动牛犊
  • 注册日期2008-03-09
  • 最后登录2024-05-07
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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);
}
maryea
驱动牛犊
驱动牛犊
  • 注册日期2006-04-11
  • 最后登录2008-03-17
  • 粉丝0
  • 关注0
  • 积分130分
  • 威望14点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-03-10 00:49
2楼的朋友 lint#发生后能进入Isr_Irq(void)函数后 你的INTCSR里面内容是什么?
zlbabc
驱动牛犊
驱动牛犊
  • 注册日期2008-03-09
  • 最后登录2024-05-07
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-03-10 19:27
恩!我用  status = m_Bar1.ind(0x68); t <<status \n;  显示的INTCSR结果为 0x0f040980;
除了INTCSR[15]不是期望的状态,其余位应该都是正常情况的。
到现在没有搞明白原因,很是奇怪。
xp4105
论坛版主
论坛版主
  • 注册日期2006-04-02
  • 最后登录2014-03-29
  • 粉丝1
  • 关注0
  • 积分905分
  • 威望570点
  • 贡献值1点
  • 好评度162点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2008-03-14 16:26
9054直接用武安河的例子就能用了
不过记得有几个地方写的不对,是地址
时光如流水 抓紧时间实现自我价值
zlbabc
驱动牛犊
驱动牛犊
  • 注册日期2008-03-09
  • 最后登录2024-05-07
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
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状态。
具体应持续多长时间不好说,实践证明要求稍长一些!
humming1981
驱动牛犊
驱动牛犊
  • 注册日期2007-03-15
  • 最后登录2009-06-10
  • 粉丝0
  • 关注0
  • 积分12分
  • 威望66点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-06-08 22:01
我也遇到相同的问题,也是把LINT时间延长,但是不同的电脑时间不相同,我大概是50us,想请教这个LINT的时间范围是多少,谢谢!!!
augusdi
驱动牛犊
驱动牛犊
  • 注册日期2008-06-16
  • 最后登录2011-03-05
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望185点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2011-03-05 20:07
很受益,谢谢大家!
lizmurray
驱动牛犊
驱动牛犊
  • 注册日期2010-11-05
  • 最后登录2011-08-31
  • 粉丝0
  • 关注1
  • 积分1分
  • 威望11点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2011-08-17 22:58
大有收获~~
mbnwpu
驱动牛犊
驱动牛犊
  • 注册日期2012-07-25
  • 最后登录2013-01-17
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望41点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2013-01-13 12:06
LINT时间延长?这个怎么做?
游客

返回顶部