ioctl中打开网卡中断死机

发布于 2022-09-23 14:29:04 字数 25 浏览 11 评论 0

ioctl中打开e1000e网卡中断死机是什么原因

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

粉红×色少女 2022-09-30 14:29:04

原帖由 gcc2007 于 2009-1-15 16:48 发表
ioctl中打开e1000e网卡中断死机是什么原因

具体怎么操作的?
只是打开中断?还是做了其它操作?在你操作的时候,网卡处于什么样的状态和工作模式?

一梦等七年七年为一梦 2022-09-30 14:29:04

正常的中断使能是在e1000_open()
static int e1000_open(struct net_device *netdev)
{
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        int err;

        /* disallow open during test */
        if (test_bit(__E1000_TESTING, &adapter->state))
                return -EBUSY;

        /* allocate transmit descriptors */
        err = e1000_setup_tx_resources(adapter);
        if (err)
                goto err_setup_tx;

        /* allocate receive descriptors */
        err = e1000_setup_rx_resources(adapter);
        if (err)
                goto err_setup_rx;

        e1000_power_up_phy(hw);

        adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
        if ((adapter->hw.mng_cookie.status &
             E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
                e1000_update_mng_vlan(adapter);

        /*
         * If AMT is enabled, let the firmware know that the network
         * interface is now open
         */
        if (adapter->flags & FLAG_HAS_AMT)
                e1000_get_hw_control(adapter);

        /*
         * before we allocate an interrupt, we must be ready to handle it.
         * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
         * as soon as we call pci_request_irq, so we have to setup our
         * clean_rx handler before we do so.
         */
        e1000_configure(adapter);

        err = e1000_request_irq(adapter);
        if (err)
                goto err_req_irq;

        /*
         * Work around PCIe errata with MSI interrupts causing some chipsets to
         * ignore e1000e MSI messages, which means we need to test our MSI
         * interrupt now
         */
#ifdef CONFIG_E1000E_MSIX
        if (adapter->int_mode != E1000E_INT_MODE_LEGACY)
#endif
        {
                err = e1000_test_msi(adapter);
                if (err) {
                        e_err("Interrupt allocation failed\n");
                        goto err_req_irq;
                }
        }

        /* From here on the code is the same as e1000_up() */
        clear_bit(__E1000_DOWN, &adapter->state);

#ifdef CONFIG_E1000E_NAPI
        napi_enable(&adapter->napi);
#endif

//        e1000_irq_enable(adapter);

        /* fire a link status change interrupt to start the watchdog */
//        ew32(ICS, E1000_ICS_LSC);

        return 0;

err_req_irq:
        e1000_release_hw_control(adapter);
        if (!adapter->wol && hw->phy.ops.power_down)
                hw->phy.ops.power_down(hw);
        e1000_free_rx_resources(adapter);
err_setup_rx:
        e1000_free_tx_resources(adapter);
err_setup_tx:
        e1000_reset(adapter);

        return err;
}
标红的被我注释掉了,我想在用户空间控制网卡中断的开关,所以注册了一个miscdevice设备,利用它的ioctl打开网卡中断
static int mapdevice_ioctl(struct inode * inode, struct file *file,
    unsigned int cmd, unsigned long arg){
  struct mapdevice_private *priv=global_mapdevice;
  struct vortex_private *vp = priv->pci_dev_private;
  long ioaddr= priv->dev->base_addr;
  int entry, tmp=0;
  unsigned char val;
  switch (cmd) {
    case WAIT_FOR_INTERRUPT:
  //Check which timer is on, if on, disable it
  switch (using_timer){
   /**/
   case WAIT_FOR_RTC_TIMER:
    spin_lock_irq(&rtc_lock);
    CMOS_WRITE(CMOS_READ(RTC_CONTROL)& ~0x40, RTC_CONTROL);
    CMOS_READ(RTC_INTR_FLAGS);
    if (rtc_status & 0x02) {
     rtc_status &= ~0x02;
     del_timer(&rtc_irq_timer);
    }
    spin_unlock_irq (&rtc_lock);
   break;
   case WAIT_FOR_LAPIC_TIMER:
   break;
  }
  using_timer=0;
  //enable irq and then sleep
  //enabling interrupt
  e1000_irq_enable(adapter);  //到这步,下面有函数定义
  wait_event_interruptible(wait_queue, interrupt_arrived);
  interrupt_arrived=0;
  //Time probe
  /*
  last_wake_ioctl = get_cycles();
  last_end_ioctl = my_rdtsc();
  //get_cycles(last_end_ioctl);
  if (first_time_ioctl) {
   first_wake_ioctl = last_wake_ioctl;
   first_time_ioctl=0;
   first_end_ioctl=last_end_ioctl;
  }
  */
break;

........................
static void e1000_irq_enable(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
#ifdef CONFIG_E1000E_MSIX
if (adapter->msix_entries) {
  ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
  ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
} else {
  ew32(IMS, IMS_ENABLE_MASK);  //到这里机器就死了
}
#else
ew32(IMS, IMS_ENABLE_MASK);
#endif /* CONFIG_E1000E_MSIX */
}

柏林苍穹下 2022-09-30 14:29:04

你应该搞清楚,内核里面是不是本身已经打开了中断?你在用户空间随意的打开中断,关闭中断,就有可能会出问题

惟欲睡 2022-09-30 14:29:04

在ioctl中运行的程序,kernel肯定会是打开中断的.

北城挽邺 2022-09-30 14:29:04

你先把 isr中什么都不执行。
你应该没修改e1000的代码吧

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文