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
This commit is contained in:
parent
00ba6aade4
commit
1781f8bd6d
@ -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. ***/
|
||||
|
Loading…
Reference in New Issue
Block a user