lsshao
驱动牛犊
驱动牛犊
  • 注册日期2004-02-03
  • 最后登录2007-10-29
  • 粉丝0
  • 关注0
  • 积分33分
  • 威望5点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:2577回复:0

DriverNetwork miniport驱动学习(3)

楼主#
更多 发布于:2004-03-18 10:36
中断
实现中断NIC的NDIS Miniport驱动必须完成下面的内容:
• Registering an Interrupt注册中断
• Processing an Interrupt处理中断
• Synchronizing with an Interrupt同步中断
• De-registering an Interrupt注销中断
1. 注册中断
1)在项目Characteristics.h文件中采用KNDIS_MINIPORT_HANDLER宏声明支持中断miniport的处理程序。例如:
KNDIS_MINIPORT_HANDLER(MyAdapter, DisableInterrupt)
KNDIS_MINIPORT_HANDLER(MyAdapter, EnableInterrupt)
KNDIS_MINIPORT_HANDLER(MyAdapter, HandleInterrupt)
KNDIS_MINIPORT_HANDLER(MyAdapter, Isr)
2)在adapter 类中包括一个KNdisInterrupt数据成员 。例如:
class MyAdapter : public KNdisMiniAdapter {
  . . .
  KNdisInterrupt m_Interrupt;
  . . .
};
3)采用KNdisXxxResource类在adapter类的Initialize()处理程序中,查询中断资源分配情况。
4)根据上面的步骤返回的资源属性对KNdisInterrupt数据成员初始化。例如:
NDIS_STATUS MyAdapter::Initialize(KNdisMedium& Medium, IN KNdisConfig& Config)
{
  . . .
  // get h/w resources
  KNdisPnpResourceRequest request(Config);
  KNdisResource<CmResourceTypeInterrupt> Int(request);
  // Make sure the resources are available
  if (!Int.IsValid())
    KNDIS_RETURN_ERROR (NDIS_STATUS_NOT_ACCEPTED);
  // Register interrupt system object:
  m_Interrupt.Initialize(this, Int, NdisInterruptLatched);
  if (!m_Interrupt.IsValid())
    KNDIS_RETURN_ERROR (NDIS_STATUS_RESOURCES);
  . . .
}
5)用NIC特有的方法使硬件中断使能。
2. 处理中断
当NIC产生中断,系统在设备IRQL级调用miniport的Isr()处理程序。如果中断被确认,系统安排DPC,在DISPATCH_LEVEL级调用miniport的HandleInterrupt()处理程序。
通常,MyAdapter::HandleInterrupt()是最有效的方法。例如,驱动一般都用HandleInterrupt()方法将有关接收分组的说明通知给NDIS。
3.同步中断
与其他DIRL级设备共享资源的miniport函数必须同步访问这些资源。NDIS在DIRQL级调用的两个处理程序是Isr()和DisableInterrupt()。为了能和这两个处理程序同步,驱动调用KNdisInterrupt::Synchronize(),调度运行在DIRL级上且具有NDIS提供的自旋锁的专门函数。这能保证在Isr(), DisableInterrupt()和专门函数之间的互斥。例如:
m_Interrupt.Synchronize(KNDIS_MEMBER_CALLBACK(CardSetMulticast), this);
schedules the execution of:
void MyAdapter::CardSetMulticast()
{
// runs at DIRQL, synchronized with Isr()
// do something we don't want to be interrupted
}
KNDIS_MEMBER_CALLBACK宏用在一个MyAdapter类成员函数中。下面的代码示例包含在MyAdapter类声明中。
class MyAdapter : public KNdisMiniAdapter {
  . . .
  KNDIS_DECLARE_SYNCHROCALLBACK (MyAdapter, CardSetMulticast);
  void CardSetMulticast();
  . . .
};
SYNCHROCALLBACK 宏注入了一个静态成员函数,当系统调度该静态函数运行时将控制交给了CardSetMulticast()。
4.注销中断
一般地,NDIS Miniport驱动在MyAdapter::Halt()处理程序中注销中断。另外,也可以在MyAdapter destructor析构函数中完成,DriverNetworks在完成Halt()处理程序之后立即调用析构函数。
m_Interrupt.Invalidate();

最新喜欢:

temptemptempte...
游客

返回顶部