summaryrefslogtreecommitdiffstats
path: root/sys/dev/xen
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2008-08-20 09:03:03 +0000
committered <ed@FreeBSD.org>2008-08-20 09:03:03 +0000
commit0fa96a54117d500129f01c362c8b246c2284a960 (patch)
tree25cfb0a277b535092cc2c37ad0c75889e285e13d /sys/dev/xen
parent4125676cd212a766a19fc13c3ab2fe75c723a74f (diff)
downloadFreeBSD-src-0fa96a54117d500129f01c362c8b246c2284a960.zip
FreeBSD-src-0fa96a54117d500129f01c362c8b246c2284a960.tar.gz
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
Diffstat (limited to 'sys/dev/xen')
-rw-r--r--sys/dev/xen/console/console.c201
1 files changed, 36 insertions, 165 deletions
diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c
index 252878d..3620bae 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,31 +350,15 @@ __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;
}
@@ -470,17 +366,6 @@ xcstart(struct tty *tp)
}
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)
{
struct tty *tp;
@@ -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. ***/
OpenPOWER on IntegriCloud