ROBINBUPT
驱动牛犊
驱动牛犊
  • 注册日期2007-12-18
  • 最后登录2013-04-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
阅读:2873回复:2

如何修改PCI BUS驱动支持MSI中断

楼主#
更多 发布于:2007-12-19 13:38
官方的MSI,DOC文档已经熟读了,觉得CONNECT_FULLY_SPECIFIED Version of IoConnectInterruptEx同原先的IoConnectInterrupt比较像就试着向这个方向修改了一下,但是感觉似乎还是只是可以跑CONNECT_LINE_BASED的。
resource = translated->PartialDescriptors;
    nres = translated->Count;

    for (i=0; i<nres; i++, resource++) {
        switch (resource->Type) {
        case CmResourceTypePort:
            portBase = resource->u.Port.Start;
            fdx->NumPorts = resource->u.Port.Length;
            fdx->MappedPort =
                (resource->Flags & CM_RESOURCE_PORT_IO) == 0;
            break;

        case CmResourceTypeInterrupt:


            if (resource->Flags & CM_RESOURCE_INTERRUPT_MESSAGE) {
                // The resource is for a message-based interrupt.  Use the u.MessageInterrupt.Translated member of IntResource.
                
                vector= resource->u.MessageInterrupt.Translated.Vector;
                irql = (KIRQL)resource->u.MessageInterrupt.Translated.Level;
                //params.FullySpecified.SynchronizeIrql = (KIRQL)IntResource->u.MessageInterrupt.Translated.Level;
                affinity = resource->u.MessageInterrupt.Translated.Affinity;
                
            } else {
                // The resource is for a line-based interrupt.    Use the u.Interrupt member of IntResource.
                
                vector = resource->u.Interrupt.Vector;
                irql = (KIRQL)resource->u.Interrupt.Level;
                //params.FullySpecified.SynchronizeIrql = (KIRQL)IntResource->u.Interrupt.Level;
                affinity = resource->u.Interrupt.Affinity;
            }

            mode = (resource->Flags & CM_RESOURCE_INTERRUPT_LATCHED ? Latched : LevelSensitive);
             irqshared= (BOOLEAN)(resource->ShareDisposition == CmResourceShareShared);



            
          //   = (KIRQL) resource->u.Interrupt.Level;
           //  = resource->u.Interrupt.Vector;
            // = resource->u.Interrupt.Affinity;
          //   = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED)?
          //      Latched: LevelSensitive;
         //   irqshared =
          //      resource->ShareDisposition == CmResourceShareShared;
            break;

        case CmResourceTypeMemory:
            memBase = resource->u.Memory.Start;
            memLen = resource->u.Memory.Length;
            break;

        case CmResourceTypeDma:
            break;
        }
    }

    /* retrieve the IRQ of the evtchn-pci device */
    resource = raw->PartialDescriptors;
    nres = raw->Count;
    for (i=0; i<nres; i++, resource++) {
        switch (resource->Type) {
        case CmResourceTypeInterrupt:
                if (resource->Flags & CM_RESOURCE_INTERRUPT_MESSAGE){

                deviceIRQ = resource->u.MessageInterrupt.Raw.Vector;

                    
                }
                else {
                
                deviceIRQ = resource->u.Interrupt.Vector;
                
                
            }


            
            
            break;
        }
    }
但是一但通过注册表开启MSI支持,设备功能就不行了。只能看到设备标签里分配的中断向量号倒是已经分配的很大了,我调用CONNECT_FULLY_SPECIFIED Version of IoConnectInterruptEx参数也应该没什么不对了。一定要修改处理中断的结构才能使用MSi么?我手中的项目的代码的中断处理结构就像这个网站上的PCI_SAMPLE代码的差不多,可是要改成怎样的结构已支持MSI呢?    
有资料这样说
Level-Triggered (PCI) Case:
1.
 The processor retrieves an IDT vector from the interrupt controller and does a look-up in the IDT to find a dispatch address.
 
2.
 The code at the dispatch address examines the interrupt service routines that were registered by device drivers for that IRQ. It then calls them in the order in which they are listed.
 
3.
 Each interrupt service routine (ISR) probes the hardware for the device and determines if the device is, in fact, interrupting.

&#8226; If the device is interrupting, the ISR queues any work to be done and causes the hardware to stop interrupting. (At this point, the device hardware has been accessed at least twice.) The ISR then returns a value indicating that the interrupt has been handled. The operating system then acknowledges the interrupt.
 
&#8226; If the device is not interrupting, the ISR returns a value indicating that the interrupt was not caused by its device. The operating system then goes on to the next ISR in the chain and returns to step 3.
 
 

Edge-Triggered Case:

1.
 The processor retrieves an IDT vector from the interrupt controller and does a look-up in the IDT to find a dispatch address. (Same as level-triggered.)
 
2.
 The code at the dispatch address examines the interrupt service routines that were registered by device drivers for that IRQ. It then calls them in the order in which they are listed. (Same as level-triggered.)
 
3.
 The operating system acknowledges the interrupt, so that any future edge-triggered interrupts are not lost.
 
4.
 The operating system calls the first ISR in the chain.
 
5.
 The ISR probes the hardware and attempts to handle the interrupt.
 
6.
 If there are additional ISRs, the operating system goes on to the next one and returns to step 5.

这种介绍又实在看不懂怎么帮助我改代码。
 
驱网无线,快乐无限
rangzh
驱动小牛
驱动小牛
  • 注册日期2005-04-24
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望150点
  • 贡献值0点
  • 好评度115点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-12-30 19:14
偶感觉这个需要设备本身对MSI的支持吧。

PCI 2.2以上的规范中有定义MSI的
yunyanrong
驱动小牛
驱动小牛
  • 注册日期2003-04-18
  • 最后登录2013-03-02
  • 粉丝0
  • 关注0
  • 积分1040分
  • 威望457点
  • 贡献值1点
  • 好评度90点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-12-31 15:11
也正在研究中。

1:设备要支持。
2:操作系统要支持,必须vista及以上。
游客

返回顶部