static void ucom_detach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc) { struct tty *tp = sc->sc_tty; DPRINTF("sc = %p, tp = %p\n", sc, sc->sc_tty); if (sc->sc_consdev != NULL) { cnremove(sc->sc_consdev); free(sc->sc_consdev, M_USBDEV); sc->sc_consdev = NULL; } if (sc->sc_flag & UCOM_FLAG_CONSOLE) { UCOM_MTX_LOCK(ucom_cons_softc); ucom_close(ucom_cons_softc->sc_tty); sc->sc_flag &= ~UCOM_FLAG_CONSOLE; UCOM_MTX_UNLOCK(ucom_cons_softc); ucom_cons_softc = NULL; } /* the config thread has been stopped when we get here */ UCOM_MTX_LOCK(sc); sc->sc_flag |= UCOM_FLAG_GONE; sc->sc_flag &= ~(UCOM_FLAG_HL_READY | UCOM_FLAG_LL_READY); UCOM_MTX_UNLOCK(sc); if (tp) { mtx_lock(&ucom_mtx); ucom_close_refs++; mtx_unlock(&ucom_mtx); tty_lock(tp); ucom_close(tp); /* close, if any */ tty_rel_gone(tp); UCOM_MTX_LOCK(sc); /* * make sure that read and write transfers are stopped */ if (sc->sc_callback->ucom_stop_read) (sc->sc_callback->ucom_stop_read) (sc); if (sc->sc_callback->ucom_stop_write) (sc->sc_callback->ucom_stop_write) (sc); UCOM_MTX_UNLOCK(sc); } }
/* cnXXX works only for FreeBSD-5 */ static int dcons_modevent(module_t mode, int type, void *data) { int err = 0, ret; switch (type) { case MOD_LOAD: ret = dcons_drv_init(1); dcons_attach(); #if __FreeBSD_version >= 500000 if (ret == 0) { dcons_cnprobe(&dcons_consdev); dcons_cninit(&dcons_consdev); cnadd(&dcons_consdev); } #endif break; case MOD_UNLOAD: printf("dcons: unload\n"); callout_stop(&dcons_callout); #if DDB && DCONS_FORCE_GDB #if CONS_NODEV gdb_arg = NULL; #else gdbdev = NODEV; #endif #endif #if __FreeBSD_version >= 500000 cnremove(&dcons_consdev); #endif dcons_detach(DCONS_CON); dcons_detach(DCONS_GDB); dcons_buf->magic = 0; contigfree(dcons_buf, DCONS_BUF_SIZE, M_DEVBUF); break; case MOD_SHUTDOWN: break; } return(err); }
static int dcons_modevent(module_t mode, int type, void *data) { int err = 0, ret; switch (type) { case MOD_LOAD: ret = dcons_drv_init(1); if (ret != -1) dcons_attach(); if (ret == 0) { dcons_cnprobe(&dcons_consdev); dcons_cninit(&dcons_consdev); cnadd(&dcons_consdev); } break; case MOD_UNLOAD: printf("dcons: unload\n"); if (drv_init == 1) { callout_stop(&dcons_callout); cnremove(&dcons_consdev); dcons_detach(DCONS_CON); dcons_detach(DCONS_GDB); dg.buf->magic = 0; contigfree(dg.buf, DCONS_BUF_SIZE, M_DEVBUF); } break; case MOD_SHUTDOWN: #if 0 /* Keep connection after halt */ dg.buf->magic = 0; #endif break; default: err = EOPNOTSUPP; break; } return(err); }
void cninit(void) { struct consdev *best_cn, *cn, **list; /* * Check if we should mute the console (for security reasons perhaps) * It can be changes dynamically using sysctl kern.consmute * once we are up and going. * */ cn_mute = ((boothowto & (RB_MUTE |RB_SINGLE |RB_VERBOSE |RB_ASKNAME)) == RB_MUTE); /* * Find the first console with the highest priority. */ best_cn = NULL; SET_FOREACH(list, cons_set) { cn = *list; cnremove(cn); /* Skip cons_consdev. */ if (cn->cn_ops == NULL) continue; cn->cn_ops->cn_probe(cn); if (cn->cn_pri == CN_DEAD) continue; if (best_cn == NULL || cn->cn_pri > best_cn->cn_pri) best_cn = cn; if (boothowto & RB_MULTIPLE) { /* * Initialize console, and attach to it. */ cn->cn_ops->cn_init(cn); cnadd(cn); } }