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