Beispiel #1
0
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);
}
Beispiel #2
0
int
ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, caddr_t data,
	      int flag, struct proc *p)
{
	struct tty *tp = sc->sc_tty;
	int error;
	int s;

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

	DPRINTF(("ucomioctl: cmd=0x%08lx\n", cmd));

	error = (*LINESW(tp, l_ioctl))(tp, cmd, data, flag, p);
	if (error >= 0)
		return (error);

	error = ttioctl(tp, cmd, data, flag, p);
	if (error >= 0)
		return (error);

	if (sc->sc_methods->ucom_ioctl != NULL) {
		error = sc->sc_methods->ucom_ioctl(sc->sc_parent,
			    sc->sc_portno, cmd, data, flag, p);
		if (error >= 0)
			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 = suser(p, 0);
		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 = ENOTTY;
		break;
	}

	splx(s);

	return (error);
}
Beispiel #3
0
int
imxuartioctl( dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct imxuart_softc *sc;
	struct tty *tp;
	int error;

	sc = imxuart_sc(dev);
	if (sc == NULL)
		return (ENODEV);

	tp = sc->sc_tty;
	if (tp == NULL)
		return (ENXIO);

	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
	if (error >= 0)
		return (error);

	error = ttioctl(tp, cmd, data, flag, p);
	if (error >= 0)
		return (error);

	switch(cmd) {
	case TIOCSBRK:
		/* */
		break;

	case TIOCCBRK:
		/* */
		break;

	case TIOCSDTR:
#if 0
		(void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
#endif
		break;

	case TIOCCDTR:
#if 0
		(void) clmctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
#endif
		break;

	case TIOCMSET:
#if 0
		(void) clmctl(dev, *(int *) data, DMSET);
#endif
		break;

	case TIOCMBIS:
#if 0
		(void) clmctl(dev, *(int *) data, DMBIS);
#endif
		break;

	case TIOCMBIC:
#if 0
		(void) clmctl(dev, *(int *) data, DMBIC);
#endif
		break;

        case TIOCMGET:
#if 0
		*(int *)data = clmctl(dev, 0, DMGET);
#endif
		break;

	case TIOCGFLAGS:
#if 0
		*(int *)data = cl->cl_swflags;
#endif
		break;

	case TIOCSFLAGS:
		error = suser(p, 0);
		if (error != 0)
			return(EPERM);

#if 0
		cl->cl_swflags = *(int *)data;
		cl->cl_swflags &= /* only allow valid flags */
		    (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
#endif
		break;
	default:
		return (ENOTTY);
	}

	return 0;
}
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;
}
Beispiel #5
0
/*ARGSUSED*/
int
ttcompat(struct tty *tp, u_long com, caddr_t data, int flag)
{
	switch (com) {
	case TIOCSETP:
	case TIOCSETN:
	case TIOCSETC:
	case TIOCSLTC:
	case TIOCLBIS:
	case TIOCLBIC:
	case TIOCLSET: {
		struct termios term;
		int error;

		term = tp->t_termios;
		if ((error = ttsetcompat(tp, &com, data, &term)) != 0)
			return error;
		return ttioctl(tp, com, &term, flag);
	}
	case TIOCGETP: {
		struct sgttyb *sg = (struct sgttyb *)data;
		cc_t *cc = tp->t_cc;

		sg->sg_ospeed = ttcompatspeedtab(tp->t_ospeed, compatspeeds);
		if (tp->t_ispeed == 0)
			sg->sg_ispeed = sg->sg_ospeed;
		else
			sg->sg_ispeed = ttcompatspeedtab(tp->t_ispeed, compatspeeds);
		sg->sg_erase = cc[VERASE];
		sg->sg_kill = cc[VKILL];
		sg->sg_flags = tp->t_flags = ttcompatgetflags(tp);
		break;
	}
	case TIOCGETC: {
		struct tchars *tc = (struct tchars *)data;
		cc_t *cc = tp->t_cc;

		tc->t_intrc = cc[VINTR];
		tc->t_quitc = cc[VQUIT];
		tc->t_startc = cc[VSTART];
		tc->t_stopc = cc[VSTOP];
		tc->t_eofc = cc[VEOF];
		tc->t_brkc = cc[VEOL];
		break;
	}
	case TIOCGLTC: {
		struct ltchars *ltc = (struct ltchars *)data;
		cc_t *cc = tp->t_cc;

		ltc->t_suspc = cc[VSUSP];
		ltc->t_dsuspc = cc[VDSUSP];
		ltc->t_rprntc = cc[VREPRINT];
		ltc->t_flushc = cc[VDISCARD];
		ltc->t_werasc = cc[VWERASE];
		ltc->t_lnextc = cc[VLNEXT];
		break;
	}
	case TIOCLGET:
		tp->t_flags =
		 (ttcompatgetflags(tp) & 0xffff0000UL)
		   | (tp->t_flags & 0xffff);
		*(int *)data = tp->t_flags>>16;
		if (ttydebug)
			kprintf("CLGET: returning %x\n", *(int *)data);
		break;

	case OTIOCGETD:
		*(int *)data = tp->t_line ? tp->t_line : 2;
		break;

	case OTIOCSETD: {
		int ldisczero = 0;

		return (ttioctl(tp, TIOCSETD,
			*(int *)data == 2 ? (caddr_t)&ldisczero : data, flag));
	    }

	case OTIOCCONS:
		*(int *)data = 1;
		return (ttioctl(tp, TIOCCONS, data, flag));

	default:
		return (ENOIOCTL);
	}
	return (0);
}
Beispiel #6
0
int
gtmpscioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
	struct gtmpsc_softc *sc =
	    device_lookup_private(&gtmpsc_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;
}
Beispiel #7
0
int
zsioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct zstty_softc *zst = zs_device_lookup(&zstty_cd, ZSUNIT(dev));
	struct zs_chanstate *cs = zst->zst_cs;
	struct tty *tp = zst->zst_tty;
	int error;
	int s;

	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
	if (error >= 0)
		return (error);

	error = ttioctl(tp, cmd, data, flag, p);
	if (error >= 0)
		return (error);

#ifdef	ZS_MD_IOCTL
	error = ZS_MD_IOCTL;
	if (error >= 0)
		return (error);
#endif	/* ZS_MD_IOCTL */

	error = 0;

	s = splzs();

	switch (cmd) {
	case TIOCSBRK:
		zs_break(cs, 1);
		break;

	case TIOCCBRK:
		zs_break(cs, 0);
		break;

	case TIOCGFLAGS:
		*(int *)data = zst->zst_swflags;
		break;

	case TIOCSFLAGS:
		error = suser(p, 0);
		if (error)
			break;
		zst->zst_swflags = *(int *)data;
		if (ISSET(zst->zst_hwflags, ZS_HWFLAG_NO_DCD))
			SET(zst->zst_swflags, TIOCFLAG_SOFTCAR);
		break;

	case TIOCSDTR:
		zs_modem(zst, 1);
		break;

	case TIOCCDTR:
		zs_modem(zst, 0);
		break;

	case TIOCMSET:
	case TIOCMBIS:
	case TIOCMBIC:
		tiocm_to_zs(zst, cmd, *(int *)data);
		break;

	case TIOCMGET:
		*(int *)data = zs_to_tiocm(zst);
		break;

	default:
		error = ENOTTY;
		break;
	}

	splx(s);

	return (error);
}
Beispiel #8
0
static int
ucom_dev_ioctl(struct dev_ioctl_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct ucom_softc *sc = (struct ucom_softc *)dev->si_drv1;
	u_long cmd = ap->a_cmd;
	caddr_t data = ap->a_data;
	struct tty *tp = sc->sc_tty;
	int error;

	UCOM_MTX_LOCK(sc);
	lwkt_gettoken(&tty_token);

	if (!(sc->sc_flag & UCOM_FLAG_HL_READY)) {
		lwkt_reltoken(&tty_token);
		return (EIO);
	}
	DPRINTF("cmd = 0x%08lx\n", cmd);

	error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
                                              ap->a_fflag, ap->a_cred);

	if (error != ENOIOCTL) {
                DPRINTF("ucomioctl: l_ioctl: error = %d\n", error);
                lwkt_reltoken(&tty_token);
		UCOM_MTX_UNLOCK(sc);
                return (error);
        }

        crit_enter();

	error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
        /*disc_optim(tp, &tp->t_termios, sc); */
        if (error != ENOIOCTL) {
                crit_exit();
                DPRINTF("ucomioctl: ttioctl: error = %d\n", error);

                lwkt_reltoken(&tty_token);
		UCOM_MTX_UNLOCK(sc);

                return (error);
        }


	switch (cmd) {
#if 0 /* XXXDF */
	case TIOCSRING:
		ucom_ring(sc, 1);
		error = 0;
		break;
	case TIOCCRING:
		ucom_ring(sc, 0);
		error = 0;
		break;
#endif
	case TIOCSBRK:
		ucom_break(sc, 1);
		error = 0;
		break;
	case TIOCCBRK:
		ucom_break(sc, 0);
		error = 0;
		break;
	default:
		if (sc->sc_callback->ucom_ioctl) {
			error = (sc->sc_callback->ucom_ioctl)
			    (sc, cmd, data, 0, curthread);
			if (error>=0) {
				crit_exit();

				lwkt_reltoken(&tty_token);
				UCOM_MTX_UNLOCK(sc);

				return(error);	
			}
		} else {
			error = ENOIOCTL;
		}
		break;
	}
	crit_exit();

	lwkt_reltoken(&tty_token);
	UCOM_MTX_UNLOCK(sc);

	return (error);
}
Beispiel #9
0
static int
ucomioctl(dev_t dev, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
{
	struct ucom_softc *sc;
	struct tty *tp;
	int error;
	int s;
	int d;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
	u_long oldcmd;
	struct termios term;
#endif

	USB_GET_SC(ucom, UCOMUNIT(dev), sc);
	tp = sc->sc_tty;

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

	DPRINTF(("ucomioctl: cmd = 0x%08lx\n", cmd));

#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
	term = tp->t_termios;
	oldcmd = cmd;
	error = ttsetcompat(tp, &cmd, data, &term);
	if (error != 0)
		return (error);
	if (cmd != oldcmd)
		data = (caddr_t)&term;
#endif

	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
	if (error != ENOIOCTL) {
		DPRINTF(("ucomioctl: l_ioctl: error = %d\n", error));
		return (error);
	}

	s = spltty();

	error = ttioctl(tp, cmd, data, flag);
	disc_optim(tp, &tp->t_termios, sc);
	if (error != ENOIOCTL) {
		splx(s);
		DPRINTF(("ucomioctl: ttioctl: error = %d\n", error));
		return (error);
	}

	if (sc->sc_callback->ucom_ioctl != NULL) {
		error = sc->sc_callback->ucom_ioctl(sc->sc_parent,
						    sc->sc_portno,
						    cmd, data, flag, p);
		if (error >= 0)
			return (error);
	}

	error = 0;

	DPRINTF(("ucomioctl: our cmd = 0x%08lx\n", cmd));

	switch (cmd) {
	case TIOCSBRK:
		DPRINTF(("ucomioctl: TIOCSBRK\n"));
		ucom_break(sc, 1);
		break;
	case TIOCCBRK:
		DPRINTF(("ucomioctl: TIOCCBRK\n"));
		ucom_break(sc, 0);
		break;

	case TIOCSDTR:
		DPRINTF(("ucomioctl: TIOCSDTR\n"));
		(void)ucomctl(sc, TIOCM_DTR, DMBIS);
		break;
	case TIOCCDTR:
		DPRINTF(("ucomioctl: TIOCCDTR\n"));
		(void)ucomctl(sc, TIOCM_DTR, DMBIC);
		break;

	case TIOCMSET:
		d = *(int *)data;
		DPRINTF(("ucomioctl: TIOCMSET, 0x%x\n", d));
		(void)ucomctl(sc, d, DMSET);
		break;
	case TIOCMBIS:
		d = *(int *)data;
		DPRINTF(("ucomioctl: TIOCMBIS, 0x%x\n", d));
		(void)ucomctl(sc, d, DMBIS);
		break;
	case TIOCMBIC:
		d = *(int *)data;
		DPRINTF(("ucomioctl: TIOCMBIC, 0x%x\n", d));
		(void)ucomctl(sc, d, DMBIC);
		break;
	case TIOCMGET:
		d = ucomctl(sc, 0, DMGET);
		DPRINTF(("ucomioctl: TIOCMGET, 0x%x\n", d));
		*(int *)data = d;
		break;

	default:
		DPRINTF(("ucomioctl: error: our cmd = 0x%08lx\n", cmd));
		error = ENOTTY;
		break;
	}

	splx(s);

	return (error);
}
Beispiel #10
0
int
iteioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
{
	struct iterepeat *irp;
	struct ite_softc *ip;
	struct itebell *ib;
	struct tty *tp;
	int error;

	ip = getitesp(dev);
	tp = ip->tp;

	KDASSERT(tp);

	error = tp->t_linesw->l_ioctl(tp, cmd, addr, flag, l);
	if (error != EPASSTHROUGH)
		return (error);
	error = ttioctl(tp, cmd, addr, flag, l);
	if (error != EPASSTHROUGH)
		return (error);

	switch (cmd) {
	case ITEIOCGBELL:
		ib = (struct itebell *)addr;
		ib->volume = bvolume;
		ib->pitch = bpitch;
		ib->msec = bmsec;
		return (0);
	case ITEIOCSBELL:
		ib = (struct itebell *)addr;

		if (ib->pitch > MAXBPITCH || ib->pitch < MINBPITCH ||
		    ib->volume > MAXBVOLUME || ib->msec > MAXBTIME)
			return (EINVAL);
		bvolume = ib->volume;
		bpitch = ib->pitch;
		bmsec = ib->msec;
		return (0);
	case ITEIOCSKMAP:
		if (addr == 0)
			return(EFAULT);
		bcopy(addr, &kbdmap, sizeof(struct kbdmap));
		return(0);
	case ITEIOCGKMAP:
		if (addr == NULL)
			return(EFAULT);
		bcopy(&kbdmap, addr, sizeof(struct kbdmap));
		return(0);
	case ITEIOCGREPT:
		irp = (struct iterepeat *)addr;
		irp->start = start_repeat_timeo;
		irp->next = next_repeat_timeo;
		return (0);
	case ITEIOCSREPT:
		irp = (struct iterepeat *)addr;
		if (irp->start < ITEMINREPEAT && irp->next < ITEMINREPEAT)
			return(EINVAL);
		start_repeat_timeo = irp->start;
		next_repeat_timeo = irp->next;
		return(0);
	}
#if NGRFCC > 0
	/* XXX */
	if (minor(dev) == 0) {
		error = ite_grf_ioctl(ip, cmd, addr, flag, l);
		if (error >= 0)
			return (error);
	}
#endif
	return (EPASSTHROUGH);
}
Beispiel #11
0
int
dartioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	int error;
	u_int port, chip;
	struct tty *tp;
	struct dart_info *dart;
	struct dartsoftc *sc;

	chip = DART_CHIP(dev);
	port = DART_PORT(dev);
	sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
	dart = &sc->sc_dart[port];

	tp = dart->tty;
	if (tp == NULL)
		return (ENXIO);

	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
	if (error >= 0)
		return(error);

	error = ttioctl(tp, cmd, data, flag, p);
	if (error >= 0)
		return(error);

	switch (cmd) {
	case TIOCSBRK:
	case TIOCCBRK:
		break;
	case TIOCSDTR:
		(void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIS);
		break;
	case TIOCCDTR:
		(void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIC);
		break;
	case TIOCMSET:
		(void)dartmctl(sc, port, *(int *) data, DMSET);
		break;
	case TIOCMBIS:
		(void)dartmctl(sc, port, *(int *) data, DMBIS);
		break;
	case TIOCMBIC:
		(void)dartmctl(sc, port, *(int *) data, DMBIC);
		break;
	case TIOCMGET:
		*(int *)data = dartmctl(sc, port, 0, DMGET);
		break;
	case TIOCGFLAGS:
		*(int *)data = dart->dart_swflags;
		break;
	case TIOCSFLAGS:
		error = suser(p, 0);
		if (error != 0)
			return (EPERM);

		dart->dart_swflags = *(int *)data;
		dart->dart_swflags &= /* only allow valid flags */
			(TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
		break;
	default:
		return (ENOTTY);
	}

	return (0);
}
Beispiel #12
0
/*ARGSUSED*/
int
ptyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	struct pt_softc *pti = pt_softc[minor(dev)];
	struct tty *tp = pti->pt_tty;
	u_char *cc = tp->t_cc;
	int stop, error;

	/*
	 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
	 * ttywflush(tp) will hang if there are characters in the outq.
	 */
	if (cmd == TIOCEXT) {
		/*
		 * When the EXTPROC bit is being toggled, we need
		 * to send an TIOCPKT_IOCTL if the packet driver
		 * is turned on.
		 */
		if (*(int *)data) {
			if (pti->pt_flags & PF_PKT) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag |= EXTPROC;
		} else {
			if ((tp->t_lflag & EXTPROC) &&
			    (pti->pt_flags & PF_PKT)) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag &= ~EXTPROC;
		}
		return(0);
	} else if (cdevsw[major(dev)].d_open == ptcopen)
		switch (cmd) {

		case TIOCGPGRP:
			/*
			 * We avoid calling ttioctl on the controller since,
			 * in that case, tp must be the controlling terminal.
			 */
			*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
			return (0);

		case TIOCPKT:
			if (*(int *)data) {
				if (pti->pt_flags & PF_UCNTL)
					return (EINVAL);
				pti->pt_flags |= PF_PKT;
			} else
				pti->pt_flags &= ~PF_PKT;
			return (0);

		case TIOCUCNTL:
			if (*(int *)data) {
				if (pti->pt_flags & PF_PKT)
					return (EINVAL);
				pti->pt_flags |= PF_UCNTL;
			} else
				pti->pt_flags &= ~PF_UCNTL;
			return (0);

		case TIOCREMOTE:
			if (*(int *)data)
				pti->pt_flags |= PF_REMOTE;
			else
				pti->pt_flags &= ~PF_REMOTE;
			ttyflush(tp, FREAD|FWRITE);
			return (0);

		case TIOCSETD:
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
			ndflush(&tp->t_outq, tp->t_outq.c_cc);
			break;

		case TIOCSIG:
			if (*(unsigned int *)data >= NSIG ||
			    *(unsigned int *)data == 0)
				return(EINVAL);
			if ((tp->t_lflag&NOFLSH) == 0)
				ttyflush(tp, FREAD|FWRITE);
			pgsignal(tp->t_pgrp, *(unsigned int *)data, 1);
			if ((*(unsigned int *)data == SIGINFO) &&
			    ((tp->t_lflag&NOKERNINFO) == 0))
				ttyinfo(tp);
			return (0);

		case FIONREAD:
			/*
			 * FIONREAD on the master side must return the amount
			 * in the output queue rather than the input.
			 */
			*(int *)data = tp->t_outq.c_cc;
			return (0);
		}
	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
	if (error < 0)
		 error = ttioctl(tp, cmd, data, flag, p);
	if (error < 0) {
		if (pti->pt_flags & PF_UCNTL &&
		    (cmd & ~0xff) == UIOCCMD(0)) {
			if (cmd & 0xff) {
				pti->pt_ucntl = (u_char)cmd;
				ptcwakeup(tp, FREAD);
			}
			return (0);
		}
		error = ENOTTY;
	}
	/*
	 * If external processing and packet mode send ioctl packet.
	 */
	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
		switch (cmd) {
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
			pti->pt_send |= TIOCPKT_IOCTL;
			ptcwakeup(tp, FREAD);
		default:
			break;
		}
	}
	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s')) &&
	    CCEQ(cc[VSTART], CTRL('q'));
	if (pti->pt_flags & PF_NOSTOP) {
		if (stop) {
			pti->pt_send &= ~TIOCPKT_NOSTOP;
			pti->pt_send |= TIOCPKT_DOSTOP;
			pti->pt_flags &= ~PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	} else {
		if (!stop) {
			pti->pt_send &= ~TIOCPKT_DOSTOP;
			pti->pt_send |= TIOCPKT_NOSTOP;
			pti->pt_flags |= PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	}
	return (error);
}
Beispiel #13
0
int
clmpccioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
	struct clmpcc_softc *sc = device_lookup_private(&clmpcc_cd, CLMPCCUNIT(dev));
	struct clmpcc_chan *ch = &sc->sc_chans[CLMPCCCHAN(dev)];
	struct tty *tp = ch->ch_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 TIOCSBRK:
		SET(ch->ch_flags, CLMPCC_FLG_START_BREAK);
		clmpcc_enable_transmitter(ch);
		break;

	case TIOCCBRK:
		SET(ch->ch_flags, CLMPCC_FLG_END_BREAK);
		clmpcc_enable_transmitter(ch);
		break;

	case TIOCSDTR:
		clmpcc_modem_control(ch, TIOCM_DTR, DMBIS);
		break;

	case TIOCCDTR:
		clmpcc_modem_control(ch, TIOCM_DTR, DMBIC);
		break;

	case TIOCMSET:
		clmpcc_modem_control(ch, *((int *)data), DMSET);
		break;

	case TIOCMBIS:
		clmpcc_modem_control(ch, *((int *)data), DMBIS);
		break;

	case TIOCMBIC:
		clmpcc_modem_control(ch, *((int *)data), DMBIC);
		break;

	case TIOCMGET:
		*((int *)data) = clmpcc_modem_control(ch, 0, DMGET);
		break;

	case TIOCGFLAGS:
		*((int *)data) = ch->ch_openflags;
		break;

	case TIOCSFLAGS:
		error = kauth_authorize_device_tty(l->l_cred,
		    KAUTH_DEVICE_TTY_PRIVSET, tp);
		if ( error )
			break;
		ch->ch_openflags = *((int *)data) &
			(TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
			 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
		if ( ISSET(ch->ch_flags, CLMPCC_FLG_IS_CONSOLE) )
			SET(ch->ch_openflags, TIOCFLAG_SOFTCAR);
		break;

	default:
		error = EPASSTHROUGH;
		break;
	}

	return error;
}
Beispiel #14
0
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);
}
Beispiel #15
0
/*ARGSUSED*/
static	int
ptyioctl(struct dev_ioctl_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct tty *tp = dev->si_tty;
	struct pt_ioctl *pti = dev->si_drv1;
	u_char *cc = tp->t_cc;
	int stop, error;

	lwkt_gettoken(&tty_token);
	if (dev_dflags(dev) & D_MASTER) {
		switch (ap->a_cmd) {

		case TIOCGPGRP:
			/*
			 * We avoid calling ttioctl on the controller since,
			 * in that case, tp must be the controlling terminal.
			 */
			*(int *)ap->a_data = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
			lwkt_reltoken(&tty_token);
			return (0);

		case TIOCPKT:
			if (*(int *)ap->a_data) {
				if (pti->pt_flags & PF_UCNTL) {
					lwkt_reltoken(&tty_token);
					return (EINVAL);
				}
				pti->pt_flags |= PF_PKT;
			} else {
				pti->pt_flags &= ~PF_PKT;
			}
			lwkt_reltoken(&tty_token);
			return (0);

		case TIOCUCNTL:
			if (*(int *)ap->a_data) {
				if (pti->pt_flags & PF_PKT) {
					lwkt_reltoken(&tty_token);
					return (EINVAL);
				}
				pti->pt_flags |= PF_UCNTL;
			} else {
				pti->pt_flags &= ~PF_UCNTL;
			}
			lwkt_reltoken(&tty_token);
			return (0);

		case TIOCREMOTE:
			if (*(int *)ap->a_data)
				pti->pt_flags |= PF_REMOTE;
			else
				pti->pt_flags &= ~PF_REMOTE;
			ttyflush(tp, FREAD|FWRITE);
			lwkt_reltoken(&tty_token);
			return (0);

#ifdef UNIX98_PTYS
		case TIOCISPTMASTER:
			if ((pti->pt_flags & PF_UNIX98) &&
			    (pti->devc == dev)) {
				lwkt_reltoken(&tty_token);
				return (0);
			} else {
				lwkt_reltoken(&tty_token);
				return (EINVAL);
			}
		}
#endif

		/*
		 * The rest of the ioctls shouldn't be called until 
		 * the slave is open.
		 */
		if ((tp->t_state & TS_ISOPEN) == 0) {
			lwkt_reltoken(&tty_token);
			return (EAGAIN);
		}

		switch (ap->a_cmd) {
#ifdef COMPAT_43
		case TIOCSETP:
		case TIOCSETN:
#endif
		case TIOCSETD:
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
			/*
			 * IF CONTROLLER STTY THEN MUST FLUSH TO PREVENT A HANG.
			 * ttywflush(tp) will hang if there are characters in
			 * the outq.
			 */
			ndflush(&tp->t_outq, tp->t_outq.c_cc);
			break;

		case TIOCSIG:
			if (*(unsigned int *)ap->a_data >= NSIG ||
			    *(unsigned int *)ap->a_data == 0) {
				lwkt_reltoken(&tty_token);
				return(EINVAL);
			}
			if ((tp->t_lflag&NOFLSH) == 0)
				ttyflush(tp, FREAD|FWRITE);
			pgsignal(tp->t_pgrp, *(unsigned int *)ap->a_data, 1);
			if ((*(unsigned int *)ap->a_data == SIGINFO) &&
			    ((tp->t_lflag&NOKERNINFO) == 0))
				ttyinfo(tp);
			lwkt_reltoken(&tty_token);
			return(0);
		}
	}
	if (ap->a_cmd == TIOCEXT) {
		/*
		 * When the EXTPROC bit is being toggled, we need
		 * to send an TIOCPKT_IOCTL if the packet driver
		 * is turned on.
		 */
		if (*(int *)ap->a_data) {
			if (pti->pt_flags & PF_PKT) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag |= EXTPROC;
		} else {
			if ((tp->t_lflag & EXTPROC) &&
			    (pti->pt_flags & PF_PKT)) {
				pti->pt_send |= TIOCPKT_IOCTL;
				ptcwakeup(tp, FREAD);
			}
			tp->t_lflag &= ~EXTPROC;
		}
		lwkt_reltoken(&tty_token);
		return(0);
	}
	error = (*linesw[tp->t_line].l_ioctl)(tp, ap->a_cmd, ap->a_data,
					      ap->a_fflag, ap->a_cred);
	if (error == ENOIOCTL)
		 error = ttioctl(tp, ap->a_cmd, ap->a_data, ap->a_fflag);
	if (error == ENOIOCTL) {
		if (pti->pt_flags & PF_UCNTL &&
		    (ap->a_cmd & ~0xff) == UIOCCMD(0)) {
			if (ap->a_cmd & 0xff) {
				pti->pt_ucntl = (u_char)ap->a_cmd;
				ptcwakeup(tp, FREAD);
			}
			lwkt_reltoken(&tty_token);
			return (0);
		}
		error = ENOTTY;
	}
	/*
	 * If external processing and packet mode send ioctl packet.
	 */
	if ((tp->t_lflag&EXTPROC) && (pti->pt_flags & PF_PKT)) {
		switch(ap->a_cmd) {
		case TIOCSETA:
		case TIOCSETAW:
		case TIOCSETAF:
#ifdef COMPAT_43
		case TIOCSETP:
		case TIOCSETN:
#endif
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
		case TIOCSETC:
		case TIOCSLTC:
		case TIOCLBIS:
		case TIOCLBIC:
		case TIOCLSET:
#endif
			pti->pt_send |= TIOCPKT_IOCTL;
			ptcwakeup(tp, FREAD);
		default:
			break;
		}
	}
	stop = (tp->t_iflag & IXON) && CCEQ(cc[VSTOP], CTRL('s'))
		&& CCEQ(cc[VSTART], CTRL('q'));
	if (pti->pt_flags & PF_NOSTOP) {
		if (stop) {
			pti->pt_send &= ~TIOCPKT_NOSTOP;
			pti->pt_send |= TIOCPKT_DOSTOP;
			pti->pt_flags &= ~PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	} else {
		if (!stop) {
			pti->pt_send &= ~TIOCPKT_DOSTOP;
			pti->pt_send |= TIOCPKT_NOSTOP;
			pti->pt_flags |= PF_NOSTOP;
			ptcwakeup(tp, FREAD);
		}
	}
	lwkt_reltoken(&tty_token);
	return (error);
}
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);
}
Beispiel #17
0
/*
 * 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);
}
Beispiel #18
0
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);
}
Beispiel #19
0
int
comioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
	struct com_softc *sc = device_lookup_private(&xcom_cd, COMUNIT(dev));
	struct tty *tp = sc->sc_tty;
	int iobase = sc->sc_iobase;
	int 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;

	switch (cmd) {
	case TIOCSBRK:
		SET(sc->sc_lcr, LCR_SBREAK);
		outb(pio(iobase , com_lcr), sc->sc_lcr);
		break;
	case TIOCCBRK:
		CLR(sc->sc_lcr, LCR_SBREAK);
		outb(pio(iobase , com_lcr), sc->sc_lcr);
		break;
	case TIOCSDTR:
		SET(sc->sc_mcr, sc->sc_dtr);
		outb(pio(iobase , com_mcr), sc->sc_mcr);
		break;
	case TIOCCDTR:
		CLR(sc->sc_mcr, sc->sc_dtr);
		outb(pio(iobase , com_mcr), sc->sc_mcr);
		break;
	case TIOCMSET:
		CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
	case TIOCMBIS:
		SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
		outb(pio(iobase , com_mcr), sc->sc_mcr);
		break;
	case TIOCMBIC:
		CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
		outb(pio(iobase , com_mcr), sc->sc_mcr);
		break;
	case TIOCMGET: {
		u_char m;
		int bits = 0;

		m = sc->sc_mcr;
		if (ISSET(m, MCR_DTR))
			SET(bits, TIOCM_DTR);
		if (ISSET(m, MCR_RTS))
			SET(bits, TIOCM_RTS);
		m = sc->sc_msr;
		if (ISSET(m, MSR_DCD))
			SET(bits, TIOCM_CD);
		if (ISSET(m, MSR_CTS))
			SET(bits, TIOCM_CTS);
		if (ISSET(m, MSR_DSR))
			SET(bits, TIOCM_DSR);
		if (ISSET(m, MSR_RI | MSR_TERI))
			SET(bits, TIOCM_RI);
		if (inb(pio(iobase , com_ier)))
			SET(bits, TIOCM_LE);
		*(int *)data = bits;
		break;
	}
	case TIOCGFLAGS: {
		int driverbits, userbits = 0;

		driverbits = sc->sc_swflags;
		if (ISSET(driverbits, COM_SW_SOFTCAR))
			SET(userbits, TIOCFLAG_SOFTCAR);
		if (ISSET(driverbits, COM_SW_CLOCAL))
			SET(userbits, TIOCFLAG_CLOCAL);
		if (ISSET(driverbits, COM_SW_CRTSCTS))
			SET(userbits, TIOCFLAG_CRTSCTS);
		if (ISSET(driverbits, COM_SW_MDMBUF))
			SET(userbits, TIOCFLAG_MDMBUF);

		*(int *)data = userbits;
		break;
	}
	case TIOCSFLAGS: {
		int userbits, driverbits = 0;

		error = kauth_authorize_device_tty(l->l_cred,
		    KAUTH_DEVICE_TTY_PRIVSET, tp);
		if (error != 0)
			return(EPERM);

		userbits = *(int *)data;
		if (ISSET(userbits, TIOCFLAG_SOFTCAR) ||
		    ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
			SET(driverbits, COM_SW_SOFTCAR);
		if (ISSET(userbits, TIOCFLAG_CLOCAL))
			SET(driverbits, COM_SW_CLOCAL);
		if (ISSET(userbits, TIOCFLAG_CRTSCTS))
			SET(driverbits, COM_SW_CRTSCTS);
		if (ISSET(userbits, TIOCFLAG_MDMBUF))
			SET(driverbits, COM_SW_MDMBUF);

		sc->sc_swflags = driverbits;
		break;
	}
	default:
		return EPASSTHROUGH;
	}

	return 0;
}