Example #1
0
static int
ucom_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
	struct ucom_softc *sc = tty_softc(tp);
	int error;

	UCOM_MTX_ASSERT(sc, MA_OWNED);

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

	switch (cmd) {
#if 0
	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, td);
		} else {
			error = ENOIOCTL;
		}
		if (error == ENOIOCTL)
			error = pps_ioctl(cmd, data, &sc->sc_pps);
		break;
	}
	return (error);
}
Example #2
0
static int
ucom_open(struct tty *tp)
{
	struct ucom_softc *sc = tty_softc(tp);
	int error;

	UCOM_MTX_ASSERT(sc, MA_OWNED);

	if (sc->sc_flag & UCOM_FLAG_GONE) {
		return (ENXIO);
	}
	if (sc->sc_flag & UCOM_FLAG_HL_READY) {
		/* already opened */
		return (0);
	}
	DPRINTF("tp = %p\n", tp);

	if (sc->sc_callback->ucom_pre_open) {
		/*
		 * give the lower layer a chance to disallow TTY open, for
		 * example if the device is not present:
		 */
		error = (sc->sc_callback->ucom_pre_open) (sc);
		if (error) {
			return (error);
		}
	}
	sc->sc_flag |= UCOM_FLAG_HL_READY;

	/* Disable transfers */
	sc->sc_flag &= ~UCOM_FLAG_GP_DATA;

	sc->sc_lsr = 0;
	sc->sc_msr = 0;
	sc->sc_mcr = 0;

	/* reset programmed line state */
	sc->sc_pls_curr = 0;
	sc->sc_pls_set = 0;
	sc->sc_pls_clr = 0;

	/* reset jitter buffer */
	sc->sc_jitterbuf_in = 0;
	sc->sc_jitterbuf_out = 0;

	ucom_queue_command(sc, ucom_cfg_open, NULL,
	    &sc->sc_open_task[0].hdr,
	    &sc->sc_open_task[1].hdr);

	/* Queue transfer enable command last */
	ucom_queue_command(sc, ucom_cfg_start_transfers, NULL,
	    &sc->sc_start_task[0].hdr, 
	    &sc->sc_start_task[1].hdr);

	ucom_modem(tp, SER_DTR | SER_RTS, 0);

	ucom_ring(sc, 0);

	ucom_break(sc, 0);

	ucom_status_change(sc);

	return (0);
}
Example #3
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);
}