diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c index 252878d4d6d..3620baed64c 100644 --- a/sys/dev/xen/console/console.c +++ b/sys/dev/xen/console/console.c @@ -32,9 +32,7 @@ __FBSDID("$FreeBSD$"); static char driver_name[] = "xc"; devclass_t xc_devclass; /* do not make static */ -static void xcstart (struct tty *); -static int xcparam (struct tty *, struct termios *); -static void xcstop (struct tty *, int); +static void xcoutwakeup(struct tty *); static void xc_timeout(void *); static void __xencons_tx_flush(void); static boolean_t xcons_putc(int c); @@ -95,27 +93,14 @@ static unsigned int wc, wp; /* write_cons, write_prod */ static struct tty *xccons; -struct xc_softc { - int xc_unit; - struct cdev *xc_dev; -}; +static tsw_open_t xcopen; +static tsw_close_t xcclose; - -static d_open_t xcopen; -static d_close_t xcclose; -static d_ioctl_t xcioctl; - -static struct cdevsw xc_cdevsw = { - .d_version = D_VERSION, - .d_flags = D_TTY | D_NEEDGIANT, - .d_name = driver_name, - .d_open = xcopen, - .d_close = xcclose, - .d_read = ttyread, - .d_write = ttywrite, - .d_ioctl = xcioctl, - .d_poll = ttypoll, - .d_kqfilter = ttykqfilter, +static struct ttydevsw xc_ttydevsw = { + .tsw_flags = TF_NOPREFIX, + .tsw_open = xcopen, + .tsw_close = xcclose, + .tsw_outwakeup = xcoutwakeup, }; static void @@ -225,32 +210,20 @@ xc_identify(driver_t *driver, device_t parent) static int xc_probe(device_t dev) { - struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev); - sc->xc_unit = device_get_unit(dev); return (0); } static int xc_attach(device_t dev) { - struct xc_softc *sc = (struct xc_softc *)device_get_softc(dev); - if (xen_start_info->flags & SIF_INITDOMAIN) { xc_consdev.cn_putc = xccnputc_dom0; } - sc->xc_dev = make_dev(&xc_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "xc%r", 0); - xccons = ttyalloc(); - - sc->xc_dev->si_drv1 = (void *)sc; - sc->xc_dev->si_tty = xccons; - - xccons->t_oproc = xcstart; - xccons->t_param = xcparam; - xccons->t_stop = xcstop; - xccons->t_dev = sc->xc_dev; + xccons = tty_alloc(&xc_ttydevsw, NULL, NULL); + tty_makedev(xccons, NULL, "xc%r", 0); callout_init(&xc_callout, 0); @@ -294,11 +267,15 @@ xencons_rx(char *buf, unsigned len) { int i; struct tty *tp = xccons; - - for (i = 0; i < len; i++) { - if (xen_console_up) - (*linesw[tp->t_line]->l_rint)(buf[i], tp); - else + + if (xen_console_up) { + tty_lock(tp); + for (i = 0; i < len; i++) + ttydisc_rint(tp, buf[i], 0); + ttydisc_rint_done(tp); + tty_unlock(tp); + } else { + for (i = 0; i < len; i++) rbuf[RBUF_MASK(rp++)] = buf[i]; } } @@ -306,7 +283,7 @@ xencons_rx(char *buf, unsigned len) static void __xencons_tx_flush(void) { - int sz, work_done = 0; + int sz; CN_LOCK(cn_mtx); while (wc != wp) { @@ -323,16 +300,8 @@ __xencons_tx_flush(void) break; wc += sent; } - work_done = 1; } CN_UNLOCK(cn_mtx); - - /* - * ttwakeup calls routines using blocking locks - * - */ - if (work_done && xen_console_up && curthread->td_critnest == 0) - ttwakeup(xccons); } void @@ -354,76 +323,19 @@ xencons_priv_interrupt(void *arg) xencons_tx(); } -int -xcopen(struct cdev *dev, int flag, int mode, struct thread *td) +static int +xcopen(struct tty *tp) { - struct xc_softc *sc; - int unit = XCUNIT(dev); - struct tty *tp; - int s, error; - - sc = (struct xc_softc *)device_get_softc( - devclass_get_device(xc_devclass, unit)); - if (sc == NULL) - return (ENXIO); - - tp = dev->si_tty; - s = spltty(); - if (!ISTTYOPEN(tp)) { - 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; - xcparam(tp, &tp->t_termios); - ttsetwater(tp); - } else if (tp->t_state & TS_XCLUDE && priv_check(td, PRIV_ROOT)) { - splx(s); - return (EBUSY); - } - splx(s); xen_console_up = 1; - - error = (*linesw[tp->t_line]->l_open)(dev, tp); - return error; -} - -int -xcclose(struct cdev *dev, int flag, int mode, struct thread *td) -{ - struct tty *tp = dev->si_tty; - - if (tp == NULL) - return (0); - xen_console_up = 0; - - spltty(); - (*linesw[tp->t_line]->l_close)(tp, flag); - tty_close(tp); - spl0(); return (0); } - -int -xcioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) +static void +xcclose(struct tty *tp) { - struct tty *tp = dev->si_tty; - int error; - - error = (*linesw[tp->t_line]->l_ioctl)(tp, cmd, data, flag, td); - if (error != ENOIOCTL) - return (error); - error = ttioctl(tp, cmd, data, flag); - - if (error != ENOIOCTL) - return (error); - - return (ENOTTY); + xen_console_up = 0; } static inline int @@ -438,48 +350,21 @@ __xencons_put_char(int ch) static void -xcstart(struct tty *tp) +xcoutwakeup(struct tty *tp) { boolean_t cons_full = FALSE; + char c; - CN_LOCK(cn_mtx); - if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { - CN_UNLOCK(cn_mtx); + while (ttydisc_getc(tp, &c, 1) == 1 && !cons_full) + cons_full = xcons_putc(c); - ttwwakeup(tp); - return; - } - - tp->t_state |= TS_BUSY; - CN_UNLOCK(cn_mtx); - - while (tp->t_outq.c_cc != 0 && !cons_full) - cons_full = xcons_putc(getc(&tp->t_outq)); - - /* if the console is close to full leave our state as busy */ - if (!cons_full) { - CN_LOCK(cn_mtx); - tp->t_state &= ~TS_BUSY; - CN_UNLOCK(cn_mtx); - ttwwakeup(tp); - } else { + if (cons_full) { /* let the timeout kick us in a bit */ xc_start_needed = TRUE; } } -static void -xcstop(struct tty *tp, int flag) -{ - - if (tp->t_state & TS_BUSY) { - if ((tp->t_state & TS_TTSTOP) == 0) { - tp->t_state |= TS_FLUSH; - } - } -} - static void xc_timeout(void *v) { @@ -488,33 +373,19 @@ xc_timeout(void *v) tp = (struct tty *)v; - while ((c = xccncheckc(NULL)) != -1) { - if (tp->t_state & TS_ISOPEN) { - (*linesw[tp->t_line]->l_rint)(c, tp); - } - } + tty_lock(tp); + while ((c = xccncheckc(NULL)) != -1) + ttydisc_rint(tp, c, 0); + tty_unlock(tp); if (xc_start_needed) { xc_start_needed = FALSE; - xcstart(tp); + xcoutwakeup(tp); } callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, tp); } -/* - * Set line parameters. - */ -int -xcparam(struct tty *tp, struct termios *t) -{ - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = t->c_cflag; - return (0); -} - - static device_method_t xc_methods[] = { DEVMETHOD(device_identify, xc_identify), DEVMETHOD(device_probe, xc_probe), @@ -525,7 +396,7 @@ static device_method_t xc_methods[] = { static driver_t xc_driver = { driver_name, xc_methods, - sizeof(struct xc_softc), + 0, }; /*** Forcibly flush console data before dying. ***/