summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1996-03-08 23:43:09 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1996-03-08 23:43:09 +0000
commit8ab2b3248060a94c830a02a994ed3772efb2413d (patch)
treecd006918f1e3eaeb33acd209b8ef855abf14489c /sys
parent85864939dde7c81c82fffc74e98da01f3f05408a (diff)
From NetBSD:
linux compatibility changes.
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/linux/files.linux4
-rw-r--r--sys/compat/linux/linux_audio.c167
-rw-r--r--sys/compat/linux/linux_audio.h34
-rw-r--r--sys/compat/linux/linux_ioctl.c614
-rw-r--r--sys/compat/linux/linux_ioctl.h249
-rw-r--r--sys/compat/linux/linux_socket.c52
-rw-r--r--sys/compat/linux/linux_sockio.h18
-rw-r--r--sys/compat/linux/linux_termios.c629
-rw-r--r--sys/compat/linux/linux_termios.h238
-rw-r--r--sys/lib/libkern/arch/i386/Makefile.inc2
-rw-r--r--sys/lib/libkern/arch/i386/memset.S58
11 files changed, 1203 insertions, 862 deletions
diff --git a/sys/compat/linux/files.linux b/sys/compat/linux/files.linux
index c8aca4ae530..9dd91177ecc 100644
--- a/sys/compat/linux/files.linux
+++ b/sys/compat/linux/files.linux
@@ -1,4 +1,4 @@
-# $NetBSD: files.linux,v 1.3 1995/08/14 01:34:11 mycroft Exp $
+# $NetBSD: files.linux,v 1.4 1996/03/08 04:55:59 mycroft Exp $
#
# Config.new file description for machine-independent Linux compat code.
# Included by ports that need it.
@@ -6,6 +6,7 @@
# ports should define any machine-specific files they need in their
# own file lists.
+file compat/linux/linux_audio.c compat_linux
file compat/linux/linux_error.c compat_linux
file compat/linux/linux_exec.c compat_linux
file compat/linux/linux_file.c compat_linux
@@ -16,3 +17,4 @@ file compat/linux/linux_signal.c compat_linux
file compat/linux/linux_socket.c compat_linux
file compat/linux/linux_syscalls.c compat_linux
file compat/linux/linux_sysent.c compat_linux
+file compat/linux/linux_termios.c compat_linux
diff --git a/sys/compat/linux/linux_audio.c b/sys/compat/linux/linux_audio.c
new file mode 100644
index 00000000000..1e21e807a06
--- /dev/null
+++ b/sys/compat/linux/linux_audio.c
@@ -0,0 +1,167 @@
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/audioio.h>
+
+#include <sys/syscallargs.h>
+
+#include <compat/linux/linux_types.h>
+#include <compat/linux/linux_ioctl.h>
+#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_syscallargs.h>
+#include <compat/linux/linux_audio.h>
+
+int
+linux_ioctl_audio(p, uap, retval)
+ register struct proc *p;
+ register struct linux_sys_ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ register_t *retval;
+{
+ register struct file *fp;
+ register struct filedesc *fdp;
+ u_long com;
+ struct audio_info tmpinfo;
+ int idat;
+ int error;
+
+ fdp = p->p_fd;
+ if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
+ return (EBADF);
+
+ if ((fp->f_flag & (FREAD | FWRITE)) == 0)
+ return (EBADF);
+
+ com = SCARG(uap, com);
+ retval[0] = 0;
+
+ switch (com) {
+ case LINUX_SNDCTL_DSP_RESET:
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_FLUSH, (caddr_t)0, p);
+ if (error)
+ return error;
+ break;
+ case LINUX_SNDCTL_DSP_SYNC:
+ case LINUX_SNDCTL_DSP_POST:
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_DRAIN, (caddr_t)0, p);
+ if (error)
+ return error;
+ break;
+ case LINUX_SNDCTL_DSP_SPEED:
+ AUDIO_INITINFO(&tmpinfo);
+ error = copyin(SCARG(uap, data), &idat, sizeof idat);
+ if (error)
+ return error;
+ tmpinfo.play.sample_rate =
+ tmpinfo.record.sample_rate = idat;
+ (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
+ if (error)
+ return error;
+ idat = tmpinfo.play.sample_rate;
+ error = copyout(&idat, SCARG(uap, data), sizeof idat);
+ if (error)
+ return error;
+ break;
+ case LINUX_SNDCTL_DSP_STEREO:
+ AUDIO_INITINFO(&tmpinfo);
+ error = copyin(SCARG(uap, data), &idat, sizeof idat);
+ if (error)
+ return error;
+ tmpinfo.play.channels =
+ tmpinfo.record.channels = idat ? 2 : 1;
+ (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
+ if (error)
+ return error;
+ idat = tmpinfo.play.channels - 1;
+ error = copyout(&idat, SCARG(uap, data), sizeof idat);
+ if (error)
+ return error;
+ break;
+ case LINUX_SNDCTL_DSP_GETBLKSIZE:
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
+ if (error)
+ return error;
+ idat = tmpinfo.blocksize;
+ error = copyout(&idat, SCARG(uap, data), sizeof idat);
+ if (error)
+ return error;
+ break;
+ case LINUX_SNDCTL_DSP_SETFMT:
+ AUDIO_INITINFO(&tmpinfo);
+ error = copyin(SCARG(uap, data), &idat, sizeof idat);
+ if (error)
+ return error;
+ switch (idat) {
+ case LINUX_AFMT_MU_LAW:
+ tmpinfo.play.precision =
+ tmpinfo.record.precision = 8;
+ tmpinfo.play.encoding =
+ tmpinfo.record.encoding = AUDIO_ENCODING_ULAW;
+ break;
+ case LINUX_AFMT_A_LAW:
+ tmpinfo.play.precision =
+ tmpinfo.record.precision = 8;
+ tmpinfo.play.encoding =
+ tmpinfo.record.encoding = AUDIO_ENCODING_ALAW;
+ break;
+ case LINUX_AFMT_U8:
+ tmpinfo.play.precision =
+ tmpinfo.record.precision = 8;
+ tmpinfo.play.encoding =
+ tmpinfo.record.encoding = AUDIO_ENCODING_LINEAR;
+ break;
+ case LINUX_AFMT_S16_LE:
+ tmpinfo.play.precision =
+ tmpinfo.record.precision = 16;
+ tmpinfo.play.encoding =
+ tmpinfo.record.encoding = AUDIO_ENCODING_LINEAR;
+ break;
+ default:
+ return EINVAL;
+ }
+ (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
+ if (error)
+ return error;
+ /*XXXX*/
+ break;
+ case LINUX_SNDCTL_DSP_SETFRAGMENT:
+ AUDIO_INITINFO(&tmpinfo);
+ error = copyin(SCARG(uap, data), &idat, sizeof idat);
+ if (error)
+ return error;
+ if ((idat & 0xffff) < 4 || (idat & 0xffff) > 17)
+ return EINVAL;
+ tmpinfo.blocksize = 1 << (idat & 0xffff);
+ tmpinfo.hiwat = (idat >> 16) & 0xffff;
+ (void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
+ error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
+ if (error)
+ return error;
+ idat = tmpinfo.blocksize;
+ error = copyout(&idat, SCARG(uap, data), sizeof idat);
+ if (error)
+ return error;
+ break;
+ case LINUX_SNDCTL_DSP_GETFMTS:
+ idat = LINUX_AFMT_MU_LAW | LINUX_AFMT_U8 | LINUX_AFMT_S16_LE;
+ error = copyout(&idat, SCARG(uap, data), sizeof idat);
+ if (error)
+ return error;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
diff --git a/sys/compat/linux/linux_audio.h b/sys/compat/linux/linux_audio.h
new file mode 100644
index 00000000000..af3e79f6770
--- /dev/null
+++ b/sys/compat/linux/linux_audio.h
@@ -0,0 +1,34 @@
+#define LINUX_IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */
+#define LINUX_IOC_VOID 0x00000000 /* no parameters */
+#define LINUX_IOC_IN 0x40000000 /* copy in parameters */
+#define LINUX_IOC_OUT 0x80000000 /* copy out parameters */
+#define LINUX_IOC_INOUT (LINUX_IOC_IN | LINUX_IOC_OUT)
+#define _LINUX_IOCTL(w,x,y,z) ((int)((w)|(((z)&LINUX_IOCPARM_MASK)<<16)|((x)<<8)|(y)))
+#if 0
+#define _LINUX_IO(x,y) _LINUX_IOCTL(LINUX_IOC_VOID, x, y, 0)
+#endif
+#define _LINUX_IOR(x,y,t) _LINUX_IOCTL(LINUX_IOC_OUT, x, y, sizeof(t))
+#define _LINUX_IOW(x,y,t) _LINUX_IOCTL(LINUX_IOC_IN, x, y, sizeof(t))
+#define _LINUX_IOWR(x,y,t) _LINUX_IOCTL(LINUX_IOC_INOUT, x, y, sizeof(t))
+
+#define LINUX_SNDCTL_DSP_RESET _LINUX_IO('P', 0)
+#define LINUX_SNDCTL_DSP_SYNC _LINUX_IO('P', 1)
+#define LINUX_SNDCTL_DSP_SPEED _LINUX_IOWR('P', 2, int)
+#define LINUX_SNDCTL_DSP_STEREO _LINUX_IOWR('P', 3, int)
+#define LINUX_SNDCTL_DSP_GETBLKSIZE _LINUX_IOWR('P', 4, int)
+#define LINUX_SNDCTL_DSP_SETFMT _LINUX_IOWR('P', 5, int)
+#define LINUX_SNDCTL_DSP_POST _LINUX_IO('P', 8)
+#define LINUX_SNDCTL_DSP_SETFRAGMENT _LINUX_IOWR('P', 10, int)
+#define LINUX_SNDCTL_DSP_GETFMTS _LINUX_IOR('P', 11, int)
+
+#define LINUX_AFMT_QUERY 0x00000000 /* Return current fmt */
+#define LINUX_AFMT_MU_LAW 0x00000001
+#define LINUX_AFMT_A_LAW 0x00000002
+#define LINUX_AFMT_IMA_ADPCM 0x00000004
+#define LINUX_AFMT_U8 0x00000008
+#define LINUX_AFMT_S16_LE 0x00000010 /* Little endian signed 16 */
+#define LINUX_AFMT_S16_BE 0x00000020 /* Big endian signed 16 */
+#define LINUX_AFMT_S8 0x00000040
+#define LINUX_AFMT_U16_LE 0x00000080 /* Little endian U16 */
+#define LINUX_AFMT_U16_BE 0x00000100 /* Big endian U16 */
+#define LINUX_AFMT_MPEG 0x00000200 /* MPEG (2) audio */
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index cd04f9ae31e..4d6ab75d3b3 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ioctl.c,v 1.12 1996/02/27 08:18:16 mycroft Exp $ */
+/* $NetBSD: linux_ioctl.c,v 1.13 1996/03/08 04:56:03 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -34,14 +34,10 @@
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/ioctl.h>
-#include <sys/termios.h>
-#include <sys/tty.h>
-#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
+
+#include <sys/socket.h>
#include <net/if.h>
#include <sys/sockio.h>
@@ -49,389 +45,9 @@
#include <compat/linux/linux_types.h>
#include <compat/linux/linux_ioctl.h>
-#include <compat/linux/linux_sockio.h>
-#include <compat/linux/linux_util.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_syscallargs.h>
-static speed_t linux_speeds[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200
-};
-
-static int linux_spmasks[] = {
- LINUX_B0, LINUX_B50, LINUX_B75, LINUX_B110, LINUX_B134, LINUX_B150,
- LINUX_B200, LINUX_B300, LINUX_B600, LINUX_B1200, LINUX_B1800,
- LINUX_B2400, LINUX_B4800, LINUX_B9600, LINUX_B19200, LINUX_B38400,
- LINUX_B57600, LINUX_B115200, LINUX_B230400
-};
-
-/*
- * Deal with termio ioctl cruft. This doesn't look very good..
- * XXX too much code duplication, obviously..
- *
- * The conversion routines between Linux and BSD structures assume
- * that the fields are already filled with the current values,
- * so that fields present in BSD but not in Linux keep their current
- * values.
- */
-
-static int
-linux_termio_to_bsd_termios(lt, bts)
- register struct linux_termio *lt;
- register struct termios *bts;
-{
- int index;
-
- bts->c_iflag = 0;
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNBRK, IGNBRK);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_BRKINT, BRKINT);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNPAR, IGNPAR);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INPCK, INPCK);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ISTRIP, ISTRIP);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INLCR, INLCR);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNCR, IGNCR);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ICRNL, ICRNL);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXON, IXON);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXANY, IXANY);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXOFF, IXOFF);
- bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IMAXBEL, IMAXBEL);
-
- bts->c_oflag = 0;
- bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_OPOST, OPOST);
- bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_ONLCR, ONLCR);
- bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_XTABS, OXTABS);
-
- /*
- * This could have been:
- * bts->c_cflag = (lt->c_flag & LINUX_CSIZE) << 4
- * But who knows, those values might perhaps change one day.
- */
- switch (lt->c_cflag & LINUX_CSIZE) {
- case LINUX_CS5:
- bts->c_cflag = CS5;
- break;
- case LINUX_CS6:
- bts->c_cflag = CS6;
- break;
- case LINUX_CS7:
- bts->c_cflag = CS7;
- break;
- case LINUX_CS8:
- bts->c_cflag = CS8;
- break;
- }
- bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CSTOPB, CSTOPB);
- bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CREAD, CREAD);
- bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARENB, PARENB);
- bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARODD, PARODD);
- bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_HUPCL, HUPCL);
- bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CLOCAL, CLOCAL);
- bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CRTSCTS, CRTSCTS);
-
- bts->c_lflag = 0;
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ISIG, ISIG);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ICANON, ICANON);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHO, ECHO);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOE, ECHOE);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOK, ECHOK);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHONL, ECHONL);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_NOFLSH, NOFLSH);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_TOSTOP, TOSTOP);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOCTL, ECHOCTL);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOPRT, ECHOPRT);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOKE, ECHOKE);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_FLUSHO, FLUSHO);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_PENDIN, PENDIN);
- bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_IEXTEN, IEXTEN);
-
- index = lt->c_cflag & LINUX_CBAUD;
- if (index & LINUX_CBAUDEX)
- index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
- bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
-
- bts->c_cc[VINTR] = lt->c_cc[LINUX_VINTR];
- bts->c_cc[VQUIT] = lt->c_cc[LINUX_VQUIT];
- bts->c_cc[VERASE] = lt->c_cc[LINUX_VERASE];
- bts->c_cc[VKILL] = lt->c_cc[LINUX_VKILL];
- bts->c_cc[VEOF] = lt->c_cc[LINUX_VEOF];
- bts->c_cc[VTIME] = lt->c_cc[LINUX_VTIME];
- bts->c_cc[VMIN] = lt->c_cc[LINUX_VMIN];
-}
-
-static int
-bsd_termios_to_linux_termio(bts, lt)
- register struct termios *bts;
- register struct linux_termio *lt;
-{
- int i, mask;
-
- lt->c_iflag = 0;
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
- lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
-
- lt->c_oflag = 0;
- lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
- lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
- lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
-
- switch (bts->c_cflag & CSIZE) {
- case CS5:
- lt->c_cflag = LINUX_CS5;
- break;
- case CS6:
- lt->c_cflag = LINUX_CS6;
- break;
- case CS7:
- lt->c_cflag = LINUX_CS7;
- break;
- case CS8:
- lt->c_cflag = LINUX_CS8;
- break;
- }
- lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
- lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
- lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
- lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
- lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
- lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
- lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
-
- lt->c_lflag = 0;
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
- lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
-
- mask = LINUX_B9600; /* XXX default value should this be 0? */
- for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
- if (bts->c_ospeed == linux_speeds[i]) {
- mask = linux_spmasks[i];
- break;
- }
- }
- lt->c_cflag |= mask;
-
- lt->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
- lt->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
- lt->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
- lt->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
- lt->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
- lt->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
- lt->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
- lt->c_cc[LINUX_VSWTC] = 0;
-
- /* XXX should be fixed someday */
- lt->c_line = 0;
-}
-
-static int
-linux_termios_to_bsd_termios(lts, bts)
- register struct linux_termios *lts;
- register struct termios *bts;
-{
- int index;
-
- bts->c_iflag = 0;
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNBRK, IGNBRK);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_BRKINT, BRKINT);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNPAR, IGNPAR);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INPCK, INPCK);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ISTRIP, ISTRIP);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INLCR, INLCR);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNCR, IGNCR);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ICRNL, ICRNL);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXON, IXON);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXANY, IXANY);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXOFF, IXOFF);
- bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IMAXBEL, IMAXBEL);
-
- bts->c_oflag = 0;
- bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_OPOST, OPOST);
- bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_ONLCR, ONLCR);
- bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_XTABS, OXTABS);
-
- bts->c_cflag = 0;
- switch (lts->c_cflag & LINUX_CSIZE) {
- case LINUX_CS5:
- bts->c_cflag = CS5;
- break;
- case LINUX_CS6:
- bts->c_cflag = CS6;
- break;
- case LINUX_CS7:
- bts->c_cflag = CS7;
- break;
- case LINUX_CS8:
- bts->c_cflag = CS8;
- break;
- }
- bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CSTOPB, CSTOPB);
- bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CREAD, CREAD);
- bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARENB, PARENB);
- bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARODD, PARODD);
- bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_HUPCL, HUPCL);
- bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CLOCAL, CLOCAL);
- bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CRTSCTS, CRTSCTS);
-
- bts->c_lflag = 0;
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ISIG, ISIG);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ICANON, ICANON);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHO, ECHO);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOE, ECHOE);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOK, ECHOK);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHONL, ECHONL);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_NOFLSH, NOFLSH);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_TOSTOP, TOSTOP);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOCTL, ECHOCTL);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOPRT, ECHOPRT);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOKE, ECHOKE);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_FLUSHO, FLUSHO);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_PENDIN, PENDIN);
- bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_IEXTEN, IEXTEN);
-
- index = lts->c_cflag & LINUX_CBAUD;
- if (index & LINUX_CBAUDEX)
- index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
- bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
-
- bts->c_cc[VINTR] = lts->c_cc[LINUX_VINTR];
- bts->c_cc[VQUIT] = lts->c_cc[LINUX_VQUIT];
- bts->c_cc[VERASE] = lts->c_cc[LINUX_VERASE];
- bts->c_cc[VKILL] = lts->c_cc[LINUX_VKILL];
- bts->c_cc[VEOF] = lts->c_cc[LINUX_VEOF];
- bts->c_cc[VTIME] = lts->c_cc[LINUX_VTIME];
- bts->c_cc[VMIN] = lts->c_cc[LINUX_VMIN];
- bts->c_cc[VEOL] = lts->c_cc[LINUX_VEOL];
- bts->c_cc[VEOL2] = lts->c_cc[LINUX_VEOL2];
- bts->c_cc[VWERASE] = lts->c_cc[LINUX_VWERASE];
- bts->c_cc[VSUSP] = lts->c_cc[LINUX_VSUSP];
- bts->c_cc[VSTART] = lts->c_cc[LINUX_VSTART];
- bts->c_cc[VSTOP] = lts->c_cc[LINUX_VSTOP];
- bts->c_cc[VLNEXT] = lts->c_cc[LINUX_VLNEXT];
- bts->c_cc[VDISCARD] = lts->c_cc[LINUX_VDISCARD];
- bts->c_cc[VREPRINT] = lts->c_cc[LINUX_VREPRINT];
-}
-
-static int
-bsd_termios_to_linux_termios(bts, lts)
- register struct termios *bts;
- register struct linux_termios *lts;
-{
- int i, mask;
-
- lts->c_iflag = 0;
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
- lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
-
- lts->c_oflag = 0;
- lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
- lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
- lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
-
- switch (bts->c_cflag & CSIZE) {
- case CS5:
- lts->c_cflag = LINUX_CS5;
- break;
- case CS6:
- lts->c_cflag = LINUX_CS6;
- break;
- case CS7:
- lts->c_cflag = LINUX_CS7;
- break;
- case CS8:
- lts->c_cflag = LINUX_CS8;
- break;
- }
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS5, LINUX_CS5);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS6, LINUX_CS6);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS7, LINUX_CS7);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS8, LINUX_CS8);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
- lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
-
- lts->c_lflag = 0;
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
- lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
-
- mask = LINUX_B9600; /* XXX default value */
- for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
- if (bts->c_ospeed == linux_speeds[i]) {
- mask = linux_spmasks[i];
- break;
- }
- }
- lts->c_cflag |= mask;
-
- lts->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
- lts->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
- lts->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
- lts->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
- lts->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
- lts->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
- lts->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
- lts->c_cc[LINUX_VEOL] = bts->c_cc[VEOL];
- lts->c_cc[LINUX_VEOL2] = bts->c_cc[VEOL2];
- lts->c_cc[LINUX_VWERASE] = bts->c_cc[VWERASE];
- lts->c_cc[LINUX_VSUSP] = bts->c_cc[VSUSP];
- lts->c_cc[LINUX_VSTART] = bts->c_cc[VSTART];
- lts->c_cc[LINUX_VSTOP] = bts->c_cc[VSTOP];
- lts->c_cc[LINUX_VLNEXT] = bts->c_cc[VLNEXT];
- lts->c_cc[LINUX_VDISCARD] = bts->c_cc[VDISCARD];
- lts->c_cc[LINUX_VREPRINT] = bts->c_cc[VREPRINT];
- lts->c_cc[LINUX_VSWTC] = 0;
-
- /* XXX should be fixed someday */
- lts->c_line = 0;
-}
-
/*
* Most ioctl command are just converted to their NetBSD values,
* and passed on. The ones that take structure pointers and (flag)
@@ -450,225 +66,15 @@ linux_sys_ioctl(p, v, retval)
syscallarg(u_long) com;
syscallarg(caddr_t) data;
} */ *uap = v;
- int fd;
- unsigned long com;
- caddr_t data, sg;
- struct file *fp;
- struct filedesc *fdp;
- struct linux_termio tmplt, *alt;
- struct linux_termios tmplts, *alts;
- struct termios tmpbts, *abts;
- struct sys_ioctl_args ia;
- int error, idat, *idatp;
-
- fd = SCARG(&ia, fd) = SCARG(uap, fd);
- com = SCARG(uap, com);
- data = SCARG(&ia, data) = SCARG(uap, data);
- retval[0] = 0;
-
- fdp = p->p_fd;
- if ((u_int)fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[fd]) == NULL)
- return (EBADF);
-
- if ((fp->f_flag & (FREAD | FWRITE)) == 0)
- return (EBADF);
- sg = stackgap_init(p->p_emul);
-
- switch (com) {
- case LINUX_TCGETS:
- SCARG(&ia, com) = TIOCGETA;
- abts = stackgap_alloc(&sg, sizeof (*abts));
- SCARG(&ia, data) = (caddr_t) abts;
- if ((error = sys_ioctl(p, &ia, retval)) != 0)
- return error;
- if ((error = copyin(abts, &tmpbts, sizeof tmpbts)))
- return error;
- bsd_termios_to_linux_termios(&tmpbts, &tmplts);
- return copyout(&tmplts, data, sizeof tmplts);
- case LINUX_TCSETS:
- case LINUX_TCSETSW:
- case LINUX_TCSETSF:
- switch (com) {
- case LINUX_TCSETS:
- SCARG(&ia, com) = TIOCSETA;
- break;
- case LINUX_TCSETSW:
- SCARG(&ia, com) = TIOCSETAW;
- break;
- case LINUX_TCSETSF:
- SCARG(&ia, com) = TIOCSETAF;
- break;
- }
- if ((error = copyin(data, &tmplts, sizeof tmplts)))
- return error;
- abts = stackgap_alloc(&sg, sizeof tmpbts);
- /*
- * First fill in all fields, so that we keep the current
- * values for fields that Linux doesn't know about.
- */
- if ((error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA,
- (caddr_t) &tmpbts, p)))
- return error;
- linux_termios_to_bsd_termios(&tmplts, &tmpbts);
- if ((error = copyout(&tmpbts, abts, sizeof tmpbts)))
- return error;
- SCARG(&ia, data) = (caddr_t) abts;
- return sys_ioctl(p, &ia, retval);
- case LINUX_TCGETA:
- SCARG(&ia, com) = TIOCGETA;
- abts = stackgap_alloc(&sg, sizeof (*abts));
- SCARG(&ia, data) = (caddr_t) abts;
- if ((error = sys_ioctl(p, &ia, retval)) != 0)
- return error;
- if ((error = copyin(abts, &tmpbts, sizeof tmpbts)))
- return error;
- bsd_termios_to_linux_termio(&tmpbts, &tmplt);
- return copyout(&tmplt, data, sizeof tmplt);
- case LINUX_TCSETA:
- case LINUX_TCSETAW:
- case LINUX_TCSETAF:
- switch (com) {
- case LINUX_TCSETA:
- SCARG(&ia, com) = TIOCSETA;
- break;
- case LINUX_TCSETAW:
- SCARG(&ia, com) = TIOCSETAW;
- break;
- case LINUX_TCSETAF:
- SCARG(&ia, com) = TIOCSETAF;
- break;
- }
- if ((error = copyin(data, &tmplt, sizeof tmplt)))
- return error;
- abts = stackgap_alloc(&sg, sizeof tmpbts);
- /*
- * First fill in all fields, so that we keep the current
- * values for fields that Linux doesn't know about.
- */
- if ((error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA,
- (caddr_t) &tmpbts, p)))
- return error;
- linux_termio_to_bsd_termios(&tmplt, &tmpbts);
- if ((error = copyout(&tmpbts, abts, sizeof tmpbts)))
- return error;
- SCARG(&ia, data) = (caddr_t) abts;
- return sys_ioctl(p, &ia, retval);
- case LINUX_TIOCSETD:
- if ((error = copyin(data, (caddr_t) &idat, sizeof idat)))
- return error;
- switch (idat) {
- case LINUX_N_TTY:
- idat = TTYDISC;
- break;
- case LINUX_N_SLIP:
- idat = SLIPDISC;
- break;
- case LINUX_N_PPP:
- idat = PPPDISC;
- break;
- /*
- * We can't handle the mouse line discipline Linux has.
- */
- case LINUX_N_MOUSE:
- default:
- return EINVAL;
- }
-
- idatp = (int *) stackgap_alloc(&sg, sizeof (int));
- if ((error = copyout(&idat, idatp, sizeof (int))))
- return error;
- SCARG(&ia, com) = TIOCSETD;
- SCARG(&ia, data) = (caddr_t) idatp;
- break;
- case LINUX_TIOCGETD:
- idatp = (int *) stackgap_alloc(&sg, sizeof (int));
- SCARG(&ia, com) = TIOCGETD;
- SCARG(&ia, data) = (caddr_t) idatp;
- if ((error = sys_ioctl(p, &ia, retval)))
- return error;
- if ((error = copyin(idatp, (caddr_t) &idat, sizeof (int))))
- return error;
- switch (idat) {
- case TTYDISC:
- idat = LINUX_N_TTY;
- break;
- case SLIPDISC:
- idat = LINUX_N_SLIP;
- break;
- case PPPDISC:
- idat = LINUX_N_PPP;
- break;
- /*
- * Linux does not have the tablet line discipline.
- */
- case TABLDISC:
- default:
- idat = -1; /* XXX What should this be? */
- break;
- }
- return copyout(&idat, data, sizeof (int));
- case LINUX_TIOCGWINSZ:
- SCARG(&ia, com) = TIOCGWINSZ;
- break;
- case LINUX_TIOCSWINSZ:
- SCARG(&ia, com) = TIOCSWINSZ;
- break;
- case LINUX_TIOCGPGRP:
- SCARG(&ia, com) = TIOCGPGRP;
- break;
- case LINUX_TIOCSPGRP:
- SCARG(&ia, com) = TIOCSPGRP;
- break;
- case LINUX_FIONREAD:
- SCARG(&ia, com) = FIONREAD;
- break;
- case LINUX_FIONBIO:
- SCARG(&ia, com) = FIONBIO;
- break;
- case LINUX_FIOASYNC:
- SCARG(&ia, com) = FIOASYNC;
- break;
- case LINUX_TIOCEXCL:
- SCARG(&ia, com) = TIOCEXCL;
- break;
- case LINUX_TIOCNXCL:
- SCARG(&ia, com) = TIOCNXCL;
- break;
- case LINUX_TIOCCONS:
- SCARG(&ia, com) = TIOCCONS;
- break;
- case LINUX_TIOCNOTTY:
- SCARG(&ia, com) = TIOCNOTTY;
- break;
- case LINUX_SIOCGIFCONF:
- SCARG(&ia, com) = OSIOCGIFCONF;
- break;
- case LINUX_SIOCGIFFLAGS:
- SCARG(&ia, com) = SIOCGIFFLAGS;
- break;
- case LINUX_SIOCGIFADDR:
- SCARG(&ia, com) = OSIOCGIFADDR;
- break;
- case LINUX_SIOCGIFDSTADDR:
- SCARG(&ia, com) = OSIOCGIFDSTADDR;
- break;
- case LINUX_SIOCGIFBRDADDR:
- SCARG(&ia, com) = OSIOCGIFBRDADDR;
- break;
- case LINUX_SIOCGIFNETMASK:
- SCARG(&ia, com) = OSIOCGIFNETMASK;
- break;
- case LINUX_SIOCADDMULTI:
- SCARG(&ia, com) = SIOCADDMULTI;
- break;
- case LINUX_SIOCDELMULTI:
- SCARG(&ia, com) = SIOCDELMULTI;
- break;
+ switch (LINUX_IOCGROUP(SCARG(uap, com))) {
+ case 'P':
+ return linux_ioctl_audio(p, uap, retval);
+ case 'T':
+ return linux_ioctl_termios(p, uap, retval);
+ case 0x89:
+ return linux_ioctl_socket(p, uap, retval);
default:
return linux_machdepioctl(p, uap, retval);
}
-
- return sys_ioctl(p, &ia, retval);
}
diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h
index 0acc5da9f02..f1c8592eaf5 100644
--- a/sys/compat/linux/linux_ioctl.h
+++ b/sys/compat/linux/linux_ioctl.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_ioctl.h,v 1.2 1995/08/16 04:14:58 mycroft Exp $ */
+/* $NetBSD: linux_ioctl.h,v 1.3 1996/03/08 04:56:04 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -31,248 +31,5 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _LINUX_IOCTL_H
-#define _LINUX_IOCTL_H
-
-#define _LINUX_IO(c,n) (((c)<< 8) | (n))
-
-#define LINUX_TCGETS _LINUX_IO('T',1)
-#define LINUX_TCSETS _LINUX_IO('T',2)
-#define LINUX_TCSETSW _LINUX_IO('T',3)
-#define LINUX_TCSETSF _LINUX_IO('T',4)
-#define LINUX_TCGETA _LINUX_IO('T',5)
-#define LINUX_TCSETA _LINUX_IO('T',6)
-#define LINUX_TCSETAW _LINUX_IO('T',7)
-#define LINUX_TCSETAF _LINUX_IO('T',8)
-#define LINUX_TCSBRK _LINUX_IO('T',9)
-#define LINUX_TCXONC _LINUX_IO('T',10)
-#define LINUX_TCFLSH _LINUX_IO('T',11)
-#define LINUX_TIOCEXCL _LINUX_IO('T',12)
-#define LINUX_TIOCNXCL _LINUX_IO('T',13)
-#define LINUX_TIOCSCTTY _LINUX_IO('T',14)
-#define LINUX_TIOCGPGRP _LINUX_IO('T',15)
-#define LINUX_TIOCSPGRP _LINUX_IO('T',16)
-#define LINUX_TIOCOUTQ _LINUX_IO('T',17)
-#define LINUX_TIOCSTI _LINUX_IO('T',18)
-#define LINUX_TIOCGWINSZ _LINUX_IO('T',19)
-#define LINUX_TIOCSWINSZ _LINUX_IO('T',20)
-#define LINUX_TIOCMGET _LINUX_IO('T',21)
-#define LINUX_TIOCMBIS _LINUX_IO('T',22)
-#define LINUX_TIOCMBIC _LINUX_IO('T',23)
-#define LINUX_TIOCMSET _LINUX_IO('T',24)
-#define LINUX_TIOCGSOFTCAR _LINUX_IO('T',25)
-#define LINUX_TIOCSSOFTCAR _LINUX_IO('T',26)
-#define LINUX_FIONREAD _LINUX_IO('T',27)
-#define LINUX_TIOCINQ LINUX_FIONREAD
-#define LINUX_TIOCLINUX _LINUX_IO('T',28)
-#define LINUX_TIOCCONS _LINUX_IO('T',29)
-#define LINUX_TIOCGSERIAL _LINUX_IO('T',30)
-#define LINUX_TIOCSSERIAL _LINUX_IO('T',31)
-#define LINUX_TIOCPKT _LINUX_IO('T',32)
-#define LINUX_FIONBIO _LINUX_IO('T',33)
-#define LINUX_TIOCNOTTY _LINUX_IO('T',34)
-#define LINUX_TIOCSETD _LINUX_IO('T',35)
-#define LINUX_TIOCGETD _LINUX_IO('T',36)
-#define LINUX_TCSBRKP _LINUX_IO('T',37)
-#define LINUX_TIOCTTYGSTRUCT _LINUX_IO('T',38)
-
-#define LINUX_FIONCLEX _LINUX_IO('T',80)
-#define LINUX_FIOCLEX _LINUX_IO('T',81)
-#define LINUX_FIOASYNC _LINUX_IO('T',82)
-#define LINUX_TIOCSERCONFIG _LINUX_IO('T',83)
-#define LINUX_TIOCSERGWILD _LINUX_IO('T',84)
-#define LINUX_TIOCSERSWILD _LINUX_IO('T',85)
-#define LINUX_TIOCGLCKTRMIOS _LINUX_IO('T',86)
-#define LINUX_TIOCSLCKTRMIOS _LINUX_IO('T',87)
-#define LINUX_TIOCSERGSTRUCT _LINUX_IO('T',88)
-#define LINUX_TIOCSERGETLSR _LINUX_IO('T',89)
-
-
-#define LINUX_NCC 8
-struct linux_termio {
- unsigned short c_iflag;
- unsigned short c_oflag;
- unsigned short c_cflag;
- unsigned short c_lflag;
- unsigned char c_line;
- unsigned char c_cc[LINUX_NCC];
-};
-
-typedef unsigned char linux_cc_t;
-typedef unsigned long linux_tcflag_t;
-
-#define LINUX_NCCS 19
-struct linux_termios {
- linux_tcflag_t c_iflag;
- linux_tcflag_t c_oflag;
- linux_tcflag_t c_cflag;
- linux_tcflag_t c_lflag;
- linux_cc_t c_line;
- linux_cc_t c_cc[LINUX_NCCS];
-};
-
-/* Just in old style linux_termio struct */
-#define LINUX_VINTR 0
-#define LINUX_VQUIT 1
-#define LINUX_VERASE 2
-#define LINUX_VKILL 3
-#define LINUX_VEOF 4
-#define LINUX_VTIME 5
-#define LINUX_VMIN 6
-#define LINUX_VSWTC 7
-
-/* In the termios struct too */
-#define LINUX_VSTART 8
-#define LINUX_VSTOP 9
-#define LINUX_VSUSP 10
-#define LINUX_VEOL 11
-#define LINUX_VREPRINT 12
-#define LINUX_VDISCARD 13
-#define LINUX_VWERASE 14
-#define LINUX_VLNEXT 15
-#define LINUX_VEOL2 16
-
-/* Linux c_iflag masks */
-#define LINUX_IGNBRK 0x0000001
-#define LINUX_BRKINT 0x0000002
-#define LINUX_IGNPAR 0x0000004
-#define LINUX_PARMRK 0x0000008
-#define LINUX_INPCK 0x0000010
-#define LINUX_ISTRIP 0x0000020
-#define LINUX_INLCR 0x0000040
-#define LINUX_IGNCR 0x0000080
-#define LINUX_ICRNL 0x0000100
-#define LINUX_IUCLC 0x0000200
-#define LINUX_IXON 0x0000400
-#define LINUX_IXANY 0x0000800
-#define LINUX_IXOFF 0x0001000
-#define LINUX_IMAXBEL 0x0002000
-
-/* Linux c_oflag masks */
-#define LINUX_OPOST 0x0000001
-#define LINUX_OLCUC 0x0000002
-#define LINUX_ONLCR 0x0000004
-#define LINUX_OCRNL 0x0000008
-#define LINUX_ONOCR 0x0000010
-#define LINUX_ONLRET 0x0000020
-#define LINUX_OFILL 0x0000040
-#define LINUX_OFDEL 0x0000080
-#define LINUX_NLDLY 0x0000100
-
-#define LINUX_NL0 0x0000000
-#define LINUX_NL1 0x0000100
-#define LINUX_CRDLY 0x0000600
-#define LINUX_CR0 0x0000000
-#define LINUX_CR1 0x0000200
-#define LINUX_CR2 0x0000400
-#define LINUX_CR3 0x0000600
-#define LINUX_TABDLY 0x0001800
-#define LINUX_TAB0 0x0000000
-#define LINUX_TAB1 0x0000800
-#define LINUX_TAB2 0x0001000
-#define LINUX_TAB3 0x0001800
-#define LINUX_XTABS 0x0001800
-#define LINUX_BSDLY 0x0002000
-#define LINUX_BS0 0x0000000
-#define LINUX_BS1 0x0002000
-#define LINUX_VTDLY 0x0004000
-#define LINUX_VT0 0x0000000
-#define LINUX_VT1 0x0004000
-#define LINUX_FFDLY 0x0008000
-#define LINUX_FF0 0x0000000
-#define LINUX_FF1 0x0008000
-
-/* Linux c_cflag bit masks */
-
-#define LINUX_NSPEEDS 16
-#define LINUX_NXSPEEDS 2
-
-#define LINUX_CBAUD 0x0000100f
-
-#define LINUX_B0 0x00000000
-#define LINUX_B50 0x00000001
-#define LINUX_B75 0x00000002
-#define LINUX_B110 0x00000003
-#define LINUX_B134 0x00000004
-#define LINUX_B150 0x00000005
-#define LINUX_B200 0x00000006
-#define LINUX_B300 0x00000007
-#define LINUX_B600 0x00000008
-#define LINUX_B1200 0x00000009
-#define LINUX_B1800 0x0000000a
-#define LINUX_B2400 0x0000000b
-#define LINUX_B4800 0x0000000c
-#define LINUX_B9600 0x0000000d
-#define LINUX_B19200 0x0000000e
-#define LINUX_B38400 0x0000000f
-#define LINUX_EXTA LINUX_B19200
-#define LINUX_EXTB LINUX_B38400
-#define LINUX_CBAUDEX 0x00001000
-#define LINUX_B57600 0x00001001
-#define LINUX_B115200 0x00001002
-#define LINUX_B230400 0x00001003
-
-#define LINUX_CSIZE 0x00000030
-#define LINUX_CS5 0x00000000
-#define LINUX_CS6 0x00000010
-#define LINUX_CS7 0x00000020
-#define LINUX_CS8 0x00000030
-#define LINUX_CSTOPB 0x00000040
-#define LINUX_CREAD 0x00000080
-#define LINUX_PARENB 0x00000100
-#define LINUX_PARODD 0x00000200
-#define LINUX_HUPCL 0x00000400
-#define LINUX_CLOCAL 0x00000800
-
-#define LINUX_CRTSCTS 0x80000000
-
-/* Linux c_lflag masks */
-#define LINUX_ISIG 0x00000001
-#define LINUX_ICANON 0x00000002
-#define LINUX_XCASE 0x00000004
-#define LINUX_ECHO 0x00000008
-#define LINUX_ECHOE 0x00000010
-#define LINUX_ECHOK 0x00000020
-#define LINUX_ECHONL 0x00000040
-#define LINUX_NOFLSH 0x00000080
-#define LINUX_TOSTOP 0x00000100
-#define LINUX_ECHOCTL 0x00000200
-#define LINUX_ECHOPRT 0x00000400
-#define LINUX_ECHOKE 0x00000800
-#define LINUX_FLUSHO 0x00001000
-#define LINUX_PENDIN 0x00002000
-#define LINUX_IEXTEN 0x00008000
-
-/* Linux modem line defines.. not sure if they'll be used */
-#define LINUX_TIOCM_LE 0x0001
-#define LINUX_TIOCM_DTR 0x0002
-#define LINUX_TIOCM_RTS 0x0004
-#define LINUX_TIOCM_ST 0x0008
-#define LINUX_TIOCM_SR 0x0010
-#define LINUX_TIOCM_CTS 0x0020
-#define LINUX_TIOCM_CAR 0x0040
-#define LINUX_TIOCM_RNG 0x0080
-#define LINUX_TIOCM_DSR 0x0100
-#define LINUX_TIOCM_CD LINUX_TIOCM_CAR
-#define LINUX_TIOCM_RI LINUX_TIOCM_RNG
-
-#define LINUX_TCIFLUSH 0
-#define LINUX_TCOFLUSH 1
-#define LINUX_TCIOFLUSH 2
-
-#define LINUX_TCOOFF 0
-#define LINUX_TCOON 1
-#define LINUX_TCIOFF 2
-#define LINUX_TCION 3
-
-#define LINUX_TCSANOW 0
-#define LINUX_TCSADRAIN 1
-#define LINUX_TCSAFLUSH 2
-
-/* Linux line disciplines */
-#define LINUX_N_TTY 0
-#define LINUX_N_SLIP 1
-#define LINUX_N_MOUSE 2
-#define LINUX_N_PPP 3
-
-#endif /* !_LINUX_IOCTL_H */
+#define _LINUX_IO(x,y) (((x) << 8) | (y))
+#define LINUX_IOCGROUP(x) (((x) >> 8) & 0xff)
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 664a246f99e..911095aae77 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_socket.c,v 1.12 1995/10/07 06:27:13 mycroft Exp $ */
+/* $NetBSD: linux_socket.c,v 1.13 1996/03/08 04:56:05 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -702,3 +702,53 @@ linux_sys_socketcall(p, v, retval)
return ENOSYS;
}
}
+
+int
+linux_ioctl_socket(p, uap, retval)
+ register struct proc *p;
+ register struct linux_sys_ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ register_t *retval;
+{
+ u_long com;
+ struct sys_ioctl_args ia;
+
+ com = SCARG(uap, com);
+ retval[0] = 0;
+
+ switch (com) {
+ case LINUX_SIOCGIFCONF:
+ SCARG(&ia, com) = OSIOCGIFCONF;
+ break;
+ case LINUX_SIOCGIFFLAGS:
+ SCARG(&ia, com) = SIOCGIFFLAGS;
+ break;
+ case LINUX_SIOCGIFADDR:
+ SCARG(&ia, com) = OSIOCGIFADDR;
+ break;
+ case LINUX_SIOCGIFDSTADDR:
+ SCARG(&ia, com) = OSIOCGIFDSTADDR;
+ break;
+ case LINUX_SIOCGIFBRDADDR:
+ SCARG(&ia, com) = OSIOCGIFBRDADDR;
+ break;
+ case LINUX_SIOCGIFNETMASK:
+ SCARG(&ia, com) = OSIOCGIFNETMASK;
+ break;
+ case LINUX_SIOCADDMULTI:
+ SCARG(&ia, com) = SIOCADDMULTI;
+ break;
+ case LINUX_SIOCDELMULTI:
+ SCARG(&ia, com) = SIOCDELMULTI;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ SCARG(&ia, fd) = SCARG(uap, fd);
+ SCARG(&ia, data) = SCARG(uap, data);
+ return sys_ioctl(p, &ia, retval);
+}
diff --git a/sys/compat/linux/linux_sockio.h b/sys/compat/linux/linux_sockio.h
index b6f466b5287..c67e65ea340 100644
--- a/sys/compat/linux/linux_sockio.h
+++ b/sys/compat/linux/linux_sockio.h
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_sockio.h,v 1.4 1996/02/27 08:18:17 mycroft Exp $ */
+/* $NetBSD: linux_sockio.h,v 1.5 1996/03/08 04:56:07 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@@ -34,13 +34,13 @@
#ifndef _LINUX_SOCKIO_H
#define _LINUX_SOCKIO_H
-#define LINUX_SIOCGIFCONF 0x8912
-#define LINUX_SIOCGIFFLAGS 0x8913
-#define LINUX_SIOCGIFADDR 0x8915
-#define LINUX_SIOCGIFDSTADDR 0x8917
-#define LINUX_SIOCGIFBRDADDR 0x8919
-#define LINUX_SIOCGIFNETMASK 0x891b
-#define LINUX_SIOCADDMULTI 0x8931
-#define LINUX_SIOCDELMULTI 0x8932
+#define LINUX_SIOCGIFCONF _LINUX_IO(0x89, 18)
+#define LINUX_SIOCGIFFLAGS _LINUX_IO(0x89, 19)
+#define LINUX_SIOCGIFADDR _LINUX_IO(0x89, 21)
+#define LINUX_SIOCGIFDSTADDR _LINUX_IO(0x89, 23)
+#define LINUX_SIOCGIFBRDADDR _LINUX_IO(0x89, 25)
+#define LINUX_SIOCGIFNETMASK _LINUX_IO(0x89, 27)
+#define LINUX_SIOCADDMULTI _LINUX_IO(0x89, 49)
+#define LINUX_SIOCDELMULTI _LINUX_IO(0x89, 50)
#endif /* _LINUX_SOCKIO_H */
diff --git a/sys/compat/linux/linux_termios.c b/sys/compat/linux/linux_termios.c
new file mode 100644
index 00000000000..205340d4592
--- /dev/null
+++ b/sys/compat/linux/linux_termios.c
@@ -0,0 +1,629 @@
+/* $NetBSD: linux_termios.c,v 1.1 1996/03/08 04:56:08 mycroft Exp $ */
+
+/*
+ * Copyright (c) 1995 Frank van der Linden
+ * All rights reserved.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project
+ * by Frank van der Linden
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/termios.h>
+
+#include <sys/syscallargs.h>
+
+#include <compat/linux/linux_types.h>
+#include <compat/linux/linux_ioctl.h>
+#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_syscallargs.h>
+#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_termios.h>
+
+static speed_t linux_speeds[] = {
+ 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+ 9600, 19200, 38400, 57600, 115200
+};
+
+static int linux_spmasks[] = {
+ LINUX_B0, LINUX_B50, LINUX_B75, LINUX_B110, LINUX_B134, LINUX_B150,
+ LINUX_B200, LINUX_B300, LINUX_B600, LINUX_B1200, LINUX_B1800,
+ LINUX_B2400, LINUX_B4800, LINUX_B9600, LINUX_B19200, LINUX_B38400,
+ LINUX_B57600, LINUX_B115200, LINUX_B230400
+};
+
+/*
+ * Deal with termio ioctl cruft. This doesn't look very good..
+ * XXX too much code duplication, obviously..
+ *
+ * The conversion routines between Linux and BSD structures assume
+ * that the fields are already filled with the current values,
+ * so that fields present in BSD but not in Linux keep their current
+ * values.
+ */
+
+static int
+linux_termio_to_bsd_termios(lt, bts)
+ register struct linux_termio *lt;
+ register struct termios *bts;
+{
+ int index;
+
+ bts->c_iflag = 0;
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNBRK, IGNBRK);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_BRKINT, BRKINT);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNPAR, IGNPAR);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INPCK, INPCK);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ISTRIP, ISTRIP);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INLCR, INLCR);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNCR, IGNCR);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ICRNL, ICRNL);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXON, IXON);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXANY, IXANY);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXOFF, IXOFF);
+ bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IMAXBEL, IMAXBEL);
+
+ bts->c_oflag = 0;
+ bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_OPOST, OPOST);
+ bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_ONLCR, ONLCR);
+ bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_XTABS, OXTABS);
+
+ /*
+ * This could have been:
+ * bts->c_cflag = (lt->c_flag & LINUX_CSIZE) << 4
+ * But who knows, those values might perhaps change one day.
+ */
+ switch (lt->c_cflag & LINUX_CSIZE) {
+ case LINUX_CS5:
+ bts->c_cflag = CS5;
+ break;
+ case LINUX_CS6:
+ bts->c_cflag = CS6;
+ break;
+ case LINUX_CS7:
+ bts->c_cflag = CS7;
+ break;
+ case LINUX_CS8:
+ bts->c_cflag = CS8;
+ break;
+ }
+ bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CSTOPB, CSTOPB);
+ bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CREAD, CREAD);
+ bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARENB, PARENB);
+ bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARODD, PARODD);
+ bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_HUPCL, HUPCL);
+ bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CLOCAL, CLOCAL);
+ bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CRTSCTS, CRTSCTS);
+
+ bts->c_lflag = 0;
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ISIG, ISIG);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ICANON, ICANON);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHO, ECHO);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOE, ECHOE);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOK, ECHOK);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHONL, ECHONL);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_NOFLSH, NOFLSH);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_TOSTOP, TOSTOP);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOCTL, ECHOCTL);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOPRT, ECHOPRT);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOKE, ECHOKE);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_FLUSHO, FLUSHO);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_PENDIN, PENDIN);
+ bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_IEXTEN, IEXTEN);
+
+ index = lt->c_cflag & LINUX_CBAUD;
+ if (index & LINUX_CBAUDEX)
+ index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
+ bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
+
+ bts->c_cc[VINTR] = lt->c_cc[LINUX_VINTR];
+ bts->c_cc[VQUIT] = lt->c_cc[LINUX_VQUIT];
+ bts->c_cc[VERASE] = lt->c_cc[LINUX_VERASE];
+ bts->c_cc[VKILL] = lt->c_cc[LINUX_VKILL];
+ bts->c_cc[VEOF] = lt->c_cc[LINUX_VEOF];
+ bts->c_cc[VTIME] = lt->c_cc[LINUX_VTIME];
+ bts->c_cc[VMIN] = lt->c_cc[LINUX_VMIN];
+}
+
+static int
+bsd_termios_to_linux_termio(bts, lt)
+ register struct termios *bts;
+ register struct linux_termio *lt;
+{
+ int i, mask;
+
+ lt->c_iflag = 0;
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
+ lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
+
+ lt->c_oflag = 0;
+ lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
+ lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
+ lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
+
+ switch (bts->c_cflag & CSIZE) {
+ case CS5:
+ lt->c_cflag = LINUX_CS5;
+ break;
+ case CS6:
+ lt->c_cflag = LINUX_CS6;
+ break;
+ case CS7:
+ lt->c_cflag = LINUX_CS7;
+ break;
+ case CS8:
+ lt->c_cflag = LINUX_CS8;
+ break;
+ }
+ lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
+ lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
+ lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
+ lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
+ lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
+ lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
+ lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
+
+ lt->c_lflag = 0;
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
+ lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
+
+ mask = LINUX_B9600; /* XXX default value should this be 0? */
+ for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
+ if (bts->c_ospeed == linux_speeds[i]) {
+ mask = linux_spmasks[i];
+ break;
+ }
+ }
+ lt->c_cflag |= mask;
+
+ lt->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
+ lt->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
+ lt->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
+ lt->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
+ lt->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
+ lt->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
+ lt->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
+ lt->c_cc[LINUX_VSWTC] = 0;
+
+ /* XXX should be fixed someday */
+ lt->c_line = 0;
+}
+
+static int
+linux_termios_to_bsd_termios(lts, bts)
+ register struct linux_termios *lts;
+ register struct termios *bts;
+{
+ int index;
+
+ bts->c_iflag = 0;
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNBRK, IGNBRK);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_BRKINT, BRKINT);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNPAR, IGNPAR);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INPCK, INPCK);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ISTRIP, ISTRIP);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INLCR, INLCR);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNCR, IGNCR);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ICRNL, ICRNL);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXON, IXON);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXANY, IXANY);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXOFF, IXOFF);
+ bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IMAXBEL, IMAXBEL);
+
+ bts->c_oflag = 0;
+ bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_OPOST, OPOST);
+ bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_ONLCR, ONLCR);
+ bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_XTABS, OXTABS);
+
+ bts->c_cflag = 0;
+ switch (lts->c_cflag & LINUX_CSIZE) {
+ case LINUX_CS5:
+ bts->c_cflag = CS5;
+ break;
+ case LINUX_CS6:
+ bts->c_cflag = CS6;
+ break;
+ case LINUX_CS7:
+ bts->c_cflag = CS7;
+ break;
+ case LINUX_CS8:
+ bts->c_cflag = CS8;
+ break;
+ }
+ bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CSTOPB, CSTOPB);
+ bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CREAD, CREAD);
+ bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARENB, PARENB);
+ bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARODD, PARODD);
+ bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_HUPCL, HUPCL);
+ bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CLOCAL, CLOCAL);
+ bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CRTSCTS, CRTSCTS);
+
+ bts->c_lflag = 0;
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ISIG, ISIG);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ICANON, ICANON);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHO, ECHO);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOE, ECHOE);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOK, ECHOK);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHONL, ECHONL);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_NOFLSH, NOFLSH);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_TOSTOP, TOSTOP);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOCTL, ECHOCTL);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOPRT, ECHOPRT);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOKE, ECHOKE);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_FLUSHO, FLUSHO);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_PENDIN, PENDIN);
+ bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_IEXTEN, IEXTEN);
+
+ index = lts->c_cflag & LINUX_CBAUD;
+ if (index & LINUX_CBAUDEX)
+ index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
+ bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
+
+ bts->c_cc[VINTR] = lts->c_cc[LINUX_VINTR];
+ bts->c_cc[VQUIT] = lts->c_cc[LINUX_VQUIT];
+ bts->c_cc[VERASE] = lts->c_cc[LINUX_VERASE];
+ bts->c_cc[VKILL] = lts->c_cc[LINUX_VKILL];
+ bts->c_cc[VEOF] = lts->c_cc[LINUX_VEOF];
+ bts->c_cc[VTIME] = lts->c_cc[LINUX_VTIME];
+ bts->c_cc[VMIN] = lts->c_cc[LINUX_VMIN];
+ bts->c_cc[VEOL] = lts->c_cc[LINUX_VEOL];
+ bts->c_cc[VEOL2] = lts->c_cc[LINUX_VEOL2];
+ bts->c_cc[VWERASE] = lts->c_cc[LINUX_VWERASE];
+ bts->c_cc[VSUSP] = lts->c_cc[LINUX_VSUSP];
+ bts->c_cc[VSTART] = lts->c_cc[LINUX_VSTART];
+ bts->c_cc[VSTOP] = lts->c_cc[LINUX_VSTOP];
+ bts->c_cc[VLNEXT] = lts->c_cc[LINUX_VLNEXT];
+ bts->c_cc[VDISCARD] = lts->c_cc[LINUX_VDISCARD];
+ bts->c_cc[VREPRINT] = lts->c_cc[LINUX_VREPRINT];
+}
+
+static int
+bsd_termios_to_linux_termios(bts, lts)
+ register struct termios *bts;
+ register struct linux_termios *lts;
+{
+ int i, mask;
+
+ lts->c_iflag = 0;
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
+ lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
+
+ lts->c_oflag = 0;
+ lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
+ lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
+ lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
+
+ switch (bts->c_cflag & CSIZE) {
+ case CS5:
+ lts->c_cflag = LINUX_CS5;
+ break;
+ case CS6:
+ lts->c_cflag = LINUX_CS6;
+ break;
+ case CS7:
+ lts->c_cflag = LINUX_CS7;
+ break;
+ case CS8:
+ lts->c_cflag = LINUX_CS8;
+ break;
+ }
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS5, LINUX_CS5);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS6, LINUX_CS6);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS7, LINUX_CS7);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS8, LINUX_CS8);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
+ lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
+
+ lts->c_lflag = 0;
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
+ lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
+
+ mask = LINUX_B9600; /* XXX default value */
+ for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
+ if (bts->c_ospeed == linux_speeds[i]) {
+ mask = linux_spmasks[i];
+ break;
+ }
+ }
+ lts->c_cflag |= mask;
+
+ lts->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
+ lts->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
+ lts->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
+ lts->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
+ lts->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
+ lts->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
+ lts->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
+ lts->c_cc[LINUX_VEOL] = bts->c_cc[VEOL];
+ lts->c_cc[LINUX_VEOL2] = bts->c_cc[VEOL2];
+ lts->c_cc[LINUX_VWERASE] = bts->c_cc[VWERASE];
+ lts->c_cc[LINUX_VSUSP] = bts->c_cc[VSUSP];
+ lts->c_cc[LINUX_VSTART] = bts->c_cc[VSTART];
+ lts->c_cc[LINUX_VSTOP] = bts->c_cc[VSTOP];
+ lts->c_cc[LINUX_VLNEXT] = bts->c_cc[VLNEXT];
+ lts->c_cc[LINUX_VDISCARD] = bts->c_cc[VDISCARD];
+ lts->c_cc[LINUX_VREPRINT] = bts->c_cc[VREPRINT];
+ lts->c_cc[LINUX_VSWTC] = 0;
+
+ /* XXX should be fixed someday */
+ lts->c_line = 0;
+}
+
+int
+linux_ioctl_termios(p, uap, retval)
+ register struct proc *p;
+ register struct linux_sys_ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ register_t *retval;
+{
+ register struct file *fp;
+ register struct filedesc *fdp;
+ u_long com;
+ struct linux_termio tmplt;
+ struct linux_termios tmplts;
+ struct termios tmpbts;
+ int idat;
+ struct sys_ioctl_args ia;
+ int error;
+
+ fdp = p->p_fd;
+ if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
+ return (EBADF);
+
+ if ((fp->f_flag & (FREAD | FWRITE)) == 0)
+ return (EBADF);
+
+ com = SCARG(uap, com);
+ retval[0] = 0;
+
+ switch (com) {
+ case LINUX_TCGETS:
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
+ if (error)
+ return error;
+ bsd_termios_to_linux_termios(&tmpbts, &tmplts);
+ error = copyout(&tmplts, SCARG(uap, data), sizeof tmplts);
+ if (error)
+ return error;
+ return 0;
+ case LINUX_TCSETS:
+ case LINUX_TCSETSW:
+ case LINUX_TCSETSF:
+ /*
+ * First fill in all fields, so that we keep the current
+ * values for fields that Linux doesn't know about.
+ */
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
+ if (error)
+ return error;
+ error = copyin(SCARG(uap, data), &tmplts, sizeof tmplts);
+ if (error)
+ return error;
+ linux_termios_to_bsd_termios(&tmplts, &tmpbts);
+ switch (com) {
+ case LINUX_TCSETS:
+ com = TIOCSETA;
+ break;
+ case LINUX_TCSETSW:
+ com = TIOCSETAW;
+ break;
+ case LINUX_TCSETSF:
+ com = TIOCSETAF;
+ break;
+ }
+ error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&tmpbts, p);
+ if (error)
+ return error;
+ return 0;
+ case LINUX_TCGETA:
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
+ if (error)
+ return error;
+ bsd_termios_to_linux_termio(&tmpbts, &tmplt);
+ error = copyout(&tmplt, SCARG(uap, data), sizeof tmplt);
+ if (error)
+ return error;
+ return 0;
+ case LINUX_TCSETA:
+ case LINUX_TCSETAW:
+ case LINUX_TCSETAF:
+ /*
+ * First fill in all fields, so that we keep the current
+ * values for fields that Linux doesn't know about.
+ */
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
+ if (error)
+ return error;
+ error = copyin(SCARG(uap, data), &tmplt, sizeof tmplt);
+ if (error)
+ return error;
+ linux_termio_to_bsd_termios(&tmplt, &tmpbts);
+ switch (com) {
+ case LINUX_TCSETA:
+ com = TIOCSETA;
+ break;
+ case LINUX_TCSETAW:
+ com = TIOCSETAW;
+ break;
+ case LINUX_TCSETAF:
+ com = TIOCSETAF;
+ break;
+ }
+ error = (*fp->f_ops->fo_ioctl)(fp, com, (caddr_t)&tmpbts, p);
+ if (error)
+ return error;
+ return 0;
+ case LINUX_TIOCGETD:
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCGETD, (caddr_t)&idat, p);
+ if (error)
+ return error;
+ switch (idat) {
+ case TTYDISC:
+ idat = LINUX_N_TTY;
+ break;
+ case SLIPDISC:
+ idat = LINUX_N_SLIP;
+ break;
+ case PPPDISC:
+ idat = LINUX_N_PPP;
+ break;
+ /*
+ * Linux does not have the tablet line discipline.
+ */
+ case TABLDISC:
+ default:
+ idat = -1; /* XXX What should this be? */
+ break;
+ }
+ error = copyout(&idat, SCARG(uap, data), sizeof idat);
+ if (error)
+ return error;
+ return 0;
+ case LINUX_TIOCSETD:
+ error = copyin(SCARG(uap, data), &idat, sizeof idat);
+ if (error)
+ return error;
+ switch (idat) {
+ case LINUX_N_TTY:
+ idat = TTYDISC;
+ break;
+ case LINUX_N_SLIP:
+ idat = SLIPDISC;
+ break;
+ case LINUX_N_PPP:
+ idat = PPPDISC;
+ break;
+ /*
+ * We can't handle the mouse line discipline Linux has.
+ */
+ case LINUX_N_MOUSE:
+ default:
+ return EINVAL;
+ }
+ error = (*fp->f_ops->fo_ioctl)(fp, TIOCSETD, (caddr_t)&idat, p);
+ if (error)
+ return error;
+ return 0;
+ case LINUX_TIOCGWINSZ:
+ SCARG(&ia, com) = TIOCGWINSZ;
+ break;
+ case LINUX_TIOCSWINSZ:
+ SCARG(&ia, com) = TIOCSWINSZ;
+ break;
+ case LINUX_TIOCGPGRP:
+ SCARG(&ia, com) = TIOCGPGRP;
+ break;
+ case LINUX_TIOCSPGRP:
+ SCARG(&ia, com) = TIOCSPGRP;
+ break;
+ case LINUX_FIONREAD:
+ SCARG(&ia, com) = FIONREAD;
+ break;
+ case LINUX_FIONBIO:
+ SCARG(&ia, com) = FIONBIO;
+ break;
+ case LINUX_FIOASYNC:
+ SCARG(&ia, com) = FIOASYNC;
+ break;
+ case LINUX_TIOCEXCL:
+ SCARG(&ia, com) = TIOCEXCL;
+ break;
+ case LINUX_TIOCNXCL:
+ SCARG(&ia, com) = TIOCNXCL;
+ break;
+ case LINUX_TIOCCONS:
+ SCARG(&ia, com) = TIOCCONS;
+ break;
+ case LINUX_TIOCNOTTY:
+ SCARG(&ia, com) = TIOCNOTTY;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ SCARG(&ia, fd) = SCARG(uap, fd);
+ SCARG(&ia, data) = SCARG(uap, data);
+ return sys_ioctl(p, &ia, retval);
+}
diff --git a/sys/compat/linux/linux_termios.h b/sys/compat/linux/linux_termios.h
new file mode 100644
index 00000000000..8bf040ec913
--- /dev/null
+++ b/sys/compat/linux/linux_termios.h
@@ -0,0 +1,238 @@
+#define LINUX_TCGETS _LINUX_IO('T', 1)
+#define LINUX_TCSETS _LINUX_IO('T', 2)
+#define LINUX_TCSETSW _LINUX_IO('T', 3)
+#define LINUX_TCSETSF _LINUX_IO('T', 4)
+#define LINUX_TCGETA _LINUX_IO('T', 5)
+#define LINUX_TCSETA _LINUX_IO('T', 6)
+#define LINUX_TCSETAW _LINUX_IO('T', 7)
+#define LINUX_TCSETAF _LINUX_IO('T', 8)
+#define LINUX_TCSBRK _LINUX_IO('T', 9)
+#define LINUX_TCXONC _LINUX_IO('T', 10)
+#define LINUX_TCFLSH _LINUX_IO('T', 11)
+#define LINUX_TIOCEXCL _LINUX_IO('T', 12)
+#define LINUX_TIOCNXCL _LINUX_IO('T', 13)
+#define LINUX_TIOCSCTTY _LINUX_IO('T', 14)
+#define LINUX_TIOCGPGRP _LINUX_IO('T', 15)
+#define LINUX_TIOCSPGRP _LINUX_IO('T', 16)
+#define LINUX_TIOCOUTQ _LINUX_IO('T', 17)
+#define LINUX_TIOCSTI _LINUX_IO('T', 18)
+#define LINUX_TIOCGWINSZ _LINUX_IO('T', 19)
+#define LINUX_TIOCSWINSZ _LINUX_IO('T', 20)
+#define LINUX_TIOCMGET _LINUX_IO('T', 21)
+#define LINUX_TIOCMBIS _LINUX_IO('T', 22)
+#define LINUX_TIOCMBIC _LINUX_IO('T', 23)
+#define LINUX_TIOCMSET _LINUX_IO('T', 24)
+#define LINUX_TIOCGSOFTCAR _LINUX_IO('T', 25)
+#define LINUX_TIOCSSOFTCAR _LINUX_IO('T', 26)
+#define LINUX_FIONREAD _LINUX_IO('T', 27)
+#define LINUX_TIOCINQ LINUX_FIONREAD
+#define LINUX_TIOCLINUX _LINUX_IO('T', 28)
+#define LINUX_TIOCCONS _LINUX_IO('T', 29)
+#define LINUX_TIOCGSERIAL _LINUX_IO('T', 30)
+#define LINUX_TIOCSSERIAL _LINUX_IO('T', 31)
+#define LINUX_TIOCPKT _LINUX_IO('T', 32)
+#define LINUX_FIONBIO _LINUX_IO('T', 33)
+#define LINUX_TIOCNOTTY _LINUX_IO('T', 34)
+#define LINUX_TIOCSETD _LINUX_IO('T', 35)
+#define LINUX_TIOCGETD _LINUX_IO('T', 36)
+#define LINUX_TCSBRKP _LINUX_IO('T', 37)
+#define LINUX_TIOCTTYGSTRUCT _LINUX_IO('T', 38)
+
+#define LINUX_FIONCLEX _LINUX_IO('T', 80)
+#define LINUX_FIOCLEX _LINUX_IO('T', 81)
+#define LINUX_FIOASYNC _LINUX_IO('T', 82)
+#define LINUX_TIOCSERCONFIG _LINUX_IO('T', 83)
+#define LINUX_TIOCSERGWILD _LINUX_IO('T', 84)
+#define LINUX_TIOCSERSWILD _LINUX_IO('T', 85)
+#define LINUX_TIOCGLCKTRMIOS _LINUX_IO('T', 86)
+#define LINUX_TIOCSLCKTRMIOS _LINUX_IO('T', 87)
+#define LINUX_TIOCSERGSTRUCT _LINUX_IO('T', 88)
+#define LINUX_TIOCSERGETLSR _LINUX_IO('T', 89)
+
+
+#define LINUX_NCC 8
+struct linux_termio {
+ unsigned short c_iflag;
+ unsigned short c_oflag;
+ unsigned short c_cflag;
+ unsigned short c_lflag;
+ unsigned char c_line;
+ unsigned char c_cc[LINUX_NCC];
+};
+
+typedef unsigned char linux_cc_t;
+typedef unsigned long linux_tcflag_t;
+
+#define LINUX_NCCS 19
+struct linux_termios {
+ linux_tcflag_t c_iflag;
+ linux_tcflag_t c_oflag;
+ linux_tcflag_t c_cflag;
+ linux_tcflag_t c_lflag;
+ linux_cc_t c_line;
+ linux_cc_t c_cc[LINUX_NCCS];
+};
+
+/* Just in old style linux_termio struct */
+#define LINUX_VINTR 0
+#define LINUX_VQUIT 1
+#define LINUX_VERASE 2
+#define LINUX_VKILL 3
+#define LINUX_VEOF 4
+#define LINUX_VTIME 5
+#define LINUX_VMIN 6
+#define LINUX_VSWTC 7
+
+/* In the termios struct too */
+#define LINUX_VSTART 8
+#define LINUX_VSTOP 9
+#define LINUX_VSUSP 10
+#define LINUX_VEOL 11
+#define LINUX_VREPRINT 12
+#define LINUX_VDISCARD 13
+#define LINUX_VWERASE 14
+#define LINUX_VLNEXT 15
+#define LINUX_VEOL2 16
+
+/* Linux c_iflag masks */
+#define LINUX_IGNBRK 0x0000001
+#define LINUX_BRKINT 0x0000002
+#define LINUX_IGNPAR 0x0000004
+#define LINUX_PARMRK 0x0000008
+#define LINUX_INPCK 0x0000010
+#define LINUX_ISTRIP 0x0000020
+#define LINUX_INLCR 0x0000040
+#define LINUX_IGNCR 0x0000080
+#define LINUX_ICRNL 0x0000100
+#define LINUX_IUCLC 0x0000200
+#define LINUX_IXON 0x0000400
+#define LINUX_IXANY 0x0000800
+#define LINUX_IXOFF 0x0001000
+#define LINUX_IMAXBEL 0x0002000
+
+/* Linux c_oflag masks */
+#define LINUX_OPOST 0x0000001
+#define LINUX_OLCUC 0x0000002
+#define LINUX_ONLCR 0x0000004
+#define LINUX_OCRNL 0x0000008
+#define LINUX_ONOCR 0x0000010
+#define LINUX_ONLRET 0x0000020
+#define LINUX_OFILL 0x0000040
+#define LINUX_OFDEL 0x0000080
+#define LINUX_NLDLY 0x0000100
+
+#define LINUX_NL0 0x0000000
+#define LINUX_NL1 0x0000100
+#define LINUX_CRDLY 0x0000600
+#define LINUX_CR0 0x0000000
+#define LINUX_CR1 0x0000200
+#define LINUX_CR2 0x0000400
+#define LINUX_CR3 0x0000600
+#define LINUX_TABDLY 0x0001800
+#define LINUX_TAB0 0x0000000
+#define LINUX_TAB1 0x0000800
+#define LINUX_TAB2 0x0001000
+#define LINUX_TAB3 0x0001800
+#define LINUX_XTABS 0x0001800
+#define LINUX_BSDLY 0x0002000
+#define LINUX_BS0 0x0000000
+#define LINUX_BS1 0x0002000
+#define LINUX_VTDLY 0x0004000
+#define LINUX_VT0 0x0000000
+#define LINUX_VT1 0x0004000
+#define LINUX_FFDLY 0x0008000
+#define LINUX_FF0 0x0000000
+#define LINUX_FF1 0x0008000
+
+/* Linux c_cflag bit masks */
+
+#define LINUX_NSPEEDS 16
+#define LINUX_NXSPEEDS 2
+
+#define LINUX_CBAUD 0x0000100f
+
+#define LINUX_B0 0x00000000
+#define LINUX_B50 0x00000001
+#define LINUX_B75 0x00000002
+#define LINUX_B110 0x00000003
+#define LINUX_B134 0x00000004
+#define LINUX_B150 0x00000005
+#define LINUX_B200 0x00000006
+#define LINUX_B300 0x00000007
+#define LINUX_B600 0x00000008
+#define LINUX_B1200 0x00000009
+#define LINUX_B1800 0x0000000a
+#define LINUX_B2400 0x0000000b
+#define LINUX_B4800 0x0000000c
+#define LINUX_B9600 0x0000000d
+#define LINUX_B19200 0x0000000e
+#define LINUX_B38400 0x0000000f
+#define LINUX_EXTA LINUX_B19200
+#define LINUX_EXTB LINUX_B38400
+#define LINUX_CBAUDEX 0x00001000
+#define LINUX_B57600 0x00001001
+#define LINUX_B115200 0x00001002
+#define LINUX_B230400 0x00001003
+
+#define LINUX_CSIZE 0x00000030
+#define LINUX_CS5 0x00000000
+#define LINUX_CS6 0x00000010
+#define LINUX_CS7 0x00000020
+#define LINUX_CS8 0x00000030
+#define LINUX_CSTOPB 0x00000040
+#define LINUX_CREAD 0x00000080
+#define LINUX_PARENB 0x00000100
+#define LINUX_PARODD 0x00000200
+#define LINUX_HUPCL 0x00000400
+#define LINUX_CLOCAL 0x00000800
+
+#define LINUX_CRTSCTS 0x80000000
+
+/* Linux c_lflag masks */
+#define LINUX_ISIG 0x00000001
+#define LINUX_ICANON 0x00000002
+#define LINUX_XCASE 0x00000004
+#define LINUX_ECHO 0x00000008
+#define LINUX_ECHOE 0x00000010
+#define LINUX_ECHOK 0x00000020
+#define LINUX_ECHONL 0x00000040
+#define LINUX_NOFLSH 0x00000080
+#define LINUX_TOSTOP 0x00000100
+#define LINUX_ECHOCTL 0x00000200
+#define LINUX_ECHOPRT 0x00000400
+#define LINUX_ECHOKE 0x00000800
+#define LINUX_FLUSHO 0x00001000
+#define LINUX_PENDIN 0x00002000
+#define LINUX_IEXTEN 0x00008000
+
+/* Linux modem line defines.. not sure if they'll be used */
+#define LINUX_TIOCM_LE 0x0001
+#define LINUX_TIOCM_DTR 0x0002
+#define LINUX_TIOCM_RTS 0x0004
+#define LINUX_TIOCM_ST 0x0008
+#define LINUX_TIOCM_SR 0x0010
+#define LINUX_TIOCM_CTS 0x0020
+#define LINUX_TIOCM_CAR 0x0040
+#define LINUX_TIOCM_RNG 0x0080
+#define LINUX_TIOCM_DSR 0x0100
+#define LINUX_TIOCM_CD LINUX_TIOCM_CAR
+#define LINUX_TIOCM_RI LINUX_TIOCM_RNG
+
+#define LINUX_TCIFLUSH 0
+#define LINUX_TCOFLUSH 1
+#define LINUX_TCIOFLUSH 2
+
+#define LINUX_TCOOFF 0
+#define LINUX_TCOON 1
+#define LINUX_TCIOFF 2
+#define LINUX_TCION 3
+
+#define LINUX_TCSANOW 0
+#define LINUX_TCSADRAIN 1
+#define LINUX_TCSAFLUSH 2
+
+/* Linux line disciplines */
+#define LINUX_N_TTY 0
+#define LINUX_N_SLIP 1
+#define LINUX_N_MOUSE 2
+#define LINUX_N_PPP 3
diff --git a/sys/lib/libkern/arch/i386/Makefile.inc b/sys/lib/libkern/arch/i386/Makefile.inc
index 533df315a66..cbeec30a509 100644
--- a/sys/lib/libkern/arch/i386/Makefile.inc
+++ b/sys/lib/libkern/arch/i386/Makefile.inc
@@ -1,5 +1,5 @@
# $NetBSD: Makefile.inc,v 1.7 1995/10/07 09:52:48 mycroft Exp $
SRCS+= __main.c imax.c imin.c lmax.c lmin.c max.c min.c ulmax.c ulmin.c \
- bcmp.S ffs.S strcat.S strcmp.S strcpy.S strlen.S strncmp.c \
+ bcmp.S ffs.S memset.S strcat.S strcmp.S strcpy.S strlen.S strncmp.c \
strncpy.c scanc.S skpc.S locc.S htonl.S htons.S ntohl.S ntohs.S
diff --git a/sys/lib/libkern/arch/i386/memset.S b/sys/lib/libkern/arch/i386/memset.S
new file mode 100644
index 00000000000..da90db37568
--- /dev/null
+++ b/sys/lib/libkern/arch/i386/memset.S
@@ -0,0 +1,58 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <machine/asm.h>
+
+#if defined(LIBC_SCCS)
+ RCSID("$NetBSD: memset.S,v 1.8 1995/04/28 22:58:05 jtc Exp $")
+#endif
+
+ENTRY(memset)
+ pushl %edi
+ pushl %ebx
+ movl 12(%esp),%edi
+ movzbl 16(%esp),%eax /* unsigned char, zero extend */
+ movl 20(%esp),%ecx
+ pushl %edi /* push address of buffer */
+
+ cld /* set fill direction forward */
+
+ /*
+ * if the string is too short, it's really not worth the overhead
+ * of aligning to word boundries, etc. So we jump to a plain
+ * unaligned set.
+ */
+ cmpl $0x0f,%ecx
+ jle L1
+
+ movb %al,%ah /* copy char to all bytes in word */
+ movl %eax,%edx
+ sall $16,%eax
+ orl %edx,%eax
+
+ movl %edi,%edx /* compute misalignment */
+ negl %edx
+ andl $3,%edx
+ movl %ecx,%ebx
+ subl %edx,%ebx
+
+ movl %edx,%ecx /* set until word aligned */
+ rep
+ stosb
+
+ movl %ebx,%ecx
+ shrl $2,%ecx /* set by words */
+ rep
+ stosl
+
+ movl %ebx,%ecx /* set remainder by bytes */
+ andl $3,%ecx
+L1: rep
+ stosb
+
+ popl %eax /* pop address of buffer */
+ popl %ebx
+ popl %edi
+ ret