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

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: static boolean_t initialized = FALSE;
                     87: 
                     88: 
                     89: /*
                     90:  * kbdinit - set up event queue.
                     91:  */
                     92: 
1.1.1.4   root       93: void
1.1.1.5 ! root       94: kbdinit(void)
1.1       root       95: {
                     96:        spl_t s = SPLKD();
1.1.1.3   root       97: 
1.1       root       98:        if (!initialized) {
                     99:                kdq_reset(&kbd_queue);
                    100:                initialized = TRUE;
                    101:        }
                    102:        splx(s);
                    103: }
                    104: 
                    105: 
                    106: /*
                    107:  * kbdopen - Verify that open is read-only and remember process
                    108:  * group leader.
                    109:  */
                    110: 
                    111: /*ARGSUSED*/
1.1.1.4   root      112: int
1.1.1.5 ! root      113: kbdopen(dev, flags, ior)
1.1       root      114:        dev_t dev;
                    115:        int flags;
1.1.1.5 ! root      116:        io_req_t ior;
1.1       root      117: {
1.1.1.4   root      118:        spl_t o_pri = spltty();
                    119:        kdinit();
                    120:        splx(o_pri);
1.1       root      121:        kbdinit();
                    122: 
                    123:        return(0);
                    124: }
                    125: 
                    126: 
                    127: /*
                    128:  * kbdclose - Make sure that the kd driver is in Ascii mode and
                    129:  * reset various flags.
                    130:  */
                    131: 
                    132: /*ARGSUSED*/
1.1.1.4   root      133: void
1.1.1.5 ! root      134: kbdclose(
        !           135:        dev_t   dev,
        !           136:        int     flags)
1.1       root      137: {
                    138:        spl_t s = SPLKD();
                    139: 
                    140:        kb_mode = KB_ASCII;
                    141:        kdq_reset(&kbd_queue);
                    142:        splx(s);
                    143: }
                    144: 
                    145: 
1.1.1.5 ! root      146: io_return_t kbdgetstat(
        !           147:        dev_t           dev,
        !           148:        int             flavor,
        !           149:        int *           data,           /* pointer to OUT array */
        !           150:        unsigned int    *count)         /* OUT */
1.1       root      151: {
                    152:        switch (flavor) {
                    153:            case KDGKBDTYPE:
                    154:                *data = KB_VANILLAKB;
                    155:                *count = 1;
                    156:                break;
1.1.1.2   root      157:            case DEV_GET_SIZE:
                    158:                data[DEV_GET_SIZE_DEVICE_SIZE] = 0;
                    159:                data[DEV_GET_SIZE_RECORD_SIZE] = sizeof(kd_event);
                    160:                *count = DEV_GET_SIZE_COUNT;
                    161:                break;
1.1       root      162:            default:
                    163:                return (D_INVALID_OPERATION);
                    164:        }
                    165:        return (D_SUCCESS);
                    166: }
                    167: 
1.1.1.5 ! root      168: io_return_t kbdsetstat(
        !           169:        dev_t           dev,
        !           170:        int             flavor,
        !           171:        int *           data,
        !           172:        unsigned int    count)
1.1       root      173: {
                    174:        switch (flavor) {
                    175:            case KDSKBDMODE:
                    176:                kb_mode = *data;
                    177:                /* XXX - what to do about unread events? */
                    178:                /* XXX - should check that 'data' contains an OK valud */
                    179:                break;
1.1.1.4   root      180:           case KDSETLEDS:
                    181:                if (count != 1)
                    182:                    return (D_INVALID_OPERATION);
                    183:                kd_setleds1 (*data);
                    184:                break;
1.1       root      185:            case K_X_KDB_ENTER:
1.1.1.5 ! root      186:                return X_kdb_enter_init((unsigned int *)data, count);
1.1       root      187:            case K_X_KDB_EXIT:
1.1.1.5 ! root      188:                return X_kdb_exit_init((unsigned int *)data, count);
1.1       root      189:            default:
                    190:                return (D_INVALID_OPERATION);
                    191:        }
                    192:        return (D_SUCCESS);
                    193: }
                    194: 
                    195: 
                    196: 
                    197: /*
                    198:  * kbdread - dequeue and return any queued events.
                    199:  */
