Annotation of coherent/d/PS2_KERNEL/io.386/nkb.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * User configurable AT keyboard/display driver.
                      3:  * 286/386 AT COHERENT
                      4:  */
                      5: #include <sys/coherent.h>
                      6: #ifdef _I386
                      7: #include <sys/reg.h>
                      8: #else
                      9: #include <sys/i8086.h>
                     10: #endif
                     11: #include <sys/con.h>
                     12: #include <errno.h>
                     13: #include <sys/stat.h>
                     14: #include <sys/tty.h>
                     15: #include <signal.h>
                     16: #include <sys/seg.h>
                     17: #include <sys/sched.h>
                     18: #include <sys/kb.h>
                     19: #include <sys/devices.h>
                     20: #include <sys/silo.h>
                     21: 
                     22: #define        ISVEC           1               /* Keyboard interrupt vector */
                     23: 
                     24: #if    DEBUG
                     25: #define        KBDEBUG(x)      printf(x)       /* debugging output */
                     26: #define        KBDEBUG2(x,y)   printf(x,y)     /* debugging output */
                     27: #define        KBDEBUG3(x,y,z) printf(x,y,z)   /* debugging output */
                     28: #else
                     29: #define        KBDEBUG(x)                      /* no output */
                     30: #define        KBDEBUG2(x,y)                   /* no output */
                     31: #define        KBDEBUG3(x,y,z)                 /* no output */
                     32: #endif
                     33: 
                     34: /*
                     35:  * values for kbstate
                     36:  */
                     37: #define        KB_IDLE         0               /* nothing going on right now */
                     38: #define        KB_SINGLE       1               /* sent a single byte cmd to the kbd */
                     39: #define        KB_DOUBLE_1     2               /* sent 1st byte of 2-byte cmd to kbd */
                     40: #define        KB_DOUBLE_2     3               /* sent 2nd byte of 2-byte cmd to kbd */
                     41: 
                     42: /*
                     43:  * patchable params for non-standard keyboards
                     44:  */
                     45: int    KBDATA = 0x60;                  /* Keyboard data */
                     46: int    KBCTRL = 0x61;                  /* Keyboard control */
                     47: int    KBSTS_CMD = 0x64;               /* Keyboard status/command */
                     48: int    KBFLAG = 0x80;                  /* Keyboard reset flag */
                     49: int    KBBOOT = 1;                     /* 0: disallow reboot from keyboard */
                     50: int    KBTIMEOUT = 10000;              /* shouldn't need this much */
                     51: int    KBCMDBYTE = 0x05;               /* no translation */
                     52: 
                     53: /*
                     54:  * KBSTATUS bits
                     55:  */
                     56: #define        STS_OBUF_FULL   0x01            /* kbd output buffer full */
                     57: #define        STS_IBUF_FULL   0x02            /* kbd input buffer full */
                     58: #define        STS_SYSTEM      0x04
                     59: #define        STS_CMD_DATA    0x08            /* 1: command or status */
                     60: #define        STS_INHIBIT     0x10            /* 0: keyboard inhibited */
                     61: #define        STS_AUX_OBUF_FULL       0x20
                     62: #define        STS_TIMEOUT     0x40            /* general timeout */
                     63: #define        STS_PAR_ERR     0x80            /* parity error */
                     64: 
                     65: /*
                     66:  * The following are magic commands which read from or write to the
                     67:  * controller command byte. These get output to the KBSTS_CMD port.
                     68:  */
                     69: #define        C_READ_CMD      0x20            /* read controller command byte */
                     70: #define        C_WRITE_CMD     0x60            /* write controller command byte */
                     71: #define        C_TRANSLATE     0x40            /* translate enable bit in cmd byte */
                     72: 
                     73: /*
                     74:  * Globals:
                     75:  * The 286 keyboard mapping table is too large to fit into kernel data space,
                     76:  * so we need to allocate a segment to it.  386 is easy.
                     77:  * The function keys tend to be small and tend to change substantially
                     78:  * more often than the mapping table, so we keep them in the kernel data space.
                     79:  */
                     80: static unsigned shift;                 /* state of all shift/lock keys */
                     81: static unsigned char   **funkeyp = 0;  /* ptr to array of func. keys ptrs */
                     82: static FNKEY   *fnkeys = 0;            /* pointer to structure of values */
                     83: static unsigned fklength;              /* length of k_fnval field in fnkeys */
                     84: static unsigned prev_cmd;              /* previous command sent to KBD */
                     85: static unsigned cmd2;                  /* 2nd byte of command to KBD */
                     86: static unsigned sh_index;              /* shift/lock state index */
                     87: #ifdef _I386
                     88: static KBTBL   kb[MAX_KEYS];           /* keyboard table */
                     89: #else
                     90: static SEG     *kbsegp;                /* keyboard table segment */
                     91: #endif
                     92: 
                     93: /*
                     94:  * State variables.
                     95:  */
                     96: int            islock;                 /* Keyboard locked flag */
                     97: int            isbusy;                 /* Raw input conversion busy */
                     98: static char    table_loaded;           /* true == keyboard table resident */
                     99: static char    fk_loaded;              /* true == function keys resident */
                    100: static int     kbstate = KB_IDLE;      /* current keyboard state */
                    101: 
                    102: /*
                    103:  * Functions.
                    104:  */
                    105: int            isrint();
                    106: int            istime();
                    107: void           isbatch();
                    108: int            mmstart();
                    109: int            isopen();
                    110: int            isclose();
                    111: int            isread();
                    112: int            mmwrite();
                    113: int            isioctl();
                    114: void           mmwatch();
                    115: int            isload();
                    116: int            isuload();
                    117: int            ispoll();
                    118: int            nulldev();
                    119: int            nonedev();
                    120: int            updleds();
                    121: 
                    122: static int     isioctl0();
                    123: 
                    124: /*
                    125:  * Configuration table.
                    126:  */
                    127: CON iscon ={
                    128:        DFCHR|DFPOL,                    /* Flags */
                    129:        KB_MAJOR,                       /* Major index */
                    130:        isopen,                         /* Open */
                    131:        isclose,                        /* Close */
                    132:        nulldev,                        /* Block */
                    133:        isread,                         /* Read */
                    134:        mmwrite,                        /* Write */
                    135: #ifdef _I386
                    136:        isioctl0,                       /* Ioctl */
                    137: #else
                    138:        isioctl,                        /* Ioctl */
                    139: #endif
                    140:        nulldev,                        /* Powerfail */
                    141:        mmwatch,                        /* Timeout */
                    142:        isload,                         /* Load */
                    143:        isuload,                        /* Unload */
                    144:        ispoll                          /* Poll */
                    145: };
                    146: 
                    147: /*
                    148:  * Terminal structure.
                    149:  */
                    150: TTY    istty = {
                    151:        {0}, {0}, 0, mmstart, NULL, 0, 0
                    152: };
                    153: 
                    154: static silo_t in_silo;
                    155: 
                    156: /*
                    157:  * Load entry point.
                    158:  */
                    159: isload()
                    160: {
                    161:        kbstate = KB_IDLE;
                    162:        table_loaded = 0;               /* no keyboard table yet */
                    163:        fk_loaded = 0;                  /* no Fn keys yet */
                    164: 
                    165:        /*
                    166:         * Enable mmwatch() invocation every second.
                    167:         */
                    168:        drvl[KB_MAJOR].d_time = 1;
                    169: 
                    170:        /*
                    171:         * Seize keyboard interrupt.
                    172:         */
                    173:        setivec(ISVEC, isrint);
                    174: 
                    175:        /*
                    176:         * Initiailize video display.
                    177:         */
                    178:        mmstart(&istty);
                    179: 
                    180: #ifndef _I386
                    181:        /*
                    182:         * Allocate a 286 segment to store the in-core keyboard table.
                    183:         * This would be a lot more convenient in kernel data space,
                    184:         * but small model COHERENT doesn't have that luxury.
                    185:         */
                    186:        kbsegp = salloc((fsize_t)MAX_TABLE_SIZE, SFSYST|SFNSWP|SFHIGH);
                    187:        if (kbsegp == (SEG *)0)
                    188:                printf("kb: unable to allocate keyboard table segment\n");
                    189: #endif
                    190:        fklength = 0;
                    191:        KBDEBUG("Exiting kbload()\n");
                    192: }
                    193: 
                    194: /*
                    195:  * Unload entry point.
                    196:  */
                    197: isuload()
                    198: {
                    199:        if (kbstate != KB_IDLE)
                    200:                printf("kb: keyboard busy during unload\n");
                    201:        clrivec(ISVEC);
                    202: #ifndef _I386
                    203:        if (kbsegp != (SEG *)0) {
                    204:                table_loaded = 0;
                    205:                sfree(kbsegp);
                    206:        }
                    207: #endif
                    208: }
                    209: 
                    210: /*
                    211:  * Open routine.
                    212:  */
                    213: isopen(dev, mode)
                    214: dev_t dev;
                    215: unsigned int mode;
                    216: {
                    217:        register int s;
                    218: 
                    219:        KBDEBUG(" kbopen()");
                    220:        if (minor(dev) != 0) {
                    221:                u.u_error = ENXIO;
                    222:                return;
                    223:        }
                    224:        if ((istty.t_flags&T_EXCL) != 0 && !super()) {
                    225:                u.u_error = ENODEV;
                    226:                return;
                    227:        }
                    228:        ttsetgrp(&istty, dev, mode);
                    229: 
                    230:        s = sphi();
                    231:        if (istty.t_open++ == 0) {
                    232:                istty.t_flags = T_CARR; /* indicate "carrier" */
                    233:                ttopen(&istty);
                    234:        }
                    235:        spl(s);
                    236: #if 0
                    237:        updleds();                      /* update keyboard status LEDS */
                    238: #endif
                    239: }
                    240: 
                    241: /*
                    242:  * Close a tty.
                    243:  */
                    244: isclose(dev)
                    245: {
                    246:        register int s;
                    247: 
                    248:        s = sphi();
                    249:        if (--istty.t_open == 0) {
                    250:                ttclose(&istty);
                    251:        }
                    252:        spl(s);
                    253: }
                    254: 
                    255: /*
                    256:  * Read routine.
                    257:  */
                    258: isread(dev, iop)
                    259: dev_t dev;
                    260: IO *iop;
                    261: {
                    262:        ttread(&istty, iop, 0);
                    263:        if (istty.t_oq.cq_cc)
                    264:                mmtime(&istty);
                    265: }
                    266: 
                    267: /*
                    268:  * Ioctl routine.
                    269:  * nb: archaic TIOCSHIFT and TIOCCSHIFT no longer needed/supported.
                    270:  */
                    271: #ifdef _I386
                    272: isioctl0(dev, com, vec)
                    273: dev_t dev;
                    274: struct sgttyb *vec;
                    275: {
                    276:        tioc286(dev, com, vec, isioctl);
                    277: }
                    278: #endif
                    279: 
                    280: isioctl(dev, com, vec)
                    281: dev_t dev;
                    282: struct sgttyb *vec;
                    283: {
                    284:        register int s;
                    285: 
                    286:        switch (com) {
                    287:        case TIOCSETF:
                    288:        case TIOCGETF:
                    289:                isfunction(com, (char *)vec);
                    290:                break;
                    291:        case TIOCSETKBT:
                    292:                issettable(vec);
                    293:                break;
                    294:        case TIOCGETKBT:
                    295:                isgettable(vec);
                    296:                break;
                    297:        default:                                /* pass to TTY driver */
                    298:                s = sphi();
                    299:                ttioctl(&istty, com, vec);
                    300:                spl(s);
                    301:                break;
                    302:        }
                    303: }
                    304: 
                    305: /*
                    306:  * Set the in-core keyboard mapping table.
                    307:  * The table is sorted by scan code prior to calling ioctl().
                    308:  * All unused table entries (holes in the scan code map) have
                    309:  * a zero for the k_key field.
                    310:  * This makes key lookup at interrupt time fast by using the scan code
                    311:  * as an index into the table.
                    312:  */
                    313: issettable(vec)
                    314: char   *vec;
                    315: {
                    316:        register unsigned i;
                    317:        register int s;
                    318:        int timeout;
                    319:        static  KBTBL   this_key;       /* current key from kbd table */
                    320:        unsigned int cmd_byte;
                    321: #ifndef _I386
                    322:        register faddr_t faddr;         /* address of keyboard table */
                    323: #endif
                    324: 
                    325:        KBDEBUG(" TIOCSETKBT");
                    326:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
                    327:        kb_cmd(K_ALL_TMB_CMD);                  /* default: TMB for all keys */
                    328: #ifndef _I386
                    329:        faddr = kbsegp->s_faddr;
                    330: #endif
                    331:        for (i = 0; i < MAX_KEYS; ++i) {
                    332:                ukcopy(vec, &this_key, sizeof(this_key));
                    333: #ifdef _I386
                    334:                kb[i] = this_key;               /* store away */
                    335: #else
                    336:                kfcopy(&this_key, faddr, sizeof(this_key));
                    337:                faddr += sizeof(this_key);
                    338: #endif
                    339:                vec += sizeof(this_key);
                    340:                if (this_key.k_key != i && this_key.k_key != 0) {
                    341:                        printf("kb: incorrect or unsorted table entry %d\n", i);
                    342: #ifdef _I386
                    343:                        u.u_error = EINVAL;
                    344: #else
                    345:                        u.u_error = EBADFMT;
                    346: #endif
                    347:                        return;
                    348:                }
                    349:                if (this_key.k_key != i)
                    350:                        continue;               /* no key */
                    351:                switch (this_key.k_flags&TMODE) {
                    352:                case T:                         /* typematic */
                    353:                        kb_cmd2(K_KEY_T_CMD, i);
                    354:                        break;
                    355:                case M:                         /* make only */
                    356:                        kb_cmd2(K_KEY_M_CMD, i);
                    357:                        break;
                    358:                case MB:                        /* make/break */
                    359:                        kb_cmd2(K_KEY_MB_CMD, i);
                    360:                        break;
                    361:                case TMB:                       /* typematic make/break */
                    362:                        break;                  /* this is the default */
                    363:                default:
                    364:                        printf("kb: bad key mode\n");
                    365:                }
                    366:        }
                    367:        updleds();
                    368:        kb_cmd2(K_SCANCODE_CMD, 3);             /* select set 3 */
                    369:        kb_cmd(K_ENABLE_CMD);                   /* start scanning */
                    370:        /*
                    371:         * The following code disables translation from the on-board
                    372:         * keyboard/aux controller. Without disabling translation, the
                    373:         * received scan codes still look like code set 1 codes even
                    374:         * though we put the keyboard controller in scan code set 3.
                    375:         * Yes, this is progress....
                    376:         */
                    377: #if 0
                    378:        while (inb(KBSTS_CMD) & STS_IBUF_FULL)
                    379:                ;
                    380:        outb(KBSTS_CMD, C_READ_CMD);            /* read controller cmd byte */
                    381:        while (!(inb(KBSTS_CMD) & STS_OBUF_FULL))
                    382:                ;
                    383:        cmd_byte = inb(KBDATA);
                    384:        KBDEBUG2(" cmd_byte=%x", cmd_byte);
                    385: #endif
                    386:        timeout = KBTIMEOUT;
                    387:        s = sphi();
                    388:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    389:                ;
                    390:        outb(KBSTS_CMD, C_WRITE_CMD);           /* write controller cmd byte */
                    391:        for (timeout = 50; --timeout > 0;)
                    392:                ;
                    393:        timeout = KBTIMEOUT;
                    394:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    395:                ;
                    396:        outb(KBDATA, KBCMDBYTE);                 /* turn off translation */     
                    397:        timeout = KBTIMEOUT;
                    398:        while ((inb(KBSTS_CMD) & STS_IBUF_FULL) && --timeout > 0)
                    399:                ;
                    400:        spl(s);
                    401: #if DEBUG
                    402:        kb_cmd2(K_SCANCODE_CMD, 0);             /* query s.c. mode */
                    403: #endif
                    404:        ++table_loaded;
                    405: }
                    406: 
                    407: /*
                    408:  * Get the in-core keyboard mapping table and pass it to the user.
                    409:  */
                    410: isgettable(vec)
                    411: char   *vec;
                    412: {
                    413: #ifdef _I386
                    414:        KBDEBUG(" TIOCGETKBT");
                    415:        kucopy(kb, vec, sizeof(kb));
                    416: #else
                    417:        register unsigned i;
                    418:        register faddr_t faddr;         /* address of keyboard table */
                    419:        static  KBTBL   this_key;       /* current key from kbd table */
                    420: 
                    421:        KBDEBUG(" TIOCGETKBT");
                    422:        faddr = kbsegp->s_faddr;
                    423:        for (i = 0; i < MAX_KEYS; ++i) {
                    424:                fkcopy(faddr, &this_key, sizeof(this_key));
                    425:                kucopy(&this_key, vec, sizeof(this_key));
                    426:                faddr += sizeof(this_key);
                    427:                vec += sizeof(this_key);
                    428:        }
                    429: #endif
                    430: }
                    431: 
                    432: 
                    433: /*
                    434:  * Set and receive the function keys.
                    435:  */
                    436: isfunction(c, v)
                    437: int c;
                    438: FNKEY *v;
                    439: {
                    440:        register unsigned char *cp;
                    441:        register unsigned i;
                    442:        unsigned char   numkeys = 0;
                    443: 
                    444:        if (c == TIOCGETF) {
                    445:                KBDEBUG(" TIOCGETF");
                    446:                if (!fk_loaded)
                    447:                        u.u_error = EINVAL;
                    448:                else
                    449:                        kucopy(fnkeys, v, fklength);    /* copy ours to user */
                    450:        } else { /* TIOCSETF */
                    451:                /*
                    452:                 * If we had a previous function key arena, free it up.
                    453:                 * Since we don't know how large the function key arena will
                    454:                 * be, we must size it in the user data space prior to
                    455:                 * (re)kalloc()'ing it. This is ugly, but a helluva lot better
                    456:                 * than the old driver which used a hard coded limit of 150!
                    457:                 */
                    458:                KBDEBUG(" TIOCSETF");
                    459:                fk_loaded = 0;
                    460:                if (fnkeys != (FNKEY *)0)
                    461:                        kfree(fnkeys);          /* free old arena */
                    462:                if (funkeyp != NULL)
                    463:                        kfree(funkeyp);         /* free old ptr array */
                    464:                ukcopy(&v->k_nfkeys, &numkeys, sizeof(numkeys));
                    465:                fklength = sizeof(FNKEY);
                    466:                cp = v->k_fnval;
                    467:                for (i = 0; i < numkeys; i++) {
                    468:                        do {
                    469:                                ++fklength;
                    470:                        } while (getubd(cp++) != DELIM);
                    471:                }
                    472:                fnkeys = (FNKEY *)kalloc(fklength);
                    473:                funkeyp = (unsigned char **)kalloc(numkeys * sizeof(char *));
                    474:                if (fnkeys == (FNKEY *)0 || funkeyp == NULL) {
                    475:                        if (fnkeys != (FNKEY *)0) {
                    476:                                kfree(fnkeys);
                    477:                                fnkeys = 0;
                    478:                        }
                    479:                        if (funkeyp != NULL) {
                    480:                                kfree(funkeyp);
                    481:                                funkeyp = 0;
                    482:                        }
                    483:                        u.u_error = ENOMEM;
                    484:                        return;
                    485:                }
                    486:                cp = fnkeys->k_fnval;                   /* point to Fn ... */
                    487:                v = v->k_fnval;                         /* ... key arena */
                    488:                for (i = 0; i < numkeys; i++) {
                    489:                        funkeyp[i] = cp;                   /* save pointer */
                    490:                        while ((*cp++ = getubd(v++)) != DELIM)  /* copy key */
                    491:                                ;
                    492:                }
                    493:                fnkeys->k_nfkeys = numkeys;
                    494:                fk_loaded = 1;
                    495:        }
                    496: }
                    497: 
                    498: 
                    499: /*
                    500:  * Poll routine.
                    501:  */
                    502: ispoll(dev, ev, msec)
                    503: dev_t dev;
                    504: int ev;
                    505: int msec;
                    506: {
                    507:        return ttpoll(&istty, ev, msec);
                    508: }
                    509: 
                    510: /*
                    511:  * Receive interrupt.
                    512:  */
                    513: isrint()
                    514: {
                    515:        register unsigned c;
                    516:        register unsigned r;
                    517:        static  char keyup;
                    518: 
                    519:        /*
                    520:         * Schedule raw input handler if not already active.
                    521:         */
                    522:        if (!isbusy) {
                    523:                defer(isbatch, &istty);
                    524:                isbusy = 1;
                    525:        }
                    526: 
                    527:        /*
                    528:         * Pull character from the data
                    529:         * port. Pulse the KBFLAG in the control
                    530:         * port to reset the data buffer.
                    531:         */
                    532:        r = inb(KBDATA) & 0xFF;
                    533:        c = inb(KBCTRL);
                    534:        outb(KBCTRL, c|KBFLAG);
                    535:        outb(KBCTRL, c);
                    536: 
                    537:        /*
                    538:         * check returned value from keyboard to see if it's a command
                    539:         * or status back to us. If not, it we assume that it's a key code.
                    540:         */
                    541:        KBDEBUG2(" intr(%x)", r);
                    542:        switch (r) {
                    543:        case K_BREAK:
                    544:                keyup = 1;                      /* key going up */
                    545:                break;
                    546:        case K_ECHO_R:
                    547:        case K_BAT_OK:
                    548:                break;                          /* very nice, but ignored */
                    549:        case K_BAT_BAD:
                    550:                printf("kb: keyboard BAT failed\n");
                    551:                break;
                    552:        case K_RESEND:
                    553:                KBDEBUG("\nkb: request to resend command\n");
                    554:                outb(KBDATA, prev_cmd);
                    555:                break;
                    556:        case K_OVERRUN_23:
                    557:                printf("kb: keyboard buffer overrun\n");
                    558:                break;
                    559:        case K_ACK:
                    560:                /*
                    561:                 * we received an ACKnowledgement from the keyboard.
                    562:                 * advance the state machine and continue.
                    563:                 */
                    564:                KBDEBUG(" ACK");
                    565:                switch (kbstate) {
                    566:                case KB_IDLE:                   /* shouldn't happen */
                    567:                        printf("kb: ACK while keyboard idle\n");
                    568:                        break;
                    569:                case KB_SINGLE:                 /* done with 1-byte command */
                    570:                case KB_DOUBLE_2:               /* done w/ 2nd of 2-byte cmd */
                    571:                        kbstate = KB_IDLE;
                    572:                        wakeup(&kbstate);
                    573:                        break;
                    574:                case KB_DOUBLE_1:
                    575:                        kbstate = KB_DOUBLE_2;
                    576:                        outb(KBDATA, cmd2);
                    577:                        break;
                    578:                default:
                    579:                        printf("kb: bad kbstate %d\n", kbstate);
                    580:                        break;
                    581:                }
                    582:                break;
                    583:        default:
                    584:                process_key(r, keyup);
                    585:                keyup = 0;
                    586:        }
                    587: }
                    588: 
                    589: /*
                    590:  * Process a key given its scan code and direction.
                    591:  * 
                    592:  * In this table driven version of the keyboard driver, we trade off the
                    593:  * code complexity associated with all the black magic that used to be
                    594:  * performed on a per-key basis with the increased memory requirements
                    595:  * associated with the table driven approach.
                    596:  */
                    597: process_key(key, up)
                    598: unsigned key;
                    599: int     up;
                    600: {
                    601:        register unsigned char *cp;
                    602:        KBTBL   key_vals;                       /* table values for this key */
                    603:        unsigned val;
                    604:        unsigned char flags;
                    605: 
                    606:        KBDEBUG3(" proc(%x %s)", key, (up ? "up" : "down"));
                    607:        if (!table_loaded)
                    608:                return;                         /* throw away key */
                    609: #ifdef _I386
                    610:        key_vals = kb[key];
                    611: #else
                    612:        fkcopy(kbsegp->s_faddr + (key * sizeof(KBTBL)),
                    613:                &key_vals, sizeof(key_vals));
                    614: #endif
                    615:        if (key_vals.k_key != key)              /* empty entry */
                    616:                return;
                    617:        flags = key_vals.k_flags;
                    618: 
                    619:        if (flags & S) {                        /* some shift/lock key ? */
                    620:                switch (key_vals.k_val[BASE]) {
                    621:                case caps:
                    622:                case num:
                    623:                        if (!up) {
                    624:                                shift ^= (1 << key_vals.k_val[BASE]);
                    625:                                updleds2();
                    626:                        }
                    627:                        break;
                    628:                case scroll:
                    629:                        if (!up) {
                    630:                                shift ^= (1 << key_vals.k_val[BASE]);
                    631:                                updleds2();
                    632:                                if (!(istty.t_sgttyb.sg_flags&RAWIN)) {
                    633:                                        if (istty.t_flags & T_STOP) {
                    634:                                                isin(istty.t_tchars.t_startc);
                    635:                                        } else {
                    636:                                                isin(istty.t_tchars.t_stopc);
                    637:                                        }
                    638:                                }
                    639:                        }
                    640:                        break;
                    641:                default:
                    642:                        if (up)
                    643:                                shift &= ~(1 << key_vals.k_val[BASE]);
                    644:                        else
                    645:                                shift |= (1 << key_vals.k_val[BASE]);
                    646:                        break;
                    647:                }
                    648:                /*
                    649:                 * Calculate the shift index based upon the state of
                    650:                 * the shift and lock keys.
                    651:                 */
                    652:                sh_index = BASE;                /* default condition */
                    653:                if (shift & (1 << altgr))
                    654:                        sh_index = ALT_GR;
                    655:                else {
                    656:                        if (shift & ((1 << lalt)|(1 << ralt)))
                    657:                                sh_index |= ALT;
                    658:                        if (shift & ((1 << lctrl)|(1 << rctrl)))
                    659:                                sh_index |= CTRL;
                    660:                        if (shift & ((1 << lshift)|(1 << rshift)))
                    661:                                sh_index |= SHIFT;
                    662:                }
                    663:                return;
                    664:        } /* if (flags & S) */
                    665: 
                    666:        /*
                    667:         * If the tty is not open or the key has no value in the current
                    668:         * shift state, the key is just tossed away.
                    669:         */
                    670:        if (up || !istty.t_open || key_vals.k_val[sh_index] == none)
                    671:                return;
                    672:        if (((flags & C) && (shift & (1 << caps)))
                    673:           || ((flags & N) && (shift & (1 << num))))
                    674:                val = key_vals.k_val[sh_index^SHIFT];
                    675:        else
                    676:                val = key_vals.k_val[sh_index];
                    677: 
                    678:        /*
                    679:         * Check for function key or special key implemented as
                    680:         * a function key (reboot == f0, tab and back-tab, etc).
                    681:         */
                    682:        if (flags & F) {
                    683:                if (val == 0 && !up && KBBOOT)
                    684:                        boot();
                    685:                if (!fk_loaded || val >= fnkeys->k_nfkeys)
                    686:                        return;
                    687:                if ((cp = funkeyp[val]) == NULL) /* has a value? */
                    688:                        return;
                    689:                while (*cp != DELIM)
                    690:                        isin(*cp++);            /* queue up Fn key value */
                    691:                return;
                    692:        }
                    693: 
                    694:        /*
                    695:         * Normal key processing.
                    696:         */
                    697:        isin(val);               /* send the char */
                    698:        return;
                    699: }
                    700: 
                    701: /**
                    702:  *
                    703:  * void
                    704:  * ismmfunc(c) -- process keyboard related output escape sequences
                    705:  * char c;
                    706:  */
                    707: void
                    708: ismmfunc(c)
                    709: register int c;
                    710: {
                    711:        switch (c) {
                    712:        case 't':       /* Enter numlock */
                    713:                shift |= (1 << num);
                    714:                updleds();                      /* update LED status */
                    715:                break;
                    716:        case 'u':       /* Leave numlock */
                    717:                shift &= ~(1 << num);
                    718:                updleds();                      /* update LED status */
                    719:                break;
                    720:        case '=':                       /* Enter alternate keypad -- ignored */
                    721:        case '>':                       /* Exit alternate keypad -- ignored */
                    722:                break;
                    723:        case 'c':       /* Reset terminal */
                    724:                islock = 0;
                    725:                break;
                    726:        }
                    727: }
                    728: 
                    729: /**
                    730:  *
                    731:  * void
                    732:  * isin(c)     -- append character to raw input silo
                    733:  * char c;
                    734:  */
                    735: static
                    736: isin(c)
                    737: register int c;
                    738: {
                    739:        int cache_it = 1;
                    740:        TTY * tp = &istty;
                    741:        void ttstart();
                    742: 
                    743:        /*
                    744:         * If using software incoming flow control, process and
                    745:         * discard t_stopc and t_startc.
                    746:         */
                    747:        if (!ISRIN) {
                    748:                if (ISSTOP) {
                    749:                        if ((tp->t_flags&T_STOP) == 0)
                    750:                                tp->t_flags |= T_STOP;
                    751:                        cache_it = 0;
                    752:                }
                    753:                if (ISSTART) {
                    754:                        tp->t_flags &= ~T_STOP;
                    755:                        defer(ttstart, tp);
                    756:                        cache_it = 0;
                    757:                }
                    758:        }
                    759: 
                    760:        /*
                    761:         * Cache received character.
                    762:         */
                    763:        if (cache_it) {
                    764:                in_silo.si_buf[ in_silo.si_ix ] = c;
                    765: 
                    766:                if (++in_silo.si_ix >= sizeof(in_silo.si_buf))
                    767:                        in_silo.si_ix = 0;
                    768:        }
                    769: }
                    770: 
                    771: /**
                    772:  *
                    773:  * void
                    774:  * isbatch()   -- raw input conversion routine
                    775:  *
                    776:  *     Action: Enable the video display.
                    777:  *             Canonize the raw input silo.
                    778:  *
                    779:  *     Notes:  isbatch() was scheduled as a deferred process by isrint().
                    780:  */
                    781: static void
                    782: isbatch(tp)
                    783: register TTY * tp;
                    784: {
                    785:        register int c;
                    786:        static int lastc;
                    787: 
                    788:        /*
                    789:         * Ensure video display is enabled.
                    790:         */
                    791:        mm_von();
                    792:        isbusy = 0;
                    793: 
                    794:        /*
                    795:         * Process all cached characters.
                    796:         */
                    797:        while (in_silo.si_ix != in_silo.si_ox) {
                    798:                /*
                    799:                 * Get next cached char.
                    800:                 */
                    801:                c = in_silo.si_buf[ in_silo.si_ox ];
                    802: 
                    803:                if (in_silo.si_ox >= sizeof(in_silo.si_buf) - 1)
                    804:                        in_silo.si_ox = 0;
                    805:                else
                    806:                        in_silo.si_ox++;
                    807: 
                    808:                if ((islock == 0) || ISINTR || ISQUIT) {
                    809:                        ttin(tp, c);
                    810:                } else if ((c == 'b') && (lastc == '\033')) {
                    811:                        islock = 0;
                    812:                        ttin(tp, lastc);
                    813:                        ttin(tp, c);
                    814:                } else if ((c == 'c') && (lastc == '\033')) {
                    815:                        ttin(tp, lastc);
                    816:                        ttin(tp, c);
                    817:                } else
                    818:                        putchar('\007');
                    819:                lastc = c;
                    820:        }
                    821: }
                    822: 
                    823: /*
                    824:  * update the keyboard status LEDS.
                    825:  * we chose the shift/lock key positions so this would be easy.
                    826:  * this flavor of routine is called while processing a system call on
                    827:  * behalf of the user.
                    828:  */
                    829: updleds()
                    830: {
                    831:        kb_cmd2(K_LED_CMD, (shift >> 1) & 0x7);
                    832: }
                    833: 
                    834: /*
                    835:  * same as above, but callable from interrupt routines and other places
                    836:  * which cannot sleep() waiting for the state machine to go idle.
                    837:  */
                    838: updleds2()
                    839: {
                    840:        register int timeout;
                    841:        register int s;
                    842: 
                    843:        timeout = KBTIMEOUT;
                    844:        s = sphi();
                    845:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                    846:                ;
                    847:        kbstate = KB_DOUBLE_1;
                    848:        cmd2 = (shift >> 1) & 0x7;
                    849:        prev_cmd = K_LED_CMD;
                    850:        outb(KBDATA, K_LED_CMD);
                    851:        spl(s);
                    852: }
                    853: 
                    854: /*
                    855:  * unlock the scroll in case an interrupt character is received
                    856:  */
                    857: kbunscroll()
                    858: {
                    859:        shift &= ~(1 << scroll);
                    860:        updleds();
                    861: }
                    862: 
                    863: /*
                    864:  * ship a single byte command to the keyboard
                    865:  */
                    866: kb_cmd(cmd)
                    867: unsigned cmd;
                    868: {
                    869:        register int timeout;
                    870:        register int s;
                    871: 
                    872:        s = sphi();
                    873:        KBDEBUG2(" kb_cmd(%x)", cmd);
                    874:        while (kbstate != KB_IDLE) {
                    875:                v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "nkbcmd");
                    876:                /* The nkb driver is waiting for a command to complete.  */
                    877:        }
                    878:        kbstate = KB_SINGLE;
                    879:        timeout = KBTIMEOUT;
                    880:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                    881:                ;
                    882:        if (!timeout)
                    883:                printf("kb: command timeout\n");
                    884:        else {
                    885:                outb(KBDATA, cmd);
                    886:                while (kbstate != KB_IDLE) {
                    887:                        v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "nkbcmd...");
                    888:                /* The nkb driver is still waiting for a command to complete.  */
                    889:                }
                    890:        }
                    891:        spl(s);
                    892: }
                    893: 
                    894: /*
                    895:  * ship a two byte command to the keyboard
                    896:  */
                    897: kb_cmd2(cmd, arg)
                    898: unsigned cmd, arg;
                    899: {
                    900:        register int timeout;
                    901:        register int s;
                    902: 
                    903:        s = sphi();
                    904:        KBDEBUG3(" kb_cmd2(%x, %x)", cmd, arg);
                    905:        while (kbstate != KB_IDLE) {
                    906:                v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "nkbcmd2");
                    907:                /*
                    908:                 * The nkb driver is waiting for a
                    909:                 * 2 byte command to complete.
                    910:                 */
                    911:        }
                    912:        kbstate = KB_DOUBLE_1;
                    913:        cmd2 = arg;
                    914:        prev_cmd = cmd;
                    915:        timeout = KBTIMEOUT;
                    916:        while (--timeout > 0 && (inb(KBSTS_CMD) & STS_IBUF_FULL))
                    917:                ;
                    918:        if (!timeout)
                    919:                printf("kb: command timeout\n");
                    920:        else {
                    921:                outb(KBDATA, cmd);
                    922:                while (kbstate != KB_IDLE) {
                    923:                        v_sleep(&kbstate, CVTTIN, IVTTIN, SVTTIN, "nkbcmd2...");
                    924:                        /*
                    925:                         * The nkb driver is still waiting for a
                    926:                         * 2 byte command to complete.
                    927:                         */
                    928:                }
                    929:        }
                    930:        spl(s);
                    931: }
                    932: 
                    933: /* End of nkb.c */

unix.superglobalmegacorp.com

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