/** * Detach entry point, to detach a device to the system or suspend it. * * @param pDip The module structure instance. * @param enmCmd Operation type (detach/suspend). * * @returns corresponding solaris error code. */ static int VBoxNetAdpSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd) { LogFunc((DEVICE_NAME ":VBoxNetAdpSolarisDetach pDip=%p enmCmd=%d\n", pDip, enmCmd)); switch (enmCmd) { case DDI_DETACH: { /* * Unregister and clean up. */ gld_mac_info_t *pMacInfo = ddi_get_driver_private(pDip); if (pMacInfo) { vboxnetadp_state_t *pState = (vboxnetadp_state_t *)pMacInfo->gldm_private; if (pState) { gld_linkstate(pMacInfo, GLD_LINKSTATE_DOWN); int rc = gld_unregister(pMacInfo); if (rc == DDI_SUCCESS) { gld_mac_free(pMacInfo); RTMemFree(pState); return DDI_SUCCESS; } else LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to unregister GLD from MAC layer.rc=%d\n", rc)); } else LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to get internal state.\n")); } else LogRel((DEVICE_NAME ":VBoxNetAdpSolarisDetach failed to get driver private GLD data.\n")); return DDI_FAILURE; } case DDI_RESUME: { /* Nothing to do here... */ return DDI_SUCCESS; } /* case DDI_SUSPEND: */ /* case DDI_HOTPLUG_DETACH: */ default: return DDI_FAILURE; } }
/* detach(9E) -- Detach a device from the system */ static int SMCG_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd) { gld_mac_info_t *macinfo; Adapter_Struc *pAd; smcg_t *smcg; int i; #ifdef DEBUG if (SMCG_debug & SMCGDDI) cmn_err(CE_CONT, SMCG_NAME "_detach(0x%p)", (void *)devinfo); #endif if (cmd != DDI_DETACH) return (DDI_FAILURE); macinfo = ddi_get_driver_private(devinfo); smcg = (smcg_t *)macinfo->gldm_private; pAd = smcg->smcg_pAd; i = 50; mutex_enter(&smcg->rlist_lock); while (smcg->rx_bufs_outstanding > 0) { mutex_exit(&smcg->rlist_lock); delay(drv_usectohz(100000)); if (--i == 0) { cmn_err(CE_WARN, SMCG_NAME "%d: %d buffers not reclaimed", macinfo->gldm_ppa, smcg->rx_bufs_outstanding); return (DDI_FAILURE); } mutex_enter(&smcg->rlist_lock); } smcg->detaching_flag = 1; mutex_exit(&smcg->rlist_lock); /* * Unregister ourselves from the GLD interface * * gld_unregister will: * remove the minor node; * unlink us from the GLD system. */ if (gld_unregister(macinfo) != DDI_SUCCESS) { mutex_enter(&smcg->rlist_lock); smcg->detaching_flag = 0; mutex_exit(&smcg->rlist_lock); return (DDI_FAILURE); } ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie); SMCG_dma_unalloc(smcg); mutex_destroy(&smcg->rbuf_lock); mutex_destroy(&smcg->txbuf_lock); mutex_destroy(&smcg->lm_lock); mutex_destroy(&smcg->rlist_lock); kmem_free(pAd, sizeof (Adapter_Struc)); kmem_free(smcg, sizeof (smcg_t)); gld_mac_free(macinfo); return (DDI_SUCCESS); }