1.1.1.4   root      200: int
1.1.1.5 ! root      201: kbdread(
        !           202:        dev_t           dev,
        !           203:        io_req_t        ior)
1.1       root      204: {
1.1.1.5 ! root      205:        int             err, count;
        !           206:        spl_t           s;
1.1       root      207: 
1.1.1.2   root      208:        /* Check if IO_COUNT is a multiple of the record size. */
                    209:        if (ior->io_count % sizeof(kd_event) != 0)
                    210:            return D_INVALID_SIZE;
                    211: 
1.1       root      212:        err = device_read_alloc(ior, (vm_size_t)ior->io_count);
                    213:        if (err != KERN_SUCCESS)
                    214:            return (err);
                    215: 
                    216:        s = SPLKD();
                    217:        if (kdq_empty(&kbd_queue)) {
                    218:            if (ior->io_mode & D_NOWAIT) {
                    219:                splx(s);
                    220:                return (D_WOULD_BLOCK);
                    221:            }
                    222:            ior->io_done = kbd_read_done;
                    223:            enqueue_tail(&kbd_read_queue, (queue_entry_t) ior);
                    224:            splx(s);
                    225:            return (D_IO_QUEUED);
                    226:        }
                    227:        count = 0;
                    228:        while (!kdq_empty(&kbd_queue) && count < ior->io_count) {
1.1.1.5 ! root      229:            kd_event *ev;
1.1       root      230: 
                    231:            ev = kdq_get(&kbd_queue);
                    232:            *(kd_event *)(&ior->io_data[count]) = *ev;
                    233:            count += sizeof(kd_event);
                    234:        }
                    235:        splx(s);
                    236:        ior->io_residual = ior->io_count - count;
                    237:        return (D_SUCCESS);
                    238: }
                    239: 
1.1.1.5 ! root      240: boolean_t kbd_read_done(io_req_t ior)
1.1       root      241: {
1.1.1.5 ! root      242:        int             count;
        !           243:        spl_t           s;
1.1       root      244: 
                    245:        s = SPLKD();
                    246:        if (kdq_empty(&kbd_queue)) {
                    247:            ior->io_done = kbd_read_done;
                    248:            enqueue_tail(&kbd_read_queue, (queue_entry_t)ior);
                    249:            splx(s);
                    250:            return (FALSE);
                    251:        }
                    252: 
                    253:        count = 0;
                    254:        while (!kdq_empty(&kbd_queue) && count < ior->io_count) {
1.1.1.5 ! root      255:            kd_event *ev;
1.1       root      256: 
                    257:            ev = kdq_get(&kbd_queue);
                    258:            *(kd_event *)(&ior->io_data[count]) = *ev;
                    259:            count += sizeof(kd_event);
                    260:        }
                    261:        splx(s);
                    262: 
                    263:        ior->io_residual = ior->io_count - count;
                    264:        ds_read_done(ior);
                    265: 
                    266:        return (TRUE);
                    267: }
                    268: 
                    269: 
                    270: 
                    271: /*
                    272:  * kd_enqsc - enqueue a scancode.  Should be called at SPLKD.
                    273:  */
                    274: 
                    275: void
1.1.1.5 ! root      276: kd_enqsc(Scancode sc)
1.1       root      277: {
                    278:        kd_event ev;
                    279: 
                    280:        ev.type = KEYBD_EVENT;
                    281:        ev.time = time;
                    282:        ev.value.sc = sc;
                    283:        kbd_enqueue(&ev);
                    284: }
                    285: 
                    286: 
                    287: /*
                    288:  * kbd_enqueue - enqueue an event and wake up selecting processes, if
                    289:  * any.  Should be called at SPLKD.
                    290:  */
                    291: 
                    292: void
