Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
int
vconsopen(dev_t dev, int flag, int mode, struct proc *p)
{
	struct vcons_softc *sc;
	struct tty *tp;
	int unit = minor(dev);

	if (unit > vcons_cd.cd_ndevs)
		return (ENXIO);
	sc = vcons_cd.cd_devs[unit];
	if (sc == NULL)
		return (ENXIO);

	if (sc->sc_tty)
		tp = sc->sc_tty;
	else
		tp = sc->sc_tty = ttymalloc(0);

	tp->t_oproc = vconsstart;
	tp->t_param = vconsparam;
	tp->t_dev = dev;
	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;
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && suser(p, 0))
		return (EBUSY);
	tp->t_state |= TS_CARR_ON;

	return ((*linesw[tp->t_line].l_open)(dev, tp, p));
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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));
}
Exemplo n.º 5
0
/*
 * cdevsw interface to km driver.
 */
int
kmopen(
    dev_t dev,
    int flag,
    int devtype,
    struct proc *pp)
{
    int rtn;
    int unit;
    struct tty *tp;
    struct winsize *wp;
    int ret;

    unit = minor(dev);
    if(unit >= 1)
        return (ENXIO);

    tp = (struct tty *)&cons;
    tp->t_oproc = kmstart;
    tp->t_param = NULL;
    tp->t_dev = dev;

    if ( !(tp->t_state & TS_ISOPEN) ) {
        tp->t_iflag = TTYDEF_IFLAG;
        tp->t_oflag = TTYDEF_OFLAG;
        tp->t_cflag = (CREAD | CS8 | CLOCAL);
        tp->t_lflag = TTYDEF_LFLAG;
        tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
        termioschars(&tp->t_termios);
        ttsetwater(tp);
    } else if ((tp->t_state & TS_XCLUDE) && pp->p_ucred->cr_uid != 0)
        return EBUSY;

    tp->t_state |= TS_CARR_ON; /* lie and say carrier exists and is on. */
    ret = ((*linesw[tp->t_line].l_open)(dev, tp));
    {
        PE_Video video;
        wp = &tp->t_winsize;
        /* Magic numbers.  These are CHARWIDTH and CHARHEIGHT
         * from osfmk/ppc/POWERMAC/video_console.c
         */
        wp->ws_xpixel = 8;
        wp->ws_ypixel = 16;

        if (flag & O_POPUP)
            PE_initialize_console(0, kPETextScreen);

        bzero(&video, sizeof(video));
        PE_current_console(&video);
        if( video.v_width != 0 && video.v_height != 0 ) {
            wp->ws_col = video.v_width / wp->ws_xpixel;
            wp->ws_row = video.v_height / wp->ws_ypixel;
        } else {
            wp->ws_col = 100;
            wp->ws_row = 36;
        }
    }
    return ret;
}
Exemplo n.º 6
0
int
vioconopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int unit = VIOCONUNIT(dev);
	int port = VIOCONPORT(dev);
	struct viocon_softc *sc;
	struct viocon_port *vp;
	struct tty *tp;
	int s, error;

	if (unit >= viocon_cd.cd_ndevs)
		return (ENXIO);
	sc = viocon_cd.cd_devs[unit];
	if (sc == NULL)
		return (ENXIO);
	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
		return (ENXIO);

	s = spltty();
	if (port >= sc->sc_max_ports) {
		splx(s);
		return (ENXIO);
	}
	vp = sc->sc_ports[port];
	tp = vp->vp_tty;
#ifdef NOTYET
	vp->vp_guest_open = 1;
