ibcs2_ioctl.c revision 280258
1/*	$NetBSD: ibcs2_ioctl.c,v 1.6 1995/03/14 15:12:28 scottb Exp $	*/
2
3/*-
4 * Copyright (c) 1994, 1995 Scott Bartram
5 * All rights reserved.
6 *
7 * based on compat/sunos/sun_ioctl.c
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: stable/10/sys/i386/ibcs2/ibcs2_ioctl.c 280258 2015-03-19 13:37:36Z rwatson $");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/capsicum.h>
35#include <sys/consio.h>
36#include <sys/fcntl.h>
37#include <sys/file.h>
38#include <sys/filedesc.h>
39#include <sys/filio.h>
40#include <sys/kbio.h>
41#include <sys/lock.h>
42#include <sys/mutex.h>
43#include <sys/sysproto.h>
44#include <sys/tty.h>
45
46#include <i386/ibcs2/ibcs2_signal.h>
47#include <i386/ibcs2/ibcs2_socksys.h>
48#include <i386/ibcs2/ibcs2_stropts.h>
49#include <i386/ibcs2/ibcs2_proto.h>
50#include <i386/ibcs2/ibcs2_termios.h>
51#include <i386/ibcs2/ibcs2_util.h>
52#include <i386/ibcs2/ibcs2_ioctl.h>
53
54static void stios2btios(struct ibcs2_termios *, struct termios *);
55static void btios2stios(struct termios *, struct ibcs2_termios *);
56static void stios2stio(struct ibcs2_termios *, struct ibcs2_termio *);
57static void stio2stios(struct ibcs2_termio *, struct ibcs2_termios *);
58
59/*
60 * iBCS2 ioctl calls.
61 */
62
63struct speedtab {
64	int sp_speed;			/* Speed. */
65	int sp_code;			/* Code. */
66};
67
68static struct speedtab sptab[] = {
69	{ 0, 0 },
70	{ 50, 1 },
71	{ 75, 2 },
72	{ 110, 3 },
73	{ 134, 4 },
74	{ 135, 4 },
75	{ 150, 5 },
76	{ 200, 6 },
77	{ 300, 7 },
78	{ 600, 8 },
79	{ 1200, 9 },
80	{ 1800, 10 },
81	{ 2400, 11 },
82	{ 4800, 12 },
83	{ 9600, 13 },
84	{ 19200, 14 },
85	{ 38400, 15 },
86	{ -1, -1 }
87};
88
89static u_long s2btab[] = {
90	0,
91	50,
92	75,
93	110,
94	134,
95	150,
96	200,
97	300,
98	600,
99	1200,
100	1800,
101	2400,
102	4800,
103	9600,
104	19200,
105	38400,
106};
107
108static int
109ttspeedtab(int speed, struct speedtab *table)
110{
111
112	for ( ; table->sp_speed != -1; table++)
113		if (table->sp_speed == speed)
114			return (table->sp_code);
115	return (-1);
116}
117
118static void
119stios2btios(st, bt)
120	struct ibcs2_termios *st;
121	struct termios *bt;
122{
123	register u_long l, r;
124
125	l = st->c_iflag;	r = 0;
126	if (l & IBCS2_IGNBRK)	r |= IGNBRK;
127	if (l & IBCS2_BRKINT)	r |= BRKINT;
128	if (l & IBCS2_IGNPAR)	r |= IGNPAR;
129	if (l & IBCS2_PARMRK)	r |= PARMRK;
130	if (l & IBCS2_INPCK)	r |= INPCK;
131	if (l & IBCS2_ISTRIP)	r |= ISTRIP;
132	if (l & IBCS2_INLCR)	r |= INLCR;
133	if (l & IBCS2_IGNCR)	r |= IGNCR;
134	if (l & IBCS2_ICRNL)	r |= ICRNL;
135	if (l & IBCS2_IXON)	r |= IXON;
136	if (l & IBCS2_IXANY)	r |= IXANY;
137	if (l & IBCS2_IXOFF)	r |= IXOFF;
138	if (l & IBCS2_IMAXBEL)	r |= IMAXBEL;
139	bt->c_iflag = r;
140
141	l = st->c_oflag;	r = 0;
142	if (l & IBCS2_OPOST)	r |= OPOST;
143	if (l & IBCS2_ONLCR)	r |= ONLCR;
144	if (l & IBCS2_TAB3)	r |= TAB3;
145	bt->c_oflag = r;
146
147	l = st->c_cflag;	r = 0;
148	switch (l & IBCS2_CSIZE) {
149	case IBCS2_CS5:		r |= CS5; break;
150	case IBCS2_CS6:		r |= CS6; break;
151	case IBCS2_CS7:		r |= CS7; break;
152	case IBCS2_CS8:		r |= CS8; break;
153	}
154	if (l & IBCS2_CSTOPB)	r |= CSTOPB;
155	if (l & IBCS2_CREAD)	r |= CREAD;
156	if (l & IBCS2_PARENB)	r |= PARENB;
157	if (l & IBCS2_PARODD)	r |= PARODD;
158	if (l & IBCS2_HUPCL)	r |= HUPCL;
159	if (l & IBCS2_CLOCAL)	r |= CLOCAL;
160	bt->c_cflag = r;
161
162	bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
163
164	l = st->c_lflag;	r = 0;
165	if (l & IBCS2_ISIG)	r |= ISIG;
166	if (l & IBCS2_ICANON)	r |= ICANON;
167	if (l & IBCS2_ECHO)	r |= ECHO;
168	if (l & IBCS2_ECHOE)	r |= ECHOE;
169	if (l & IBCS2_ECHOK)	r |= ECHOK;
170	if (l & IBCS2_ECHONL)	r |= ECHONL;
171	if (l & IBCS2_NOFLSH)	r |= NOFLSH;
172	if (l & IBCS2_TOSTOP)	r |= TOSTOP;
173	bt->c_lflag = r;
174
175	bt->c_cc[VINTR]	=
176	    st->c_cc[IBCS2_VINTR]  ? st->c_cc[IBCS2_VINTR]  : _POSIX_VDISABLE;
177	bt->c_cc[VQUIT] =
178	    st->c_cc[IBCS2_VQUIT]  ? st->c_cc[IBCS2_VQUIT]  : _POSIX_VDISABLE;
179	bt->c_cc[VERASE] =
180	    st->c_cc[IBCS2_VERASE] ? st->c_cc[IBCS2_VERASE] : _POSIX_VDISABLE;
181	bt->c_cc[VKILL] =
182	    st->c_cc[IBCS2_VKILL]  ? st->c_cc[IBCS2_VKILL]  : _POSIX_VDISABLE;
183	if (bt->c_lflag & ICANON) {
184		bt->c_cc[VEOF] =
185		    st->c_cc[IBCS2_VEOF] ? st->c_cc[IBCS2_VEOF] : _POSIX_VDISABLE;
186		bt->c_cc[VEOL] =
187		    st->c_cc[IBCS2_VEOL] ? st->c_cc[IBCS2_VEOL] : _POSIX_VDISABLE;
188	} else {
189		bt->c_cc[VMIN]  = st->c_cc[IBCS2_VMIN];
190		bt->c_cc[VTIME] = st->c_cc[IBCS2_VTIME];
191	}
192	bt->c_cc[VEOL2] =
193	    st->c_cc[IBCS2_VEOL2]  ? st->c_cc[IBCS2_VEOL2]  : _POSIX_VDISABLE;
194#if 0
195	bt->c_cc[VSWTCH] =
196	    st->c_cc[IBCS2_VSWTCH] ? st->c_cc[IBCS2_VSWTCH] : _POSIX_VDISABLE;
197#endif
198	bt->c_cc[VSTART] =
199	    st->c_cc[IBCS2_VSTART] ? st->c_cc[IBCS2_VSTART] : _POSIX_VDISABLE;
200	bt->c_cc[VSTOP] =
201	    st->c_cc[IBCS2_VSTOP]  ? st->c_cc[IBCS2_VSTOP]  : _POSIX_VDISABLE;
202	bt->c_cc[VSUSP] =
203	    st->c_cc[IBCS2_VSUSP]  ? st->c_cc[IBCS2_VSUSP]  : _POSIX_VDISABLE;
204	bt->c_cc[VDSUSP]   = _POSIX_VDISABLE;
205	bt->c_cc[VREPRINT] = _POSIX_VDISABLE;
206	bt->c_cc[VDISCARD] = _POSIX_VDISABLE;
207	bt->c_cc[VWERASE]  = _POSIX_VDISABLE;
208	bt->c_cc[VLNEXT]   = _POSIX_VDISABLE;
209	bt->c_cc[VSTATUS]  = _POSIX_VDISABLE;
210}
211
212static void
213btios2stios(bt, st)
214	struct termios *bt;
215	struct ibcs2_termios *st;
216{
217	register u_long l, r;
218
219	l = bt->c_iflag;	r = 0;
220	if (l & IGNBRK)		r |= IBCS2_IGNBRK;
221	if (l & BRKINT)		r |= IBCS2_BRKINT;
222	if (l & IGNPAR)		r |= IBCS2_IGNPAR;
223	if (l & PARMRK)		r |= IBCS2_PARMRK;
224	if (l & INPCK)		r |= IBCS2_INPCK;
225	if (l & ISTRIP)		r |= IBCS2_ISTRIP;
226	if (l & INLCR)		r |= IBCS2_INLCR;
227	if (l & IGNCR)		r |= IBCS2_IGNCR;
228	if (l & ICRNL)		r |= IBCS2_ICRNL;
229	if (l & IXON)		r |= IBCS2_IXON;
230	if (l & IXANY)		r |= IBCS2_IXANY;
231	if (l & IXOFF)		r |= IBCS2_IXOFF;
232	if (l & IMAXBEL)	r |= IBCS2_IMAXBEL;
233	st->c_iflag = r;
234
235	l = bt->c_oflag;	r = 0;
236	if (l & OPOST)		r |= IBCS2_OPOST;
237	if (l & ONLCR)		r |= IBCS2_ONLCR;
238	if (l & TAB3)		r |= IBCS2_TAB3;
239	st->c_oflag = r;
240
241	l = bt->c_cflag;	r = 0;
242	switch (l & CSIZE) {
243	case CS5:		r |= IBCS2_CS5; break;
244	case CS6:		r |= IBCS2_CS6; break;
245	case CS7:		r |= IBCS2_CS7; break;
246	case CS8:		r |= IBCS2_CS8; break;
247	}
248	if (l & CSTOPB)		r |= IBCS2_CSTOPB;
249	if (l & CREAD)		r |= IBCS2_CREAD;
250	if (l & PARENB)		r |= IBCS2_PARENB;
251	if (l & PARODD)		r |= IBCS2_PARODD;
252	if (l & HUPCL)		r |= IBCS2_HUPCL;
253	if (l & CLOCAL)		r |= IBCS2_CLOCAL;
254	st->c_cflag = r;
255
256	l = bt->c_lflag;	r = 0;
257	if (l & ISIG)		r |= IBCS2_ISIG;
258	if (l & ICANON)		r |= IBCS2_ICANON;
259	if (l & ECHO)		r |= IBCS2_ECHO;
260	if (l & ECHOE)		r |= IBCS2_ECHOE;
261	if (l & ECHOK)		r |= IBCS2_ECHOK;
262	if (l & ECHONL)		r |= IBCS2_ECHONL;
263	if (l & NOFLSH)		r |= IBCS2_NOFLSH;
264	if (l & TOSTOP)		r |= IBCS2_TOSTOP;
265	st->c_lflag = r;
266
267	l = ttspeedtab(bt->c_ospeed, sptab);
268	if ((int)l >= 0)
269		st->c_cflag |= l;
270
271	st->c_cc[IBCS2_VINTR] =
272	    bt->c_cc[VINTR]  != _POSIX_VDISABLE ? bt->c_cc[VINTR]  : 0;
273	st->c_cc[IBCS2_VQUIT] =
274	    bt->c_cc[VQUIT]  != _POSIX_VDISABLE ? bt->c_cc[VQUIT]  : 0;
275	st->c_cc[IBCS2_VERASE] =
276	    bt->c_cc[VERASE] != _POSIX_VDISABLE ? bt->c_cc[VERASE] : 0;
277	st->c_cc[IBCS2_VKILL] =
278	    bt->c_cc[VKILL]  != _POSIX_VDISABLE ? bt->c_cc[VKILL]  : 0;
279	if (bt->c_lflag & ICANON) {
280		st->c_cc[IBCS2_VEOF] =
281		    bt->c_cc[VEOF] != _POSIX_VDISABLE ? bt->c_cc[VEOF] : 0;
282		st->c_cc[IBCS2_VEOL] =
283		    bt->c_cc[VEOL] != _POSIX_VDISABLE ? bt->c_cc[VEOL] : 0;
284	} else {
285		st->c_cc[IBCS2_VMIN]  = bt->c_cc[VMIN];
286		st->c_cc[IBCS2_VTIME] = bt->c_cc[VTIME];
287	}
288	st->c_cc[IBCS2_VEOL2] =
289	    bt->c_cc[VEOL2]  != _POSIX_VDISABLE ? bt->c_cc[VEOL2]  : 0;
290	st->c_cc[IBCS2_VSWTCH] =
291	    0;
292	st->c_cc[IBCS2_VSUSP] =
293	    bt->c_cc[VSUSP]  != _POSIX_VDISABLE ? bt->c_cc[VSUSP]  : 0;
294	st->c_cc[IBCS2_VSTART] =
295	    bt->c_cc[VSTART] != _POSIX_VDISABLE ? bt->c_cc[VSTART] : 0;
296	st->c_cc[IBCS2_VSTOP] =
297	    bt->c_cc[VSTOP]  != _POSIX_VDISABLE ? bt->c_cc[VSTOP]  : 0;
298
299	st->c_line = 0;
300}
301
302static void
303stios2stio(ts, t)
304	struct ibcs2_termios *ts;
305	struct ibcs2_termio *t;
306{
307	t->c_iflag = ts->c_iflag;
308	t->c_oflag = ts->c_oflag;
309	t->c_cflag = ts->c_cflag;
310	t->c_lflag = ts->c_lflag;
311	t->c_line  = ts->c_line;
312	bcopy(ts->c_cc, t->c_cc, IBCS2_NCC);
313}
314
315static void
316stio2stios(t, ts)
317	struct ibcs2_termio *t;
318	struct ibcs2_termios *ts;
319{
320	ts->c_iflag = t->c_iflag;
321	ts->c_oflag = t->c_oflag;
322	ts->c_cflag = t->c_cflag;
323	ts->c_lflag = t->c_lflag;
324	ts->c_line  = t->c_line;
325	bcopy(t->c_cc, ts->c_cc, IBCS2_NCC);
326}
327
328int
329ibcs2_ioctl(td, uap)
330	struct thread *td;
331	struct ibcs2_ioctl_args *uap;
332{
333	struct proc *p = td->td_proc;
334	cap_rights_t rights;
335	struct file *fp;
336	int error;
337
338	error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp);
339	if (error != 0) {
340		DPRINTF(("ibcs2_ioctl(%d): bad fd %d ", p->p_pid,
341			 uap->fd));
342		return EBADF;
343	}
344
345	if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
346		fdrop(fp, td);
347		DPRINTF(("ibcs2_ioctl(%d): bad fp flag ", p->p_pid));
348		return EBADF;
349	}
350
351	switch (uap->cmd) {
352	case IBCS2_TCGETA:
353	case IBCS2_XCGETA:
354	case IBCS2_OXCGETA:
355	    {
356		struct termios bts;
357		struct ibcs2_termios sts;
358		struct ibcs2_termio st;
359
360		if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts,
361		    td->td_ucred, td)) != 0)
362			break;
363
364		btios2stios (&bts, &sts);
365		if (uap->cmd == IBCS2_TCGETA) {
366			stios2stio (&sts, &st);
367			error = copyout((caddr_t)&st, uap->data,
368					sizeof (st));
369#ifdef DEBUG_IBCS2
370			if (error)
371				DPRINTF(("ibcs2_ioctl(%d): copyout failed ",
372					 p->p_pid));
373#endif
374			break;
375		} else {
376			error = copyout((caddr_t)&sts, uap->data,
377					sizeof (sts));
378			break;
379		}
380		/*NOTREACHED*/
381	    }
382
383	case IBCS2_TCSETA:
384	case IBCS2_TCSETAW:
385	case IBCS2_TCSETAF:
386	    {
387		struct termios bts;
388		struct ibcs2_termios sts;
389		struct ibcs2_termio st;
390
391		if ((error = copyin(uap->data, (caddr_t)&st,
392				    sizeof(st))) != 0) {
393			DPRINTF(("ibcs2_ioctl(%d): TCSET copyin failed ",
394				 p->p_pid));
395			break;
396		}
397
398		/* get full BSD termios so we don't lose information */
399		if ((error = fo_ioctl(fp, TIOCGETA, (caddr_t)&bts,
400		    td->td_ucred, td)) != 0) {
401			DPRINTF(("ibcs2_ioctl(%d): TCSET ctl failed fd %d ",
402				 p->p_pid, uap->fd));
403			break;
404		}
405
406		/*
407		 * convert to iBCS2 termios, copy in information from
408		 * termio, and convert back, then set new values.
409		 */
410		btios2stios(&bts, &sts);
411		stio2stios(&st, &sts);
412		stios2btios(&sts, &bts);
413
414		error = fo_ioctl(fp, uap->cmd - IBCS2_TCSETA + TIOCSETA,
415			      (caddr_t)&bts, td->td_ucred, td);
416		break;
417	    }
418
419	case IBCS2_XCSETA:
420	case IBCS2_XCSETAW:
421	case IBCS2_XCSETAF:
422	    {
423		struct termios bts;
424		struct ibcs2_termios sts;
425
426		if ((error = copyin(uap->data, (caddr_t)&sts,
427				    sizeof (sts))) != 0)
428			break;
429		stios2btios (&sts, &bts);
430		error = fo_ioctl(fp, uap->cmd - IBCS2_XCSETA + TIOCSETA,
431			      (caddr_t)&bts, td->td_ucred, td);
432		break;
433	    }
434
435	case IBCS2_OXCSETA:
436	case IBCS2_OXCSETAW:
437	case IBCS2_OXCSETAF:
438	    {
439		struct termios bts;
440		struct ibcs2_termios sts;
441
442		if ((error = copyin(uap->data, (caddr_t)&sts,
443				    sizeof (sts))) != 0)
444			break;
445		stios2btios (&sts, &bts);
446		error = fo_ioctl(fp, uap->cmd - IBCS2_OXCSETA + TIOCSETA,
447			      (caddr_t)&bts, td->td_ucred, td);
448		break;
449	    }
450
451	case IBCS2_TCSBRK:
452		DPRINTF(("ibcs2_ioctl(%d): TCSBRK ", p->p_pid));
453		error = ENOSYS;
454		break;
455
456	case IBCS2_TCXONC:
457	    {
458		switch ((int)uap->data) {
459		case 0:
460		case 1:
461			DPRINTF(("ibcs2_ioctl(%d): TCXONC ", p->p_pid));
462			error = ENOSYS;
463			break;
464		case 2:
465			error = fo_ioctl(fp, TIOCSTOP, (caddr_t)0,
466			    td->td_ucred, td);
467			break;
468		case 3:
469			error = fo_ioctl(fp, TIOCSTART, (caddr_t)1,
470			    td->td_ucred, td);
471			break;
472		default:
473			error = EINVAL;
474			break;
475		}
476		break;
477	    }
478
479	case IBCS2_TCFLSH:
480	    {
481		int arg;
482
483		switch ((int)uap->data) {
484		case 0:
485			arg = FREAD;
486			break;
487		case 1:
488			arg = FWRITE;
489			break;
490		case 2:
491			arg = FREAD | FWRITE;
492			break;
493		default:
494			fdrop(fp, td);
495			return EINVAL;
496		}
497		error = fo_ioctl(fp, TIOCFLUSH, (caddr_t)&arg, td->td_ucred,
498		    td);
499		break;
500	    }
501
502	case IBCS2_TIOCGWINSZ:
503		uap->cmd = TIOCGWINSZ;
504		error = sys_ioctl(td, (struct ioctl_args *)uap);
505		break;
506
507	case IBCS2_TIOCSWINSZ:
508		uap->cmd = TIOCSWINSZ;
509		error = sys_ioctl(td, (struct ioctl_args *)uap);
510		break;
511
512	case IBCS2_TIOCGPGRP:
513	    {
514		pid_t	pg_id;
515
516		PROC_LOCK(p);
517		pg_id = p->p_pgrp->pg_id;
518		PROC_UNLOCK(p);
519		error = copyout((caddr_t)&pg_id, uap->data,
520				sizeof(pg_id));
521		break;
522	    }
523
524	case IBCS2_TIOCSPGRP:	/* XXX - is uap->data a pointer to pgid? */
525	    {
526		struct setpgid_args sa;
527
528		sa.pid = 0;
529		sa.pgid = (int)uap->data;
530		error = sys_setpgid(td, &sa);
531		break;
532	    }
533
534	case IBCS2_TCGETSC:	/* SCO console - get scancode flags */
535		error = EINTR;  /* ENOSYS; */
536		break;
537
538	case IBCS2_TCSETSC:	/* SCO console - set scancode flags */
539		error = 0;   /* ENOSYS; */
540		break;
541
542	case IBCS2_JWINSIZE:	/* Unix to Jerq I/O control */
543	    {
544	        struct ibcs2_jwinsize {
545		  char bytex, bytey;
546		  short bitx, bity;
547	        } ibcs2_jwinsize;
548
549		PROC_LOCK(p);
550		SESS_LOCK(p->p_session);
551                ibcs2_jwinsize.bytex = 80;
552	          /* p->p_session->s_ttyp->t_winsize.ws_col; XXX */
553	        ibcs2_jwinsize.bytey = 25;
554                  /* p->p_session->s_ttyp->t_winsize.ws_row; XXX */
555	        ibcs2_jwinsize.bitx =
556		  p->p_session->s_ttyp->t_winsize.ws_xpixel;
557	        ibcs2_jwinsize.bity =
558		  p->p_session->s_ttyp->t_winsize.ws_ypixel;
559		SESS_UNLOCK(p->p_session);
560		PROC_UNLOCK(p);
561	        error = copyout((caddr_t)&ibcs2_jwinsize, uap->data,
562			       sizeof(ibcs2_jwinsize));
563		break;
564	     }
565
566	/* keyboard and display ioctl's -- type 'K' */
567	case IBCS2_KDGKBMODE:        /* get keyboard translation mode */
568	        uap->cmd = KDGKBMODE;
569/* printf("ioctl KDGKBMODE = %x\n", uap->cmd);*/
570	        error = sys_ioctl(td, (struct ioctl_args *)uap);
571		break;
572
573	case IBCS2_KDSKBMODE:        /* set keyboard translation mode */
574	        uap->cmd = KDSKBMODE;
575	        error = sys_ioctl(td, (struct ioctl_args *)uap);
576		break;
577
578	case IBCS2_KDMKTONE:        /* sound tone */
579	        uap->cmd = KDMKTONE;
580	        error = sys_ioctl(td, (struct ioctl_args *)uap);
581		break;
582
583	case IBCS2_KDGETMODE:        /* get text/graphics mode */
584	        uap->cmd = KDGETMODE;
585	        error = sys_ioctl(td, (struct ioctl_args *)uap);
586		break;
587
588	case IBCS2_KDSETMODE:       /* set text/graphics mode */
589	        uap->cmd = KDSETMODE;
590	        error = sys_ioctl(td, (struct ioctl_args *)uap);
591		break;
592
593	case IBCS2_KDSBORDER:       /* set ega color border */
594	        uap->cmd = KDSBORDER;
595	        error = sys_ioctl(td, (struct ioctl_args *)uap);
596		break;
597
598	case IBCS2_KDGKBSTATE:
599	        uap->cmd = KDGKBSTATE;
600	        error = sys_ioctl(td, (struct ioctl_args *)uap);
601		break;
602
603	case IBCS2_KDSETRAD:
604	        uap->cmd = KDSETRAD;
605	        error = sys_ioctl(td, (struct ioctl_args *)uap);
606		break;
607
608	case IBCS2_KDENABIO:       /* enable direct I/O to ports */
609	        uap->cmd = KDENABIO;
610	        error = sys_ioctl(td, (struct ioctl_args *)uap);
611		break;
612
613	case IBCS2_KDDISABIO:       /* disable direct I/O to ports */
614	        uap->cmd = KDDISABIO;
615	        error = sys_ioctl(td, (struct ioctl_args *)uap);
616		break;
617
618	case IBCS2_KIOCSOUND:       /* start sound generation */
619	        uap->cmd = KIOCSOUND;
620	        error = sys_ioctl(td, (struct ioctl_args *)uap);
621		break;
622
623	case IBCS2_KDGKBTYPE:       /* get keyboard type */
624	        uap->cmd = KDGKBTYPE;
625	        error = sys_ioctl(td, (struct ioctl_args *)uap);
626		break;
627
628	case IBCS2_KDGETLED:       /* get keyboard LED status */
629	        uap->cmd = KDGETLED;
630	        error = sys_ioctl(td, (struct ioctl_args *)uap);
631		break;
632
633	case IBCS2_KDSETLED:       /* set keyboard LED status */
634	        uap->cmd = KDSETLED;
635	        error = sys_ioctl(td, (struct ioctl_args *)uap);
636		break;
637
638	    /* Xenix keyboard and display ioctl's from sys/kd.h -- type 'k' */
639	case IBCS2_GETFKEY:      /* Get function key */
640	        uap->cmd = GETFKEY;
641	        error = sys_ioctl(td, (struct ioctl_args *)uap);
642		break;
643
644	case IBCS2_SETFKEY:      /* Set function key */
645	        uap->cmd = SETFKEY;
646	        error = sys_ioctl(td, (struct ioctl_args *)uap);
647		break;
648
649	case IBCS2_GIO_SCRNMAP:      /* Get screen output map table */
650	        uap->cmd = GIO_SCRNMAP;
651	        error = sys_ioctl(td, (struct ioctl_args *)uap);
652		break;
653
654	case IBCS2_PIO_SCRNMAP:      /* Set screen output map table */
655	        uap->cmd = PIO_SCRNMAP;
656	        error = sys_ioctl(td, (struct ioctl_args *)uap);
657		break;
658
659	case IBCS2_GIO_KEYMAP:      /* Get keyboard map table */
660	        uap->cmd = OGIO_KEYMAP;
661	        error = sys_ioctl(td, (struct ioctl_args *)uap);
662		break;
663
664	case IBCS2_PIO_KEYMAP:      /* Set keyboard map table */
665	        uap->cmd = OPIO_KEYMAP;
666	        error = sys_ioctl(td, (struct ioctl_args *)uap);
667		break;
668
669	    /* socksys */
670	case IBCS2_SIOCSOCKSYS:
671		error = ibcs2_socksys(td, (struct ibcs2_socksys_args *)uap);
672		break;
673
674	case IBCS2_FIONREAD:
675	case IBCS2_I_NREAD:     /* STREAMS */
676	        uap->cmd = FIONREAD;
677		error = sys_ioctl(td, (struct ioctl_args *)uap);
678		break;
679
680	default:
681		DPRINTF(("ibcs2_ioctl(%d): unknown cmd 0x%lx ",
682			 td->proc->p_pid, uap->cmd));
683		error = ENOSYS;
684		break;
685	}
686
687	fdrop(fp, td);
688	return error;
689}
690