Home | History | Annotate | Line # | Download | only in wscons
wsdisplay_compat_usl.c revision 1.9.2.1
      1  1.9.2.1   thorpej /* $NetBSD: wsdisplay_compat_usl.c,v 1.9.2.1 1999/10/20 22:56:01 thorpej Exp $ */
      2      1.1  drochner 
      3      1.1  drochner /*
      4      1.1  drochner  * Copyright (c) 1998
      5      1.1  drochner  *	Matthias Drochner.  All rights reserved.
      6      1.1  drochner  *
      7      1.1  drochner  * Redistribution and use in source and binary forms, with or without
      8      1.1  drochner  * modification, are permitted provided that the following conditions
      9      1.1  drochner  * are met:
     10      1.1  drochner  * 1. Redistributions of source code must retain the above copyright
     11      1.1  drochner  *    notice, this list of conditions and the following disclaimer.
     12      1.1  drochner  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1  drochner  *    notice, this list of conditions and the following disclaimer in the
     14      1.1  drochner  *    documentation and/or other materials provided with the distribution.
     15      1.1  drochner  * 3. All advertising materials mentioning features or use of this software
     16      1.1  drochner  *    must display the following acknowledgement:
     17      1.1  drochner  *	This product includes software developed for the NetBSD Project
     18      1.1  drochner  *	by Matthias Drochner.
     19      1.1  drochner  * 4. The name of the author may not be used to endorse or promote products
     20      1.1  drochner  *    derived from this software without specific prior written permission.
     21      1.1  drochner  *
     22      1.1  drochner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23      1.1  drochner  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24      1.1  drochner  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25      1.1  drochner  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26      1.1  drochner  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27      1.1  drochner  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28      1.1  drochner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29      1.1  drochner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30      1.1  drochner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31      1.1  drochner  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32      1.1  drochner  *
     33      1.1  drochner  */
     34      1.4   thorpej 
     35      1.4   thorpej #include "opt_compat_freebsd.h"
     36      1.5  jonathan #include "opt_compat_netbsd.h"
     37      1.1  drochner 
     38      1.1  drochner #include <sys/param.h>
     39      1.1  drochner #include <sys/systm.h>
     40      1.1  drochner #include <sys/ioctl.h>
     41      1.1  drochner #include <sys/kernel.h>
     42      1.1  drochner #include <sys/proc.h>
     43      1.1  drochner #include <sys/signalvar.h>
     44      1.1  drochner #include <sys/malloc.h>
     45      1.1  drochner #include <sys/errno.h>
     46      1.1  drochner 
     47      1.1  drochner #include <dev/wscons/wsconsio.h>
     48      1.1  drochner #include <dev/wscons/wsdisplayvar.h>
     49      1.1  drochner #include <dev/wscons/wscons_callbacks.h>
     50      1.1  drochner #include <dev/wscons/wsdisplay_usl_io.h>
     51      1.1  drochner 
     52      1.1  drochner #include "opt_wsdisplay_compat.h"
     53      1.1  drochner 
     54      1.1  drochner struct usl_syncdata {
     55      1.1  drochner 	struct wsscreen *s_scr;
     56      1.1  drochner 	struct proc *s_proc;
     57      1.1  drochner 	pid_t s_pid;
     58      1.1  drochner 	int s_flags;
     59      1.1  drochner #define SF_DETACHPENDING 1
     60      1.1  drochner #define SF_ATTACHPENDING 2
     61      1.1  drochner 	int s_acqsig, s_relsig;
     62      1.1  drochner 	int s_frsig; /* unused */
     63      1.6  drochner 	void (*s_callback) __P((void *, int, int));
     64      1.1  drochner 	void *s_cbarg;
     65      1.1  drochner };
     66      1.1  drochner 
     67      1.3  drochner static int usl_sync_init __P((struct wsscreen *, struct usl_syncdata **,
     68      1.3  drochner 			      struct proc *, int, int, int));
     69      1.1  drochner static void usl_sync_done __P((struct usl_syncdata *));
     70      1.1  drochner static int usl_sync_check __P((struct usl_syncdata *));
     71      1.1  drochner static struct usl_syncdata *usl_sync_get __P((struct wsscreen *));
     72      1.1  drochner 
     73      1.6  drochner static int usl_detachproc __P((void *, int,
     74      1.6  drochner 			       void (*)(void *, int, int), void *));
     75      1.1  drochner static int usl_detachack __P((struct usl_syncdata *, int));
     76      1.1  drochner static void usl_detachtimeout __P((void *));
     77      1.6  drochner static int usl_attachproc __P((void *, int,
     78      1.6  drochner 			       void (*)(void *, int, int), void *));
     79      1.1  drochner static int usl_attachack __P((struct usl_syncdata *, int));
     80      1.1  drochner static void usl_attachtimeout __P((void *));
     81      1.1  drochner 
     82      1.1  drochner static const struct wscons_syncops usl_syncops = {
     83      1.1  drochner 	usl_detachproc,
     84      1.1  drochner 	usl_attachproc,
     85      1.1  drochner #define _usl_sync_check ((int (*) __P((void *)))usl_sync_check)
     86      1.1  drochner 	_usl_sync_check,
     87      1.1  drochner #define _usl_sync_destroy ((void (*) __P((void *)))usl_sync_done)
     88      1.1  drochner 	_usl_sync_destroy
     89      1.1  drochner };
     90      1.1  drochner 
     91      1.7  drochner #ifndef WSCOMPAT_USL_SYNCTIMEOUT
     92      1.7  drochner #define WSCOMPAT_USL_SYNCTIMEOUT 5 /* seconds */
     93      1.7  drochner #endif
     94      1.7  drochner static int wscompat_usl_synctimeout = WSCOMPAT_USL_SYNCTIMEOUT;
     95      1.7  drochner 
     96      1.1  drochner static int
     97      1.3  drochner usl_sync_init(scr, sdp, p, acqsig, relsig, frsig)
     98      1.1  drochner 	struct wsscreen *scr;
     99      1.1  drochner 	struct usl_syncdata **sdp;
    100      1.3  drochner 	struct proc *p;
    101      1.3  drochner 	int acqsig, relsig, frsig;
    102      1.1  drochner {
    103      1.1  drochner 	struct usl_syncdata *sd;
    104      1.1  drochner 	int res;
    105      1.1  drochner 
    106      1.1  drochner 	sd = malloc(sizeof(struct usl_syncdata), M_DEVBUF, M_WAITOK);
    107      1.1  drochner 	if (!sd)
    108      1.1  drochner 		return (ENOMEM);
    109      1.1  drochner 	sd->s_scr = scr;
    110      1.3  drochner 	sd->s_proc = p;
    111      1.3  drochner 	sd->s_pid = p->p_pid;
    112      1.2  drochner 	sd->s_flags = 0;
    113      1.3  drochner 	sd->s_acqsig = acqsig;
    114      1.3  drochner 	sd->s_relsig = relsig;
    115      1.3  drochner 	sd->s_frsig = frsig;
    116      1.1  drochner 	res = wsscreen_attach_sync(scr, &usl_syncops, sd);
    117      1.1  drochner 	if (res) {
    118      1.1  drochner 		free(sd, M_DEVBUF);
    119      1.1  drochner 		return (res);
    120      1.1  drochner 	}
    121      1.1  drochner 	*sdp = sd;
    122      1.1  drochner 	return (0);
    123      1.1  drochner }
    124      1.1  drochner 
    125      1.1  drochner static void
    126      1.1  drochner usl_sync_done(sd)
    127      1.1  drochner 	struct usl_syncdata *sd;
    128      1.1  drochner {
    129      1.2  drochner 	if (sd->s_flags & SF_DETACHPENDING) {
    130      1.2  drochner 		untimeout(usl_detachtimeout, sd);
    131      1.6  drochner 		(*sd->s_callback)(sd->s_cbarg, 0, 0);
    132      1.2  drochner 	}
    133      1.6  drochner 	if (sd->s_flags & SF_ATTACHPENDING) {
    134      1.2  drochner 		untimeout(usl_attachtimeout, sd);
    135      1.6  drochner 		(*sd->s_callback)(sd->s_cbarg, ENXIO, 0);
    136      1.6  drochner 	}
    137      1.1  drochner 	wsscreen_detach_sync(sd->s_scr);
    138      1.1  drochner 	free(sd, M_DEVBUF);
    139      1.1  drochner }
    140      1.1  drochner 
    141      1.1  drochner static int
    142      1.1  drochner usl_sync_check(sd)
    143      1.1  drochner 	struct usl_syncdata *sd;
    144      1.1  drochner {
    145      1.1  drochner 	if (sd->s_proc == pfind(sd->s_pid))
    146      1.1  drochner 		return (1);
    147      1.1  drochner 	printf("usl_sync_check: process %d died\n", sd->s_pid);
    148      1.1  drochner 	usl_sync_done(sd);
    149      1.1  drochner 	return (0);
    150      1.1  drochner }
    151      1.1  drochner 
    152      1.1  drochner static struct usl_syncdata *
    153      1.1  drochner usl_sync_get(scr)
    154      1.1  drochner 	struct wsscreen *scr;
    155      1.1  drochner {
    156      1.1  drochner 	struct usl_syncdata *sd;
    157      1.1  drochner 
    158      1.1  drochner 	if (wsscreen_lookup_sync(scr, &usl_syncops, (void **)&sd))
    159      1.1  drochner 		return (0);
    160      1.1  drochner 	return (sd);
    161      1.1  drochner }
    162      1.1  drochner 
    163      1.1  drochner static int
    164      1.1  drochner usl_detachproc(cookie, waitok, callback, cbarg)
    165      1.1  drochner 	void *cookie;
    166      1.1  drochner 	int waitok;
    167      1.6  drochner 	void (*callback) __P((void *, int, int));
    168      1.1  drochner 	void *cbarg;
    169      1.1  drochner {
    170      1.1  drochner 	struct usl_syncdata *sd = cookie;
    171      1.1  drochner 
    172      1.1  drochner 	if (!usl_sync_check(sd))
    173      1.1  drochner 		return (0);
    174      1.1  drochner 
    175      1.1  drochner 	/*
    176      1.1  drochner 	 * Normally, this is called from the controlling process.
    177      1.1  drochner 	 * Is is supposed to reply with a VT_RELDISP ioctl(), so
    178      1.1  drochner 	 * it is not useful to tsleep() here.
    179      1.1  drochner 	 */
    180      1.1  drochner 	sd->s_callback = callback;
    181      1.1  drochner 	sd->s_cbarg = cbarg;
    182      1.1  drochner 	sd->s_flags |= SF_DETACHPENDING;
    183      1.1  drochner 	psignal(sd->s_proc, sd->s_relsig);
    184      1.7  drochner 	timeout(usl_detachtimeout, sd, wscompat_usl_synctimeout * hz);
    185      1.1  drochner 
    186      1.1  drochner 	return (EAGAIN);
    187      1.1  drochner }
    188      1.1  drochner 
    189      1.1  drochner static int
    190      1.1  drochner usl_detachack(sd, ack)
    191      1.1  drochner 	struct usl_syncdata *sd;
    192      1.1  drochner 	int ack;
    193      1.1  drochner {
    194      1.1  drochner 	if (!(sd->s_flags & SF_DETACHPENDING)) {
    195      1.1  drochner 		printf("usl_detachack: not detaching\n");
    196      1.1  drochner 		return (EINVAL);
    197      1.1  drochner 	}
    198      1.1  drochner 
    199      1.1  drochner 	untimeout(usl_detachtimeout, sd);
    200      1.1  drochner 	sd->s_flags &= ~SF_DETACHPENDING;
    201      1.1  drochner 
    202      1.6  drochner 	if (sd->s_callback)
    203      1.6  drochner 		(*sd->s_callback)(sd->s_cbarg, (ack ? 0 : EIO), 1);
    204      1.1  drochner 
    205      1.1  drochner 	return (0);
    206      1.1  drochner }
    207      1.1  drochner 
    208      1.1  drochner static void
    209      1.1  drochner usl_detachtimeout(arg)
    210      1.1  drochner 	void *arg;
    211      1.1  drochner {
    212      1.1  drochner 	struct usl_syncdata *sd = arg;
    213      1.1  drochner 
    214      1.1  drochner 	printf("usl_detachtimeout\n");
    215      1.1  drochner 
    216      1.1  drochner 	if (!(sd->s_flags & SF_DETACHPENDING)) {
    217      1.1  drochner 		printf("usl_detachtimeout: not detaching\n");
    218      1.1  drochner 		return;
    219      1.1  drochner 	}
    220      1.1  drochner 
    221      1.1  drochner 	sd->s_flags &= ~SF_DETACHPENDING;
    222      1.6  drochner 
    223      1.6  drochner 	if (sd->s_callback)
    224      1.6  drochner 		(*sd->s_callback)(sd->s_cbarg, EIO, 0);
    225      1.6  drochner 
    226      1.1  drochner 	(void) usl_sync_check(sd);
    227      1.1  drochner }
    228      1.1  drochner 
    229      1.1  drochner static int
    230      1.6  drochner usl_attachproc(cookie, waitok, callback, cbarg)
    231      1.1  drochner 	void *cookie;
    232      1.1  drochner 	int waitok;
    233      1.6  drochner 	void (*callback) __P((void *, int, int));
    234      1.6  drochner 	void *cbarg;
    235      1.1  drochner {
    236      1.1  drochner 	struct usl_syncdata *sd = cookie;
    237      1.1  drochner 
    238      1.1  drochner 	if (!usl_sync_check(sd))
    239      1.1  drochner 		return (0);
    240      1.1  drochner 
    241      1.6  drochner 	sd->s_callback = callback;
    242      1.6  drochner 	sd->s_cbarg = cbarg;
    243      1.1  drochner 	sd->s_flags |= SF_ATTACHPENDING;
    244      1.1  drochner 	psignal(sd->s_proc, sd->s_acqsig);
    245      1.7  drochner 	timeout(usl_attachtimeout, sd, wscompat_usl_synctimeout * hz);
    246      1.1  drochner 
    247      1.1  drochner 	return (EAGAIN);
    248      1.1  drochner }
    249      1.1  drochner 
    250      1.1  drochner static int
    251      1.1  drochner usl_attachack(sd, ack)
    252      1.1  drochner 	struct usl_syncdata *sd;
    253      1.1  drochner 	int ack;
    254      1.1  drochner {
    255      1.1  drochner 	if (!(sd->s_flags & SF_ATTACHPENDING)) {
    256      1.1  drochner 		printf("usl_attachack: not attaching\n");
    257      1.1  drochner 		return (EINVAL);
    258      1.1  drochner 	}
    259      1.1  drochner 
    260      1.1  drochner 	untimeout(usl_attachtimeout, sd);
    261      1.1  drochner 	sd->s_flags &= ~SF_ATTACHPENDING;
    262      1.6  drochner 
    263      1.6  drochner 	if (sd->s_callback)
    264      1.6  drochner 		(*sd->s_callback)(sd->s_cbarg, (ack ? 0 : EIO), 1);
    265      1.6  drochner 
    266      1.1  drochner 	return (0);
    267      1.1  drochner }
    268      1.1  drochner 
    269      1.1  drochner static void
    270      1.1  drochner usl_attachtimeout(arg)
    271      1.1  drochner 	void *arg;
    272      1.1  drochner {
    273      1.1  drochner 	struct usl_syncdata *sd = arg;
    274      1.1  drochner 
    275      1.1  drochner 	printf("usl_attachtimeout\n");
    276      1.1  drochner 
    277      1.1  drochner 	if (!(sd->s_flags & SF_ATTACHPENDING)) {
    278      1.1  drochner 		printf("usl_attachtimeout: not attaching\n");
    279      1.1  drochner 		return;
    280      1.1  drochner 	}
    281      1.1  drochner 
    282      1.1  drochner 	sd->s_flags &= ~SF_ATTACHPENDING;
    283      1.6  drochner 
    284      1.6  drochner 	if (sd->s_callback)
    285      1.6  drochner 		(*sd->s_callback)(sd->s_cbarg, EIO, 0);
    286      1.6  drochner 
    287      1.1  drochner 	(void) usl_sync_check(sd);
    288      1.1  drochner }
    289      1.1  drochner 
    290      1.1  drochner int
    291  1.9.2.1   thorpej wsdisplay_usl_ioctl1(sc, cmd, data, flag, p)
    292  1.9.2.1   thorpej 	struct wsdisplay_softc *sc;
    293  1.9.2.1   thorpej 	u_long cmd;
    294  1.9.2.1   thorpej 	caddr_t data;
    295  1.9.2.1   thorpej 	int flag;
    296  1.9.2.1   thorpej 	struct proc *p;
    297  1.9.2.1   thorpej {
    298  1.9.2.1   thorpej 	int idx, maxidx;
    299  1.9.2.1   thorpej 
    300  1.9.2.1   thorpej 	switch (cmd) {
    301  1.9.2.1   thorpej 	    case VT_OPENQRY:
    302  1.9.2.1   thorpej 		maxidx = wsdisplay_maxscreenidx(sc);
    303  1.9.2.1   thorpej 		for (idx = 0; idx <= maxidx; idx++) {
    304  1.9.2.1   thorpej 			if (wsdisplay_screenstate(sc, idx) == 0) {
    305  1.9.2.1   thorpej 				*(int *)data = idx + 1;
    306  1.9.2.1   thorpej 				return (0);
    307  1.9.2.1   thorpej 			}
    308  1.9.2.1   thorpej 		}
    309  1.9.2.1   thorpej 		return (ENXIO);
    310  1.9.2.1   thorpej 	    case VT_GETACTIVE:
    311  1.9.2.1   thorpej 		idx = wsdisplay_getactivescreen(sc);
    312  1.9.2.1   thorpej 		*(int *)data = idx + 1;
    313  1.9.2.1   thorpej 		return (0);
    314  1.9.2.1   thorpej 	    case VT_ACTIVATE:
    315  1.9.2.1   thorpej 		idx = *(int *)data - 1;
    316  1.9.2.1   thorpej 		return (wsdisplay_switch((struct device *)sc, idx, 1));
    317  1.9.2.1   thorpej 	    case VT_WAITACTIVE:
    318  1.9.2.1   thorpej 		idx = *(int *)data - 1;
    319  1.9.2.1   thorpej 		return (wsscreen_switchwait(sc, idx));
    320  1.9.2.1   thorpej 	    case VT_GETSTATE:
    321  1.9.2.1   thorpej #define ss ((struct vt_stat *)data)
    322  1.9.2.1   thorpej 		idx = wsdisplay_getactivescreen(sc);
    323  1.9.2.1   thorpej 		ss->v_active = idx + 1;
    324  1.9.2.1   thorpej 		ss->v_state = 0;
    325  1.9.2.1   thorpej 		maxidx = wsdisplay_maxscreenidx(sc);
    326  1.9.2.1   thorpej 		for (idx = 0; idx <= maxidx; idx++)
    327  1.9.2.1   thorpej 			if (wsdisplay_screenstate(sc, idx) == EBUSY)
    328  1.9.2.1   thorpej 				ss->v_state |= (1 << (idx + 1));
    329  1.9.2.1   thorpej #undef s
    330  1.9.2.1   thorpej 		return (0);
    331  1.9.2.1   thorpej 
    332  1.9.2.1   thorpej #ifdef WSDISPLAY_COMPAT_PCVT
    333  1.9.2.1   thorpej 	    case VGAPCVTID:
    334  1.9.2.1   thorpej #define id ((struct pcvtid *)data)
    335  1.9.2.1   thorpej 		strcpy(id->name, "pcvt");
    336  1.9.2.1   thorpej 		id->rmajor = 3;
    337  1.9.2.1   thorpej 		id->rminor = 32;
    338  1.9.2.1   thorpej #undef id
    339  1.9.2.1   thorpej 		return (0);
    340  1.9.2.1   thorpej #endif
    341  1.9.2.1   thorpej #ifdef WSDISPLAY_COMPAT_SYSCONS
    342  1.9.2.1   thorpej 	    case CONS_GETVERS:
    343  1.9.2.1   thorpej 		*(int *)data = 0x200;    /* version 2.0 */
    344  1.9.2.1   thorpej 		return (0);
    345  1.9.2.1   thorpej #endif
    346  1.9.2.1   thorpej 
    347  1.9.2.1   thorpej 	    default:
    348  1.9.2.1   thorpej 		return (-1);
    349  1.9.2.1   thorpej 	}
    350  1.9.2.1   thorpej 
    351  1.9.2.1   thorpej 	return (0);
    352  1.9.2.1   thorpej }
    353  1.9.2.1   thorpej 
    354  1.9.2.1   thorpej int
    355  1.9.2.1   thorpej wsdisplay_usl_ioctl2(sc, scr, cmd, data, flag, p)
    356      1.1  drochner 	struct wsdisplay_softc *sc;
    357      1.1  drochner 	struct wsscreen *scr;
    358      1.1  drochner 	u_long cmd;
    359      1.1  drochner 	caddr_t data;
    360      1.1  drochner 	int flag;
    361      1.1  drochner 	struct proc *p;
    362      1.1  drochner {
    363  1.9.2.1   thorpej 	int res;
    364      1.1  drochner 	struct usl_syncdata *sd;
    365      1.1  drochner 	int req, intarg;
    366      1.1  drochner 	struct wskbd_bell_data bd;
    367      1.1  drochner 	void *arg;
    368      1.1  drochner 
    369      1.1  drochner 	switch (cmd) {
    370      1.1  drochner 	    case VT_SETMODE:
    371      1.1  drochner #define newmode ((struct vt_mode *)data)
    372      1.1  drochner 		if (newmode->mode == VT_PROCESS) {
    373      1.3  drochner 			res = usl_sync_init(scr, &sd, p, newmode->acqsig,
    374      1.3  drochner 					    newmode->relsig, newmode->frsig);
    375      1.1  drochner 			if (res)
    376      1.1  drochner 				return (res);
    377      1.1  drochner 		} else {
    378      1.1  drochner 			sd = usl_sync_get(scr);
    379      1.1  drochner 			if (sd)
    380      1.1  drochner 				usl_sync_done(sd);
    381      1.1  drochner 		}
    382      1.1  drochner #undef newmode
    383      1.1  drochner 		return (0);
    384      1.1  drochner 	    case VT_GETMODE:
    385      1.1  drochner #define cmode ((struct vt_mode *)data)
    386      1.1  drochner 		sd = usl_sync_get(scr);
    387      1.1  drochner 		if (sd) {
    388      1.1  drochner 			cmode->mode = VT_PROCESS;
    389      1.1  drochner 			cmode->relsig = sd->s_relsig;
    390      1.1  drochner 			cmode->acqsig = sd->s_acqsig;
    391      1.1  drochner 			cmode->frsig = sd->s_frsig;
    392      1.1  drochner 		} else
    393      1.1  drochner 			cmode->mode = VT_AUTO;
    394      1.1  drochner #undef cmode
    395      1.1  drochner 		return (0);
    396      1.1  drochner 	    case VT_RELDISP:
    397      1.1  drochner #define d (*(int *)data)
    398      1.1  drochner 		sd = usl_sync_get(scr);
    399      1.1  drochner 		if (!sd)
    400      1.1  drochner 			return (EINVAL);
    401      1.1  drochner 		switch (d) {
    402      1.1  drochner 		    case VT_FALSE:
    403      1.1  drochner 		    case VT_TRUE:
    404      1.1  drochner 			return (usl_detachack(sd, (d == VT_TRUE)));
    405      1.1  drochner 		    case VT_ACKACQ:
    406      1.1  drochner 			return (usl_attachack(sd, 1));
    407      1.1  drochner 		    default:
    408      1.1  drochner 			return (EINVAL);
    409      1.1  drochner 		}
    410      1.1  drochner #undef d
    411      1.1  drochner 		return (0);
    412  1.9.2.1   thorpej 
    413      1.1  drochner 	    case KDENABIO:
    414      1.1  drochner 		if (suser(p->p_ucred, &p->p_acflag) || securelevel > 1)
    415      1.1  drochner 			return (EPERM);
    416      1.1  drochner 		/* FALLTHRU */
    417      1.1  drochner 	    case KDDISABIO:
    418      1.1  drochner #if defined(__i386__)
    419      1.1  drochner #if defined(COMPAT_10) || defined(COMPAT_11) || defined(COMPAT_FREEBSD)
    420      1.1  drochner 		{
    421      1.1  drochner 		struct trapframe *fp = (struct trapframe *)p->p_md.md_regs;
    422      1.1  drochner 		if (cmd == KDENABIO)
    423      1.1  drochner 			fp->tf_eflags |= PSL_IOPL;
    424      1.1  drochner 		else
    425      1.1  drochner 			fp->tf_eflags &= ~PSL_IOPL;
    426      1.1  drochner 		}
    427      1.1  drochner #endif
    428      1.1  drochner #endif
    429      1.1  drochner 		return (0);
    430      1.1  drochner 	    case KDSETRAD:
    431      1.1  drochner 		/* XXX ignore for now */
    432      1.1  drochner 		return (0);
    433      1.1  drochner 
    434      1.1  drochner 	    default:
    435      1.1  drochner 		return (-1);
    436      1.1  drochner 
    437      1.1  drochner 	    /*
    438      1.1  drochner 	     * the following are converted to wsdisplay ioctls
    439      1.1  drochner 	     */
    440      1.1  drochner 	    case KDSETMODE:
    441      1.1  drochner 		req = WSDISPLAYIO_SMODE;
    442      1.1  drochner #define d (*(int *)data)
    443      1.1  drochner 		switch (d) {
    444      1.1  drochner 		    case KD_GRAPHICS:
    445      1.1  drochner 			intarg = WSDISPLAYIO_MODE_MAPPED;
    446      1.1  drochner 			break;
    447      1.1  drochner 		    case KD_TEXT:
    448      1.1  drochner 			intarg = WSDISPLAYIO_MODE_EMUL;
    449      1.1  drochner 			break;
    450      1.1  drochner 		    default:
    451      1.1  drochner 			return (EINVAL);
    452      1.1  drochner 		}
    453      1.1  drochner #undef d
    454      1.1  drochner 		arg = &intarg;
    455      1.1  drochner 		break;
    456      1.1  drochner 	    case KDMKTONE:
    457      1.1  drochner 		req = WSKBDIO_COMPLEXBELL;
    458      1.1  drochner #define d (*(int *)data)
    459      1.1  drochner 		if (d) {
    460      1.8  christos #define PCVT_SYSBEEPF	1193182
    461      1.8  christos 			if (d >> 16) {
    462      1.8  christos 				bd.which = WSKBD_BELL_DOPERIOD;
    463      1.8  christos 				bd.period = d >> 16; /* ms */
    464      1.8  christos 			}
    465      1.9  christos 			else
    466      1.9  christos 				bd.which = 0;
    467      1.8  christos 			if (d & 0xffff) {
    468      1.8  christos 				bd.which |= WSKBD_BELL_DOPITCH;
    469      1.8  christos 				bd.pitch = PCVT_SYSBEEPF/(d & 0xffff); /* Hz */
    470      1.8  christos 			}
    471      1.1  drochner 		} else
    472      1.1  drochner 			bd.which = 0; /* default */
    473      1.1  drochner #undef d
    474      1.1  drochner 		arg = &bd;
    475      1.1  drochner 		break;
    476      1.1  drochner 	    case KDSETLED:
    477      1.1  drochner 		req = WSKBDIO_SETLEDS;
    478      1.1  drochner 		intarg = 0;
    479      1.1  drochner #define d (*(int *)data)
    480      1.1  drochner 		if (d & LED_CAP)
    481      1.1  drochner 			intarg |= WSKBD_LED_CAPS;
    482      1.1  drochner 		if (d & LED_NUM)
    483      1.1  drochner 			intarg |= WSKBD_LED_NUM;
    484      1.1  drochner 		if (d & LED_SCR)
    485      1.1  drochner 			intarg |= WSKBD_LED_SCROLL;
    486      1.1  drochner #undef d
    487      1.1  drochner 		arg = &intarg;
    488      1.1  drochner 		break;
    489      1.1  drochner 	    case KDGETLED:
    490      1.1  drochner 		req = WSKBDIO_GETLEDS;
    491      1.1  drochner 		arg = &intarg;
    492      1.1  drochner 		break;
    493      1.1  drochner #ifdef WSDISPLAY_COMPAT_RAWKBD
    494      1.1  drochner 	    case KDSKBMODE:
    495      1.1  drochner 		req = WSKBDIO_SETMODE;
    496      1.1  drochner 		switch (*(int *)data) {
    497      1.1  drochner 		    case K_RAW:
    498      1.1  drochner 			intarg = WSKBD_RAW;
    499      1.1  drochner 			break;
    500      1.1  drochner 		    case K_XLATE:
    501      1.1  drochner 			intarg = WSKBD_TRANSLATED;
    502      1.1  drochner 			break;
    503      1.1  drochner 		    default:
    504      1.1  drochner 			return (EINVAL);
    505      1.1  drochner 		}
    506      1.1  drochner 		arg = &intarg;
    507      1.1  drochner 		break;
    508      1.1  drochner 	    case KDGKBMODE:
    509      1.1  drochner 		req = WSKBDIO_GETMODE;
    510      1.1  drochner 		arg = &intarg;
    511      1.1  drochner 		break;
    512      1.1  drochner #endif
    513      1.1  drochner 	}
    514      1.1  drochner 
    515      1.1  drochner 	res = wsdisplay_internal_ioctl(sc, scr, req, arg, flag, p);
    516      1.1  drochner 	if (res)
    517      1.1  drochner 		return (res);
    518      1.1  drochner 
    519      1.1  drochner 	switch (cmd) {
    520      1.1  drochner 	    case KDGETLED:
    521      1.1  drochner #define d (*(int *)data)
    522      1.1  drochner 		d = 0;
    523      1.1  drochner 		if (intarg & WSKBD_LED_CAPS)
    524      1.1  drochner 			d |= LED_CAP;
    525      1.1  drochner 		if (intarg & WSKBD_LED_NUM)
    526      1.1  drochner 			d |= LED_NUM;
    527      1.1  drochner 		if (intarg & WSKBD_LED_SCROLL)
    528      1.1  drochner 			d |= LED_SCR;
    529      1.1  drochner #undef d
    530      1.1  drochner 		break;
    531      1.1  drochner #ifdef WSDISPLAY_COMPAT_RAWKBD
    532      1.1  drochner 	    case KDGKBMODE:
    533      1.1  drochner 		*(int *)data = (intarg == WSKBD_RAW ? K_RAW : K_XLATE);
    534      1.1  drochner 		break;
    535      1.1  drochner #endif
    536      1.1  drochner 	}
    537      1.1  drochner 
    538      1.1  drochner 	return (0);
    539      1.1  drochner }
    540