Annotation of Gnu-Mach/i386/i386at/kd_event.c, revision 1.1.1.4

1.1.1.3   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.3   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.3   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.3   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.3   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.3   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /* **********************************************************************
                     27:  File:         kd_event.c
                     28:  Description:  Driver for event interface to keyboard.
                     29: 
                     30:  $ Header: $
                     31: 
                     32:  Copyright Ing. C. Olivetti & C. S.p.A. 1989.  All rights reserved.
                     33: ********************************************************************** */
                     34: /*
                     35:   Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc.,
                     36: Cupertino, California.
                     37: 
                     38:                All Rights Reserved
                     39: 
                     40:   Permission to use, copy, modify, and distribute this software and
                     41: its documentation for any purpose and without fee is hereby
                     42: granted, provided that the above copyright notice appears in all
                     43: copies and that both the copyright notice and this permission notice
                     44: appear in supporting documentation, and that the name of Olivetti
                     45: not be used in advertising or publicity pertaining to distribution
                     46: of the software without specific, written prior permission.
                     47: 
                     48:   OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
                     49: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
                     50: IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
                     51: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
                     52: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
                     53: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
                     54: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     55: */
                     56: 
                     57: #include <mach/boolean.h>
                     58: #include <sys/types.h>
1.1.1.4 ! root       59: #include <kern/printf.h>
        !            60: #include <string.h>
        !            61: 
        !            62: #include <device/ds_routines.h>
        !            63: #include <device/device_types.h>
1.1       root       64: #include <device/io_req.h>
                     65: #include <i386/machspl.h>
1.1.1.4 ! root       66: #include <i386/pio.h>
1.1       root       67: #include <i386at/kd.h>
                     68: #include <i386at/kd_queue.h>
                     69: 
1.1.1.4 ! root       70: #include "kd_event.h"
        !            71: 
1.1       root       72: /*
                     73:  * Code for /dev/kbd.   The interrupt processing is done in kd.c,
                     74:  * which calls into this module to enqueue scancode events when
                     75:  * the keyboard is in Event mode.
                     76:  */
                     77: 
                     78: /*
                     79:  * Note: These globals are protected by raising the interrupt level
                     80:  * via SPLKD.
                     81:  */
                     82: 
                     83: kd_event_queue kbd_queue;              /* queue of keyboard events */
                     84: queue_head_t   kbd_read_queue = { &kbd_read_queue, &kbd_read_queue };
                     85: 
                     86: 
                     87: void kbd_enqueue();
                     88: io_return_t X_kdb_enter_init();
                     89: io_return_t X_kdb_exit_init();
                     90: 
                     91: static boolean_t initialized = FALSE;
                     92: 
                     93: 
                     94: /*
                     95:  * kbdinit - set up event queue.
                     96:  */
                     97: 
1.1.1.4 ! root       98: void
1.1       root       99: kbdinit()
                    100: {
                    101:        spl_t s = SPLKD();
1.1.1.3   root      102: 
1.1       root      103:        if (!initialized) {
                    104:                kdq_reset(&kbd_queue);
                    105:                initialized = TRUE;
                    106:        }
                    107:        splx(s);
                    108: }
                    109: 
                    110: 
                    111: /*
                    112:  * kbdopen - Verify that open is read-only and remember process
                    113:  * group leader.
                    114:  */
                    115: 
                    116: /*ARGSUSED*/
1.1.1.4 ! root      117: int
1.1       root      118: kbdopen(dev, flags)
                    119:        dev_t dev;
                    120:        int flags;
                    121: {
1.1.1.4 ! root      122:        spl_t o_pri = spltty();
        !           123:        kdinit();
        !           124:        splx(o_pri);
1.1       root      125:        kbdinit();
                    126: 
                    127:        return(0);
                    128: }
                    129: 
                    130: 
                    131: /*
                    132:  * kbdclose - Make sure that the kd driver is in Ascii mode and
                    133:  * reset various flags.
                    134:  */
                    135: 
                    136: /*ARGSUSED*/
