svn commit: r223722 - in head/sys: kern sys

Ed Schouten ed at FreeBSD.org
Sat Jul 2 13:54:20 UTC 2011


Author: ed
Date: Sat Jul  2 13:54:20 2011
New Revision: 223722
URL: http://svn.freebsd.org/changeset/base/223722

Log:
  Reintroduce the cioctl() hook in the TTY layer for digi(4).
  
  The cioctl() hook can be used by drivers to add ioctls to the *.init and
  *.lock devices. This commit breaks the ttydevsw ABI, since this
  structure didn't provide any padding. To prevent ABI breakage in the
  future, add a tsw_spare.
  
  Submitted by:	Peter Jeremy <peter jeremy alcatel lucent com>
  Obtained from:	kern/152254 (slightly modified)

Modified:
  head/sys/kern/tty.c
  head/sys/sys/tty.h
  head/sys/sys/ttydevsw.h

Modified: head/sys/kern/tty.c
==============================================================================
--- head/sys/kern/tty.c	Sat Jul  2 12:56:03 2011	(r223721)
+++ head/sys/kern/tty.c	Sat Jul  2 13:54:20 2011	(r223722)
@@ -91,7 +91,7 @@ static const char	*dev_console_filename;
 			HUPCL|CLOCAL|CCTS_OFLOW|CRTS_IFLOW|CDTR_IFLOW|\
 			CDSR_OFLOW|CCAR_OFLOW)
 
-#define	TTY_CALLOUT(tp,d) ((d) != (tp)->t_dev && (d) != dev_console)
+#define	TTY_CALLOUT(tp,d) (dev2unit(d) & TTYUNIT_CALLOUT)
 
 /*
  * Set TTY buffer sizes.
@@ -772,6 +772,10 @@ ttyil_ioctl(struct cdev *dev, u_long cmd
 		goto done;
 	}
 
+	error = ttydevsw_cioctl(tp, dev2unit(dev), cmd, data, td);
+	if (error != ENOIOCTL)
+		goto done;
+
 	switch (cmd) {
 	case TIOCGETA:
 		/* Obtain terminal flags through tcgetattr(). */
@@ -878,6 +882,13 @@ ttydevsw_defioctl(struct tty *tp, u_long
 }
 
 static int
