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); }
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); }
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); }