FreeBSD/sys/dev/e1000/if_lem.c
/*********************************************************************
 *  Device removal routine
 *
 *  The detach entry point is called when the driver is being removed.
 *  This routine stops the adapter and deallocates all the resources
 *  that were allocated for driver operation.
 *
 *  return 0 on success, positive on failure
 *********************************************************************/
Device removal routine
The detach entry point is called when the driver is being removed.
This routine stops the adapter and deallocates all the resources
that were allocated for driver operation.

return 0 on success, positive on failure
Device removal routine The detach entry point is called when the driver is being removed . This routine stops the adapter and deallocates all the resources that were allocated for driver operation . return 0 on success positive on failure
static int
lem_detach(device_t dev)
{
	struct adapter	*adapter = device_get_softc(dev);
	if_t ifp = adapter->ifp;
	INIT_DEBUGOUT("em_detach: begin");
	if (if_vlantrunkinuse(ifp)) {
		device_printf(dev,"Vlan in use, detach first\n");
		return (EBUSY);
	}
#ifdef DEVICE_POLLING
	if (if_getcapenable(ifp) & IFCAP_POLLING)
		ether_poll_deregister(ifp);
#endif
	if (adapter->led_dev != NULL)
		led_destroy(adapter->led_dev);
	EM_CORE_LOCK(adapter);
	EM_TX_LOCK(adapter);
	adapter->in_detach = 1;
	lem_stop(adapter);
	e1000_phy_hw_reset(&adapter->hw);
	lem_release_manageability(adapter);
	EM_TX_UNLOCK(adapter);
	EM_CORE_UNLOCK(adapter);
	if (adapter->vlan_attach != NULL)
		EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach);
	if (adapter->vlan_detach != NULL)
		EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); 
	ether_ifdetach(adapter->ifp);
	callout_drain(&adapter->timer);
	callout_drain(&adapter->tx_fifo_timer);
#ifdef DEV_NETMAP
	netmap_detach(ifp);
#endif 
	lem_free_pci_resources(adapter);
	bus_generic_detach(dev);
	if_free(ifp);
	lem_free_transmit_structures(adapter);
	lem_free_receive_structures(adapter);
	if (adapter->tx_desc_base) {
		lem_dma_free(adapter, &adapter->txdma);
		adapter->tx_desc_base = NULL;
	}
	if (adapter->rx_desc_base) {
		lem_dma_free(adapter, &adapter->rxdma);
		adapter->rx_desc_base = NULL;
	}
#ifdef NIC_PARAVIRT
	if (adapter->csb) {
		lem_dma_free(adapter, &adapter->csb_mem);
		adapter->csb = NULL;
	}
#endif 
	lem_release_hw_control(adapter);
	free(adapter->mta, M_DEVBUF);
	EM_TX_LOCK_DESTROY(adapter);
	EM_RX_LOCK_DESTROY(adapter);
	EM_CORE_LOCK_DESTROY(adapter);
	return (0);
}
static int lem_detach ( device_t dev ) { struct adapter * adapter = device_get_softc ( dev ) ; if_t ifp = adapter -> ifp ; INIT_DEBUGOUT ( " " ) ; if ( if_vlantrunkinuse ( ifp ) ) { device_printf ( dev , " \n " ) ; return ( EBUSY ) ; } #ifdef DEVICE_POLLING if ( if_getcapenable ( ifp ) & IFCAP_POLLING ) ether_poll_deregister ( ifp ) ; #endif if ( adapter -> led_dev != NULL ) led_destroy ( adapter -> led_dev ) ; EM_CORE_LOCK ( adapter ) ; EM_TX_LOCK ( adapter ) ; adapter -> in_detach = 1 ; lem_stop ( adapter ) ; e1000_phy_hw_reset ( & adapter -> hw ) ; lem_release_manageability ( adapter ) ; EM_TX_UNLOCK ( adapter ) ; EM_CORE_UNLOCK ( adapter ) ; if ( adapter -> vlan_attach != NULL ) EVENTHANDLER_DEREGISTER ( vlan_config , adapter -> vlan_attach ) ; if ( adapter -> vlan_detach != NULL ) EVENTHANDLER_DEREGISTER ( vlan_unconfig , adapter -> vlan_detach ) ; ether_ifdetach ( adapter -> ifp ) ; callout_drain ( & adapter -> timer ) ; callout_drain ( & adapter -> tx_fifo_timer ) ; #ifdef DEV_NETMAP netmap_detach ( ifp ) ; #endif lem_free_pci_resources ( adapter ) ; bus_generic_detach ( dev ) ; if_free ( ifp ) ; lem_free_transmit_structures ( adapter ) ; lem_free_receive_structures ( adapter ) ; if ( adapter -> tx_desc_base ) { lem_dma_free ( adapter , & adapter -> txdma ) ; adapter -> tx_desc_base = NULL ; } if ( adapter -> rx_desc_base ) { lem_dma_free ( adapter , & adapter -> rxdma ) ; adapter -> rx_desc_base = NULL ; } #ifdef NIC_PARAVIRT if ( adapter -> csb ) { lem_dma_free ( adapter , & adapter -> csb_mem ) ; adapter -> csb = NULL ; } #endif lem_release_hw_control ( adapter ) ; free ( adapter -> mta , M_DEVBUF ) ; EM_TX_LOCK_DESTROY ( adapter ) ; EM_RX_LOCK_DESTROY ( adapter ) ; EM_CORE_LOCK_DESTROY ( adapter ) ; return ( 0 ) ; }
Device removal routine
  The detach entry point is called when the driver is being removed.
Device removal routine The detach entry point is called when the driver is being removed .
/* Make sure VLANS are not using driver */ /* Unregister VLAN events */ /* DEV_NETMAP */ /* Free Transmit Descriptor ring */ /* Free Receive Descriptor ring */ /* NIC_PARAVIRT */