--- //depot/yahoo/ybsd_6/src/sys/dev/em/if_em.c 2006/09/26 14:59:47 +++ //depot/jhb/bsd6/src/sys/dev/em/if_em.c 2006/10/30 09:54:13 @@ -1239,14 +1261,20 @@ if (em_rxeof(adapter, adapter->rx_process_limit) != 0) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); EM_LOCK(adapter); + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + EM_UNLOCK(adapter); + goto out; + } em_txeof(adapter); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) em_start_locked(ifp); + + em_enable_intr(adapter); EM_UNLOCK(adapter); } - em_enable_intr(adapter); +out: NET_UNLOCK_GIANT(); } @@ -1947,12 +1964,19 @@ INIT_DEBUGOUT("em_stop: begin"); em_disable_intr(adapter); - em_reset_hw(&adapter->hw); callout_stop(&adapter->timer); callout_stop(&adapter->tx_fifo_timer); /* Tell the stack that the interface is no longer active */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + /* Unlock so that the defered contexts can drain without blocking */ + EM_UNLOCK(adapter); + taskqueue_drain(adapter->tq, &adapter->rxtx_task); + taskqueue_drain(taskqueue_fast, &adapter->link_task); + + EM_LOCK(adapter); + em_reset_hw(&adapter->hw); }