svn commit: r183905 - projects/releng_6_xen/sys/dev/xen/console

Kip Macy kmacy at FreeBSD.org
Wed Oct 15 05:43:13 UTC 2008


Author: kmacy
Date: Wed Oct 15 05:43:13 2008
New Revision: 183905
URL: http://svn.freebsd.org/changeset/base/183905

Log:
  update console to pre-MPSAFE tty interfaces

Modified:
  projects/releng_6_xen/sys/dev/xen/console/console.c

Modified: projects/releng_6_xen/sys/dev/xen/console/console.c
==============================================================================
--- projects/releng_6_xen/sys/dev/xen/console/console.c	Wed Oct 15 05:00:50 2008	(r183904)
+++ projects/releng_6_xen/sys/dev/xen/console/console.c	Wed Oct 15 05:43:13 2008	(r183905)
@@ -1,5 +1,5 @@
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+
 
 #include <sys/param.h>
 #include <sys/module.h>
@@ -18,7 +18,6 @@ __FBSDID("$FreeBSD$");
 #include <machine/xen/hypervisor.h>
 #include <machine/xen/xen_intr.h>
 #include <sys/cons.h>
-#include <sys/priv.h>
 #include <sys/proc.h>
 
 #include <dev/xen/console/xencons_ring.h>
@@ -32,7 +31,9 @@ __FBSDID("$FreeBSD$");
 
 static char driver_name[] = "xc";
 devclass_t xc_devclass; /* do not make static */
-static void	xcoutwakeup(struct tty *);
+static void	xcstart (struct tty *);
+static int	xcparam (struct tty *, struct termios *);
+static void	xcstop (struct tty *, int);
 static void	xc_timeout(void *);
 static void __xencons_tx_flush(void);
 static boolean_t xcons_putc(int c);
@@ -72,7 +73,7 @@ static unsigned int cnsl_evt_reg;
 static unsigned int wc, wp; /* write_cons, write_prod */
 
 #define CDEV_MAJOR 12
-#define	XCUNIT(x)	(dev2unit(x))
+#define	XCUNIT(x)	(minor(x))
 #define ISTTYOPEN(tp)	((tp) && ((tp)->t_state & TS_ISOPEN))
 #define CN_LOCK_INIT(x, _name) \
         mtx_init(&x, _name, NULL, MTX_SPIN|MTX_RECURSE)
@@ -93,14 +94,27 @@ static unsigned int wc, wp; /* write_con
 
 static struct tty *xccons;
 
-static tsw_open_t	xcopen;
-static tsw_close_t	xcclose;
+struct xc_softc {
+	int    xc_unit;
+	struct cdev *xc_dev;
+};
+
 
-static struct ttydevsw xc_ttydevsw = {
-        .tsw_flags	= TF_NOPREFIX,
-        .tsw_open	= xcopen,
-        .tsw_close	= xcclose,
-        .tsw_outwakeup	= xcoutwakeup,
+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 void
@@ -210,20 +224,32 @@ xc_identify(driver_t *driver, device_t p
 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;
 	} 
 
-	xccons = tty_alloc(&xc_ttydevsw, NULL, NULL);
-	tty_makedev(xccons, NULL, "xc%r", 0);
+	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;
 
 	callout_init(&xc_callout, 0);
 
@@ -237,7 +263,6 @@ xc_attach(device_t dev) 
 				 VIRQ_CONSOLE,
 				 0,
 				 "console",
-				 NULL,
 				 xencons_priv_interrupt,
 				 INTR_TYPE_TTY) < 0);
 		
@@ -267,15 +292,11 @@ xencons_rx(char *buf, unsigned len)
 {
 	int           i;
 	struct tty *tp = xccons;
-
-	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++)
+	
+	for (i = 0; i < len; i++) {
+		if (xen_console_up) 
+			(*linesw[tp->t_line]->l_rint)(buf[i], tp);
+		else
 			rbuf[RBUF_MASK(rp++)] = buf[i];
 	}
 }
@@ -283,7 +304,7 @@ xencons_rx(char *buf, unsigned len)
 static void 
 __xencons_tx_flush(void)
 {
-	int        sz;
+	int        sz, work_done = 0;
 
 	CN_LOCK(cn_mtx);
 	while (wc != wp) {
@@ -300,8 +321,16 @@ __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
@@ -323,19 +352,76 @@ xencons_priv_interrupt(void *arg)
 	xencons_tx();
 }
 
-static int
-xcopen(struct tty *tp)
+int
+xcopen(struct cdev *dev, int flag, int mode, struct thread *td)
 {
+	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 && suser(td)) {
+		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);
 }
 
-static void
-xcclose(struct tty *tp)
+
+int
+xcioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
 {
+	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);
 
-	xen_console_up = 0;
+	error = ttioctl(tp, cmd, data, flag);
+
+	if (error != ENOIOCTL)
+		return (error);
+
+	return (ENOTTY);
 }
 
 static inline int 
@@ -350,15 +436,31 @@ __xencons_put_char(int ch)
 
 
 static void
-xcoutwakeup(struct tty *tp)
+xcstart(struct tty *tp)
 {
 	boolean_t cons_full = FALSE;
-	char c;
 
-	while (ttydisc_getc(tp, &c, 1) == 1 && !cons_full)
-		cons_full = xcons_putc(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 (tp->t_outq.c_cc != 0 && !cons_full)
+		cons_full = xcons_putc(getc(&tp->t_outq));
 
-	if (cons_full) {
+	/* 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 {
 	    	/* let the timeout kick us in a bit */
 	    	xc_start_needed = TRUE;
 	}
@@ -366,6 +468,17 @@ xcoutwakeup(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;
@@ -373,19 +486,33 @@ xc_timeout(void *v)
 
 	tp = (struct tty *)v;
 
-	tty_lock(tp);
-	while ((c = xccncheckc(NULL)) != -1)
-		ttydisc_rint(tp, c, 0);
+	while ((c = xccncheckc(NULL)) != -1) {
+		if (tp->t_state & TS_ISOPEN) {
+			(*linesw[tp->t_line]->l_rint)(c, tp);
+		}
+	}
 
 	if (xc_start_needed) {
 	    	xc_start_needed = FALSE;
-		xcoutwakeup(tp);
+		xcstart(tp);
 	}
-	tty_unlock(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),
@@ -396,7 +523,7 @@ static device_method_t xc_methods[] = {
 static driver_t xc_driver = {
 	driver_name,
 	xc_methods,
-	0,
+	sizeof(struct xc_softc),
 };
 
 /*** Forcibly flush console data before dying. ***/


More information about the svn-src-projects mailing list