int sddetach(struct device *self, int flags) { struct sd_softc *sc = (struct sd_softc *)self; int bmaj, cmaj, mn; sd_kill_buffers(sc); /* Locate the lowest minor number to be detached. */ mn = DISKMINOR(self->dv_unit, 0); for (bmaj = 0; bmaj < nblkdev; bmaj++) if (bdevsw[bmaj].d_open == sdopen) vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK); for (cmaj = 0; cmaj < nchrdev; cmaj++) if (cdevsw[cmaj].d_open == sdopen) vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR); /* Get rid of the shutdown hook. */ if (sc->sc_sdhook != NULL) shutdownhook_disestablish(sc->sc_sdhook); /* Detach disk. */ disk_detach(&sc->sc_dk); return (0); }
int sysctl_wdog(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { int error, period; if (wdog_ctl_cb == NULL) return (EOPNOTSUPP); switch (name[0]) { case KERN_WATCHDOG_PERIOD: period = wdog_period; error = sysctl_int(oldp, oldlenp, newp, newlen, &period); if (error) return (error); if (newp) { timeout_del(&wdog_timeout); wdog_period = (*wdog_ctl_cb)(wdog_ctl_cb_arg, period); } break; case KERN_WATCHDOG_AUTO: error = sysctl_int(oldp, oldlenp, newp, newlen, &wdog_auto); if (error) return (error); if (wdog_auto && wdog_cookie == NULL) wdog_cookie = shutdownhook_establish(wdog_shutdown, NULL); else if (!wdog_auto && wdog_cookie) { shutdownhook_disestablish(wdog_cookie); wdog_cookie = NULL; } break; default: return (EINVAL); } if (wdog_auto && wdog_period > 0) { (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period); timeout_add(&wdog_timeout, wdog_period * hz / 2); } else timeout_del(&wdog_timeout); return (error); }
int sddetach(struct device *self, int flags) { struct sd_softc *sc = (struct sd_softc *)self; bufq_drain(&sc->sc_bufq); disk_gone(sdopen, self->dv_unit); /* Get rid of the shutdown hook. */ if (sc->sc_sdhook != NULL) shutdownhook_disestablish(sc->sc_sdhook); /* Detach disk. */ bufq_destroy(&sc->sc_bufq); disk_detach(&sc->sc_dk); return (0); }
/* * ae_detach: * * Detach a device interface. */ int ae_detach(device_t self, int flags) { struct ae_softc *sc = device_private(self); struct ifnet *ifp = &sc->sc_ethercom.ec_if; struct ae_rxsoft *rxs; struct ae_txsoft *txs; int i; /* * Succeed now if there isn't any work to do. */ if ((sc->sc_flags & AE_ATTACHED) == 0) return (0); /* Unhook our tick handler. */ if (sc->sc_tick) callout_stop(&sc->sc_tick_callout); /* Detach all PHYs */ mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); /* Delete all remaining media. */ ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); rnd_detach_source(&sc->sc_rnd_source); ether_ifdetach(ifp); if_detach(ifp); for (i = 0; i < AE_NRXDESC; i++) { rxs = &sc->sc_rxsoft[i]; if (rxs->rxs_mbuf != NULL) { bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap); m_freem(rxs->rxs_mbuf); rxs->rxs_mbuf = NULL; } bus_dmamap_destroy(sc->sc_dmat, rxs->rxs_dmamap); } for (i = 0; i < AE_TXQUEUELEN; i++) { txs = &sc->sc_txsoft[i]; if (txs->txs_mbuf != NULL) { bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap); m_freem(txs->txs_mbuf); txs->txs_mbuf = NULL; } bus_dmamap_destroy(sc->sc_dmat, txs->txs_dmamap); } bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap); bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap); bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data, sizeof(struct ae_control_data)); bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg); shutdownhook_disestablish(sc->sc_sdhook); powerhook_disestablish(sc->sc_powerhook); bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size); return (0); }