1.1.1.4 ! root      137: void
1.1       root      138: kbdclose(dev, flags)
                    139:        dev_t dev;
                    140:        int flags;
                    141: {
                    142:        spl_t s = SPLKD();
                    143: 
                    144:        kb_mode = KB_ASCII;
                    145:        kdq_reset(&kbd_queue);
                    146:        splx(s);
                    147: }
                    148: 
                    149: 
                    150: io_return_t kbdgetstat(dev, flavor, data, count)
                    151:        dev_t           dev;
                    152:        int             flavor;
                    153:        int *           data;           /* pointer to OUT array */
                    154:        unsigned int    *count;         /* OUT */
                    155: {
                    156:        switch (flavor) {
                    157:            case KDGKBDTYPE:
                    158:                *data = KB_VANILLAKB;
                    159:                *count = 1;
                    160:                break;
1.1.1.2   root      161:            case DEV_GET_SIZE:
                    162:                data[DEV_GET_SIZE_DEVICE_SIZE] = 0;
                    163:                data[DEV_GET_SIZE_RECORD_SIZE] = sizeof(kd_event);
                    164:                *count = DEV_GET_SIZE_COUNT;
                    165:                break;
1.1       root      166:            default:
                    167:                return (D_INVALID_OPERATION);
                    168:        }
                    169:        return (D_SUCCESS);
                    170: }
                    171: 
                    172: io_return_t kbdsetstat(dev, flavor, data, count)
                    173:        dev_t           dev;
                    174:        int             flavor;
                    175:        int *           data;
                    176:        unsigned int    count;
                    177: {
                    178:        switch (flavor) {
                    179:            case KDSKBDMODE:
                    180:                kb_mode = *data;
                    181:                /* XXX - what to do about unread events? */
                    182:                /* XXX - should check that 'data' contains an OK valud */
                    183:                break;
1.1.1.4 ! root      184:           case KDSETLEDS:
        !           185:                if (count != 1)
        !           186:                    return (D_INVALID_OPERATION);
        !           187:                kd_setleds1 (*data);
        !           188:                break;
1.1       root      189:            case K_X_KDB_ENTER:
                    190:                return X_kdb_enter_init(data, count);
                    191:            case K_X_KDB_EXIT:
                    192:                return X_kdb_exit_init(data, count);
                    193:            default:
                    194:                return (D_INVALID_OPERATION);
                    195:        }
                    196:        return (D_SUCCESS);
                    197: }
                    198: 
                    199: 
                    200: 
                    201: /*
                    202:  * kbdread - dequeue and return any queued events.
                    203:  */
                    204: 
                    205: boolean_t      kbd_read_done();        /* forward */
                    206: 
1.1.1.4 ! root      207: int
1.1       root      208: kbdread(dev, ior)
                    209:        dev_t   dev;
                    210:        register io_req_t       ior;
                    211: {
                    212:        register int    err, count;
                    213:        register spl_t  s;
                    214: 
1.1.1.2   root      215:        /* Check if IO_COUNT is a multiple of the record size. */
                    216:        if (ior->io_count % sizeof(kd_event) != 0)
                    217:            return D_INVALID_SIZE;
                    218: 
1.1       root      219:        err = device_read_alloc(ior, (vm_size_t)ior->io_count);
                    220:        if (err != KERN_SUCCESS)
                    221:            return (err);
                    222: 
                    223:        s = SPLKD();
                    224:        if (kdq_empty(&kbd_queue)) {
                    225:            if (ior->io_mode & D_NOWAIT) {
                    226:                splx(s);
                    227:                return (D_WOULD_BLOCK);
                    228:            }
                    229:            ior->io_done = kbd_read_done;
                    230:            enqueue_tail(&kbd_read_queue, (queue_entry_t) ior);
                    231:            splx(s);
                    232:            return (D_IO_QUEUED);
                    233:        }
                    234:        count = 0;
                    235:        while (!kdq_empty(&kbd_queue) && count < ior->io_count) {
                    236:            register kd_event *ev;
                    237: 
                    238:            ev = kdq_get(&kbd_queue);
                    239:            *(kd_event *)(&ior->io_data[count]) = *ev;
                    240:            count += sizeof(kd_event);
                    241:        }
                    242:        splx(s);
                    243:        ior->io_residual = ior->io_count - count;
                    244:        return (D_SUCCESS);
                    245: }
                    246: 
                    247: boolean_t kbd_read_done(ior)
                    248:        register io_req_t       ior;
                    249: {
                    250:        register int    count;
                    251:        register spl_t  s;
                    252: 
                    253:        s = SPLKD();
                    254:        if (kdq_empty(&kbd_queue)) {
                    255:            ior->io_done = kbd_read_done;
                    256:            enqueue_tail(&kbd_read_queue, (queue_entry_t)ior);
                    257:            splx(s);
                    258:            return (FALSE);
                    259:        }
                    260: 
                    261:        count = 0;
                    262:        while (!kdq_empty(&kbd_queue) && count < ior->io_count) {
                    263:            register kd_event *ev;
                    264: 
                    265:            ev = kdq_get(&kbd_queue);
                    266:            *(kd_event *)(&ior->io_data[count]) = *ev;
                    267:            count += sizeof(kd_event);
                    268:        }
                    269:        splx(s);
                    270: 
                    271:        ior->io_residual = ior->io_count - count;
                    272:        ds_read_done(ior);
                    273: 
                    274:        return (TRUE);
                    275: }
                    276: 
                    277: 
                    278: 
                    279: /*
                    280:  * kd_enqsc - enqueue a scancode.  Should be called at SPLKD.
                    281:  */
                    282: 
                    283: void
                    284: kd_enqsc(sc)
                    285:        Scancode sc;
                    286: {
                    287:        kd_event ev;
                    288: 
                    289:        ev.type = KEYBD_EVENT;
                    290:        ev.time = time;
                    291:        ev.value.sc = sc;
                    292:        kbd_enqueue(&ev);
                    293: }
                    294: 
                    295: 
                    296: /*
                    297:  * kbd_enqueue - enqueue an event and wake up selecting processes, if
                    298:  * any.  Should be called at SPLKD.
                    299:  */
                    300: 
                    301: void
                    302: kbd_enqueue(ev)
                    303:        kd_event *ev;
                    304: {
                    305:        if (kdq_full(&kbd_queue))
                    306:                printf("kbd: queue full\n");
                    307:        else
                    308:                kdq_put(&kbd_queue, ev);
                    309: 
                    310:        {
                    311:            register io_req_t   ior;
                    312:            while ((ior = (io_req_t)dequeue_head(&kbd_read_queue)) != 0)
                    313:                iodone(ior);
                    314:        }
                    315: }
                    316: 
                    317: u_int X_kdb_enter_str[512], X_kdb_exit_str[512];
                    318: int   X_kdb_enter_len = 0,  X_kdb_exit_len = 0;
                    319: 
