aboutsummaryrefslogtreecommitdiff
path: root/sys/sys
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2008-08-20 08:31:58 +0000
committerEd Schouten <ed@FreeBSD.org>2008-08-20 08:31:58 +0000
commitbc093719ca478fe10b938cef32c30b528042cbcd (patch)
treebd0c08a66997254385160ce71ea32029b99f99f9 /sys/sys
parentb14f19cf9742655c453d9c1dd672393c31080af4 (diff)
downloadsrc-bc093719ca478fe10b938cef32c30b528042cbcd.tar.gz
src-bc093719ca478fe10b938cef32c30b528042cbcd.zip
Integrate the new MPSAFE TTY layer to the FreeBSD operating system.
The last half year I've been working on a replacement TTY layer for the FreeBSD kernel. The new TTY layer was designed to improve the following: - Improved driver model: The old TTY layer has a driver model that is not abstract enough to make it friendly to use. A good example is the output path, where the device drivers directly access the output buffers. This means that an in-kernel PPP implementation must always convert network buffers into TTY buffers. If a PPP implementation would be built on top of the new TTY layer (still needs a hooks layer, though), it would allow the PPP implementation to directly hand the data to the TTY driver. - Improved hotplugging: With the old TTY layer, it isn't entirely safe to destroy TTY's from the system. This implementation has a two-step destructing design, where the driver first abandons the TTY. After all threads have left the TTY, the TTY layer calls a routine in the driver, which can be used to free resources (unit numbers, etc). The pts(4) driver also implements this feature, which means posix_openpt() will now return PTY's that are created on the fly. - Improved performance: One of the major improvements is the per-TTY mutex, which is expected to improve scalability when compared to the old Giant locking. Another change is the unbuffered copying to userspace, which is both used on TTY device nodes and PTY masters. Upgrading should be quite straightforward. Unlike previous versions, existing kernel configuration files do not need to be changed, except when they reference device drivers that are listed in UPDATING. Obtained from: //depot/projects/mpsafetty/... Approved by: philip (ex-mentor) Discussed: on the lists, at BSDCan, at the DevSummit Sponsored by: Snow B.V., the Netherlands dcons(4) fixed by: kan
Notes
Notes: svn path=/head/; revision=181905
Diffstat (limited to 'sys/sys')
-rw-r--r--sys/sys/conf.h3
-rw-r--r--sys/sys/file.h1
-rw-r--r--sys/sys/linedisc.h141
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/proc.h9
-rw-r--r--sys/sys/resource.h3
-rw-r--r--sys/sys/resourcevar.h2
-rw-r--r--sys/sys/syscall.h5
-rw-r--r--sys/sys/syscall.mk5
-rw-r--r--sys/sys/sysproto.h7
-rw-r--r--sys/sys/termios.h19
-rw-r--r--sys/sys/tty.h23
-rw-r--r--sys/sys/ttycom.h3
-rw-r--r--sys/sys/ttydefaults.h1
-rw-r--r--sys/sys/ttydevsw.h158
-rw-r--r--sys/sys/ttydisc.h105
-rw-r--r--sys/sys/ttyqueue.h157
-rw-r--r--sys/sys/user.h1
18 files changed, 464 insertions, 181 deletions
diff --git a/sys/sys/conf.h b/sys/sys/conf.h
index 739c3fe9cebd..8128fa7c87c4 100644
--- a/sys/sys/conf.h
+++ b/sys/sys/conf.h
@@ -46,7 +46,6 @@
#include <sys/queue.h>
#endif
-struct tty;
struct snapdata;
struct devfs_dirent;
struct cdevsw;
@@ -85,13 +84,11 @@ struct cdev {
u_long si_usecount;
u_long si_threadcount;
union {
- struct tty *__sit_tty;
struct snapdata *__sid_snapdata;
} __si_u;
char __si_namebuf[SPECNAMELEN + 1];
};
-#define si_tty __si_u.__sit_tty
#define si_snapdata __si_u.__sid_snapdata
#ifdef _KERNEL
diff --git a/sys/sys/file.h b/sys/sys/file.h
index 6f7dc0021a1b..461b7e8353c1 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -62,6 +62,7 @@ struct socket;
#define DTYPE_MQUEUE 7 /* posix message queue */
#define DTYPE_SHM 8 /* swap-backed shared memory */
#define DTYPE_SEM 9 /* posix semaphore */
+#define DTYPE_PTS 10 /* pseudo teletype master device */
#ifdef _KERNEL
diff --git a/sys/sys/linedisc.h b/sys/sys/linedisc.h
deleted file mode 100644
index 659aa4b56025..000000000000
--- a/sys/sys/linedisc.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 2004
- * Poul-Henning Kamp. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)conf.h 8.5 (Berkeley) 1/9/95
- * $FreeBSD$
- */
-
-#ifndef _SYS_LINEDISC_H_
-#define _SYS_LINEDISC_H_
-
-#ifdef _KERNEL
-
-struct tty;
-
-typedef int l_open_t(struct cdev *dev, struct tty *tp);
-typedef int l_close_t(struct tty *tp, int flag);
-typedef int l_read_t(struct tty *tp, struct uio *uio, int flag);
-typedef int l_write_t(struct tty *tp, struct uio *uio, int flag);
-typedef int l_ioctl_t(struct tty *tp, u_long cmd, caddr_t data,
- int flag, struct thread *td);
-typedef int l_rint_t(int c, struct tty *tp);
-typedef int l_start_t(struct tty *tp);
-typedef int l_modem_t(struct tty *tp, int flag);
-
-/*
- * Line discipline switch table
- */
-struct linesw {
- l_open_t *l_open;
- l_close_t *l_close;
- l_read_t *l_read;
- l_write_t *l_write;
- l_ioctl_t *l_ioctl;
- l_rint_t *l_rint;
- l_start_t *l_start;
- l_modem_t *l_modem;
-};
-
-extern struct linesw *linesw[];
-extern int nlinesw;
-
-int ldisc_register(int , struct linesw *);
-void ldisc_deregister(int);
-#define LDISC_LOAD -1 /* Loadable line discipline */
-
-l_read_t l_noread;
-l_write_t l_nowrite;
-l_ioctl_t l_nullioctl;
-
-static __inline int
-ttyld_open(struct tty *tp, struct cdev *dev)
-{
-
- return ((*linesw[tp->t_line]->l_open)(dev, tp));
-}
-
-static __inline int
-ttyld_close(struct tty *tp, int flag)
-{
-
- return ((*linesw[tp->t_line]->l_close)(tp, flag));
-}
-
-static __inline int
-ttyld_read(struct tty *tp, struct uio *uio, int flag)
-{
-
- return ((*linesw[tp->t_line]->l_read)(tp, uio, flag));
-}
-
-static __inline int
-ttyld_write(struct tty *tp, struct uio *uio, int flag)
-{
-
- return ((*linesw[tp->t_line]->l_write)(tp, uio, flag));
-}
-
-static __inline int
-ttyld_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
- struct thread *td)
-{
-
- return ((*linesw[tp->t_line]->l_ioctl)(tp, cmd, data, flag, td));
-}
-
-static __inline int
-ttyld_rint(struct tty *tp, int c)
-{
-
- return ((*linesw[tp->t_line]->l_rint)(c, tp));
-}
-
-static __inline int
-ttyld_start(struct tty *tp)
-{
-
- return ((*linesw[tp->t_line]->l_start)(tp));
-}
-
-static __inline int
-ttyld_modem(struct tty *tp, int flag)
-{
-
- return ((*linesw[tp->t_line]->l_modem)(tp, flag));
-}
-
-#endif /* _KERNEL */
-
-#endif /* !_SYS_LINEDISC_H_ */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 773f24fae25c..c0415b0459da 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 800044 /* Master, propagated to newvers */
+#define __FreeBSD_version 800045 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 3779591aef39..0b919b24e3d4 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -72,10 +72,10 @@
* (c) const until freeing
*/
struct session {
- int s_count; /* (m) Ref cnt; pgrps in session. */
+ u_int s_count; /* Ref cnt; pgrps in session - atomic. */
struct proc *s_leader; /* (m + e) Session leader. */
struct vnode *s_ttyvp; /* (m) Vnode of controlling tty. */
- struct tty *s_ttyp; /* (m) Controlling tty. */
+ struct tty *s_ttyp; /* (e) Controlling tty. */
pid_t s_sid; /* (c) Session ID. */
/* (m) Setlogin() name: */
char s_login[roundup(MAXLOGNAME, sizeof(long))];
@@ -644,8 +644,6 @@ MALLOC_DECLARE(M_ZOMBIE);
#define NO_PID 100000
#define SESS_LEADER(p) ((p)->p_session->s_leader == (p))
-#define SESSHOLD(s) ((s)->s_count++)
-#define SESSRELE(s) sessrele(s)
#define STOPEVENT(p, e, v) do { \
@@ -807,7 +805,8 @@ void pstats_fork(struct pstats *src, struct pstats *dst);
void pstats_free(struct pstats *ps);
int securelevel_ge(struct ucred *cr, int level);
int securelevel_gt(struct ucred *cr, int level);
-void sessrele(struct session *);
+void sess_hold(struct session *);
+void sess_release(struct session *);
int setrunnable(struct thread *);
void setsugid(struct proc *p);
int sigonstack(size_t sp);
diff --git a/sys/sys/resource.h b/sys/sys/resource.h
index d01b0bd67f4c..03fbd709d50c 100644
--- a/sys/sys/resource.h
+++ b/sys/sys/resource.h
@@ -93,8 +93,9 @@ struct rusage {
#define RLIMIT_SBSIZE 9 /* maximum size of all socket buffers */
#define RLIMIT_VMEM 10 /* virtual process size (inclusive of mmap) */
#define RLIMIT_AS RLIMIT_VMEM /* standard name for RLIMIT_VMEM */
+#define RLIMIT_NPTS 11 /* pseudo-terminals */
-#define RLIM_NLIMITS 11 /* number of resource limits */
+#define RLIM_NLIMITS 12 /* number of resource limits */
#define RLIM_INFINITY ((rlim_t)(((uint64_t)1 << 63) - 1))
/* XXX Missing: RLIM_SAVED_MAX, RLIM_SAVED_CUR */
diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h
index cd80cd4050a4..0a867d1f894a 100644
--- a/sys/sys/resourcevar.h
+++ b/sys/sys/resourcevar.h
@@ -91,6 +91,7 @@ struct uidinfo {
LIST_ENTRY(uidinfo) ui_hash; /* (c) hash chain of uidinfos */
long ui_sbsize; /* (b) socket buffer space consumed */
long ui_proccnt; /* (b) number of processes */
+ long ui_ptscnt; /* (b) number of pseudo-terminals */
uid_t ui_uid; /* (a) uid */
u_int ui_ref; /* (b) reference count */
};
@@ -106,6 +107,7 @@ void calcru(struct proc *p, struct timeval *up, struct timeval *sp);
int chgproccnt(struct uidinfo *uip, int diff, rlim_t maxval);
int chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to,
rlim_t maxval);
+int chgptscnt(struct uidinfo *uip, int diff, rlim_t maxval);
int fuswintr(void *base);
struct plimit
*lim_alloc(void);
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index 3b1b2c1bd615..a92fc9f8cece 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: src/sys/kern/syscalls.master,v 1.242 2008/03/31 12:06:55 kib Exp
+ * created from FreeBSD: head/sys/kern/syscalls.master 178888 2008-05-09 23:03:00Z julian
*/
#define SYS_syscall 0
@@ -419,4 +419,5 @@
#define SYS_renameat 501
#define SYS_symlinkat 502
#define SYS_unlinkat 503
-#define SYS_MAXSYSCALL 504
+#define SYS_posix_openpt 504
+#define SYS_MAXSYSCALL 505
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
index b0172f45115f..b09938a4671e 100644
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -1,7 +1,7 @@
# FreeBSD system call names.
# DO NOT EDIT-- this file is automatically generated.
# $FreeBSD$
-# created from FreeBSD: src/sys/kern/syscalls.master,v 1.242 2008/03/31 12:06:55 kib Exp
+# created from FreeBSD: head/sys/kern/syscalls.master 178888 2008-05-09 23:03:00Z julian
MIASM = \
syscall.o \
exit.o \
@@ -367,4 +367,5 @@ MIASM = \
readlinkat.o \
renameat.o \
symlinkat.o \
- unlinkat.o
+ unlinkat.o \
+ posix_openpt.o
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index feb582a5843a..fe2a2293c373 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: src/sys/kern/syscalls.master,v 1.242 2008/03/31 12:06:55 kib Exp
+ * created from FreeBSD: head/sys/kern/syscalls.master 178888 2008-05-09 23:03:00Z julian
*/
#ifndef _SYS_SYSPROTO_H_
@@ -1630,6 +1630,9 @@ struct unlinkat_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)];
};
+struct posix_openpt_args {
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_exit(struct thread *, struct sys_exit_args *);
int fork(struct thread *, struct fork_args *);
@@ -1987,6 +1990,7 @@ int readlinkat(struct thread *, struct readlinkat_args *);
int renameat(struct thread *, struct renameat_args *);
int symlinkat(struct thread *, struct symlinkat_args *);
int unlinkat(struct thread *, struct unlinkat_args *);
+int posix_openpt(struct thread *, struct posix_openpt_args *);
#ifdef COMPAT_43
@@ -2569,6 +2573,7 @@ int freebsd4_sigreturn(struct thread *, struct freebsd4_sigreturn_args *);
#define SYS_AUE_renameat AUE_RENAMEAT
#define SYS_AUE_symlinkat AUE_SYMLINKAT
#define SYS_AUE_unlinkat AUE_UNLINKAT
+#define SYS_AUE_posix_openpt AUE_POSIXOPENPT
#undef PAD_
#undef PADL_
diff --git a/sys/sys/termios.h b/sys/sys/termios.h
index 00259f1c4673..7defbd3fb580 100644
--- a/sys/sys/termios.h
+++ b/sys/sys/termios.h
@@ -83,10 +83,6 @@ typedef __pid_t pid_t;
#define _POSIX_VDISABLE 0xff
-#ifndef _POSIX_SOURCE
-#define CCEQ(val, c) ((c) == (val) ? (val) != _POSIX_VDISABLE : 0)
-#endif
-
/*
* Input flags - software input processing
*/
@@ -112,7 +108,12 @@ typedef __pid_t pid_t;
#define OPOST 0x00000001 /* enable following output processing */
#ifndef _POSIX_SOURCE
#define ONLCR 0x00000002 /* map NL to CR-NL (ala CRMOD) */
-#define OXTABS 0x00000004 /* expand tabs to spaces */
+#define TABDLY 0x00000004 /* tab delay mask */
+#define TAB0 0x00000000 /* no tab delay and expansion */
+#define TAB3 0x00000004 /* expand tabs to spaces */
+#ifndef _KERNEL
+#define OXTABS TAB3
+#endif /* !_KERNEL */
#define ONOEOT 0x00000008 /* discard EOT's (^D) on output) */
#define OCRNL 0x00000010 /* map CR to NL on output */
#define ONOCR 0x00000020 /* no CR output at column 0 */
@@ -143,7 +144,9 @@ typedef __pid_t pid_t;
#define CDTR_IFLOW 0x00040000 /* DTR flow control of input */
#define CDSR_OFLOW 0x00080000 /* DSR flow control of output */
#define CCAR_OFLOW 0x00100000 /* DCD flow control of output */
-#define MDMBUF 0x00100000 /* old name for CCAR_OFLOW */
+#ifndef _KERNEL
+#define MDMBUF CCAR_OFLOW
+#endif /* !_KERNEL */
#endif
@@ -230,6 +233,10 @@ struct termios {
#ifndef _KERNEL
+#ifndef _POSIX_SOURCE
+#define CCEQ(val, c) ((c) != _POSIX_VDISABLE && (c) == (val))
+#endif
+
/*
* Commands passed to tcsetattr() for setting the termios structure.
*/
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index e887a2a14e6d..8e0e77d5e0ac 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -1,19 +1,9 @@
/*-
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Copyright (c) 2002 Networks Associates Technologies, Inc.
+ * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
* All rights reserved.
*
- * Portions of this software were developed for the FreeBSD Project by
- * ThinkSec AS and NAI Labs, the Security Research Division of Network
- * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
- * ("CBOSS"), as part of the DARPA CHATS research program.
+ * Portions of this software were developed under sponsorship from Snow
+ * B.V., the Netherlands.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,14 +13,11 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
diff --git a/sys/sys/ttycom.h b/sys/sys/ttycom.h
index 1d97ab38e33d..60b6145ef27e 100644
--- a/sys/sys/ttycom.h
+++ b/sys/sys/ttycom.h
@@ -73,7 +73,8 @@ struct winsize {
/* 23-25 obsolete or unused */
#define TIOCGETD _IOR('t', 26, int) /* get line discipline */
#define TIOCSETD _IOW('t', 27, int) /* set line discipline */
- /* 28-69 free */
+#define TIOCPTMASTER _IO('t', 28) /* pts master validation */
+ /* 29-69 free */
/* 80-84 slip */
#define TIOCGDRAINWAIT _IOR('t', 86, int) /* get ttywait timeout */
#define TIOCSDRAINWAIT _IOW('t', 87, int) /* set ttywait timeout */
diff --git a/sys/sys/ttydefaults.h b/sys/sys/ttydefaults.h
index 5813bda62076..d120fb028fda 100644
--- a/sys/sys/ttydefaults.h
+++ b/sys/sys/ttydefaults.h
@@ -52,6 +52,7 @@
#define TTYDEF_LFLAG TTYDEF_LFLAG_ECHO
#define TTYDEF_CFLAG (CREAD | CS8 | HUPCL)
#define TTYDEF_SPEED (B9600)
+#define TTYDEF_SPEED_PSEUDO (B38400)
/*
* Control Character Defaults
diff --git a/sys/sys/ttydevsw.h b/sys/sys/ttydevsw.h
new file mode 100644
index 000000000000..a4f5afbbc572
--- /dev/null
+++ b/sys/sys/ttydevsw.h
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Portions of this software were developed under sponsorship from Snow
+ * B.V., the Netherlands.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_TTYDEVSW_H_
+#define _SYS_TTYDEVSW_H_
+
+#ifndef _SYS_TTY_H_
+#error "can only be included through <sys/tty.h>"
+#endif /* !_SYS_TTY_H_ */
+
+/*
+ * Driver routines that are called from the line discipline to adjust
+ * hardware parameters and such.
+ */
+typedef int tsw_open_t(struct tty *);
+typedef void tsw_close_t(struct tty *);
+typedef void tsw_outwakeup_t(struct tty *);
+typedef void tsw_inwakeup_t(struct tty *);
+typedef int tsw_ioctl_t(struct tty *, u_long, caddr_t, struct thread *);
+typedef int tsw_param_t(struct tty *, struct termios *);
+typedef int tsw_modem_t(struct tty *, int, int);
+typedef int tsw_mmap_t(struct tty *, vm_offset_t, vm_paddr_t *, int);
+typedef void tsw_free_t(void *);
+
+struct ttydevsw {
+ unsigned int tsw_flags; /* Default TTY flags. */
+
+ tsw_open_t *tsw_open; /* Device opening. */
+ tsw_close_t *tsw_close; /* Device closure. */
+
+ tsw_outwakeup_t *tsw_outwakeup; /* Output available. */
+ tsw_inwakeup_t *tsw_inwakeup; /* Input can be stored again. */
+
+ tsw_ioctl_t *tsw_ioctl; /* ioctl() hooks. */
+ tsw_param_t *tsw_param; /* TIOCSETA device parameter setting. */
+ tsw_modem_t *tsw_modem; /* Modem sigon/sigoff. */
+
+ tsw_mmap_t *tsw_mmap; /* mmap() hooks. */
+
+ tsw_free_t *tsw_free; /* Destructor. */
+};
+
+static __inline int
+ttydevsw_open(struct tty *tp)
+{
+ tty_lock_assert(tp, MA_OWNED);
+ MPASS(!tty_gone(tp));
+
+ return tp->t_devsw->tsw_open(tp);
+}
+
+static __inline void
+ttydevsw_close(struct tty *tp)
+{
+ tty_lock_assert(tp, MA_OWNED);
+ MPASS(!tty_gone(tp));
+
+ tp->t_devsw->tsw_close(tp);
+}
+
+static __inline void
+ttydevsw_outwakeup(struct tty *tp)
+{
+ tty_lock_assert(tp, MA_OWNED);
+ MPASS(!tty_gone(tp));
+
+ /* Prevent spurious wakeups. */
+ if (tp->t_flags & TF_STOPPED)
+ return;
+ if (ttyoutq_bytesused(&tp->t_outq) == 0)
+ return;
+
+ tp->t_devsw->tsw_outwakeup(tp);
+}
+
+static __inline void
+ttydevsw_inwakeup(struct tty *tp)
+{
+ tty_lock_assert(tp, MA_OWNED);
+ MPASS(!tty_gone(tp));
+
+ /* Prevent spurious wakeups. */
+ if (tp->t_flags & TF_HIWAT_IN)
+ return;
+
+ tp->t_devsw->tsw_inwakeup(tp);
+}
+
+static __inline int
+ttydevsw_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
+{
+ tty_lock_assert(tp, MA_OWNED);
+ MPASS(!tty_gone(tp));
+
+ return tp->t_devsw->tsw_ioctl(tp, cmd, data, td);
+}
+
+static __inline int
+ttydevsw_param(struct tty *tp, struct termios *t)
+{
+ MPASS(!tty_gone(tp));
+
+ return tp->t_devsw->tsw_param(tp, t);
+}
+
+static __inline int
+ttydevsw_modem(struct tty *tp, int sigon, int sigoff)
+{
+ MPASS(!tty_gone(tp));
+
+ return tp->t_devsw->tsw_modem(tp, sigon, sigoff);
+}
+
+static __inline int
+ttydevsw_mmap(struct tty *tp, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
+{
+ MPASS(!tty_gone(tp));
+
+ return tp->t_devsw->tsw_mmap(tp, offset, paddr, nprot);
+}
+
+static __inline void
+ttydevsw_free(struct tty *tp)
+{
+ MPASS(tty_gone(tp));
+
+ tp->t_devsw->tsw_free(tty_softc(tp));
+}
+
+#endif /* !_SYS_TTYDEVSW_H_ */
diff --git a/sys/sys/ttydisc.h b/sys/sys/ttydisc.h
new file mode 100644
index 000000000000..dd170e6cc4b1
--- /dev/null
+++ b/sys/sys/ttydisc.h
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Portions of this software were developed under sponsorship from Snow
+ * B.V., the Netherlands.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_TTYDISC_H_
+#define _SYS_TTYDISC_H_
+
+#ifndef _SYS_TTY_H_
+#error "can only be included through <sys/tty.h>"
+#endif /* !_SYS_TTY_H_ */
+
+struct cv;
+struct thread;
+struct tty;
+struct uio;
+
+/* Top half routines. */
+void ttydisc_open(struct tty *);
+void ttydisc_close(struct tty *);
+int ttydisc_read(struct tty *, struct uio *, int);
+int ttydisc_write(struct tty *, struct uio *, int);
+void ttydisc_optimize(struct tty *);
+
+/* Bottom half routines. */
+void ttydisc_modem(struct tty *, int);
+#define ttydisc_can_bypass(tp) ((tp)->t_flags & TF_BYPASS)
+int ttydisc_rint(struct tty *, char, int);
+size_t ttydisc_rint_bypass(struct tty *, char *, size_t);
+void ttydisc_rint_done(struct tty *);
+size_t ttydisc_getc(struct tty *, void *buf, size_t);
+int ttydisc_getc_uio(struct tty *, struct uio *);
+
+/* Error codes for ttydisc_rint(). */
+#define TRE_FRAMING 0x01
+#define TRE_PARITY 0x02
+#define TRE_OVERRUN 0x04
+#define TRE_BREAK 0x08
+
+static __inline size_t
+ttydisc_read_poll(struct tty *tp)
+{
+
+ tty_lock_assert(tp, MA_OWNED);
+
+ return ttyinq_bytescanonicalized(&tp->t_inq);
+}
+
+static __inline size_t
+ttydisc_write_poll(struct tty *tp)
+{
+
+ tty_lock_assert(tp, MA_OWNED);
+
+ return ttyoutq_bytesleft(&tp->t_outq);
+}
+
+static __inline size_t
+ttydisc_rint_poll(struct tty *tp)
+{
+
+ tty_lock_assert(tp, MA_OWNED);
+
+ return ttyinq_bytesleft(&tp->t_inq);
+}
+
+static __inline size_t
+ttydisc_getc_poll(struct tty *tp)
+{
+
+ tty_lock_assert(tp, MA_OWNED);
+
+ if (tp->t_flags & TF_STOPPED)
+ return (0);
+
+ return ttyoutq_bytesused(&tp->t_outq);
+}
+
+#endif /* !_SYS_TTYDISC_H_ */
diff --git a/sys/sys/ttyqueue.h b/sys/sys/ttyqueue.h
new file mode 100644
index 000000000000..3e72fefb0c97
--- /dev/null
+++ b/sys/sys/ttyqueue.h
@@ -0,0 +1,157 @@
+/*-
+ * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Portions of this software were developed under sponsorship from Snow
+ * B.V., the Netherlands.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_TTYQUEUE_H_
+#define _SYS_TTYQUEUE_H_
+
+#ifndef _SYS_TTY_H_
+#error "can only be included through <sys/tty.h>"
+#endif /* !_SYS_TTY_H_ */
+
+struct tty;
+struct ttyinq_block;
+struct ttyoutq_block;
+struct uio;
+
+/* Data input queue. */
+struct ttyinq {
+ TAILQ_HEAD(ttyinq_bhead, ttyinq_block) ti_list;
+ struct ttyinq_block *ti_startblock;
+ struct ttyinq_block *ti_reprintblock;
+ struct ttyinq_block *ti_lastblock;
+ unsigned int ti_begin;
+ unsigned int ti_linestart;
+ unsigned int ti_reprint;
+ unsigned int ti_end;
+ unsigned int ti_nblocks;
+};
+#define TTYINQ_DATASIZE 128
+
+/* Data output queue. */
+struct ttyoutq {
+ STAILQ_HEAD(, ttyoutq_block) to_list;
+ struct ttyoutq_block *to_lastblock;
+ unsigned int to_begin;
+ unsigned int to_end;
+ unsigned int to_nblocks;
+};
+#define TTYOUTQ_DATASIZE (256 - sizeof(STAILQ_ENTRY(ttyoutq_block)))
+
+#ifdef _KERNEL
+/* Input queue handling routines. */
+void ttyinq_setsize(struct ttyinq *, struct tty *, size_t);
+int ttyinq_read_uio(struct ttyinq *, struct tty *, struct uio *,
+ size_t, size_t);
+size_t ttyinq_write(struct ttyinq *, const void *, size_t, int);
+int ttyinq_write_nofrag(struct ttyinq *, const void *, size_t, int);
+void ttyinq_canonicalize(struct ttyinq *);
+size_t ttyinq_findchar(struct ttyinq *, const char *, size_t, char *);
+void ttyinq_flush(struct ttyinq *);
+int ttyinq_peekchar(struct ttyinq *, char *, int *);
+void ttyinq_unputchar(struct ttyinq *);
+void ttyinq_reprintpos_set(struct ttyinq *);
+void ttyinq_reprintpos_reset(struct ttyinq *);
+
+static __inline size_t
+ttyinq_getsize(struct ttyinq *ti)
+{
+ return (ti->ti_nblocks * TTYINQ_DATASIZE);
+}
+
+static __inline size_t
+ttyinq_bytesleft(struct ttyinq *ti)
+{
+ size_t len;
+
+ /* Make sure the usage never exceeds the length. */
+ len = ti->ti_nblocks * TTYINQ_DATASIZE;
+ MPASS(len >= ti->ti_end);
+
+ return (len - ti->ti_end);
+}
+
+static __inline size_t
+ttyinq_bytescanonicalized(struct ttyinq *ti)
+{
+ MPASS(ti->ti_begin <= ti->ti_linestart);
+
+ return (ti->ti_linestart - ti->ti_begin);
+}
+
+static __inline size_t
+ttyinq_bytesline(struct ttyinq *ti)
+{
+ MPASS(ti->ti_linestart <= ti->ti_end);
+
+ return (ti->ti_end - ti->ti_linestart);
+}
+
+/* Input buffer iteration. */
+typedef void ttyinq_line_iterator_t(void *, char, int);
+void ttyinq_line_iterate_from_linestart(struct ttyinq *,
+ ttyinq_line_iterator_t *, void *);
+void ttyinq_line_iterate_from_reprintpos(struct ttyinq *,
+ ttyinq_line_iterator_t *, void *);
+
+/* Output queue handling routines. */
+void ttyoutq_flush(struct ttyoutq *);
+void ttyoutq_setsize(struct ttyoutq *, struct tty *, size_t);
+size_t ttyoutq_read(struct ttyoutq *, void *, size_t);
+int ttyoutq_read_uio(struct ttyoutq *, struct tty *, struct uio *);
+size_t ttyoutq_write(struct ttyoutq *, const void *, size_t);
+int ttyoutq_write_nofrag(struct ttyoutq *, const void *, size_t);
+
+static __inline size_t
+ttyoutq_getsize(struct ttyoutq *to)
+{
+ return (to->to_nblocks * TTYOUTQ_DATASIZE);
+}
+
+static __inline size_t
+ttyoutq_bytesleft(struct ttyoutq *to)
+{
+ size_t len;
+
+ /* Make sure the usage never exceeds the length. */
+ len = to->to_nblocks * TTYOUTQ_DATASIZE;
+ MPASS(len >= to->to_end);
+
+ return (len - to->to_end);
+}
+
+static __inline size_t
+ttyoutq_bytesused(struct ttyoutq *to)
+{
+ return (to->to_end - to->to_begin);
+}
+#endif /* _KERNEL */
+
+#endif /* !_SYS_TTYQUEUE_H_ */
diff --git a/sys/sys/user.h b/sys/sys/user.h
index e8b6a1f2f4e3..0af8528c67c6 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -250,6 +250,7 @@ struct user {
#define KF_TYPE_MQUEUE 7
#define KF_TYPE_SHM 8
#define KF_TYPE_SEM 9
+#define KF_TYPE_PTS 10
#define KF_TYPE_UNKNOWN 255
#define KF_VTYPE_VNON 0