#endif
	splx(s);

	if (!ISSET(tp->t_state, TS_ISOPEN)) {
		SET(tp->t_state, TS_WOPEN);
		ttychars(tp);
		tp->t_ispeed = 1000000;
		tp->t_ospeed = 1000000;
		tp->t_cflag = TTYDEF_CFLAG|CLOCAL|CRTSCTS;
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		if (vp->vp_cols != 0) {
			tp->t_winsize.ws_col = vp->vp_cols;
			tp->t_winsize.ws_row = vp->vp_rows;
		}

		s = spltty();
		vioconparam(tp, &tp->t_termios);
		ttsetwater(tp);
		splx(s);
	}
	else if (ISSET(tp->t_state, TS_XCLUDE) && suser(p, 0) != 0) {
		return (EBUSY);
	}

	error = linesw[tp->t_line].l_open(dev, tp, p);
	return error;
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
Arquivo: zs.c Projeto: MarginC/kame
static int
zsttyopen(dev_t dev, int flags, int mode, struct thread *td)
{
	struct zstty_softc *sc;
	struct tty *tp;
	int error;

	sc = dev->si_drv1;
	tp = dev->si_tty;

	if ((tp->t_state & TS_ISOPEN) != 0 &&
	    (tp->t_state & TS_XCLUDE) != 0 &&
	    !suser(td))
		return (EBUSY);

	if ((tp->t_state & TS_ISOPEN) == 0) {
		struct termios t;

		/*
		 * Enable receive and status interrupts in zstty_param.
		 */
		sc->sc_preg[1] |= ZSWR1_RIE | ZSWR1_SIE;
		sc->sc_iput = sc->sc_iget = sc->sc_ibuf;

		/*
		 * Initialize the termios status to the defaults.  Add in the
		 * sticky bits from TIOCSFLAGS.
		 */
		t.c_ispeed = 0;
		t.c_ospeed = tp->t_ospeed;
		t.c_cflag = TTYDEF_CFLAG;
		/* Make sure zstty_param() will do something. */
		tp->t_ospeed = 0;
		(void)zstty_param(sc, tp, &t);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		ttychars(tp);
		ttsetwater(tp);

		/* XXX turn on DTR */

		/* XXX handle initial DCD */
	}

	error = ttyopen(dev, tp);
	if (error != 0)
		return (error);

	error = (*linesw[tp->t_line].l_open)(dev, tp);
	if (error != 0)
		return (error);

	return (0);
}
Exemplo n.º 9
0
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
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);
}
Exemplo n.º 11
0
int
dartopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int s, port;
	struct dart_info *dart;
	struct dartsoftc *sc;
	struct tty *tp;

	port = DART_PORT(dev);
	if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS)
		return (ENODEV);
	sc = (struct dartsoftc *)dart_cd.cd_devs[0]; /* the only one */
	dart = &sc->sc_dart[port];

	s = spltty();
	if (dart->tty != NULL)
		tp = dart->tty;
	else
		tp = dart->tty = ttymalloc();

	tp->t_oproc = dartstart;
	tp->t_param = dartparam;
	tp->t_dev = dev;

	if ((tp->t_state & TS_ISOPEN) == 0) {
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = B9600;
		dartparam(tp, &tp->t_termios);
		if (port == CONS_PORT) {
			/* console is 8N1 */
			tp->t_cflag = (CREAD | CS8 | HUPCL);
		} else {
			tp->t_cflag = TTYDEF_CFLAG;
		}
		ttsetwater(tp);
		(void)dartmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
		tp->t_state |= TS_CARR_ON;
	} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
		splx(s);
		return (EBUSY);
	}

	/*
	 * Reset the tty pointer, as there could have been a dialout
	 * use of the tty with a dialin open waiting.
	 */
	tp->t_dev = dev;
	splx(s);
	return ((*linesw[tp->t_line].l_open)(dev, tp));
}
Exemplo n.º 12
0
static int
ofw_dev_open(dev_t dev, int flag, int mode, struct thread *td)
{
	struct	tty *tp;
	int	unit;
	int	error, setuptimeout;

	error = 0;
	setuptimeout = 0;
	unit = minor(dev);

	tp = ofw_tp = dev->si_tty = ttymalloc(ofw_tp);

	tp->t_oproc = ofw_tty_start;
	tp->t_param = ofw_tty_param;
	tp->t_stop = ofw_tty_stop;
	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 = TTYDEF_SPEED;
		ttsetwater(tp);

		setuptimeout = 1;
	} else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
		return (EBUSY);
	}

	error = (*linesw[tp->t_line].l_open)(dev, tp);

	if (error == 0 && setuptimeout) {
		polltime = hz / OFW_POLL_HZ;
		if (polltime < 1) {
			polltime = 1;
		}

		ofw_timeouthandle = timeout(ofw_timeout, tp, polltime);
	}

	return (error);
}
Exemplo n.º 13
0
/*ARGSUSED*/
int
ptsopen(dev_t dev, int flag, int devtype, struct proc *p)
{
	struct pt_softc *pti;
	struct tty *tp;
	int error;

	if ((error = check_pty(minor(dev))))
		return (error);

	pti = pt_softc[minor(dev)];
	if (!pti->pt_tty) {
		tp = pti->pt_tty = ttymalloc();
	} else
		tp = pti->pt_tty;
	if ((tp->t_state & TS_ISOPEN) == 0) {
		tp->t_state |= TS_WOPEN;
		ttychars(tp);		/* Set up default chars */
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_cflag = TTYDEF_CFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		ttsetwater(tp);		/* would be done in xxparam() */
	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
		return (EBUSY);
	if (tp->t_oproc)			/* Ctrlr still around. */
		tp->t_state |= TS_CARR_ON;
	while ((tp->t_state & TS_CARR_ON) == 0) {
		tp->t_state |= TS_WOPEN;
		if (flag&FNONBLOCK)
			break;
		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
				 ttopen, 0);
		if (error)
			return (error);
	}
	error = (*linesw[tp->t_line].l_open)(dev, tp);
	ptcwakeup(tp, FREAD|FWRITE);
	return (error);
}
Exemplo n.º 14
0
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));
}
Exemplo n.º 15
0
static int
dcons_open(dev_t dev, int flag, int mode, struct THREAD *td)
{
	struct tty *tp;
	int unit, error, s;

	unit = minor(dev);
	if (unit != 0)
		return (ENXIO);

	tp = dev->si_tty = ttymalloc(dev->si_tty);
	tp->t_oproc = dcons_tty_start;
	tp->t_param = dcons_tty_param;
	tp->t_stop = nottystop;
	tp->t_dev = dev;

	error = 0;

	s = spltty();
	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 = TTYDEF_SPEED;
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && suser(td)) {
		splx(s);
		return (EBUSY);
	}
	splx(s);

	error = (*linesw[tp->t_line].l_open)(dev, tp);

	return (error);
}
Exemplo n.º 16
0
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);
}
Exemplo n.º 17
0
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);
}
Exemplo n.º 18
0
/*
 * 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);
}
Exemplo n.º 19
0
int
ucomopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int unit = UCOMUNIT(dev);
	usbd_status err;
	struct ucom_softc *sc;
	struct tty *tp;
	struct termios t;
	int s;
	int error;

	if (unit >= ucom_cd.cd_ndevs)
		return (ENXIO);
	sc = ucom_cd.cd_devs[unit];
	if (sc == NULL)
		return (ENXIO);

	if (sc->sc_dying)
		return (EIO);

	if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
		return (ENXIO);

	/* open the pipes if this is the first open */
	ucom_lock(sc);
	if (sc->sc_open++ == 0) {
		s = splusb();

		DPRINTF(("ucomopen: open pipes in=%d out=%d\n",
		    sc->sc_bulkin_no, sc->sc_bulkout_no));
		DPRINTF(("ucomopen: hid %p pipes in=%p out=%p\n",
		    sc->sc_uhidev, sc->sc_ipipe, sc->sc_opipe));

		if (sc->sc_bulkin_no != -1) {

			/* Open the bulk pipes */
			err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, 0,
			    &sc->sc_bulkin_pipe);
			if (err) {
				DPRINTF(("%s: open bulk out error (addr %d), err=%s\n",
				    sc->sc_dev.dv_xname, 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 in error (addr %d), err=%s\n",
				    sc->sc_dev.dv_xname, sc->sc_bulkout_no,
				    usbd_errstr(err)));
				error = EIO;
				goto fail_1;
			}

			/* Allocate a request and an input buffer and start reading. */
			sc->sc_ixfer = usbd_alloc_xfer(sc->sc_udev);
			if (sc->sc_ixfer == NULL) {
				error = ENOMEM;
				goto fail_2;
			}

			sc->sc_ibuf = usbd_alloc_buffer(sc->sc_ixfer,
			    sc->sc_ibufsizepad);
			if (sc->sc_ibuf == NULL) {
				error = ENOMEM;
				goto fail_2;
			}

			sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev);
			if (sc->sc_oxfer == NULL) {
				error = ENOMEM;
				goto fail_3;
			}
		} else {
			/*
			 * input/output pipes and xfers already allocated
			 * as is the input buffer.
			 */
			sc->sc_ipipe = sc->sc_uhidev->sc_ipipe;
			sc->sc_ixfer = sc->sc_uhidev->sc_ixfer;
			sc->sc_opipe = sc->sc_uhidev->sc_opipe;
			sc->sc_oxfer = sc->sc_uhidev->sc_oxfer;
		}

		sc->sc_obuf = usbd_alloc_buffer(sc->sc_oxfer,
		    sc->sc_obufsize + sc->sc_opkthdrlen);
		if (sc->sc_obuf == NULL) {
			error = ENOMEM;
			goto fail_4;
		}

		if (sc->sc_methods->ucom_open != NULL) {
			error = sc->sc_methods->ucom_open(sc->sc_parent,
			    sc->sc_portno);
			if (error) {
				ucom_cleanup(sc);
				splx(s);
				ucom_unlock(sc);
				return (error);
			}
		}

		ucom_status_change(sc);

		ucomstartread(sc);

		splx(s);
	}
	ucom_unlock(sc);

	s = spltty();
	tp = sc->sc_tty;
	splx(s);

	DPRINTF(("ucomopen: unit=%d, tp=%p\n", unit, tp));

	tp->t_dev = dev;
	if (!ISSET(tp->t_state, TS_ISOPEN)) {
		SET(tp->t_state, TS_WOPEN);
		ttychars(tp);

		/*
		 * 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;

		s = spltty();
		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.
		 */
		ucom_dtr(sc, 1);

		/* XXX CLR(sc->sc_rx_flags, RX_ANY_BLOCK);*/
		ucom_hwiflow(sc);

		if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || UCOMCUA(dev) ||
		    ISSET(sc->sc_msr, UMSR_DCD) || ISSET(tp->t_cflag, MDMBUF))
			SET(tp->t_state, TS_CARR_ON);
		else
			CLR(tp->t_state, TS_CARR_ON);
	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) {
		error = EBUSY;
		goto bad;
	} else
		s = spltty();

	if (UCOMCUA(dev)) {
		if (ISSET(tp->t_state, TS_ISOPEN)) {
			/* Someone is already dialed in */
			error = EBUSY;
			goto bad1;
		}
		sc->sc_cua = 1;
	} else {
		/* tty (not cua) device, wait for carrier */
		if (ISSET(flag, O_NONBLOCK)) {
			if (sc->sc_cua) {
				error = EBUSY;
				goto bad1;
			}
		} else {
			while (sc->sc_cua || (!ISSET(tp->t_cflag, CLOCAL) &&
			    !ISSET(tp->t_state, TS_CARR_ON))) {
				SET(tp->t_state, TS_WOPEN);
				error = ttysleep(tp, &tp->t_rawq,
				    TTIPRI | PCATCH, ttopen, 0);
				/*
				 * If TS_WOPEN has been reset, that means the
				 * cua device has been closed.  We don't want
				 * to fail in that case, so just go around
				 * again.
				 */
				if (error && ISSET(tp->t_state, TS_WOPEN)) {
					CLR(tp->t_state, TS_WOPEN);
					goto bad1;
				}
			}
		}
	}
	splx(s);

	error = ttyopen(UCOMUNIT(dev), tp);
	if (error)
		goto bad;

	error = (*LINESW(tp, l_open))(dev, tp);
	if (error)
		goto bad;

	return (0);

