FreeBSD/sys/dev/ixgbe/if_ixv.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
ixv_detach(device_t dev)
{
	struct adapter *adapter = device_get_softc(dev);
	struct ix_queue *que = adapter->queues;
	INIT_DEBUGOUT("ixv_detach: begin");
	if (adapter->ifp->if_vlantrunk != NULL) {
		device_printf(dev, "Vlan in use, detach first\n");
		return (EBUSY);
	}
	IXGBE_CORE_LOCK(adapter);
	ixv_stop(adapter);
	IXGBE_CORE_UNLOCK(adapter);
	for (int i = 0; i < adapter->num_queues; i++, que++) {
		if (que->tq) {
			struct tx_ring  *txr = que->txr;
			taskqueue_drain(que->tq, &txr->txq_task);
			taskqueue_drain(que->tq, &que->que_task);
			taskqueue_free(que->tq);
		}
	}
	if (adapter->tq) {
		taskqueue_drain(adapter->tq, &adapter->link_task);
		taskqueue_free(adapter->tq);
	}
	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);
#ifdef DEV_NETMAP
	netmap_detach(adapter->ifp);
#endif 
	ixv_free_pci_resources(adapter);
	bus_generic_detach(dev);
	if_free(adapter->ifp);
	ixgbe_free_transmit_structures(adapter);
	ixgbe_free_receive_structures(adapter);
	IXGBE_CORE_LOCK_DESTROY(adapter);
	return (0);
}
static int ixv_detach ( device_t dev ) { struct adapter * adapter = device_get_softc ( dev ) ; struct ix_queue * que = adapter -> queues ; INIT_DEBUGOUT ( " " ) ; if ( adapter -> ifp -> if_vlantrunk != NULL ) { device_printf ( dev , " \n " ) ; return ( EBUSY ) ; } IXGBE_CORE_LOCK ( adapter ) ; ixv_stop ( adapter ) ; IXGBE_CORE_UNLOCK ( adapter ) ; for ( int i = 0 ; i < adapter -> num_queues ; i ++ , que ++ ) { if ( que -> tq ) { struct tx_ring * txr = que -> txr ; taskqueue_drain ( que -> tq , & txr -> txq_task ) ; taskqueue_drain ( que -> tq , & que -> que_task ) ; taskqueue_free ( que -> tq ) ; } } if ( adapter -> tq ) { taskqueue_drain ( adapter -> tq , & adapter -> link_task ) ; taskqueue_free ( adapter -> tq ) ; } 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 ) ; #ifdef DEV_NETMAP netmap_detach ( adapter -> ifp ) ; #endif ixv_free_pci_resources ( adapter ) ; bus_generic_detach ( dev ) ; if_free ( adapter -> ifp ) ; ixgbe_free_transmit_structures ( adapter ) ; ixgbe_free_receive_structures ( adapter ) ; IXGBE_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 */ /* Drain the Mailbox(link) queue */ /* Unregister VLAN events */ /* DEV_NETMAP */