[BACK]Return to wsdisplay_compat_usl.c CVS log [TXT][DIR] Up to [local] / sys / dev / wscons

Annotation of sys/dev/wscons/wsdisplay_compat_usl.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: wsdisplay_compat_usl.c,v 1.19 2007/02/14 01:12:16 jsg Exp $ */
        !             2: /* $NetBSD: wsdisplay_compat_usl.c,v 1.12 2000/03/23 07:01:47 thorpej Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1998
        !             6:  *     Matthias Drochner.  All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            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:
        !            30: #include <sys/param.h>
        !            31: #include <sys/systm.h>
        !            32: #include <sys/timeout.h>
        !            33: #include <sys/ioctl.h>
        !            34: #include <sys/kernel.h>
        !            35: #include <sys/proc.h>
        !            36: #include <sys/signalvar.h>
        !            37: #include <sys/malloc.h>
        !            38: #include <sys/errno.h>
        !            39:
        !            40: #include <dev/wscons/wsconsio.h>
        !            41: #include <dev/wscons/wsdisplayvar.h>
        !            42: #include <dev/wscons/wscons_callbacks.h>
        !            43: #include <dev/wscons/wsdisplay_usl_io.h>
        !            44:
        !            45: #ifdef WSDISPLAY_DEBUG
        !            46: #define DPRINTF(x)      if (wsdisplaydebug) printf x
        !            47: int    wsdisplaydebug = 0;
        !            48: #else
        !            49: #define DPRINTF(x)
        !            50: #endif
        !            51:
        !            52: struct usl_syncdata {
        !            53:        struct wsscreen *s_scr;
        !            54:        struct proc *s_proc;
        !            55:        pid_t s_pid;
        !            56:        int s_flags;
        !            57: #define SF_DETACHPENDING 1
        !            58: #define SF_ATTACHPENDING 2
        !            59:        int s_acqsig, s_relsig;
        !            60:        int s_frsig; /* unused */
        !            61:        void (*s_callback)(void *, int, int);
        !            62:        void *s_cbarg;
        !            63:        struct timeout s_attach_ch;
        !            64:        struct timeout s_detach_ch;
        !            65: };
        !            66:
        !            67: int usl_sync_init(struct wsscreen *, struct usl_syncdata **,
        !            68:                       struct proc *, int, int, int);
        !            69: void usl_sync_done(struct usl_syncdata *);
        !            70: int usl_sync_check(struct usl_syncdata *);
        !            71: struct usl_syncdata *usl_sync_get(struct wsscreen *);
        !            72:
        !            73: int usl_detachproc(void *, int, void (*)(void *, int, int), void *);
        !            74: int usl_detachack(struct usl_syncdata *, int);
        !            75: void usl_detachtimeout(void *);
        !            76: int usl_attachproc(void *, int, void (*)(void *, int, int), void *);
        !            77: int usl_attachack(struct usl_syncdata *, int);
        !            78: void usl_attachtimeout(void *);
        !            79:
        !            80: static const struct wscons_syncops usl_syncops = {
        !            81:        usl_detachproc,
        !            82:        usl_attachproc,
        !            83: #define _usl_sync_check ((int (*)(void *))usl_sync_check)
        !            84:        _usl_sync_check,
        !            85: #define _usl_sync_destroy ((void (*)(void *))usl_sync_done)
        !            86:        _usl_sync_destroy
        !            87: };
        !            88:
        !            89: #ifndef WSCOMPAT_USL_SYNCTIMEOUT
        !            90: #define WSCOMPAT_USL_SYNCTIMEOUT 5 /* seconds */
        !            91: #endif
        !            92: static int wscompat_usl_synctimeout = WSCOMPAT_USL_SYNCTIMEOUT;
        !            93:
        !            94: int
        !            95: usl_sync_init(scr, sdp, p, acqsig, relsig, frsig)
        !            96:        struct wsscreen *scr;
        !            97:        struct usl_syncdata **sdp;
        !            98:        struct proc *p;
        !            99:        int acqsig, relsig, frsig;
        !           100: {
        !           101:        struct usl_syncdata *sd;
        !           102:        int res;
        !           103:
        !           104:        if (acqsig <= 0 || acqsig >= NSIG || relsig <= 0 || relsig >= NSIG ||
        !           105:            frsig <= 0 || frsig >= NSIG)
        !           106:                return (EINVAL);
        !           107:        sd = malloc(sizeof(struct usl_syncdata), M_DEVBUF, M_NOWAIT);
        !           108:        if (!sd)
        !           109:                return (ENOMEM);
        !           110:        sd->s_scr = scr;
        !           111:        sd->s_proc = p;
        !           112:        sd->s_pid = p->p_pid;
        !           113:        sd->s_flags = 0;
        !           114:        sd->s_acqsig = acqsig;
        !           115:        sd->s_relsig = relsig;
        !           116:        sd->s_frsig = frsig;
        !           117:        timeout_set(&sd->s_attach_ch, usl_attachtimeout, sd);
        !           118:        timeout_set(&sd->s_detach_ch, usl_detachtimeout, sd);
        !           119:        res = wsscreen_attach_sync(scr, &usl_syncops, sd);
        !           120:        if (res) {
        !           121:                free(sd, M_DEVBUF);
        !           122:                return (res);
        !           123:        }
        !           124:        *sdp = sd;
        !           125:        return (0);
        !           126: }
        !           127:
        !           128: void
        !           129: usl_sync_done(sd)
        !           130:        struct usl_syncdata *sd;
        !           131: {
        !           132:        if (sd->s_flags & SF_DETACHPENDING) {
        !           133:                timeout_del(&sd->s_detach_ch);
        !           134:                (*sd->s_callback)(sd->s_cbarg, 0, 0);
        !           135:        }
        !           136:        if (sd->s_flags & SF_ATTACHPENDING) {
        !           137:                timeout_del(&sd->s_attach_ch);
        !           138:                (*sd->s_callback)(sd->s_cbarg, ENXIO, 0);
        !           139:        }
        !           140:        wsscreen_detach_sync(sd->s_scr);
        !           141:        free(sd, M_DEVBUF);
        !           142: }
        !           143:
        !           144: int
        !           145: usl_sync_check(sd)
        !           146:        struct usl_syncdata *sd;
        !           147: {
        !           148:        if (sd->s_proc == pfind(sd->s_pid))
        !           149:                return (1);
        !           150:        DPRINTF(("usl_sync_check: process %d died\n", sd->s_pid));
        !           151:        usl_sync_done(sd);
        !           152:        return (0);
        !           153: }
        !           154:
        !           155: struct usl_syncdata *
        !           156: usl_sync_get(scr)
        !           157:        struct wsscreen *scr;
        !           158: {
        !           159:        struct usl_syncdata *sd;
        !           160:
        !           161:        if (wsscreen_lookup_sync(scr, &usl_syncops, (void **)&sd))
        !           162:                return (0);
        !           163:        return (sd);
        !           164: }
        !           165:
        !           166: int
        !           167: usl_detachproc(cookie, waitok, callback, cbarg)
        !           168:        void *cookie;
        !           169:        int waitok;
        !           170:        void (*callback)(void *, int, int);
        !           171:        void *cbarg;
        !           172: {
        !           173:        struct usl_syncdata *sd = cookie;
        !           174:
        !           175:        if (!usl_sync_check(sd))
        !           176:                return (0);
        !           177:
        !           178:        /* we really need a callback */
        !           179:        if (!callback)
        !           180:                return (EINVAL);
        !           181:
        !           182:        /*
        !           183:         * Normally, this is called from the controlling process.
        !           184:         * It is supposed to reply with a VT_RELDISP ioctl(), so
        !           185:         * it is not useful to tsleep() here.
        !           186:         */
        !           187:        sd->s_callback = callback;
        !           188:        sd->s_cbarg = cbarg;
        !           189:        sd->s_flags |= SF_DETACHPENDING;
        !           190:        psignal(sd->s_proc, sd->s_relsig);
        !           191:        timeout_add(&sd->s_detach_ch, wscompat_usl_synctimeout * hz);
        !           192:
        !           193:        return (EAGAIN);
        !           194: }
        !           195:
        !           196: int
        !           197: usl_detachack(sd, ack)
        !           198:        struct usl_syncdata *sd;
        !           199:        int ack;
        !           200: {
        !           201:        if (!(sd->s_flags & SF_DETACHPENDING)) {
        !           202:                DPRINTF(("usl_detachack: not detaching\n"));
        !           203:                return (EINVAL);
        !           204:        }
        !           205:
        !           206:        timeout_del(&sd->s_detach_ch);
        !           207:        sd->s_flags &= ~SF_DETACHPENDING;
        !           208:
        !           209:        if (sd->s_callback)
        !           210:                (*sd->s_callback)(sd->s_cbarg, (ack ? 0 : EIO), 1);
        !           211:
        !           212:        return (0);
        !           213: }
        !           214:
        !           215: void
        !           216: usl_detachtimeout(arg)
        !           217:        void *arg;
        !           218: {
        !           219:        struct usl_syncdata *sd = arg;
        !           220:
        !           221:        DPRINTF(("usl_detachtimeout\n"));
        !           222:
        !           223:        if (!(sd->s_flags & SF_DETACHPENDING)) {
        !           224:                DPRINTF(("usl_detachtimeout: not detaching\n"));
        !           225:                return;
        !           226:        }
        !           227:
        !           228:        sd->s_flags &= ~SF_DETACHPENDING;
        !           229:
        !           230:        if (sd->s_callback)
        !           231:                (*sd->s_callback)(sd->s_cbarg, EIO, 0);
        !           232:
        !           233:        (void) usl_sync_check(sd);
        !           234: }
        !           235:
        !           236: int
        !           237: usl_attachproc(cookie, waitok, callback, cbarg)
        !           238:        void *cookie;
        !           239:        int waitok;
        !           240:        void (*callback)(void *, int, int);
        !           241:        void *cbarg;
        !           242: {
        !           243:        struct usl_syncdata *sd = cookie;
        !           244:
        !           245:        if (!usl_sync_check(sd))
        !           246:                return (0);
        !           247:
        !           248:        /* we really need a callback */
        !           249:        if (!callback)
        !           250:                return (EINVAL);
        !           251:
        !           252:        sd->s_callback = callback;
        !           253:        sd->s_cbarg = cbarg;
        !           254:        sd->s_flags |= SF_ATTACHPENDING;
        !           255:        psignal(sd->s_proc, sd->s_acqsig);
        !           256:        timeout_add(&sd->s_attach_ch, wscompat_usl_synctimeout * hz);
        !           257:
        !           258:        return (EAGAIN);
        !           259: }
        !           260:
        !           261: int
        !           262: usl_attachack(sd, ack)
        !           263:        struct usl_syncdata *sd;
        !           264:        int ack;
        !           265: {
        !           266:        if (!(sd->s_flags & SF_ATTACHPENDING)) {
        !           267:                DPRINTF(("usl_attachack: not attaching\n"));
        !           268:                return (EINVAL);
        !           269:        }
        !           270:
        !           271:        timeout_del(&sd->s_attach_ch);
        !           272:        sd->s_flags &= ~SF_ATTACHPENDING;
        !           273:
        !           274:        if (sd->s_callback)
        !           275:                (*sd->s_callback)(sd->s_cbarg, (ack ? 0 : EIO), 1);
        !           276:
        !           277:        return (0);
        !           278: }
        !           279:
        !           280: void
        !           281: usl_attachtimeout(arg)
        !           282:        void *arg;
        !           283: {
        !           284:        struct usl_syncdata *sd = arg;
        !           285:
        !           286:        DPRINTF(("usl_attachtimeout\n"));
        !           287:
        !           288:        if (!(sd->s_flags & SF_ATTACHPENDING)) {
        !           289:                DPRINTF(("usl_attachtimeout: not attaching\n"));
        !           290:                return;
        !           291:        }
        !           292:
        !           293:        sd->s_flags &= ~SF_ATTACHPENDING;
        !           294:
        !           295:        if (sd->s_callback)
        !           296:                (*sd->s_callback)(sd->s_cbarg, EIO, 0);
        !           297:
        !           298:        (void) usl_sync_check(sd);
        !           299: }
        !           300:
        !           301: int
        !           302: wsdisplay_usl_ioctl1(sc, cmd, data, flag, p)
        !           303:        struct wsdisplay_softc *sc;
        !           304:        u_long cmd;
        !           305:        caddr_t data;
        !           306:        int flag;
        !           307:        struct proc *p;
        !           308: {
        !           309:        int idx, maxidx;
        !           310:
        !           311:        switch (cmd) {
        !           312:            case VT_OPENQRY:
        !           313:                maxidx = wsdisplay_maxscreenidx(sc);
        !           314:                for (idx = 0; idx <= maxidx; idx++) {
        !           315:                        if (wsdisplay_screenstate(sc, idx) == 0) {
        !           316:                                *(int *)data = idx + 1;
        !           317:                                return (0);
        !           318:                        }
        !           319:                }
        !           320:                return (ENXIO);
        !           321:            case VT_GETACTIVE:
        !           322:                idx = wsdisplay_getactivescreen(sc);
        !           323:                *(int *)data = idx + 1;
        !           324:                return (0);
        !           325:            case VT_ACTIVATE:
        !           326:                idx = *(int *)data - 1;
        !           327:                if (idx < 0)
        !           328:                        return (EINVAL);
        !           329:                return (wsdisplay_switch((struct device *)sc, idx, 1));
        !           330:            case VT_WAITACTIVE:
        !           331:                idx = *(int *)data - 1;
        !           332:                if (idx < 0)
        !           333:                        return (EINVAL);
        !           334:                return (wsscreen_switchwait(sc, idx));
        !           335:            case VT_GETSTATE:
        !           336: #define ss ((struct vt_stat *)data)
        !           337:                idx = wsdisplay_getactivescreen(sc);
        !           338:                ss->v_active = idx + 1;
        !           339:                ss->v_state = 0;
        !           340:                maxidx = wsdisplay_maxscreenidx(sc);
        !           341:                for (idx = 0; idx <= maxidx; idx++)
        !           342:                        if (wsdisplay_screenstate(sc, idx) == EBUSY)
        !           343:                                ss->v_state |= (1 << (idx + 1));
        !           344: #undef ss
        !           345:                return (0);
        !           346:
        !           347: #ifdef WSDISPLAY_COMPAT_PCVT
        !           348:            case VGAPCVTID:
        !           349: #define id ((struct pcvtid *)data)
        !           350:                strlcpy(id->name, "pcvt", sizeof id->name);
        !           351:                id->rmajor = 3;
        !           352:                id->rminor = 32;
        !           353: #undef id
        !           354:                return (0);
        !           355: #endif
        !           356: #ifdef WSDISPLAY_COMPAT_SYSCONS
        !           357:            case CONS_GETVERS:
        !           358:                *(int *)data = 0x200;    /* version 2.0 */
        !           359:                return (0);
        !           360: #endif
        !           361:
        !           362:            default:
        !           363:                return (-1);
        !           364:        }
        !           365:
        !           366:        return (0);
        !           367: }
        !           368:
        !           369: int
        !           370: wsdisplay_usl_ioctl2(sc, scr, cmd, data, flag, p)
        !           371:        struct wsdisplay_softc *sc;
        !           372:        struct wsscreen *scr;
        !           373:        u_long cmd;
        !           374:        caddr_t data;
        !           375:        int flag;
        !           376:        struct proc *p;
        !           377: {
        !           378:        int intarg, res;
        !           379:        u_long req;
        !           380:        void *arg;
        !           381:        struct usl_syncdata *sd;
        !           382:        struct wskbd_bell_data bd;
        !           383:
        !           384:        switch (cmd) {
        !           385:            case VT_SETMODE:
        !           386: #define newmode ((struct vt_mode *)data)
        !           387:                if (newmode->mode == VT_PROCESS) {
        !           388:                        res = usl_sync_init(scr, &sd, p, newmode->acqsig,
        !           389:                                            newmode->relsig, newmode->frsig);
        !           390:                        if (res)
        !           391:                                return (res);
        !           392:                } else {
        !           393:                        sd = usl_sync_get(scr);
        !           394:                        if (sd)
        !           395:                                usl_sync_done(sd);
        !           396:                }
        !           397: #undef newmode
        !           398:                return (0);
        !           399:            case VT_GETMODE:
        !           400: #define cmode ((struct vt_mode *)data)
        !           401:                sd = usl_sync_get(scr);
        !           402:                if (sd) {
        !           403:                        cmode->mode = VT_PROCESS;
        !           404:                        cmode->relsig = sd->s_relsig;
        !           405:                        cmode->acqsig = sd->s_acqsig;
        !           406:                        cmode->frsig = sd->s_frsig;
        !           407:                } else
        !           408:                        cmode->mode = VT_AUTO;
        !           409: #undef cmode
        !           410:                return (0);
        !           411:            case VT_RELDISP:
        !           412: #define d (*(int *)data)
        !           413:                sd = usl_sync_get(scr);
        !           414:                if (!sd)
        !           415:                        return (EINVAL);
        !           416:                switch (d) {
        !           417:                    case VT_FALSE:
        !           418:                    case VT_TRUE:
        !           419:                        return (usl_detachack(sd, (d == VT_TRUE)));
        !           420:                    case VT_ACKACQ:
        !           421:                        return (usl_attachack(sd, 1));
        !           422:                    default:
        !           423:                        return (EINVAL);
        !           424:                }
        !           425: #undef d
        !           426:                return (0);
        !           427:
        !           428: #if defined(__i386__)
        !           429:            case KDENABIO:
        !           430:                if (suser(p, 0) || securelevel > 0)
        !           431:                        return (EPERM);
        !           432:                /* FALLTHROUGH */
        !           433:            case KDDISABIO:
        !           434: #if defined(COMPAT_FREEBSD)
        !           435:                {
        !           436:                struct trapframe *fp = (struct trapframe *)p->p_md.md_regs;
        !           437:                extern struct emul emul_freebsd_aout;
        !           438:                extern struct emul emul_freebsd_elf;
        !           439:
        !           440:                if (p->p_emul == &emul_freebsd_aout ||
        !           441:                    p->p_emul == &emul_freebsd_elf) {
        !           442:                        if (cmd == KDENABIO)
        !           443:                                fp->tf_eflags |= PSL_IOPL;
        !           444:                        else
        !           445:                                fp->tf_eflags &= ~PSL_IOPL;
        !           446:                        }
        !           447:                }
        !           448: #endif
        !           449:                return (0);
        !           450: #else
        !           451:            case KDENABIO:
        !           452:            case KDDISABIO:
        !           453:                /*
        !           454:                 * This is a lie, but non-x86 platforms are not supposed to
        !           455:                 * issue these ioctls anyway.
        !           456:                 */
        !           457:                return (0);
        !           458: #endif
        !           459:            case KDSETRAD:
        !           460:                /* XXX ignore for now */
        !           461:                return (0);
        !           462:
        !           463:            default:
        !           464:                return (-1);
        !           465:
        !           466:            /*
        !           467:             * the following are converted to wsdisplay ioctls
        !           468:             */
        !           469:            case KDSETMODE:
        !           470:                req = WSDISPLAYIO_SMODE;
        !           471: #define d (*(int *)data)
        !           472:                switch (d) {
        !           473:                    case KD_GRAPHICS:
        !           474:                        intarg = WSDISPLAYIO_MODE_MAPPED;
        !           475:                        break;
        !           476:                    case KD_TEXT:
        !           477:                        intarg = WSDISPLAYIO_MODE_EMUL;
        !           478:                        break;
        !           479:                    default:
        !           480:                        return (EINVAL);
        !           481:                }
        !           482: #undef d
        !           483:                arg = &intarg;
        !           484:                break;
        !           485:            case KDMKTONE:
        !           486:                req = WSKBDIO_COMPLEXBELL;
        !           487: #define d (*(int *)data)
        !           488:                if (d) {
        !           489: #define PCVT_SYSBEEPF  1193182
        !           490:                        if (d >> 16) {
        !           491:                                bd.which = WSKBD_BELL_DOPERIOD;
        !           492:                        bd.period = d >> 16; /* ms */
        !           493:                        }
        !           494:                        else
        !           495:                                bd.which = 0;
        !           496:                        if (d & 0xffff) {
        !           497:                                bd.which |= WSKBD_BELL_DOPITCH;
        !           498:                                bd.pitch = PCVT_SYSBEEPF/(d & 0xffff); /* Hz */
        !           499:                        }
        !           500:                } else
        !           501:                        bd.which = 0; /* default */
        !           502: #undef d
        !           503:                arg = &bd;
        !           504:                break;
        !           505:            case KDSETLED:
        !           506:                req = WSKBDIO_SETLEDS;
        !           507:                intarg = 0;
        !           508: #define d (*(int *)data)
        !           509:                if (d & LED_CAP)
        !           510:                        intarg |= WSKBD_LED_CAPS;
        !           511:                if (d & LED_NUM)
        !           512:                        intarg |= WSKBD_LED_NUM;
        !           513:                if (d & LED_SCR)
        !           514:                        intarg |= WSKBD_LED_SCROLL;
        !           515: #undef d
        !           516:                arg = &intarg;
        !           517:                break;
        !           518:            case KDGETLED:
        !           519:                req = WSKBDIO_GETLEDS;
        !           520:                arg = &intarg;
        !           521:                break;
        !           522: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           523:            case KDSKBMODE:
        !           524:                req = WSKBDIO_SETMODE;
        !           525:                switch (*(int *)data) {
        !           526:                    case K_RAW:
        !           527:                        intarg = WSKBD_RAW;
        !           528:                        break;
        !           529:                    case K_XLATE:
        !           530:                        intarg = WSKBD_TRANSLATED;
        !           531:                        break;
        !           532:                    default:
        !           533:                        return (EINVAL);
        !           534:                }
        !           535:                arg = &intarg;
        !           536:                break;
        !           537:            case KDGKBMODE:
        !           538:                req = WSKBDIO_GETMODE;
        !           539:                arg = &intarg;
        !           540:                break;
        !           541: #endif
        !           542:        }
        !           543:
        !           544:        res = wsdisplay_internal_ioctl(sc, scr, req, arg, flag, p);
        !           545:        if (res)
        !           546:                return (res);
        !           547:
        !           548:        switch (cmd) {
        !           549:            case KDGETLED:
        !           550: #define d (*(int *)data)
        !           551:                d = 0;
        !           552:                if (intarg & WSKBD_LED_CAPS)
        !           553:                        d |= LED_CAP;
        !           554:                if (intarg & WSKBD_LED_NUM)
        !           555:                        d |= LED_NUM;
        !           556:                if (intarg & WSKBD_LED_SCROLL)
        !           557:                        d |= LED_SCR;
        !           558: #undef d
        !           559:                break;
        !           560: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           561:            case KDGKBMODE:
        !           562:                *(int *)data = (intarg == WSKBD_RAW ? K_RAW : K_XLATE);
        !           563:                break;
        !           564: #endif
        !           565:        }
        !           566:
        !           567:        return (0);
        !           568: }

CVSweb