Пример #1
0
static int
nmdmclose(struct dev_close_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct tty *tp, *tp2;
	int err;
	struct softpart *ourpart, *otherpart;

	/*
	 * let the other end know that the game is up
	 */
	tp = dev->si_tty;
	lwkt_gettoken(&tp->t_token);
	GETPARTS(tp, ourpart, otherpart);
	tp2 = &otherpart->nm_tty;
	lwkt_gettoken(&tp2->t_token);
	(void)(*linesw[tp2->t_line].l_modem)(tp2, 0);

	/*
	 * XXX MDMBUF makes no sense for nmdms but would inhibit the above
	 * l_modem().  CLOCAL makes sense but isn't supported.   Special
	 * l_modem()s that ignore carrier drop make no sense for nmdms but
	 * may be in use because other parts of the line discipline make
	 * sense for nmdms.  Recover by doing everything that a normal
	 * ttymodem() would have done except for sending a SIGHUP.
	 */
	if (tp2->t_state & TS_ISOPEN) {
		tp2->t_state &= ~(TS_CARR_ON | TS_CONNECTED);
		tp2->t_state |= TS_ZOMBIE;
		ttyflush(tp2, FREAD | FWRITE);
	}

	err = (*linesw[tp->t_line].l_close)(tp, ap->a_fflag);
	ourpart->modemsignals &= ~TIOCM_DTR;
	nmdm_crossover(dev->si_drv1, ourpart, otherpart);
	nmdmstop(tp, FREAD|FWRITE);
	ttyclose(tp);
	lwkt_reltoken(&tp2->t_token);
	lwkt_reltoken(&tp->t_token);

	return (err);
}
Пример #2
0
/*ARGSUSED*/
static	int
nmdmopen(struct dev_open_args *ap)
{
	cdev_t dev = ap->a_head.a_dev;
	struct tty *tp, *tp2;
	int error;
	int minr;
#if 0
	cdev_t nextdev;
#endif
	struct nm_softc *pti;
	int is_b;
	int	pair;
	struct	softpart *ourpart, *otherpart;

	minr = lminor(dev);
	pair = minr >> 1;
	is_b = minr & 1;
	
#if 0
	/*
	 * XXX: Gross hack for DEVFS:
	 * If we openned this device, ensure we have the
	 * next one too, so people can open it.
	 */
	if (pair < 127) {
		nextdev = makedev(major(dev), (pair+pair) + 1);
		if (!nextdev->si_drv1) {
			nmdminit(pair + 1);
		}
	}
#endif
	if (!dev->si_drv1)
		nmdminit(pair);

	if (!dev->si_drv1)
		return(ENXIO);	

	lwkt_gettoken(&tty_token);
	pti = dev->si_drv1;
	if (is_b) 
		tp = &pti->part2.nm_tty;
	else 
		tp = &pti->part1.nm_tty;
	GETPARTS(tp, ourpart, otherpart);
	tp2 = &otherpart->nm_tty;
	ourpart->modemsignals |= TIOCM_LE;

	if ((tp->t_state & TS_ISOPEN) == 0) {
		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;
	} else if (tp->t_state & TS_XCLUDE && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) {
		lwkt_reltoken(&tty_token);
		return (EBUSY);
	} else if (pti->pt_prison != ap->a_cred->cr_prison) {
		lwkt_reltoken(&tty_token);
		return (EBUSY);
	}

	/*
	 * If the other side is open we have carrier
	 */
	if (tp2->t_state & TS_ISOPEN) {
		(void)(*linesw[tp->t_line].l_modem)(tp, 1);
	}

	/*
	 * And the other side gets carrier as we are now open.
	 */
	(void)(*linesw[tp2->t_line].l_modem)(tp2, 1);

	/* External processing makes no sense here */
	tp->t_lflag &= ~EXTPROC;

	/* 
	 * Wait here if we don't have carrier.
	 */
#if 0
	while ((tp->t_state & TS_CARR_ON) == 0) {
		if (flag & FNONBLOCK)
			break;
		error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "nmdopn", 0);
		if (error) {
			lwkt_reltoken(&tty_token);
			return (error);
		}
	}
#endif

	/*
	 * Give the line disciplin a chance to set this end up.
	 */
	error = (*linesw[tp->t_line].l_open)(dev, tp);

	/*
	 * Wake up the other side.
	 * Theoretically not needed.
	 */
	ourpart->modemsignals |= TIOCM_DTR;
	nmdm_crossover(pti, ourpart, otherpart);
	if (error == 0)
		wakeup_other(tp, FREAD|FWRITE); /* XXX */
	lwkt_reltoken(&tty_token);
	return (error);
}