int xencons_open(dev_t dev, int flag, int mode, struct lwp *l) { struct xencons_softc *sc; struct tty *tp; sc = device_lookup_private(&xencons_cd, XENCONS_UNIT(dev)); if (sc == NULL) return (ENXIO); tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) { tp->t_dev = dev; ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; xencons_param(tp, &tp->t_termios); ttsetwater(tp); } tp->t_state |= TS_CARR_ON; return ((*tp->t_linesw->l_open)(dev, tp)); }
int uart_open(dev_t dev, int flag, int mode, struct lwp *l) { struct uart_softc *sc = device_lookup_private(&uart_cd, minor(dev)); struct tty *tp = sc->sc_tty; int s, error = 0; s = spltty(); tp->t_dev = dev; if ((tp->t_state & TS_ISOPEN) == 0) { tp->t_state |= TS_CARR_ON; ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG | CLOCAL; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = 115200; ttsetwater(tp); } else if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp) != 0) { splx(s); return (EBUSY); } splx(s); error = (*tp->t_linesw->l_open)(dev, tp); return (error); }
int biconsdevopen(dev_t dev, int flag, int mode, struct lwp *l) { struct tty *tp = &biconsdev_tty[0]; int status; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); if ((tp->t_state & TS_ISOPEN) == 0) { /* * Leave baud rate alone! */ ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_state = TS_ISOPEN | TS_CARR_ON; (void)(*tp->t_param)(tp, &tp->t_termios); ttsetwater(tp); } status = (*tp->t_linesw->l_open)(dev, tp); return status; }
int cnioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { int error; error = 0; /* * Superuser can always use this to wrest control of console * output from the "virtual" console. */ if (cmd == TIOCCONS && constty != NULL) { error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_VIRTUAL, constty); if (!error) constty = NULL; return (error); } /* * Redirect the ioctl, if that's appropriate. * Note that strange things can happen, if a program does * ioctls on /dev/console, then the console is redirected * out from under it. */ if (!cn_redirect(&dev, 0, &error)) return error; return cdev_ioctl(dev, cmd, data, flag, l); }
int dzopen(dev_t dev, int flag, int mode, struct lwp *l) { struct tty *tp; int unit, line; struct dz_softc *sc; int s, error = 0; unit = DZ_I2C(minor(dev)); sc = device_lookup_private(&dz_cd, unit); if (sc == NULL) return ENXIO; line = DZ_PORT(minor(dev)); if (line > 0) /* FIXME for more than one line */ return ENXIO; tp = sc->sc_dz.dz_tty; if (tp == NULL) return ENODEV; tp->t_oproc = dzstart; tp->t_param = dzparam; tp->t_dev = dev; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); if ((tp->t_state & TS_ISOPEN) == 0) { ttychars(tp); if (tp->t_ispeed == 0) { tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; } (void)dzparam(tp, &tp->t_termios); ttsetwater(tp); } /* we have no modem control but..*/ if (dzmctl(sc, line, TIOCM_DTR, DMBIS) & TIOCM_CD) tp->t_state |= TS_CARR_ON; s = spltty(); while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) && !(tp->t_state & TS_CARR_ON)) { tp->t_wopen++; error = ttysleep(tp, &tp->t_rawcv, true, 0); tp->t_wopen--; if (error) break; } (void)splx(s); if (error) return error; return (*tp->t_linesw->l_open)(dev, tp); }
int kdopen(dev_t dev, int flag, int mode, struct lwp *l) { struct kd_softc *kd; int error, s, unit; struct tty *tp; static int firstopen = 1; unit = minor(dev); if (unit != 0) return ENXIO; kd = &kd_softc; /* XXX */ if (firstopen) { kd_init(kd); firstopen = 0; } tp = kd->kd_tty; /* It's simpler to do this up here. */ if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); if ((tp->t_state & TS_ISOPEN) == 0) { /* First open. */ /* Notify the input device that serves us */ struct cons_channel *cc = kd->kd_in; if (cc != NULL && (error = (*cc->cc_iopen)(cc)) != 0) { return (error); } ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; (void) kdparam(tp, &tp->t_termios); ttsetwater(tp); tp->t_winsize.ws_row = kd->rows; tp->t_winsize.ws_col = kd->cols; /* Flush pending input? Clear translator? */ /* This (pseudo)device always has SOFTCAR */ tp->t_state |= TS_CARR_ON; } splx(s); return ((*tp->t_linesw->l_open)(dev, tp)); }
int at91usart_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { struct at91usart_softc *sc = device_lookup_private(&at91usart_cd, COMUNIT(dev)); struct tty *tp = sc->sc_tty; int error; int s; if (COM_ISALIVE(sc) == 0) return (EIO); error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); error = 0; s = spltty(); switch (cmd) { case TIOCSBRK: at91usart_break(sc, 1); break; case TIOCCBRK: at91usart_break(sc, 0); break; case TIOCGFLAGS: *(int *)data = sc->sc_swflags; break; case TIOCSFLAGS: error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp); if (error) break; sc->sc_swflags = *(int *)data; break; default: error = EPASSTHROUGH; break; } splx(s); return (error); }
int arcbios_ttyopen(dev_t dev, int flag, int mode, struct lwp *l) { int unit = minor(dev); struct tty *tp; int s, error = 0, setuptimeout = 0; if (!arcbios_ch_init) { arcbios_ch_init = true; callout_init(&arcbios_tty_ch, 0); } if (unit != 0) return (ENODEV); s = spltty(); if (arcbios_tty[unit] == NULL) { tp = arcbios_tty[unit] = tty_alloc(); tty_attach(tp); } else tp = arcbios_tty[unit]; tp->t_oproc = arcbios_tty_start; tp->t_param = arcbios_tty_param; tp->t_dev = dev; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) { splx(s); return (EBUSY); } if ((tp->t_state & TS_ISOPEN) == 0) { tp->t_state |= TS_CARR_ON; ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG | CLOCAL; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = 9600; ttsetwater(tp); setuptimeout = 1; } splx(s); error = (*tp->t_linesw->l_open)(dev, tp); if (error == 0 && setuptimeout) callout_reset(&arcbios_tty_ch, 1, arcbios_tty_poll, tp); return (error); }
int dlopen(dev_t dev, int flag, int mode, struct lwp *l) { struct tty *tp; struct dl_softc *sc; int unit; unit = minor(dev); sc = device_lookup_private(&dl_cd, unit); if (!sc) return ENXIO; tp = sc->sc_tty; if (tp == NULL) return ENODEV; tp->t_oproc = dlstart; tp->t_param = dlparam; tp->t_dev = dev; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); if (!(tp->t_state & TS_ISOPEN)) { ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; /* No modem control, so set CLOCAL. */ tp->t_cflag = TTYDEF_CFLAG | CLOCAL; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; dlparam(tp, &tp->t_termios); ttsetwater(tp); } return ((*tp->t_linesw->l_open)(dev, tp)); }
int pconsopen(dev_t dev, int flag, int mode, struct lwp *l) { struct pconssoftc *sc; struct tty *tp; sc = device_lookup_private(&pcons_cd, minor(dev)); if (sc == NULL) return ENXIO; if ((tp = sc->of_tty) == NULL) sc->of_tty = tp = tty_alloc(); tp->t_oproc = pconsstart; tp->t_param = pconsparam; tp->t_dev = dev; cn_tab->cn_dev = dev; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); if ((tp->t_state & TS_ISOPEN) == 0) { ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; pconsparam(tp, &tp->t_termios); ttsetwater(tp); } tp->t_state |= TS_CARR_ON; if ((sc->of_flags & OFPOLL) == 0) { sc->of_flags |= OFPOLL; callout_reset(&sc->sc_poll_ch, 1, pcons_poll, sc); } return (*tp->t_linesw->l_open)(dev, tp); }
/* * open routine. returns zero if successful, else error code */ int mttyopen(dev_t dev, int flags, int mode, struct lwp *l) { int card = MAGMA_CARD(dev); int port = MAGMA_PORT(dev); struct mtty_softc *ms; struct mtty_port *mp; struct tty *tp; struct cd1400 *cd; int error, s; if ((ms = device_lookup_private(&mtty_cd, card)) == NULL || port >= ms->ms_nports ) return(ENXIO); /* device not configured */ mp = &ms->ms_port[port]; tp = mp->mp_tty; tp->t_dev = dev; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); if( !ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* set defaults */ ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; if( ISSET(mp->mp_openflags, TIOCFLAG_CLOCAL) ) SET(tp->t_cflag, CLOCAL); if( ISSET(mp->mp_openflags, TIOCFLAG_CRTSCTS) ) SET(tp->t_cflag, CRTSCTS); if( ISSET(mp->mp_openflags, TIOCFLAG_MDMBUF) ) SET(tp->t_cflag, MDMBUF); tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; /* init ring buffer */ mp->mp_rput = mp->mp_rget = mp->mp_rbuf; /* reset CD1400 channel */ cd = mp->mp_cd1400; cd1400_write_reg(cd, CD1400_CAR, mp->mp_channel); cd1400_write_ccr(cd, CD1400_CCR_CMDRESET); /* encode the port number in top half of LIVR */ cd1400_write_reg(cd, CD1400_LIVR, port << 4 ); /* sets parameters and raises DTR */ (void)mtty_param(tp, &tp->t_termios); /* set tty watermarks */ ttsetwater(tp); /* enable service requests */ cd1400_write_reg(cd, CD1400_SRER, CD1400_SRER_RXDATA | CD1400_SRER_MDMCH); /* tell the tty about the carrier status */ if( ISSET(mp->mp_openflags, TIOCFLAG_SOFTCAR) || mp->mp_carrier ) SET(tp->t_state, TS_CARR_ON); else CLR(tp->t_state, TS_CARR_ON); } splx(s); error = ttyopen(tp, MTTY_DIALOUT(dev), ISSET(flags, O_NONBLOCK)); if (error != 0) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error != 0) goto bad; bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ /* XXX - do that here */ } return (error); }
/* * czttyopen: * * Open a Cyclades-Z serial port. */ static int czttyopen(dev_t dev, int flags, int mode, struct lwp *l) { struct cztty_softc *sc = CZTTY_SOFTC(dev); struct cz_softc *cz; struct tty *tp; int s, error; if (sc == NULL) return (ENXIO); if (sc->sc_channel == CZTTY_CHANNEL_DEAD) return (ENXIO); cz = CZTTY_CZ(sc); tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ if (!ISSET(tp->t_state, TS_ISOPEN) && (tp->t_wopen == 0)) { struct termios t; tp->t_dev = dev; /* If we're turning things on, enable interrupts */ if ((cz->cz_nopenchan++ == 0) && (cz->cz_ih == NULL)) { #ifdef CZ_DEBUG printf("%s: Enabling polling.\n", device_xname(cz->cz_dev)); #endif callout_reset(&cz->cz_callout, cz_timeout_ticks, cz_poll, cz); } /* * Enable the channel. Don't actually ring the * doorbell here; czttyparam() will do it for us. */ cz_wait_pci_doorbell(cz, "czopen"); CZTTY_CHAN_WRITE(sc, CHNCTL_OP_MODE, C_CH_ENABLE); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); /* * Reset the input and output rings. Do this before * we call czttyparam(), as that function enables * the channel. */ CZTTY_BUF_WRITE(sc, BUFCTL_RX_GET, CZTTY_BUF_READ(sc, BUFCTL_RX_PUT)); CZTTY_BUF_WRITE(sc, BUFCTL_TX_PUT, CZTTY_BUF_READ(sc, BUFCTL_TX_GET)); /* Make sure czttyparam() will see changes. */ tp->t_ospeed = 0; (void) czttyparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. */ cztty_modem(sc, 1); } splx(s); error = ttyopen(tp, CZTTY_DIALOUT(dev), ISSET(flags, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ cztty_shutdown(sc); } return (error); }
int at91dbgu_open(dev_t dev, int flag, int mode, struct lwp *l) { struct at91dbgu_softc *sc; struct tty *tp; int s, s2; int error; sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) || sc->sc_rbuf == NULL) return (ENXIO); if (!device_is_active(sc->sc_dev)) return (ENXIO); #ifdef KGDB /* * If this is the kgdb port, no other use is permitted. */ if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) return (EBUSY); #endif tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; s2 = splserial(); if (sc->enable) { if ((*sc->enable)(sc)) { splx(s2); splx(s); printf("%s: device enable failed\n", device_xname(sc->sc_dev)); return (EIO); } sc->enabled = 1; #if 0 /* XXXXXXXXXXXXXXX */ com_config(sc); #endif } /* Turn on interrupts. */ sc->sc_ier |= DBGU_INT_RXRDY; DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; #if 0 /* Fetch the current modem control status, needed later. */ sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr); /* Clear PPS capture state on first open. */ sc->sc_ppsmask = 0; sc->ppsparam.mode = 0; #endif splx(s2); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { t.c_ospeed = dbgu_cn_sc.sc_ospeed; t.c_cflag = dbgu_cn_sc.sc_cflag; } else { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure at91dbgu_param() will do something. */ tp->t_ospeed = 0; (void) at91dbgu_param(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); s2 = splserial(); /* Clear the input ring, and unblock. */ sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = AT91DBGU_RING_SIZE; at91dbgu_iflush(sc); CLR(sc->sc_rx_flags, RX_ANY_BLOCK); #ifdef COM_DEBUG if (at91dbgu_debug) comstatus(sc, "at91dbgu_open "); #endif splx(s2); } splx(s); error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ at91dbgu_shutdown(sc); } return (error); }
/* * ioctl routine */ int mttyioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) { struct mtty_softc *ms = device_lookup_private(&mtty_cd, MAGMA_CARD(dev)); struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; struct tty *tp = mp->mp_tty; int error; error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l); if( error != EPASSTHROUGH ) return(error); error = ttioctl(tp, cmd, data, flags, l); if( error != EPASSTHROUGH ) return(error); error = 0; switch(cmd) { case TIOCSBRK: /* set break */ SET(mp->mp_flags, MTTYF_SET_BREAK); cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); break; case TIOCCBRK: /* clear break */ SET(mp->mp_flags, MTTYF_CLR_BREAK); cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); break; case TIOCSDTR: /* set DTR */ mtty_modem_control(mp, TIOCM_DTR, DMBIS); break; case TIOCCDTR: /* clear DTR */ mtty_modem_control(mp, TIOCM_DTR, DMBIC); break; case TIOCMSET: /* set modem lines */ mtty_modem_control(mp, *((int *)data), DMSET); break; case TIOCMBIS: /* bit set modem lines */ mtty_modem_control(mp, *((int *)data), DMBIS); break; case TIOCMBIC: /* bit clear modem lines */ mtty_modem_control(mp, *((int *)data), DMBIC); break; case TIOCMGET: /* get modem lines */ *((int *)data) = mtty_modem_control(mp, 0, DMGET); break; case TIOCGFLAGS: *((int *)data) = mp->mp_openflags; break; case TIOCSFLAGS: if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp)) error = EPERM; else mp->mp_openflags = *((int *)data) & (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); break; default: error = EPASSTHROUGH; } return(error); }
/* * czttyioctl: * * Perform a control operation on a Cyclades-Z serial port. */ static int czttyioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { struct cztty_softc *sc = CZTTY_SOFTC(dev); struct tty *tp = sc->sc_tty; int s, error; error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); error = 0; s = spltty(); switch (cmd) { case TIOCSBRK: cztty_break(sc, 1); break; case TIOCCBRK: cztty_break(sc, 0); break; case TIOCGFLAGS: *(int *)data = sc->sc_swflags; break; case TIOCSFLAGS: error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp); if (error) break; sc->sc_swflags = *(int *)data; break; case TIOCSDTR: cztty_modem(sc, 1); break; case TIOCCDTR: cztty_modem(sc, 0); break; case TIOCMSET: case TIOCMBIS: case TIOCMBIC: tiocm_to_cztty(sc, cmd, *(int *)data); break; case TIOCMGET: *(int *)data = cztty_to_tiocm(sc); break; default: error = EPASSTHROUGH; break; } splx(s); return (error); }
int sscomopen(dev_t dev, int flag, int mode, struct lwp *l) { struct sscom_softc *sc; struct tty *tp; int s, s2; int error; sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); if (sc == NULL || !ISSET(sc->sc_hwflags, SSCOM_HW_DEV_OK) || sc->sc_rbuf == NULL) return ENXIO; if (!device_is_active(sc->sc_dev)) return ENXIO; #ifdef KGDB /* * If this is the kgdb port, no other use is permitted. */ if (ISSET(sc->sc_hwflags, SSCOM_HW_KGDB)) return EBUSY; #endif tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; s2 = splserial(); SSCOM_LOCK(sc); /* Turn on interrupts. */ sscom_enable_txrxint(sc); /* Fetch the current modem control status, needed later. */ sc->sc_msts = sc->sc_read_modem_status(sc); #if 0 /* Clear PPS capture state on first open. */ sc->sc_ppsmask = 0; sc->ppsparam.mode = 0; #endif SSCOM_UNLOCK(sc); splx(s2); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; if (ISSET(sc->sc_hwflags, SSCOM_HW_CONSOLE)) { t.c_ospeed = sscomconsrate; t.c_cflag = sscomconscflag; } else { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure sscomparam() will do something. */ tp->t_ospeed = 0; (void) sscomparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); s2 = splserial(); SSCOM_LOCK(sc); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. */ sscom_modem(sc, 1); /* Clear the input ring, and unblock. */ sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = sscom_rbuf_size; sscom_iflush(sc); CLR(sc->sc_rx_flags, RX_ANY_BLOCK); sscom_hwiflow(sc); if (sscom_debug) sscomstatus(sc, "sscomopen "); SSCOM_UNLOCK(sc); splx(s2); } splx(s); error = ttyopen(tp, SSCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return 0; bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ sscom_shutdown(sc); } return error; }
static int ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, void *data, int flag, struct lwp *l) { struct tty *tp = sc->sc_tty; int error; int s; DPRINTF(("ucomioctl: cmd=0x%08lx\n", cmd)); error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); if (sc->sc_methods->ucom_ioctl != NULL) { error = sc->sc_methods->ucom_ioctl(sc->sc_parent, sc->sc_portno, cmd, data, flag, l->l_proc); if (error != EPASSTHROUGH) return (error); } error = 0; DPRINTF(("ucomioctl: our cmd=0x%08lx\n", cmd)); s = spltty(); switch (cmd) { case TIOCSBRK: ucom_break(sc, 1); break; case TIOCCBRK: ucom_break(sc, 0); break; case TIOCSDTR: ucom_dtr(sc, 1); break; case TIOCCDTR: ucom_dtr(sc, 0); break; case TIOCGFLAGS: *(int *)data = sc->sc_swflags; break; case TIOCSFLAGS: error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp); if (error) break; sc->sc_swflags = *(int *)data; break; case TIOCMSET: case TIOCMBIS: case TIOCMBIC: tiocm_to_ucom(sc, cmd, *(int *)data); break; case TIOCMGET: *(int *)data = ucom_to_tiocm(sc); break; case PPS_IOC_CREATE: case PPS_IOC_DESTROY: case PPS_IOC_GETPARAMS: case PPS_IOC_SETPARAMS: case PPS_IOC_GETCAP: case PPS_IOC_FETCH: #ifdef PPS_SYNC case PPS_IOC_KCBIND: #endif mutex_spin_enter(&timecounter_lock); error = pps_ioctl(cmd, data, &sc->sc_pps_state); mutex_spin_exit(&timecounter_lock); break; default: error = EPASSTHROUGH; break; } splx(s); return (error); }
int sscomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { struct sscom_softc *sc = device_lookup_private(&sscom_cd, SSCOMUNIT(dev)); struct tty *tp = sc->sc_tty; int error; int s; if (SSCOM_ISALIVE(sc) == 0) return EIO; error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return error; error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return error; error = 0; s = splserial(); SSCOM_LOCK(sc); switch (cmd) { case TIOCSBRK: sscom_break(sc, 1); break; case TIOCCBRK: sscom_break(sc, 0); break; case TIOCSDTR: sscom_modem(sc, 1); break; case TIOCCDTR: sscom_modem(sc, 0); break; case TIOCGFLAGS: *(int *)data = sc->sc_swflags; break; case TIOCSFLAGS: error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp); if (error) break; sc->sc_swflags = *(int *)data; break; case TIOCMSET: case TIOCMBIS: case TIOCMBIC: tiocm_to_sscom(sc, cmd, *(int *)data); break; case TIOCMGET: *(int *)data = sscom_to_tiocm(sc); break; default: error = EPASSTHROUGH; break; } SSCOM_UNLOCK(sc); splx(s); if (sscom_debug) sscomstatus(sc, "sscomioctl "); return error; }
int at91usart_open(dev_t dev, int flag, int mode, struct lwp *l) { struct at91usart_softc *sc; struct tty *tp; int s; int error; sc = device_lookup_private(&at91usart_cd, COMUNIT(dev)); if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK)) return (ENXIO); if (!device_is_active(sc->sc_dev)) return (ENXIO); #ifdef KGDB /* * If this is the kgdb port, no other use is permitted. */ if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) return (EBUSY); #endif tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; if (sc->enable) { if ((*sc->enable)(sc)) { splx(s); printf("%s: device enable failed\n", device_xname(sc->sc_dev)); return (EIO); } sc->enabled = 1; #if 0 /* XXXXXXXXXXXXXXX */ com_config(sc); #endif } /* reset fifos: */ AT91PDC_RESET_FIFO(sc->sc_iot, sc->sc_ioh, sc->sc_dmat, US_PDC, &sc->sc_rx_fifo, 0); AT91PDC_RESET_FIFO(sc->sc_iot, sc->sc_ioh, sc->sc_dmat, US_PDC, &sc->sc_tx_fifo, 1); /* reset receive */ at91usart_writereg(sc, US_CR, US_CR_RSTSTA | US_CR_STTTO); /* Turn on interrupts. */ sc->sc_ier = US_CSR_ENDRX|US_CSR_RXBUFF|US_CSR_TIMEOUT|US_CSR_RXBRK; at91usart_writereg(sc, US_IER, sc->sc_ier); /* enable DMA: */ at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_RXTEN); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; /* if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { t.c_ospeed = usart_cn_sc.sc_ospeed; t.c_cflag = usart_cn_sc.sc_cflag; } else*/ { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure at91usart_param() will do something. */ tp->t_ospeed = 0; (void) at91usart_param(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); /* and unblock. */ CLR(sc->sc_rx_flags, RX_ANY_BLOCK); #ifdef COM_DEBUG if (at91usart_debug) comstatus(sc, "at91usart_open "); #endif } splx(s); error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ at91usart_shutdown(sc); } return (error); }
int ucomopen(dev_t dev, int flag, int mode, struct lwp *l) { int unit = UCOMUNIT(dev); usbd_status err; struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit); struct ucom_buffer *ub; struct tty *tp; int s, i; int error; if (sc == NULL) return (ENXIO); if (sc->sc_dying) return (EIO); if (!device_is_active(sc->sc_dev)) return (ENXIO); tp = sc->sc_tty; DPRINTF(("ucomopen: unit=%d, tp=%p\n", unit, tp)); if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ while (sc->sc_opening) tsleep(&sc->sc_opening, PRIBIO, "ucomop", 0); if (sc->sc_dying) { splx(s); return (EIO); } sc->sc_opening = 1; if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; if (sc->sc_methods->ucom_open != NULL) { error = sc->sc_methods->ucom_open(sc->sc_parent, sc->sc_portno); if (error) { ucom_cleanup(sc); sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); } } ucom_status_change(sc); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure ucomparam() will do something. */ tp->t_ospeed = 0; (void) ucomparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. Ditto RTS. */ ucom_dtr(sc, 1); ucom_rts(sc, 1); DPRINTF(("ucomopen: open pipes in=%d out=%d\n", sc->sc_bulkin_no, sc->sc_bulkout_no)); /* Open the bulk pipes */ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); if (err) { DPRINTF(("%s: open bulk in error (addr %d), err=%s\n", USBDEVNAME(sc->sc_dev), sc->sc_bulkin_no, usbd_errstr(err))); error = EIO; goto fail_0; } err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); if (err) { DPRINTF(("%s: open bulk out error (addr %d), err=%s\n", USBDEVNAME(sc->sc_dev), sc->sc_bulkout_no, usbd_errstr(err))); error = EIO; goto fail_1; } sc->sc_rx_unblock = 0; sc->sc_rx_stopped = 0; sc->sc_tx_stopped = 0; memset(sc->sc_ibuff, 0, sizeof(sc->sc_ibuff)); memset(sc->sc_obuff, 0, sizeof(sc->sc_obuff)); SIMPLEQ_INIT(&sc->sc_ibuff_empty); SIMPLEQ_INIT(&sc->sc_ibuff_full); SIMPLEQ_INIT(&sc->sc_obuff_free); SIMPLEQ_INIT(&sc->sc_obuff_full); /* Allocate input buffers */ for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; ub++) { ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); if (ub->ub_xfer == NULL) { error = ENOMEM; goto fail_2; } ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, sc->sc_ibufsizepad); if (ub->ub_data == NULL) { error = ENOMEM; goto fail_2; } if (ucomsubmitread(sc, ub) != USBD_NORMAL_COMPLETION) { error = EIO; goto fail_2; } } for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; ub++) { ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); if (ub->ub_xfer == NULL) { error = ENOMEM; goto fail_2; } ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, sc->sc_obufsize); if (ub->ub_data == NULL) { error = ENOMEM; goto fail_2; } SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); } } sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); fail_2: usbd_abort_pipe(sc->sc_bulkin_pipe); for (i = 0; i < UCOM_IN_BUFFS; i++) { if (sc->sc_ibuff[i].ub_xfer != NULL) { usbd_free_xfer(sc->sc_ibuff[i].ub_xfer); sc->sc_ibuff[i].ub_xfer = NULL; sc->sc_ibuff[i].ub_data = NULL; } } usbd_abort_pipe(sc->sc_bulkout_pipe); for (i = 0; i < UCOM_OUT_BUFFS; i++) { if (sc->sc_obuff[i].ub_xfer != NULL) { usbd_free_xfer(sc->sc_obuff[i].ub_xfer); sc->sc_obuff[i].ub_xfer = NULL; sc->sc_obuff[i].ub_data = NULL; } } usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; fail_1: usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; fail_0: sc->sc_opening = 0; wakeup(&sc->sc_opening); splx(s); return (error); bad: s = spltty(); CLR(tp->t_state, TS_BUSY); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ ucom_cleanup(sc); } splx(s); return (error); }
int stty_open(dev_t dev, int flags, int mode, struct lwp *l) { struct spif_softc *csc; struct stty_softc *sc; struct stty_port *sp; struct tty *tp; int card = SPIF_CARD(dev); int port = SPIF_PORT(dev); sc = device_lookup_private(&stty_cd, card); csc = device_lookup_private(&spif_cd, card); if (sc == NULL || csc == NULL) return (ENXIO); if (port >= sc->sc_nports) return (ENXIO); sp = &sc->sc_port[port]; tp = sp->sp_tty; tp->t_dev = dev; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); mutex_spin_enter(&tty_lock); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL)) SET(tp->t_cflag, CLOCAL); if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS)) SET(tp->t_cflag, CRTSCTS); if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF)) SET(tp->t_cflag, MDMBUF); tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; sp->sp_rput = sp->sp_rget = sp->sp_rbuf; STC_WRITE(csc, STC_CAR, sp->sp_channel); stty_write_ccr(csc, CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN); STC_WRITE(csc, STC_CAR, sp->sp_channel); stty_param(tp, &tp->t_termios); ttsetwater(tp); STC_WRITE(csc, STC_SRER, CD180_SRER_CD | CD180_SRER_RXD); if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier) SET(tp->t_state, TS_CARR_ON); else CLR(tp->t_state, TS_CARR_ON); } if (!ISSET(flags, O_NONBLOCK)) { while (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) { int error; error = ttysleep(tp, &tp->t_rawcv, true, 0); if (error != 0) { mutex_spin_exit(&tty_lock); return (error); } } } mutex_spin_exit(&tty_lock); return ((*tp->t_linesw->l_open)(dev, tp)); }
int gtmpscopen(dev_t dev, int flag, int mode, struct lwp *l) { struct gtmpsc_softc *sc; int unit = GTMPSCUNIT(dev); struct tty *tp; int s; int error; sc = device_lookup_private(>mpsc_cd, unit); if (!sc) return ENXIO; #ifdef KGDB /* * If this is the kgdb port, no other use is permitted. */ if (sc->sc_flags & GTMPSC_KGDB) return EBUSY; #endif tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return EBUSY; s = spltty(); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; mutex_spin_enter(&sc->sc_lock); /* Turn on interrupts. */ sdma_imask |= SDMA_INTR_RXBUF(sc->sc_unit); gt_sdma_imask(device_parent(sc->sc_dev), sdma_imask); /* Clear PPS capture state on first open. */ mutex_spin_enter(&timecounter_lock); memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; pps_init(&sc->sc_pps_state); mutex_spin_exit(&timecounter_lock); mutex_spin_exit(&sc->sc_lock); if (sc->sc_flags & GTMPSC_CONSOLE) { t.c_ospeed = sc->sc_baudrate; t.c_cflag = sc->sc_cflag; } else { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } t.c_ispeed = t.c_ospeed; /* Make sure gtmpscparam() will do something. */ tp->t_ospeed = 0; (void) gtmpscparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); mutex_spin_enter(&sc->sc_lock); /* Clear the input/output ring */ sc->sc_rcvcnt = 0; sc->sc_roffset = 0; sc->sc_rcvrx = 0; sc->sc_rcvdrx = 0; sc->sc_nexttx = 0; sc->sc_lasttx = 0; /* * enable SDMA receive */ GT_SDMA_WRITE(sc, SDMA_SDCM, SDMA_SDCM_ERD); mutex_spin_exit(&sc->sc_lock); } splx(s); error = ttyopen(tp, GTMPSCDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return 0; bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ gtmpscshutdown(sc); } return error; }
int sabioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) { struct sabtty_softc *sc = device_lookup_private(&sabtty_cd, SABUNIT(dev)); struct tty *tp = sc->sc_tty; int error; error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flags, l); if (error >= 0) return (error); error = 0; switch (cmd) { case TIOCSBRK: SAB_WRITE(sc, SAB_DAFO, SAB_READ(sc, SAB_DAFO) | SAB_DAFO_XBRK); break; case TIOCCBRK: SAB_WRITE(sc, SAB_DAFO, SAB_READ(sc, SAB_DAFO) & ~SAB_DAFO_XBRK); break; case TIOCSDTR: sabtty_mdmctrl(sc, TIOCM_DTR, DMBIS); break; case TIOCCDTR: sabtty_mdmctrl(sc, TIOCM_DTR, DMBIC); break; case TIOCMBIS: sabtty_mdmctrl(sc, *((int *)data), DMBIS); break; case TIOCMBIC: sabtty_mdmctrl(sc, *((int *)data), DMBIC); break; case TIOCMGET: *((int *)data) = sabtty_mdmctrl(sc, 0, DMGET); break; case TIOCMSET: sabtty_mdmctrl(sc, *((int *)data), DMSET); break; case TIOCGFLAGS: *((int *)data) = sc->sc_openflags; break; case TIOCSFLAGS: if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp)) error = EPERM; else sc->sc_openflags = *((int *)data) & (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); break; default: error = ENOTTY; } return (error); }
int sabopen(dev_t dev, int flags, int mode, struct lwp *l) { struct sabtty_softc *sc; struct tty *tp; struct proc *p; int s, s1; sc = device_lookup_private(&sabtty_cd, SABUNIT(dev)); if (sc == NULL) return (ENXIO); tp = sc->sc_tty; tp->t_dev = dev; p = l->l_proc; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); mutex_spin_enter(&tty_lock); if ((tp->t_state & TS_ISOPEN) == 0) { ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; if (sc->sc_openflags & TIOCFLAG_CLOCAL) tp->t_cflag |= CLOCAL; if (sc->sc_openflags & TIOCFLAG_CRTSCTS) tp->t_cflag |= CRTSCTS; if (sc->sc_openflags & TIOCFLAG_MDMBUF) tp->t_cflag |= MDMBUF; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; sc->sc_rput = sc->sc_rget = sc->sc_rbuf; ttsetwater(tp); s1 = splhigh(); sabtty_reset(sc); sabtty_param(tp, &tp->t_termios); sc->sc_imr0 = SAB_IMR0_PERR | SAB_IMR0_FERR | SAB_IMR0_PLLA; SAB_WRITE(sc, SAB_IMR0, sc->sc_imr0); sc->sc_imr1 = SAB_IMR1_BRK | SAB_IMR1_ALLS | SAB_IMR1_XDU | SAB_IMR1_TIN | SAB_IMR1_CSC | SAB_IMR1_XMR | SAB_IMR1_XPR; SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); SAB_WRITE(sc, SAB_CCR0, SAB_READ(sc, SAB_CCR0) | SAB_CCR0_PU); sabtty_cec_wait(sc); SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XRES); sabtty_cec_wait(sc); SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_RRES); sabtty_cec_wait(sc); splx(s1); sabtty_flush(sc); if ((sc->sc_openflags & TIOCFLAG_SOFTCAR) || (SAB_READ(sc, SAB_VSTR) & SAB_VSTR_CD)) tp->t_state |= TS_CARR_ON; else tp->t_state &= ~TS_CARR_ON; } if ((flags & O_NONBLOCK) == 0) { while ((tp->t_cflag & CLOCAL) == 0 && (tp->t_state & TS_CARR_ON) == 0) { int error; error = ttysleep(tp, &tp->t_rawcv, true, 0); if (error != 0) { mutex_spin_exit(&tty_lock); return (error); } } } mutex_spin_exit(&tty_lock); s = (*tp->t_linesw->l_open)(dev, tp); if (s != 0) { mutex_spin_enter(&tty_lock); if (tp->t_state & TS_ISOPEN) { mutex_spin_exit(&tty_lock); return (s); } if (tp->t_cflag & HUPCL) { sabtty_mdmctrl(sc, 0, DMSET); cv_wait(&lbolt, &tty_lock); } if ((sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) == 0) { /* Flush and power down if we're not the console */ sabtty_flush(sc); sabtty_reset(sc); } mutex_spin_exit(&tty_lock); } return (s); }
int mfcsioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { register struct tty *tp; register int error; struct mfcs_softc *sc = device_lookup_private(&mfcs_cd, dev & 31); tp = sc->sc_tty; if (!tp) return ENXIO; error = tp->t_linesw->l_ioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return(error); error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return(error); switch (cmd) { case TIOCSBRK: sc->sc_duart->ch_cr = 0x60; /* start break */ break; case TIOCCBRK: sc->sc_duart->ch_cr = 0x70; /* stop break */ break; case TIOCSDTR: (void) mfcsmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS); break; case TIOCCDTR: (void) mfcsmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC); break; case TIOCMSET: (void) mfcsmctl(dev, *(int *) data, DMSET); break; case TIOCMBIS: (void) mfcsmctl(dev, *(int *) data, DMBIS); break; case TIOCMBIC: (void) mfcsmctl(dev, *(int *) data, DMBIC); break; case TIOCMGET: *(int *)data = mfcsmctl(dev, 0, DMGET); break; case TIOCGFLAGS: *(int *)data = SWFLAGS(dev); break; case TIOCSFLAGS: error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp); if (error != 0) return(EPERM); sc->swflags = *(int *)data; sc->swflags &= /* only allow valid flags */ (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS); /* XXXX need to change duart parameters? */ break; default: return(EPASSTHROUGH); } return(0); }
/* * Open a zs serial port. */ int zsopen(dev_t dev, int flags, int mode, struct lwp *l) { struct tty *tp; struct zs_chanstate *cs; struct zs_softc *sc; int unit = ZS_UNIT(dev); int zs = unit >> 1; int error, s; sc = device_lookup_private(&zs_cd, zs); if (sc == NULL) return ENXIO; cs = sc->sc_cs[unit & 1]; /* * When port A (ser02) is selected on the TT, make sure * the port is enabled. */ if ((machineid & ATARI_TT) && !(unit & 1)) ym2149_ser2(1); if (cs->cs_rbuf == NULL) { cs->cs_rbuf = malloc(ZLRB_RING_SIZE * sizeof(int), M_DEVBUF, M_WAITOK); } tp = cs->cs_ttyp; if (tp == NULL) { cs->cs_ttyp = tp = tty_alloc(); tty_attach(tp); tp->t_dev = dev; tp->t_oproc = zsstart; tp->t_param = zsparam; } if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return EBUSY; s = spltty(); /* * Do the following iff this is a first open. */ if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) { if (tp->t_ispeed == 0) { tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; } ttychars(tp); ttsetwater(tp); (void)zsparam(tp, &tp->t_termios); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. */ zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET); /* May never get a status intr. if DCD already on. -gwr */ if (((cs->cs_rr0 = cs->cs_zc->zc_csr) & ZSRR0_DCD) != 0) tp->t_state |= TS_CARR_ON; if (cs->cs_softcar) tp->t_state |= TS_CARR_ON; } splx(s); error = ttyopen(tp, ZS_DIALOUT(dev), (flags & O_NONBLOCK)); if (error) goto bad; error = tp->t_linesw->l_open(dev, tp); if (error) goto bad; return 0; bad: if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ zs_shutdown(cs); } return error; }
int stty_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) { struct stty_softc *stc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)]; struct spif_softc *sc = sp->sp_sc; struct tty *tp = sp->sp_tty; int error; error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flags, l); if (error >= 0) return (error); error = 0; switch (cmd) { case TIOCSBRK: SET(sp->sp_flags, STTYF_SET_BREAK); STC_WRITE(sc, STC_CAR, sp->sp_channel); STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) | CD180_SRER_TXD); break; case TIOCCBRK: SET(sp->sp_flags, STTYF_CLR_BREAK); STC_WRITE(sc, STC_CAR, sp->sp_channel); STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) | CD180_SRER_TXD); break; case TIOCSDTR: stty_modem_control(sp, TIOCM_DTR, DMBIS); break; case TIOCCDTR: stty_modem_control(sp, TIOCM_DTR, DMBIC); break; case TIOCMBIS: stty_modem_control(sp, *((int *)data), DMBIS); break; case TIOCMBIC: stty_modem_control(sp, *((int *)data), DMBIC); break; case TIOCMGET: *((int *)data) = stty_modem_control(sp, 0, DMGET); break; case TIOCMSET: stty_modem_control(sp, *((int *)data), DMSET); break; case TIOCGFLAGS: *((int *)data) = sp->sp_openflags; break; case TIOCSFLAGS: if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp)) error = EPERM; else sp->sp_openflags = *((int *)data) & (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); break; default: error = ENOTTY; } return (error); }
int gtmpscioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { struct gtmpsc_softc *sc = device_lookup_private(>mpsc_cd, GTMPSCUNIT(dev)); struct tty *tp = sc->sc_tty; int error; error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return error; error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return error; error = 0; switch (cmd) { case TIOCSFLAGS: error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp); if (error) return error; break; default: /* nothing */ break; } mutex_spin_enter(&sc->sc_lock); switch (cmd) { case PPS_IOC_CREATE: case PPS_IOC_DESTROY: case PPS_IOC_GETPARAMS: case PPS_IOC_SETPARAMS: case PPS_IOC_GETCAP: case PPS_IOC_FETCH: #ifdef PPS_SYNC case PPS_IOC_KCBIND: #endif mutex_spin_enter(&timecounter_lock); error = pps_ioctl(cmd, data, &sc->sc_pps_state); mutex_spin_exit(&timecounter_lock); break; case TIOCDCDTIMESTAMP: /* XXX old, overloaded API used by xntpd v3 */ mutex_spin_enter(&timecounter_lock); #ifndef PPS_TRAILING_EDGE TIMESPEC_TO_TIMEVAL((struct timeval *)data, &sc->sc_pps_state.ppsinfo.assert_timestamp); #else TIMESPEC_TO_TIMEVAL((struct timeval *)data, &sc->sc_pps_state.ppsinfo.clear_timestamp); #endif mutex_spin_exit(&timecounter_lock); break; default: error = EPASSTHROUGH; break; } mutex_spin_exit(&sc->sc_lock); return error; }
static int ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, void *data, int flag, struct lwp *l) { struct tty *tp = sc->sc_tty; int error; int s; if (sc->sc_dying) return (EIO); DPRINTF(("ucomioctl: cmd=0x%08lx\n", cmd)); error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); if (sc->sc_methods->ucom_ioctl != NULL) { error = sc->sc_methods->ucom_ioctl(sc->sc_parent, sc->sc_portno, cmd, data, flag, l->l_proc); if (error != EPASSTHROUGH) return (error); } error = 0; DPRINTF(("ucomioctl: our cmd=0x%08lx\n", cmd)); s = spltty(); switch (cmd) { case TIOCSBRK: ucom_break(sc, 1); break; case TIOCCBRK: ucom_break(sc, 0); break; case TIOCSDTR: ucom_dtr(sc, 1); break; case TIOCCDTR: ucom_dtr(sc, 0); break; case TIOCGFLAGS: *(int *)data = sc->sc_swflags; break; case TIOCSFLAGS: error = kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_PRIVSET, tp); if (error) break; sc->sc_swflags = *(int *)data; break; case TIOCMSET: case TIOCMBIS: case TIOCMBIC: tiocm_to_ucom(sc, cmd, *(int *)data); break; case TIOCMGET: *(int *)data = ucom_to_tiocm(sc); break; default: error = EPASSTHROUGH; break; } splx(s); return (error); }
int mfcsopen(dev_t dev, int flag, int mode, struct lwp *l) { struct tty *tp; struct mfcs_softc *sc; int unit, error; error = 0; unit = dev & 0x1f; sc = device_lookup_private(&mfcs_cd, unit); if (sc == NULL || (mfcs_active & (1 << unit)) == 0) return (ENXIO); if (sc->sc_tty) tp = sc->sc_tty; else { tp = sc->sc_tty = tty_alloc(); tty_attach(tp); } tp->t_oproc = (void (*) (struct tty *)) mfcsstart; tp->t_param = mfcsparam; tp->t_dev = dev; tp->t_hwiflow = mfcshwiflow; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); mutex_spin_enter(&tty_lock); if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) { ttychars(tp); if (tp->t_ispeed == 0) { /* * only when cleared do we reset to defaults. */ tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = mfcsdefaultrate; } /* * do these all the time */ if (sc->swflags & TIOCFLAG_CLOCAL) tp->t_cflag |= CLOCAL; if (sc->swflags & TIOCFLAG_CRTSCTS) tp->t_cflag |= CRTSCTS; if (sc->swflags & TIOCFLAG_MDMBUF) tp->t_cflag |= MDMBUF; mfcsparam(tp, &tp->t_termios); ttsetwater(tp); (void)mfcsmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET); if ((SWFLAGS(dev) & TIOCFLAG_SOFTCAR) || (mfcsmctl(dev, 0, DMGET) & TIOCM_CD)) tp->t_state |= TS_CARR_ON; else tp->t_state &= ~TS_CARR_ON; } /* * if NONBLOCK requested, ignore carrier */ if (flag & O_NONBLOCK) goto done; /* * block waiting for carrier */ while ((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0) { tp->t_wopen++; error = ttysleep(tp, &tp->t_rawcv, true, 0); tp->t_wopen--; if (error) { mutex_spin_exit(&tty_lock); return(error); } } done: /* This is a way to handle lost XON characters */ if ((flag & O_TRUNC) && (tp->t_state & TS_TTSTOP)) { tp->t_state &= ~TS_TTSTOP; ttstart (tp); } /* * Reset the tty pointer, as there could have been a dialout * use of the tty with a dialin open waiting. */ tp->t_dev = dev; mutex_spin_exit(&tty_lock); return tp->t_linesw->l_open(dev, tp); }