int com_detach(struct device *self, int flags) { struct com_softc *sc = (struct com_softc *)self; int maj, mn; sc->sc_swflags |= COM_SW_DEAD; /* Locate the major number. */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == comopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; vdevgone(maj, mn, mn, VCHR); /* XXX a symbolic constant for the cua bit would be nicer. */ mn |= 0x80; vdevgone(maj, mn, mn, VCHR); /* Detach and free the tty. */ if (sc->sc_tty) { ttyfree(sc->sc_tty); } timeout_del(&sc->sc_dtr_tmo); timeout_del(&sc->sc_diag_tmo); softintr_disestablish(sc->sc_si); return (0); }
/* This is necessary when dynamically changing SAIP configuration. */ int sacom_detach(struct device *self, int flags) { struct sacom_softc *sc = (struct sacom_softc *)self; int maj, mn; /* locate the major number */ maj = cdevsw_lookup_major(&sacom_cdevsw); /* Nuke the vnodes for any open instances. */ mn = device_unit(self); vdevgone(maj, mn, mn, VCHR); mn |= COMDIALOUT_MASK; vdevgone(maj, mn, mn, VCHR); /* Free the receive buffer. */ free(sc->sc_rbuf, M_DEVBUF); /* Detach and free the tty. */ tty_detach(sc->sc_tty); ttyfree(sc->sc_tty); /* Unhook the soft interrupt handler. */ softint_disestablish(sc->sc_si); #if NRND > 0 && defined(RND_COM) /* Unhook the entropy source. */ rnd_detach_source(&sc->rnd_source); #endif return 0; }
int comclose(dev_t dev, int flag, int mode, struct lwp *l) { struct com_softc *sc = device_lookup_private(&xcom_cd, COMUNIT(dev)); struct tty *tp = sc->sc_tty; int iobase = sc->sc_iobase; int s; /* XXX This is for cons.c. */ if (!ISSET(tp->t_state, TS_ISOPEN)) return 0; (*tp->t_linesw->l_close)(tp, flag); s = spltty(); CLR(sc->sc_lcr, LCR_SBREAK); outb(pio(iobase , com_lcr), sc->sc_lcr); outb(pio(iobase , com_ier), 0); if (ISSET(tp->t_cflag, HUPCL) && !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) { /* XXX perhaps only clear DTR */ outb(pio(iobase , com_mcr), 0); } CLR(tp->t_state, TS_BUSY | TS_FLUSH); if (--comsopen == 0) callout_stop(&com_poll_ch); splx(s); ttyclose(tp); #ifdef notyet /* XXXX */ if (unit != comconsole) { ttyfree(tp); sc->sc_tty = 0; } #endif return 0; }
int ucom_detach(struct device *self, int flags) { struct ucom_softc *sc = (struct ucom_softc *)self; struct tty *tp = sc->sc_tty; int maj, mn; int s; DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p, pipe=%d,%d\n", sc, flags, tp, sc->sc_bulkin_no, sc->sc_bulkout_no)); sc->sc_dying = 1; if (sc->sc_bulkin_pipe != NULL) usbd_abort_pipe(sc->sc_bulkin_pipe); if (sc->sc_bulkout_pipe != NULL) usbd_abort_pipe(sc->sc_bulkout_pipe); s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wake up anyone waiting */ if (tp != NULL) { CLR(tp->t_state, TS_CARR_ON); CLR(tp->t_cflag, CLOCAL | MDMBUF); ttyflush(tp, FREAD|FWRITE); } /* Wait for processes to go away. */ usb_detach_wait(&sc->sc_dev); } splx(s); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == ucomopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn)); vdevgone(maj, mn, mn, VCHR); vdevgone(maj, mn | UCOMCUA_MASK, mn | UCOMCUA_MASK, VCHR); /* Detach and free the tty. */ if (tp != NULL) { ttyfree(tp); sc->sc_tty = NULL; } return (0); }
static int ufoma_detach(device_t self) { struct ufoma_softc *sc = device_get_softc(self); int rv = 0; usbd_free_xfer(sc->sc_msgxf); sc->sc_ucom.sc_dying = 1; usbd_abort_pipe(sc->sc_notify_pipe); usbd_close_pipe(sc->sc_notify_pipe); if(sc->sc_is_ucom) ucom_detach(&sc->sc_ucom); else ttyfree(sc->sc_ucom.sc_tty); free(sc->sc_modetable, M_USBDEV); return rv; }
int comclose(dev_t dev, int flag, int mode, struct proc *p) { int unit = DEVUNIT(dev); struct com_softc *sc = com_cd.cd_devs[unit]; bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; struct tty *tp = sc->sc_tty; int s; #ifdef COM_CONSOLE /* XXX This is for cons.c. */ if (!ISSET(tp->t_state, TS_ISOPEN)) return 0; #endif if(sc->sc_swflags & COM_SW_DEAD) return 0; (*linesw[tp->t_line].l_close)(tp, flag, p); s = spltty(); if (ISSET(tp->t_state, TS_WOPEN)) { /* tty device is waiting for carrier; drop dtr then re-raise */ CLR(sc->sc_mcr, MCR_DTR | MCR_RTS); bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr); timeout_add_sec(&sc->sc_dtr_tmo, 2); } else { /* no one else waiting; turn off the uart */ compwroff(sc); } CLR(tp->t_state, TS_BUSY | TS_FLUSH); sc->sc_cua = 0; splx(s); ttyclose(tp); #ifdef COM_CONSOLE #ifdef notyet /* XXXX */ if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { ttyfree(tp); sc->sc_tty = 0; } #endif #endif return 0; }
int ucom_detach(struct device *self, int flags) { struct ucom_softc *sc = (struct ucom_softc *)self; struct tty *tp = sc->sc_tty; int maj, mn; int s; DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p, pipe=%d,%d\n", sc, flags, tp, sc->sc_bulkin_no, sc->sc_bulkout_no)); if (sc->sc_bulkin_pipe != NULL) { usbd_abort_pipe(sc->sc_bulkin_pipe); usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; } if (sc->sc_bulkout_pipe != NULL) { usbd_abort_pipe(sc->sc_bulkout_pipe); usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; } if (sc->sc_ixfer != NULL) { if (sc->sc_uhidev == NULL) usbd_free_xfer(sc->sc_ixfer); sc->sc_ixfer = NULL; } if (sc->sc_oxfer != NULL) { usbd_free_buffer(sc->sc_oxfer); if (sc->sc_uhidev == NULL) usbd_free_xfer(sc->sc_oxfer); sc->sc_oxfer = NULL; } s = splusb(); if (--sc->sc_refcnt >= 0) { /* Wake up anyone waiting */ if (tp != NULL) { CLR(tp->t_state, TS_CARR_ON); CLR(tp->t_cflag, CLOCAL | MDMBUF); ttyflush(tp, FREAD|FWRITE); } usb_detach_wait(&sc->sc_dev); } splx(s); /* locate the major number */ for (maj = 0; maj < nchrdev; maj++) if (cdevsw[maj].d_open == ucomopen) break; /* Nuke the vnodes for any open instances. */ mn = self->dv_unit; DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn)); vdevgone(maj, mn, mn, VCHR); vdevgone(maj, mn | UCOMCUA_MASK, mn | UCOMCUA_MASK, VCHR); /* Detach and free the tty. */ if (tp != NULL) { (*LINESW(tp, l_close))(tp, FNONBLOCK, curproc); s = spltty(); CLR(tp->t_state, TS_BUSY | TS_FLUSH); ttyclose(tp); splx(s); ttyfree(tp); sc->sc_tty = NULL; } return (0); }