fail_4:
	if (sc->sc_uhidev == NULL)
		usbd_free_xfer(sc->sc_oxfer);
	sc->sc_oxfer = NULL;
fail_3:
	usbd_free_xfer(sc->sc_ixfer);
	sc->sc_ixfer = NULL;
fail_2:
	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:
	splx(s);
	ucom_unlock(sc);
	return (error);

bad1:
	splx(s);
bad:
	ucom_lock(sc);
	ucom_cleanup(sc);
	ucom_unlock(sc);

	return (error);
}
Exemplo n.º 20
0
int
imxuartopen(dev_t dev, int flag, int mode, struct proc *p)
{
	int unit = DEVUNIT(dev);
	struct imxuart_softc *sc;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	struct tty *tp;
	int s;
	int error = 0;

	if (unit >= imxuart_cd.cd_ndevs)
		return ENXIO;
	sc = imxuart_cd.cd_devs[unit];
	if (sc == NULL)
		return ENXIO;

	s = spltty();
	if (sc->sc_tty == NULL)
		tp = sc->sc_tty = ttymalloc(0);
	else
		tp = sc->sc_tty;

	splx(s);

	tp->t_oproc = imxuart_start;
	tp->t_param = imxuart_param;
	tp->t_dev = dev;

	if (!ISSET(tp->t_state, TS_ISOPEN)) {
		SET(tp->t_state, TS_WOPEN);
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;

		if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
			tp->t_cflag = imxuartconscflag;
		else
			tp->t_cflag = TTYDEF_CFLAG;
		if (ISSET(sc->sc_swflags, COM_SW_CLOCAL))
			SET(tp->t_cflag, CLOCAL);
		if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS))
			SET(tp->t_cflag, CRTSCTS);
		if (ISSET(sc->sc_swflags, COM_SW_MDMBUF))
			SET(tp->t_cflag, MDMBUF);
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = imxuartdefaultrate;

		s = spltty();

		sc->sc_initialize = 1;
		imxuart_param(tp, &tp->t_termios);
		ttsetwater(tp);
		sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0];
		sc->sc_ibufhigh = sc->sc_ibuf + IMXUART_IHIGHWATER;
		sc->sc_ibufend = sc->sc_ibuf + IMXUART_IBUFSIZE;

		iot = sc->sc_iot;
		ioh = sc->sc_ioh;

		sc->sc_ucr1 = bus_space_read_2(iot, ioh, IMXUART_UCR1);
		sc->sc_ucr2 = bus_space_read_2(iot, ioh, IMXUART_UCR2);
		sc->sc_ucr3 = bus_space_read_2(iot, ioh, IMXUART_UCR3);
		sc->sc_ucr4 = bus_space_read_2(iot, ioh, IMXUART_UCR4);

		/* interrupt after one char on tx/rx */
		/* reference frequency divider: 1 */
		bus_space_write_2(iot, ioh, IMXUART_UFCR,
		    1 << IMXUART_FCR_TXTL_SH |
		    5 << IMXUART_FCR_RFDIV_SH |
		    1 << IMXUART_FCR_RXTL_SH);

		bus_space_write_2(iot, ioh, IMXUART_UBIR,
		    (imxuartdefaultrate / 100) - 1);

		/* formula: clk / (rfdiv * 1600) */
		bus_space_write_2(iot, ioh, IMXUART_UBMR,
		    (imxccm_get_uartclk() * 1000) / 1600);

		SET(sc->sc_ucr1, IMXUART_CR1_EN|IMXUART_CR1_RRDYEN);
		SET(sc->sc_ucr2, IMXUART_CR2_TXEN|IMXUART_CR2_RXEN);
		bus_space_write_2(iot, ioh, IMXUART_UCR1, sc->sc_ucr1);
		bus_space_write_2(iot, ioh, IMXUART_UCR2, sc->sc_ucr2);

		/* sc->sc_mcr = MCR_DTR | MCR_RTS;  XXX */
		SET(sc->sc_ucr3, IMXUART_CR3_DSR); /* XXX */
		bus_space_write_2(iot, ioh, IMXUART_UCR3, sc->sc_ucr3);

		SET(tp->t_state, TS_CARR_ON); /* XXX */


	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0)
		return EBUSY;
	else
		s = spltty();

	if (DEVCUA(dev)) {
		if (ISSET(tp->t_state, TS_ISOPEN)) {
			splx(s);
			return EBUSY;
		}
		sc->sc_cua = 1;
	} else {
		/* tty (not cua) device; wait for carrier if necessary */
		if (ISSET(flag, O_NONBLOCK)) {
			if (sc->sc_cua) {
				/* Opening TTY non-blocking... but the CUA is busy */
				splx(s);
				return EBUSY;
			}
		} else {
			while (sc->sc_cua ||
			    (!ISSET(tp->t_cflag, CLOCAL) &&
				!ISSET(tp->t_state, TS_CARR_ON))) {
				SET(tp->t_state, TS_WOPEN);
				error = ttysleep(tp, &tp->t_rawq,
				    TTIPRI | PCATCH, ttopen, 0);
				/*
				 * If TS_WOPEN has been reset, that means the
				 * cua device has been closed.  We don't want
				 * to fail in that case,
				 * so just go around again.
				 */
				if (error && ISSET(tp->t_state, TS_WOPEN)) {
					CLR(tp->t_state, TS_WOPEN);
					if (!sc->sc_cua && !ISSET(tp->t_state,
					    TS_ISOPEN))
						imxuart_pwroff(sc);
					splx(s);
					return error;
				}
			}
		}
	}
	splx(s);
	return (*linesw[tp->t_line].l_open)(dev,tp,p);
}
Exemplo n.º 21
0
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);
}
Exemplo n.º 22
0
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);
}
Exemplo n.º 23
0
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));
}
Exemplo n.º 24
0
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;
}
Exemplo n.º 25
0
Arquivo: zs.c Projeto: MarginC/kame
static int
zstty_param(struct zstty_softc *sc, struct tty *tp, struct termios *t)
{
	tcflag_t cflag;
	uint8_t wr3;
	uint8_t wr4;
	uint8_t wr5;
	int ospeed;

	ospeed = zstty_speed(sc, t->c_ospeed);
	if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
		return (EINVAL);

	/*
	 * If there were no changes, don't do anything.  This avoids dropping
	 * input and improves performance when all we did was frob things like
	 * VMIN and VTIME.
	 */
	if (tp->t_ospeed == t->c_ospeed &&
	    tp->t_cflag == t->c_cflag)
		return (0);

	zstty_mdmctrl(sc, TIOCM_DTR,
	    (t->c_ospeed == 0) ? DMBIC : DMBIS);

	cflag = t->c_cflag;

	if (sc->sc_console != 0) {
		cflag |= CLOCAL;
		cflag &= ~HUPCL;
	}

	wr3 = ZSWR3_RX_ENABLE;
	wr5 = ZSWR5_TX_ENABLE | ZSWR5_DTR | ZSWR5_RTS;

	switch (cflag & CSIZE) {
	case CS5:
		wr3 |= ZSWR3_RX_5;
		wr5 |= ZSWR5_TX_5;
		break;
	case CS6:
		wr3 |= ZSWR3_RX_6;
		wr5 |= ZSWR5_TX_6;
		break;
	case CS7:
		wr3 |= ZSWR3_RX_7;
		wr5 |= ZSWR5_TX_7;
		break;
	case CS8:
	default:
		wr3 |= ZSWR3_RX_8;
		wr5 |= ZSWR5_TX_8;
		break;
	}

	wr4 = ZSWR4_CLK_X16 | (cflag & CSTOPB ? ZSWR4_TWOSB : ZSWR4_ONESB);
	if ((cflag & PARODD) == 0)
		wr4 |= ZSWR4_EVENP;
	if (cflag & PARENB)
		wr4 |= ZSWR4_PARENB;

	tp->t_ispeed = 0;
	tp->t_ospeed = t->c_ospeed;
	tp->t_cflag = cflag;

	ttsetwater(tp);

	ZSTTY_LOCK(sc);

	sc->sc_preg[3] = wr3;
	sc->sc_preg[4] = wr4;
	sc->sc_preg[5] = wr5;

	zstty_set_speed(sc, ospeed);

	if (cflag & CRTSCTS)
		sc->sc_preg[15] |= ZSWR15_CTS_IE;
	else
		sc->sc_preg[15] &= ~ZSWR15_CTS_IE;

	zstty_load_regs(sc);

	ZSTTY_UNLOCK(sc);
	
	return (0);
}
Exemplo n.º 26
0
/*
 * open routine. returns zero if successful, else error code
 */
