From 0fa96a54117d500129f01c362c8b246c2284a960 Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 20 Aug 2008 09:03:03 +0000 Subject: [PATCH] Integrate the Xen console driver. I initially didn't want to integrate the Xen console driver, because it did not receive any testing. Kip Macy suggested that I'd better check it in right now, because this is the easiest way for him to test it while he is working on the Xen import. Requested by: kmacy --- sys/dev/xen/console/console.c | 201 ++++++---------------------------- 1 file changed, 36 insertions(+), 165 deletions(-) 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); - - ttwwakeup(tp); - return; - } - - tp->t_state |= TS_BUSY; - CN_UNLOCK(cn_mtx); + while (ttydisc_getc(tp, &c, 1) == 1 && !cons_full) + cons_full = xcons_putc(c); - 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. ***/ -- 2.45.0