1.1.1.4 ! root      320: void
1.1       root      321: kdb_in_out(p)
                    322: u_int *p;
                    323: {
                    324: register int t = p[0];
                    325: 
                    326:        switch (t & K_X_TYPE) {
                    327:                case K_X_IN|K_X_BYTE:
                    328:                        inb(t & K_X_PORT);
                    329:                        break;
                    330: 
                    331:                case K_X_IN|K_X_WORD:
                    332:                        inw(t & K_X_PORT);
                    333:                        break;
                    334: 
                    335:                case K_X_IN|K_X_LONG:
                    336:                        inl(t & K_X_PORT);
                    337:                        break;
                    338: 
                    339:                case K_X_OUT|K_X_BYTE:
                    340:                        outb(t & K_X_PORT, p[1]);
                    341:                        break;
                    342: 
                    343:                case K_X_OUT|K_X_WORD:
                    344:                        outw(t & K_X_PORT, p[1]);
                    345:                        break;
                    346: 
                    347:                case K_X_OUT|K_X_LONG:
                    348:                        outl(t & K_X_PORT, p[1]);
                    349:                        break;
                    350:        }
                    351: }
                    352: 
1.1.1.4 ! root      353: void
1.1       root      354: X_kdb_enter()
                    355: {
                    356: register u_int *u_ip, *endp;
                    357: 
                    358:        for (u_ip = X_kdb_enter_str, endp = &X_kdb_enter_str[X_kdb_enter_len];
                    359:             u_ip < endp;
                    360:             u_ip += 2)
                    361:            kdb_in_out(u_ip);
                    362: }
                    363: 
1.1.1.4 ! root      364: void
1.1       root      365: X_kdb_exit()
                    366: {
                    367: register u_int *u_ip, *endp;
                    368: 
                    369:        for (u_ip = X_kdb_exit_str, endp = &X_kdb_exit_str[X_kdb_exit_len];
                    370:             u_ip < endp;
                    371:             u_ip += 2)
                    372:           kdb_in_out(u_ip);
                    373: }
                    374: 
                    375: io_return_t
                    376: X_kdb_enter_init(data, count)
                    377:     u_int *data;
                    378:     u_int count;
                    379: {
                    380:     if (count * sizeof X_kdb_enter_str[0] > sizeof X_kdb_enter_str)
                    381:        return D_INVALID_OPERATION;
                    382: 
1.1.1.4 ! root      383:     memcpy(X_kdb_enter_str, data, count * sizeof X_kdb_enter_str[0]);
1.1       root      384:     X_kdb_enter_len = count;
                    385:     return D_SUCCESS;
                    386: }
                    387: 
                    388: io_return_t
                    389: X_kdb_exit_init(data, count)
                    390:     u_int *data;
                    391:     u_int count;
                    392: {
                    393:     if (count * sizeof X_kdb_exit_str[0] > sizeof X_kdb_exit_str)
                    394:        return D_INVALID_OPERATION;
                    395: 
1.1.1.4 ! root      396:     memcpy(X_kdb_exit_str, data, count * sizeof X_kdb_exit_str[0]);
1.1       root      397:     X_kdb_exit_len = count;
                    398:     return D_SUCCESS;
                    399: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.