int
mttyopen(dev_t dev, int flags, int mode, struct proc *p)
{
    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 s;

    if (card >= mtty_cd.cd_ndevs || (ms = mtty_cd.cd_devs[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 (!ISSET(tp->t_state, TS_ISOPEN)) {
        SET(tp->t_state, TS_WOPEN);

        /* 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;

        s = spltty();

        /* 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);
    } else if (ISSET(tp->t_state, TS_XCLUDE) && suser(p, 0) != 0) {
        return (EBUSY);	/* superuser can break exclusive access */
    } else {
        s = spltty();
    }

    /* wait for carrier if necessary */
    if (!ISSET(flags, O_NONBLOCK)) {
        while (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
            int error;

            SET(tp->t_state, TS_WOPEN);
            error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, "mttydcd", 0);
            if (error != 0) {
                splx(s);
                CLR(tp->t_state, TS_WOPEN);
                return (error);
            }
        }
    }

    splx(s);

    return ((*linesw[tp->t_line].l_open)(dev, tp, p));
}
Exemplo n.º 27
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;
}
Exemplo n.º 28
0
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);
}
Exemplo n.º 29
0
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);
}
Exemplo n.º 30
0
/*
 * cdevsw interface to km driver.
 */
int
kmopen(dev_t dev, int flag, __unused int devtype, proc_t pp)
{
	int             unit;
	struct tty     *tp;
	struct winsize *wp;
	int             ret;

	unit = minor(dev);
	if (unit >= 1)
		return (ENXIO);

	tp = km_tty[unit];

	tty_lock(tp);

	tp->t_oproc = kmstart;
	tp->t_param = NULL;
	tp->t_dev = dev;

	if (!(tp->t_state & TS_ISOPEN)) {
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = (CREAD | CS8 | CLOCAL);
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
		termioschars(&tp->t_termios);
		ttsetwater(tp);
	} else if ((tp->t_state & TS_XCLUDE) && proc_suser(pp)) {
		ret = EBUSY;
		goto out;
	}

	tp->t_state |= TS_CARR_ON;	/* lie and say carrier exists and is
					 * on. */
	ret = ((*linesw[tp->t_line].l_open) (dev, tp));
	{
		PE_Video        video;
		wp = &tp->t_winsize;
		/*
		 * Magic numbers.  These are CHARWIDTH and CHARHEIGHT from
		 * pexpert/i386/video_console.c
		 */
		wp->ws_xpixel = 8;
		wp->ws_ypixel = 16;

		tty_unlock(tp);		/* XXX race window */

		if (flag & O_POPUP)
			PE_initialize_console(0, kPETextScreen);

		bzero(&video, sizeof(video));
		PE_current_console(&video);

		tty_lock(tp);

		if (serialmode & SERIALMODE_OUTPUT) {
			wp->ws_col = 80;
			wp->ws_row = 24;
		} else if (video.v_width != 0 && video.v_height != 0) {
			wp->ws_col = video.v_width / wp->ws_xpixel;
			wp->ws_row = video.v_height / wp->ws_ypixel;
		} else {
			wp->ws_col = 100;
			wp->ws_row = 36;
		}
	}

out:
	tty_unlock(tp);

	return ret;
}