+ttydevsw_defcioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td)
+{
+
+	return (ENOIOCTL);
+}
+
+static int
 ttydevsw_defparam(struct tty *tp, struct termios *t)
 {
 
@@ -955,6 +966,7 @@ tty_alloc_mutex(struct ttydevsw *tsw, vo
 	PATCH_FUNC(outwakeup);
 	PATCH_FUNC(inwakeup);
 	PATCH_FUNC(ioctl);
+	PATCH_FUNC(cioctl);
 	PATCH_FUNC(param);
 	PATCH_FUNC(modem);
 	PATCH_FUNC(mmap);
@@ -1190,13 +1202,13 @@ tty_makedev(struct tty *tp, struct ucred
 
 	/* Slave call-in devices. */
 	if (tp->t_flags & TF_INITLOCK) {
-		dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
+		dev = make_dev_cred(&ttyil_cdevsw, TTYUNIT_INIT, cred,
 		    uid, gid, mode, "%s%s.init", prefix, name);
 		dev_depends(tp->t_dev, dev);
 		dev->si_drv1 = tp;
 		dev->si_drv2 = &tp->t_termios_init_in;
 
-		dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
+		dev = make_dev_cred(&ttyil_cdevsw, TTYUNIT_LOCK, cred,
 		    uid, gid, mode, "%s%s.lock", prefix, name);
 		dev_depends(tp->t_dev, dev);
 		dev->si_drv1 = tp;
@@ -1205,20 +1217,22 @@ tty_makedev(struct tty *tp, struct ucred
 
 	/* Call-out devices. */
 	if (tp->t_flags & TF_CALLOUT) {
-		dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
+		dev = make_dev_cred(&ttydev_cdevsw, TTYUNIT_CALLOUT, cred,
 		    UID_UUCP, GID_DIALER, 0660, "cua%s", name);
 		dev_depends(tp->t_dev, dev);
 		dev->si_drv1 = tp;
 
 		/* Slave call-out devices. */
 		if (tp->t_flags & TF_INITLOCK) {
-			dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
+			dev = make_dev_cred(&ttyil_cdevsw, 
+			    TTYUNIT_CALLOUT | TTYUNIT_INIT, cred,
 			    UID_UUCP, GID_DIALER, 0660, "cua%s.init", name);
 			dev_depends(tp->t_dev, dev);
 			dev->si_drv1 = tp;
 			dev->si_drv2 = &tp->t_termios_init_out;
 
-			dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
+			dev = make_dev_cred(&ttyil_cdevsw,
+			    TTYUNIT_CALLOUT | TTYUNIT_LOCK, cred,
 			    UID_UUCP, GID_DIALER, 0660, "cua%s.lock", name);
 			dev_depends(tp->t_dev, dev);
 			dev->si_drv1 = tp;

Modified: head/sys/sys/tty.h
==============================================================================
--- head/sys/sys/tty.h	Sat Jul  2 12:56:03 2011	(r223721)
+++ head/sys/sys/tty.h	Sat Jul  2 13:54:20 2011	(r223722)
@@ -152,6 +152,11 @@ struct xtty {
 
 #ifdef _KERNEL
 
+/* Used to distinguish between normal, callout, lock and init devices. */
+#define	TTYUNIT_INIT		0x1
+#define	TTYUNIT_LOCK		0x2
+#define	TTYUNIT_CALLOUT		0x4
+
 /* Allocation and deallocation. */
 struct tty *tty_alloc(struct ttydevsw *tsw, void *softc);
 struct tty *tty_alloc_mutex(struct ttydevsw *tsw, void *softc, struct mtx *mtx);

Modified: head/sys/sys/ttydevsw.h
==============================================================================
--- head/sys/sys/ttydevsw.h	Sat Jul  2 12:56:03 2011	(r223721)
+++ head/sys/sys/ttydevsw.h	Sat Jul  2 13:54:20 2011	(r223722)
@@ -46,6 +46,8 @@ typedef void tsw_outwakeup_t(struct tty 
 typedef void tsw_inwakeup_t(struct tty *tp);
 typedef int tsw_ioctl_t(struct tty *tp, u_long cmd, caddr_t data,
     struct thread *td);
+typedef int tsw_cioctl_t(struct tty *tp, int unit, u_long cmd, caddr_t data,
+    struct thread *td);
 typedef int tsw_param_t(struct tty *tp, struct termios *t);
 typedef int tsw_modem_t(struct tty *tp, int sigon, int sigoff);
 typedef int tsw_mmap_t(struct tty *tp, vm_ooffset_t offset,
@@ -63,6 +65,7 @@ struct ttydevsw {
 	tsw_inwakeup_t	*tsw_inwakeup;	/* Input can be stored again. */
 
 	tsw_ioctl_t	*tsw_ioctl;	/* ioctl() hooks. */
+	tsw_cioctl_t	*tsw_cioctl;	/* ioctl() on control devices. */
 	tsw_param_t	*tsw_param;	/* TIOCSETA device parameter setting. */
 	tsw_modem_t	*tsw_modem;	/* Modem sigon/sigoff. */
 
@@ -70,6 +73,8 @@ struct ttydevsw {
 	tsw_pktnotify_t	*tsw_pktnotify;	/* TIOCPKT events. */
 
 	tsw_free_t	*tsw_free;	/* Destructor. */
+
+	void		*tsw_spare[4];	/* For future use. */
 };
 
 static __inline int
@@ -126,6 +131,15 @@ ttydevsw_ioctl(struct tty *tp, u_long cm
 }
 
 static __inline int
+ttydevsw_cioctl(struct tty *tp, int unit, u_long cmd, caddr_t data, struct thread *td)
+{
+	tty_lock_assert(tp, MA_OWNED);
+	MPASS(!tty_gone(tp));
+
+	return tp->t_devsw->tsw_cioctl(tp, unit, cmd, data, td);
+}
+
+static __inline int
 ttydevsw_param(struct tty *tp, struct termios *t)
 {
 	MPASS(!tty_gone(tp));


More information about the svn-src-head mailing list