1.1.1.5 ! root      293: kbd_enqueue(kd_event *ev)
1.1       root      294: {
                    295:        if (kdq_full(&kbd_queue))
1.1.1.5 ! root      296:                printf_once("kbd: queue full\n");
1.1       root      297:        else
                    298:                kdq_put(&kbd_queue, ev);
                    299: 
                    300:        {
1.1.1.5 ! root      301:            io_req_t    ior;
1.1       root      302:            while ((ior = (io_req_t)dequeue_head(&kbd_read_queue)) != 0)
                    303:                iodone(ior);
                    304:        }
                    305: }
                    306: 
                    307: u_int X_kdb_enter_str[512], X_kdb_exit_str[512];
                    308: int   X_kdb_enter_len = 0,  X_kdb_exit_len = 0;
                    309: 
1.1.1.4   root      310: void
1.1       root      311: kdb_in_out(p)
1.1.1.5 ! root      312: const u_int *p;
1.1       root      313: {
1.1.1.5 ! root      314:        int t = p[0];
1.1       root      315: 
                    316:        switch (t & K_X_TYPE) {
                    317:                case K_X_IN|K_X_BYTE:
                    318:                        inb(t & K_X_PORT);
                    319:                        break;
                    320: 
                    321:                case K_X_IN|K_X_WORD:
                    322:                        inw(t & K_X_PORT);
                    323:                        break;
                    324: 
                    325:                case K_X_IN|K_X_LONG:
                    326:                        inl(t & K_X_PORT);
                    327:                        break;
                    328: 
                    329:                case K_X_OUT|K_X_BYTE:
                    330:                        outb(t & K_X_PORT, p[1]);
                    331:                        break;
                    332: 
                    333:                case K_X_OUT|K_X_WORD:
                    334:                        outw(t & K_X_PORT, p[1]);
                    335:                        break;
                    336: 
                    337:                case K_X_OUT|K_X_LONG:
                    338:                        outl(t & K_X_PORT, p[1]);
                    339:                        break;
                    340:        }
                    341: }
                    342: 
1.1.1.4   root      343: void
1.1.1.5 ! root      344: X_kdb_enter(void)
1.1       root      345: {
1.1.1.5 ! root      346:        u_int *u_ip, *endp;
1.1       root      347: 
                    348:        for (u_ip = X_kdb_enter_str, endp = &X_kdb_enter_str[X_kdb_enter_len];
                    349:             u_ip < endp;
                    350:             u_ip += 2)
                    351:            kdb_in_out(u_ip);
                    352: }
                    353: 
1.1.1.4   root      354: void
1.1.1.5 ! root      355: X_kdb_exit(void)
1.1       root      356: {
1.1.1.5 ! root      357:        u_int *u_ip, *endp;
1.1       root      358: 
                    359:        for (u_ip = X_kdb_exit_str, endp = &X_kdb_exit_str[X_kdb_exit_len];
                    360:             u_ip < endp;
                    361:             u_ip += 2)
                    362:           kdb_in_out(u_ip);
                    363: }
                    364: 
                    365: io_return_t
1.1.1.5 ! root      366: X_kdb_enter_init(
        !           367:     u_int *data,
        !           368:     u_int count)
1.1       root      369: {
                    370:     if (count * sizeof X_kdb_enter_str[0] > sizeof X_kdb_enter_str)
                    371:        return D_INVALID_OPERATION;
                    372: 
1.1.1.4   root      373:     memcpy(X_kdb_enter_str, data, count * sizeof X_kdb_enter_str[0]);
1.1       root      374:     X_kdb_enter_len = count;
                    375:     return D_SUCCESS;
                    376: }
                    377: 
                    378: io_return_t
1.1.1.5 ! root      379: X_kdb_exit_init(
        !           380:     u_int *data,
        !           381:     u_int count)
1.1       root      382: {
                    383:     if (count * sizeof X_kdb_exit_str[0] > sizeof X_kdb_exit_str)
                    384:        return D_INVALID_OPERATION;
                    385: 
1.1.1.4   root      386:     memcpy(X_kdb_exit_str, data, count * sizeof X_kdb_exit_str[0]);
1.1       root      387:     X_kdb_exit_len = count;
                    388:     return D_SUCCESS;
                    389: }

unix.superglobalmegacorp.com

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