Annotation of 43BSDReno/sys/hpdev/hil.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 University of Utah.
                      3:  * Copyright (c) 1990 The Regents of the University of California.
                      4:  * All rights reserved.
                      5:  *
                      6:  * This code is derived from software contributed to Berkeley by
                      7:  * the Systems Programming Group of the University of Utah Computer
                      8:  * Science Department.
                      9:  *
                     10:  * Redistribution is only permitted until one year after the first shipment
                     11:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                     12:  * binary forms are permitted provided that: (1) source distributions retain
                     13:  * this entire copyright notice and comment, and (2) distributions including
                     14:  * binaries display the following acknowledgement:  This product includes
                     15:  * software developed by the University of California, Berkeley and its
                     16:  * contributors'' in the documentation or other materials provided with the
                     17:  * distribution and in all advertising materials mentioning features or use
                     18:  * of this software.  Neither the name of the University nor the names of
                     19:  * its contributors may be used to endorse or promote products derived from
                     20:  * this software without specific prior written permission.
                     21:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     22:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     23:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     24:  *
                     25:  * from: Utah $Hdr: hil.c 1.33 89/12/22$
                     26:  *
                     27:  *     @(#)hil.c       7.4 (Berkeley) 6/22/90
                     28:  */
                     29: 
                     30: #include "param.h"
                     31: #include "conf.h"
                     32: #include "user.h"
                     33: #include "proc.h"
                     34: #include "ioctl.h"
                     35: #include "file.h"
                     36: #include "tty.h"
                     37: #include "systm.h"
                     38: #include "uio.h"
                     39: #include "kernel.h"
                     40: #include "mapmem.h"
                     41: 
                     42: #include "hilreg.h"
                     43: #include "hilioctl.h"
                     44: #include "hilvar.h"
                     45: #include "kbdmap.h"
                     46: 
                     47: #include "machine/cpu.h"
                     48: 
                     49: struct hilloop hil0;
                     50: struct _hilbell default_bell = { BELLDUR, BELLFREQ };
                     51: 
                     52: #ifdef MAPMEM
                     53: int    hilqfork(), hilqvfork(), hilqexit();
                     54: struct mapmemops hilqops = { hilqfork, hilqvfork, hilqexit, hilqexit };
                     55: #endif
                     56: 
                     57: #ifdef DEBUG
                     58: int    hildebug = 0;
                     59: #define HDB_FOLLOW     0x01
                     60: #define HDB_MMAP       0x02
                     61: #define HDB_MASK       0x04
                     62: #define HDB_CONFIG     0x08
                     63: #define HDB_KEYBOARD   0x10
                     64: #define HDB_IDMODULE   0x20
                     65: #define HDB_EVENTS     0x80
                     66: #endif
                     67: 
                     68: /* symbolic sleep message strings */
                     69: char hilin[] = "hilin";
                     70: 
                     71: hilinit()
                     72: {
                     73:        register struct hilloop *hilp = &hil0;  /* XXX */
                     74:        register int i;
                     75: 
                     76:        /*
                     77:         * Initialize loop information
                     78:         */
                     79:        hilp->hl_addr = HILADDR;
                     80:        hilp->hl_cmdending = FALSE;
                     81:        hilp->hl_actdev = hilp->hl_cmddev = 0;
                     82:        hilp->hl_cmddone = FALSE;
                     83:        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                     84:        hilp->hl_pollbp = hilp->hl_pollbuf;
                     85:        hilp->hl_kbddev = 0;
                     86:        hilp->hl_kbdlang = KBD_DEFAULT;
                     87:        hilp->hl_kbdflags = 0;
                     88:        /*
                     89:         * Clear all queues and device associations with queues
                     90:         */
                     91:        for (i = 0; i < NHILQ; i++) {
                     92:                hilp->hl_queue[i].hq_eventqueue = NULL;
                     93:                hilp->hl_queue[i].hq_procp = NULL;
                     94:                hilp->hl_queue[i].hq_devmask = 0;
                     95:        }
                     96:        for (i = 0; i < NHILD; i++)
                     97:                hilp->hl_device[i].hd_qmask = 0;
                     98:        hilp->hl_device[HILLOOPDEV].hd_flags = (HIL_ALIVE|HIL_PSEUDO);
                     99:        /*
                    100:         * Reset the loop hardware, and collect keyboard/id info
                    101:         */
                    102:        hilreset(hilp);
                    103:        hilinfo(hilp);
                    104:        kbdenable();
                    105: }
                    106: 
                    107: hilopen(dev, flags)
                    108:        dev_t dev;
                    109: {
                    110:        struct proc *p = u.u_procp;             /* XXX */
                    111:        register struct hilloop *hilp = &hil0;  /* XXX */
                    112:        register struct hilloopdev *dptr;
                    113:        u_char device = HILUNIT(dev);
                    114: 
                    115: #ifdef DEBUG
                    116:        if (hildebug & HDB_FOLLOW)
                    117:                printf("hilopen(%d): device %x\n", p->p_pid, device);
                    118: #endif
                    119:        
                    120:        if ((hilp->hl_device[HILLOOPDEV].hd_flags & HIL_ALIVE) == 0)
                    121:                return(ENXIO);
                    122: 
                    123:        dptr = &hilp->hl_device[device];
                    124:        if ((dptr->hd_flags & HIL_ALIVE) == 0)
                    125:                return(ENODEV);
                    126: 
                    127:        /*
                    128:         * Pseudo-devices cannot be read, nothing more to do.
                    129:         */
                    130:        if (dptr->hd_flags & HIL_PSEUDO)
                    131:                return(0);
                    132: 
                    133:        /*
                    134:         * Open semantics:
                    135:         * 1.   Open devices have only one of HIL_READIN/HIL_QUEUEIN.
                    136:         * 2.   HPUX processes always get read syscall interface and
                    137:         *      must have exclusive use of the device.
                    138:         * 3.   BSD processes default to shared queue interface.
                    139:         *      Multiple processes can open the device.
                    140:         */
                    141:        if (p->p_flag & SHPUX) {
                    142:                if (dptr->hd_flags & (HIL_READIN|HIL_QUEUEIN))
                    143:                        return(EBUSY);
                    144:                dptr->hd_flags |= HIL_READIN;
                    145:        } else {
                    146:                if (dptr->hd_flags & HIL_READIN)
                    147:                        return(EBUSY);
                    148:                dptr->hd_flags |= HIL_QUEUEIN;
                    149:        }
                    150:        if (flags & FNDELAY)
                    151:                dptr->hd_flags |= HIL_NOBLOCK;
                    152:        /*
                    153:         * It is safe to flush the read buffer as we are guarenteed
                    154:         * that no one else is using it.
                    155:         */
                    156:        ndflush(&dptr->hd_queue, dptr->hd_queue.c_cc);
                    157: 
                    158:        send_hil_cmd(hilp->hl_addr, HIL_INTON, NULL, 0, NULL);
                    159:        /*
                    160:         * Opened the keyboard, put in raw mode.
                    161:         */
                    162:        (void) splhil();
                    163:        if (device == hilp->hl_kbddev) {
                    164:                u_char mask = 0;
                    165:                send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &mask, 1, NULL);
                    166:                hilp->hl_kbdflags |= KBD_RAW;
                    167: #ifdef DEBUG
                    168:                if (hildebug & HDB_KEYBOARD)
                    169:                        printf("hilopen: keyboard %d raw\n", hilp->hl_kbddev);
                    170: #endif
                    171:        }
                    172:        (void) spl0();
                    173:        return (0);
                    174: }
                    175: 
                    176: /* ARGSUSED */
                    177: hilclose(dev, flags)
                    178:        dev_t dev;
                    179: {
                    180:        struct proc *p = u.u_procp;             /* XXX */
                    181:        register struct hilloop *hilp = &hil0;  /* XXX */
                    182:        register struct hilloopdev *dptr;
                    183:        register int i;
                    184:        u_char device = HILUNIT(dev);
                    185:        char mask, lpctrl;
                    186: 
                    187: #ifdef DEBUG
                    188:        if (hildebug & HDB_FOLLOW)
                    189:                printf("hilclose(%d): device %x\n", p->p_pid, device);
                    190: #endif
                    191: 
                    192:        dptr = &hilp->hl_device[device];
                    193:        if (device && (dptr->hd_flags & HIL_PSEUDO))
                    194:                return (0);
                    195: 
                    196:        if ((p->p_flag & SHPUX) == 0) {
                    197:                /*
                    198:                 * If this is the loop device,
                    199:                 * free up all queues belonging to this process.
                    200:                 */
                    201:                if (device == 0) {
                    202:                        for (i = 0; i < NHILQ; i++)
                    203:                                if (hilp->hl_queue[i].hq_procp == p)
                    204:                                        (void) hilqfree(i);
                    205:                } else {
                    206:                        mask = ~hildevmask(device);
                    207:                        (void) splhil();
                    208:                        for (i = 0; i < NHILQ; i++)
                    209:                                if (hilp->hl_queue[i].hq_procp == p) {
                    210:                                        dptr->hd_qmask &= ~hilqmask(i);
                    211:                                        hilp->hl_queue[i].hq_devmask &= mask;
                    212:                                }
                    213:                        (void) spl0();
                    214:                }
                    215:        }
                    216:        /*
                    217:         * Always flush the read buffer
                    218:         */
                    219:        dptr->hd_flags &= ~(HIL_QUEUEIN|HIL_READIN|HIL_NOBLOCK);
                    220:        ndflush(&dptr->hd_queue, dptr->hd_queue.c_cc);
                    221:        /*
                    222:         * Set keyboard back to cooked mode when closed.
                    223:         */
                    224:        (void) splhil();
                    225:        if (device && device == hilp->hl_kbddev) {
                    226:                mask = 1 << (hilp->hl_kbddev - 1);
                    227:                send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &mask, 1, NULL);
                    228:                hilp->hl_kbdflags &= ~(KBD_RAW|KBD_AR1|KBD_AR2);
                    229:                /*
                    230:                 * XXX: We have had trouble with keyboards remaining raw
                    231:                 * after close due to the LPC_KBDCOOK bit getting cleared
                    232:                 * somewhere along the line.  Hence we check and reset
                    233:                 * LPCTRL if necessary.
                    234:                 */
                    235:                send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &lpctrl);
                    236:                if ((lpctrl & LPC_KBDCOOK) == 0) {
                    237:                        printf("hilclose: bad LPCTRL %x, reset to %x\n",
                    238:                               lpctrl, lpctrl|LPC_KBDCOOK);
                    239:                        lpctrl |= LPC_KBDCOOK;
                    240:                        send_hil_cmd(hilp->hl_addr, HIL_WRITELPCTRL,
                    241:                                        &lpctrl, 1, NULL);
                    242:                }
                    243: #ifdef DEBUG
                    244:                if (hildebug & HDB_KEYBOARD)
                    245:                        printf("hilclose: keyboard %d cooked\n",
                    246:                               hilp->hl_kbddev);
                    247: #endif
                    248:                kbdenable();
                    249:        }
                    250:        (void) spl0();
                    251:        return (0);
                    252: }
                    253: 
                    254: /*
                    255:  * Read interface to HIL device.
                    256:  */
                    257: hilread(dev, uio)
                    258:        dev_t dev;
                    259:        register struct uio *uio;
                    260: {
                    261:        struct hilloop *hilp = &hil0;           /* XXX */
                    262:        register struct hilloopdev *dptr;
                    263:        register int cc;
                    264:        u_char device = HILUNIT(dev);
                    265:        char buf[HILBUFSIZE];
                    266:        int error;
                    267: 
                    268: #if 0
                    269:        /*
                    270:         * XXX: Don't do this since HP-UX doesn't.
                    271:         *
                    272:         * Check device number.
                    273:         * This check is necessary since loop can reconfigure.
                    274:         */
                    275:        if (device > hilp->hl_maxdev)
                    276:                return(ENODEV);
                    277: #endif
                    278: 
                    279:        dptr = &hilp->hl_device[device];
                    280:        if ((dptr->hd_flags & HIL_READIN) == 0)
                    281:                return(ENODEV);
                    282: 
                    283:        (void) splhil();
                    284:        while (dptr->hd_queue.c_cc == 0) {
                    285:                if (dptr->hd_flags & HIL_NOBLOCK) {
                    286:                        spl0();
                    287:                        return(EWOULDBLOCK);
                    288:                }
                    289:                dptr->hd_flags |= HIL_ASLEEP;
                    290:                if (error = tsleep((caddr_t)dptr, TTIPRI | PCATCH, hilin, 0)) {
                    291:                        (void) spl0();
                    292:                        return (error);
                    293:                }
                    294:        }
                    295:        (void) spl0();
                    296: 
                    297:        error = 0;
                    298:        while (uio->uio_resid > 0 && error == 0) {
                    299:                cc = hilq_to_b(&dptr->hd_queue, buf,
                    300:                               MIN(uio->uio_resid, HILBUFSIZE));
                    301:                if (cc <= 0)
                    302:                        break;
                    303:                error = uiomove(buf, cc, uio);
                    304:        }
                    305:        return(error);
                    306: }
                    307: 
                    308: hilioctl(dev, cmd, data, flag)
                    309:        dev_t dev;
                    310:        caddr_t data;
                    311: {
                    312:        struct proc *p = u.u_procp;             /* XXX */
                    313:        register struct hilloop *hilp = &hil0;  /* XXX */
                    314:        char device = HILUNIT(dev);
                    315:        struct hilloopdev *dptr;
                    316:        register int i;
                    317:        u_char hold;
                    318:        int error;
                    319: 
                    320: #ifdef DEBUG
                    321:        if (hildebug & HDB_FOLLOW)
                    322:                printf("hilioctl(%d): dev %x cmd %x\n",
                    323:                       p->p_pid, device, cmd);
                    324: #endif
                    325: 
                    326:        dptr = &hilp->hl_device[device];
                    327:        if ((dptr->hd_flags & HIL_ALIVE) == 0)
                    328:                return (ENODEV);
                    329: 
                    330:        /*
                    331:         * Don't allow hardware ioctls on virtual devices.
                    332:         * Note that though these are the BSD names, they have the same
                    333:         * values as the HP-UX equivalents so we catch them as well.
                    334:         */
                    335:        if (dptr->hd_flags & HIL_PSEUDO) {
                    336:                switch (cmd) {
                    337:                case HILIOCSC:
                    338:                case HILIOCID:
                    339:                case HILIOCRN:
                    340:                case HILIOCRS:
                    341:                case HILIOCED:
                    342:                        return(ENODEV);
                    343: 
                    344:                /*
                    345:                 * XXX: should also return ENODEV but HP-UX compat
                    346:                 * breaks if we do.  They work ok right now because
                    347:                 * we only recognize one keyboard on the loop.  This
                    348:                 * will have to change if we remove that restriction.
                    349:                 */
                    350:                case HILIOCAROFF:
                    351:                case HILIOCAR1:
                    352:                case HILIOCAR2:
                    353:                        break;
                    354: 
                    355:                default:
                    356:                        break;
                    357:                }
                    358:        }
                    359: 
                    360: #ifdef HPUXCOMPAT
                    361:        if (p->p_flag & SHPUX)
                    362:                return(hpuxhilioctl(dev, cmd, data, flag));
                    363: #endif
                    364: 
                    365:        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                    366:        bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE);
                    367:        hilp->hl_cmddev = device;
                    368:        error = 0;
                    369:        switch (cmd) {
                    370: 
                    371:        case HILIOCSBP:
                    372:                /* Send four data bytes to the tone gererator. */
                    373:                send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL);
                    374:                /* Send the trigger beeper command to the 8042. */
                    375:                send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL);
                    376:                break;
                    377: 
                    378:        case HILIOCRRT:
                    379:                /* Transfer the real time to the 8042 data buffer */
                    380:                send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL);
                    381:                /* Read each byte of the real time */
                    382:                for (i = 0; i < 5; i++) {
                    383:                        send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL,
                    384:                                        0, &hold);
                    385:                        data[4-i] = hold;
                    386:                }
                    387:                break;
                    388:                
                    389:        case HILIOCRT:
                    390:                for (i = 0; i < 4; i++) {
                    391:                        send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i,
                    392:                                        NULL, 0, &hold);
                    393:                        data[i] = hold;
                    394:                }
                    395:                break;
                    396: 
                    397:        case HILIOCID:
                    398:        case HILIOCSC:
                    399:        case HILIOCRN:
                    400:        case HILIOCRS:
                    401:        case HILIOCED:
                    402:                send_hildev_cmd(hilp, device, (cmd & 0xFF));
                    403:                bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf);
                    404:                break;
                    405: 
                    406:         case HILIOCAROFF:
                    407:         case HILIOCAR1:
                    408:         case HILIOCAR2:
                    409:                if (hilp->hl_kbddev) {
                    410:                        hilp->hl_cmddev = hilp->hl_kbddev;
                    411:                        send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF));
                    412:                        hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2);
                    413:                        if (cmd == HILIOCAR1)
                    414:                                hilp->hl_kbdflags |= KBD_AR1;
                    415:                        else if (cmd == HILIOCAR2)
                    416:                                hilp->hl_kbdflags |= KBD_AR2;
                    417:                }
                    418:                break;
                    419: 
                    420:        case HILIOCBEEP:
                    421:                hilbeep(hilp, (struct _hilbell *)data);
                    422:                break;
                    423: 
                    424:        case FIONBIO:
                    425:                dptr = &hilp->hl_device[device];
                    426:                if (*(int *)data)
                    427:                        dptr->hd_flags |= HIL_NOBLOCK;
                    428:                else
                    429:                        dptr->hd_flags &= ~HIL_NOBLOCK;
                    430:                break;
                    431: 
                    432:        /*
                    433:         * FIOASYNC must be present for FIONBIO above to work!
                    434:         * (See fcntl in kern_descrip.c).
                    435:         */
                    436:        case FIOASYNC:
                    437:                break;
                    438: 
                    439:         case HILIOCALLOCQ:
                    440:                error = hilqalloc((struct hilqinfo *)data);
                    441:                break;
                    442: 
                    443:         case HILIOCFREEQ:
                    444:                error = hilqfree(((struct hilqinfo *)data)->qid);
                    445:                break;
                    446: 
                    447:         case HILIOCMAPQ:
                    448:                error = hilqmap(*(int *)data, device);
                    449:                break;
                    450: 
                    451:         case HILIOCUNMAPQ:
                    452:                error = hilqunmap(*(int *)data, device);
                    453:                break;
                    454: 
                    455:        case HILIOCHPUX:
                    456:                dptr = &hilp->hl_device[device];
                    457:                dptr->hd_flags |= HIL_READIN;
                    458:                dptr->hd_flags &= ~HIL_QUEUEIN;
                    459:                break;
                    460: 
                    461:         case HILIOCRESET:
                    462:                hilreset(hilp);
                    463:                break;
                    464:                
                    465: #ifdef DEBUG
                    466:         case HILIOCTEST:
                    467:                hildebug = *(int *) data;
                    468:                break;
                    469: #endif
                    470: 
                    471:         default:
                    472:                error = EINVAL;
                    473:                break;
                    474: 
                    475:        }
                    476:        hilp->hl_cmddev = 0;
                    477:        return(error);
                    478: }
                    479: 
                    480: #ifdef HPUXCOMPAT
                    481: /* ARGSUSED */
                    482: hpuxhilioctl(dev, cmd, data, flag)
                    483:        dev_t dev;
                    484:        caddr_t data;
                    485: {
                    486:        register struct hilloop *hilp = &hil0;  /* XXX */
                    487:        char device = HILUNIT(dev);
                    488:        struct hilloopdev *dptr;
                    489:        register int i;
                    490:        u_char hold;
                    491: 
                    492:        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                    493:        bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE);
                    494:        hilp->hl_cmddev = device;
                    495:        switch (cmd) {
                    496: 
                    497:        case HILSC:
                    498:        case HILID:
                    499:        case HILRN:
                    500:        case HILRS:
                    501:        case HILED:
                    502:        case HILP1:
                    503:        case HILP2:
                    504:        case HILP3:
                    505:        case HILP4:
                    506:        case HILP5:
                    507:        case HILP6:
                    508:        case HILP7:
                    509:        case HILP:
                    510:        case HILA1:
                    511:        case HILA2:
                    512:        case HILA3:
                    513:        case HILA4:
                    514:        case HILA5:
                    515:        case HILA6:
                    516:        case HILA7:
                    517:        case HILA:
                    518:                send_hildev_cmd(hilp, device, (cmd & 0xFF));
                    519:                bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf);
                    520:                break;
                    521: 
                    522:         case HILDKR:
                    523:         case HILER1:
                    524:         case HILER2:
                    525:                if (hilp->hl_kbddev) {
                    526:                        hilp->hl_cmddev = hilp->hl_kbddev;
                    527:                        send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF));
                    528:                        hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2);
                    529:                        if (cmd == HILIOCAR1)
                    530:                                hilp->hl_kbdflags |= KBD_AR1;
                    531:                        else if (cmd == HILIOCAR2)
                    532:                                hilp->hl_kbdflags |= KBD_AR2;
                    533:                }
                    534:                break;
                    535: 
                    536:        case EFTSBP:
                    537:                /* Send four data bytes to the tone gererator. */
                    538:                send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL);
                    539:                /* Send the trigger beeper command to the 8042. */
                    540:                send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL);
                    541:                break;
                    542: 
                    543:        case EFTRRT:
                    544:                /* Transfer the real time to the 8042 data buffer */
                    545:                send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL);
                    546:                /* Read each byte of the real time */
                    547:                for (i = 0; i < 5; i++) {
                    548:                        send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL,
                    549:                                        0, &hold);
                    550:                        data[4-i] = hold;
                    551:                }
                    552:                break;
                    553:                
                    554:        case EFTRT:
                    555:                for (i = 0; i < 4; i++) {
                    556:                        send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i,
                    557:                                        NULL, 0, &hold);
                    558:                        data[i] = hold;
                    559:                }
                    560:                break;
                    561: 
                    562:         case EFTRLC:
                    563:         case EFTRCC:
                    564:                send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, &hold);
                    565:                *data = hold;
                    566:                break;
                    567:                
                    568:         case EFTSRPG:
                    569:         case EFTSRD:
                    570:         case EFTSRR:
                    571:                send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), data, 1, NULL);
                    572:                break;
                    573:                
                    574:        case EFTSBI:
                    575:                hilbeep(hilp, (struct _hilbell *)data);
                    576:                break;
                    577: 
                    578:        case FIONBIO:
                    579:                dptr = &hilp->hl_device[device];
                    580:                if (*(int *)data)
                    581:                        dptr->hd_flags |= HIL_NOBLOCK;
                    582:                else
                    583:                        dptr->hd_flags &= ~HIL_NOBLOCK;
                    584:                break;
                    585: 
                    586:        case FIOASYNC:
                    587:                break;
                    588: 
                    589:         default:
                    590:                hilp->hl_cmddev = 0;
                    591:                return(EINVAL);
                    592:        }
                    593:        hilp->hl_cmddev = 0;
                    594:        return(0);
                    595: }
                    596: #endif
                    597: 
                    598: /*
                    599:  * XXX: the mmap inteface for HIL devices should be rethought.
                    600:  * We used it only briefly in conjuntion with shared queues
                    601:  * (instead of HILIOCMAPQ ioctl).  Perhaps mmap()ing a device
                    602:  * should give a single queue per process.
                    603:  */
                    604: /* ARGSUSED */
                    605: hilmap(dev, off, prot)
                    606:        dev_t dev;
                    607:        register int off;
                    608: {
                    609: #ifdef MMAP
                    610:        struct proc *p = u.u_procp;             /* XXX */
                    611:        register struct hilloop *hilp = &hil0;  /* XXX */
                    612:        register struct hiliqueue *qp;
                    613:        register int qnum;
                    614: 
                    615:        /*
                    616:         * Only allow mmap() on loop device
                    617:         */
                    618:        if (HILUNIT(dev) != 0 || off >= NHILQ*sizeof(HILQ))
                    619:                return(-1);
                    620:        /*
                    621:         * Determine which queue we want based on the offset.
                    622:         * Queue must belong to calling process.
                    623:         */
                    624:        qp = &hilp->hl_queue[off / sizeof(HILQ)];
                    625:        if (qp->hq_procp != p)
                    626:                return(-1);
                    627: 
                    628:        off %= sizeof(HILQ);
                    629:        return(kvtop((u_int)qp->hq_eventqueue + off) >> PGSHIFT);
                    630: #endif
                    631: }
                    632: 
                    633: /*ARGSUSED*/
                    634: hilselect(dev, rw)
                    635:        dev_t dev;
                    636: {
                    637:        struct proc *p = u.u_procp;             /* XXX */
                    638:        register struct hilloop *hilp = &hil0;  /* XXX */
                    639:        register struct hilloopdev *dptr;
                    640:        register struct hiliqueue *qp;
                    641:        register int mask;
                    642:        int s, device;
                    643:        
                    644:        if (rw == FWRITE)
                    645:                return (1);
                    646:        device = HILUNIT(dev);
                    647: 
                    648:        /*
                    649:         * Read interface.
                    650:         * Return 1 if there is something in the queue, 0 ow.
                    651:         */
                    652:        dptr = &hilp->hl_device[device];
                    653:        if (dptr->hd_flags & HIL_READIN) {
                    654:                s = splhil();
                    655:                if (dptr->hd_queue.c_cc) {
                    656:                        splx(s);
                    657:                        return (1);
                    658:                }
                    659:                if (dptr->hd_selr &&
                    660:                    dptr->hd_selr->p_wchan == (caddr_t)&selwait)
                    661:                        dptr->hd_flags |= HIL_SELCOLL;
                    662:                else
                    663:                        dptr->hd_selr = p;
                    664:                splx(s);
                    665:                return (0);
                    666:        }
                    667: 
                    668:        /*
                    669:         * Make sure device is alive and real (or the loop device).
                    670:         * Note that we do not do this for the read interface.
                    671:         * This is primarily to be consistant with HP-UX.
                    672:         */
                    673:        if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE)
                    674:                return (1);
                    675: 
                    676:        /*
                    677:         * Select on loop device is special.
                    678:         * Check to see if there are any data for any loop device
                    679:         * provided it is associated with a queue belonging to this user.
                    680:         */
                    681:        if (device == 0)
                    682:                mask = -1;
                    683:        else
                    684:                mask = hildevmask(device);
                    685:        /*
                    686:         * Must check everybody with interrupts blocked to prevent races.
                    687:         */
                    688:        s = splhil();
                    689:        for (qp = hilp->hl_queue; qp < &hilp->hl_queue[NHILQ]; qp++)
                    690:                if (qp->hq_procp == p && (mask & qp->hq_devmask) &&
                    691:                    qp->hq_eventqueue->hil_evqueue.head !=
                    692:                    qp->hq_eventqueue->hil_evqueue.tail) {
                    693:                        splx(s);
                    694:                        return (1);
                    695:                }
                    696: 
                    697:        if (dptr->hd_selr && dptr->hd_selr->p_wchan == (caddr_t)&selwait)
                    698:                dptr->hd_flags |= HIL_SELCOLL;
                    699:        else
                    700:                dptr->hd_selr = p;
                    701:        splx(s);
                    702:        return (0);
                    703: }
                    704: 
                    705: hilint()
                    706: {
                    707:        struct hilloop *hilp = &hil0;           /* XXX */
                    708:        register struct hil_dev *hildevice = hilp->hl_addr;
                    709:        u_char c, stat;
                    710: 
                    711:        stat = hildevice->hil_stat;
                    712:        c = hildevice->hil_data;                /* clears interrupt */
                    713:        hil_process_int(stat, c);
                    714: }
                    715: 
                    716: #include "ite.h"
                    717: 
                    718: hil_process_int(stat, c)
                    719:        register u_char stat, c;
                    720: {
                    721:        register struct hilloop *hilp;
                    722: 
                    723: #ifdef DEBUG
                    724:        if (hildebug & HDB_EVENTS)
                    725:                printf("hilint: %x %x\n", stat, c);
                    726: #endif
                    727: 
                    728:        /* the shift enables the compiler to generate a jump table */
                    729:        switch ((stat>>HIL_SSHIFT) & HIL_SMASK) {
                    730: 
                    731: #if NITE > 0
                    732:        case HIL_KEY:
                    733:        case HIL_SHIFT:
                    734:        case HIL_CTRL:
                    735:        case HIL_CTRLSHIFT:
                    736:                itefilter(stat, c);
                    737:                return;
                    738: #endif
                    739:                
                    740:        case HIL_STATUS:                        /* The status info. */
                    741:                hilp = &hil0;                   /* XXX */
                    742:                if (c & HIL_ERROR) {
                    743:                        hilp->hl_cmddone = TRUE;
                    744:                        if (c == HIL_RECONFIG)
                    745:                                hilconfig(hilp);
                    746:                        break;
                    747:                }
                    748:                if (c & HIL_COMMAND) {
                    749:                        if (c & HIL_POLLDATA)   /* End of data */
                    750:                                hilevent(hilp);
                    751:                        else                    /* End of command */
                    752:                                hilp->hl_cmdending = TRUE;
                    753:                        hilp->hl_actdev = 0;
                    754:                } else {
                    755:                        if (c & HIL_POLLDATA) { /* Start of polled data */
                    756:                                if (hilp->hl_actdev != 0)
                    757:                                        hilevent(hilp);
                    758:                                hilp->hl_actdev = (c & HIL_DEVMASK);
                    759:                                hilp->hl_pollbp = hilp->hl_pollbuf;
                    760:                        } else {                /* Start of command */
                    761:                                if (hilp->hl_cmddev == (c & HIL_DEVMASK)) {
                    762:                                        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                    763:                                        hilp->hl_actdev = 0;
                    764:                                }
                    765:                        }
                    766:                }
                    767:                return;
                    768: 
                    769:        case HIL_DATA:
                    770:                hilp = &hil0;                   /* XXX */
                    771:                if (hilp->hl_actdev != 0)       /* Collecting poll data */
                    772:                        *hilp->hl_pollbp++ = c;
                    773:                else if (hilp->hl_cmddev != 0)  /* Collecting cmd data */
                    774:                        if (hilp->hl_cmdending) {
                    775:                                hilp->hl_cmddone = TRUE;
                    776:                                hilp->hl_cmdending = FALSE;
                    777:                        } else  
                    778:                                *hilp->hl_cmdbp++ = c;
                    779:                return;
                    780:                
                    781:        case 0:         /* force full jump table */
                    782:        default:
                    783:                return;
                    784:        }
                    785: }
                    786: 
                    787: #if defined(DEBUG) && !defined(PANICBUTTON)
                    788: #define PANICBUTTON
                    789: #endif
                    790: 
                    791: /*
                    792:  * Optimized macro to compute:
                    793:  *     eq->head == (eq->tail + 1) % eq->size
                    794:  * i.e. has tail caught up with head.  We do this because 32 bit long
                    795:  * remaidering is expensive (a function call with our compiler).
                    796:  */
                    797: #define HQFULL(eq)     (((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1)
                    798: #define HQVALID(eq) \
                    799:        ((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE)
                    800: 
                    801: hilevent(hilp)
                    802:        struct hilloop *hilp;
                    803: {
                    804:        register struct hilloopdev *dptr = &hilp->hl_device[hilp->hl_actdev];
                    805:        register int len, mask, qnum;
                    806:        register u_char *cp, *pp;
                    807:        register HILQ *hq;
                    808:        struct timeval ourtime;
                    809:        hil_packet *proto;
                    810:        int s, len0;
                    811:        long tenths;
                    812: 
                    813: #ifdef PANICBUTTON
                    814:        static int first;
                    815:        extern int panicbutton;
                    816: 
                    817:        cp = hilp->hl_pollbuf;
                    818:        if (panicbutton && (*cp & HIL_KBDDATA)) {
                    819:                if (*++cp == 0x4E)
                    820:                        first = 1;
                    821:                else if (first && *cp == 0x46 && !panicstr)
                    822:                        panic("are we having fun yet?");
                    823:                else
                    824:                        first = 0;
                    825:        }
                    826: #endif
                    827: #ifdef DEBUG
                    828:        if (hildebug & HDB_EVENTS) {
                    829:                printf("hilevent: dev %d pollbuf: ", hilp->hl_actdev);
                    830:                printhilpollbuf(hilp);
                    831:                printf("\n");
                    832:        }
                    833: #endif
                    834: 
                    835:        /*
                    836:         * Note that HIL_READIN effectively "shuts off" any queues
                    837:         * that may have been in use at the time of an HILIOCHPUX call.
                    838:         */
                    839:        if (dptr->hd_flags & HIL_READIN) {
                    840:                hpuxhilevent(hilp, dptr);
                    841:                return;
                    842:        }
                    843: 
                    844:        /*
                    845:         * If this device isn't on any queue or there are no data
                    846:         * in the packet (can this happen?) do nothing.
                    847:         */
                    848:        if (dptr->hd_qmask == 0 ||
                    849:            (len0 = hilp->hl_pollbp - hilp->hl_pollbuf) <= 0)
                    850:                return;
                    851: 
                    852:        /*
                    853:         * Everybody gets the same time stamp
                    854:         */
                    855:        s = splclock();
                    856:        ourtime = time;
                    857:        splx(s);
                    858:        tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);
                    859: 
                    860:        proto = NULL;
                    861:        mask = dptr->hd_qmask;
                    862:        for (qnum = 0; mask; qnum++) {
                    863:                if ((mask & hilqmask(qnum)) == 0)
                    864:                        continue;
                    865:                mask &= ~hilqmask(qnum);
                    866:                hq = hilp->hl_queue[qnum].hq_eventqueue;
                    867:                
                    868:                /*
                    869:                 * Ensure that queue fields that we rely on are valid
                    870:                 * and that there is space in the queue.  If either
                    871:                 * test fails, we just skip this queue.
                    872:                 */
                    873:                if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue))
                    874:                        continue;
                    875: 
                    876:                /*
                    877:                 * Copy data to queue.
                    878:                 * If this is the first queue we construct the packet
                    879:                 * with length, timestamp and poll buffer data.
                    880:                 * For second and sucessive packets we just duplicate
                    881:                 * the first packet.
                    882:                 */
                    883:                pp = (u_char *) &hq->hil_event[hq->hil_evqueue.tail];
                    884:                if (proto == NULL) {
                    885:                        proto = (hil_packet *)pp;
                    886:                        cp = hilp->hl_pollbuf;
                    887:                        len = len0;
                    888:                        *pp++ = len + 6;
                    889:                        *pp++ = hilp->hl_actdev;
                    890:                        *(long *)pp = tenths;
                    891:                        pp += sizeof(long);
                    892:                        do *pp++ = *cp++; while (--len);
                    893:                } else
                    894:                        *(hil_packet *)pp = *proto;
                    895: 
                    896:                if (++hq->hil_evqueue.tail == hq->hil_evqueue.size)
                    897:                        hq->hil_evqueue.tail = 0;
                    898:        }
                    899: 
                    900:        /*
                    901:         * Wake up anyone selecting on this device or the loop itself
                    902:         */
                    903:        if (dptr->hd_selr) {
                    904:                selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL);
                    905:                dptr->hd_selr = NULL;
                    906:                dptr->hd_flags &= ~HIL_SELCOLL;
                    907:        }
                    908:        dptr = &hilp->hl_device[HILLOOPDEV];
                    909:        if (dptr->hd_selr) {
                    910:                selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL);
                    911:                dptr->hd_selr = NULL;
                    912:                dptr->hd_flags &= ~HIL_SELCOLL;
                    913:        }
                    914: }
                    915: 
                    916: #undef HQFULL
                    917: 
                    918: hpuxhilevent(hilp, dptr)
                    919:        register struct hilloop *hilp;
                    920:        register struct hilloopdev *dptr;
                    921: {
                    922:        register int len;
                    923:        struct timeval ourtime;
                    924:        long tstamp;
                    925:        int s;
                    926: 
                    927:        /*
                    928:         * Everybody gets the same time stamp
                    929:         */
                    930:        s = splclock();
                    931:        ourtime = time;
                    932:        splx(s);
                    933:        tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);
                    934: 
                    935:        /*
                    936:         * Each packet that goes into the buffer must be preceded by the
                    937:         * number of bytes in the packet, and the timestamp of the packet.
                    938:         * This adds 5 bytes to the packet size. Make sure there is enough
                    939:         * room in the buffer for it, and if not, toss the packet.
                    940:         */
                    941:        len = hilp->hl_pollbp - hilp->hl_pollbuf;
                    942:        if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len+5))) {
                    943:                putc(len+5, &dptr->hd_queue);
                    944:                (void) b_to_q((char *)&tstamp, sizeof tstamp, &dptr->hd_queue);
                    945:                (void) b_to_q((char *)hilp->hl_pollbuf, len, &dptr->hd_queue);
                    946:        }
                    947: 
                    948:        /*
                    949:         * Wake up any one blocked on a read or select
                    950:         */
                    951:        if (dptr->hd_flags & HIL_ASLEEP) {
                    952:                dptr->hd_flags &= ~HIL_ASLEEP;
                    953:                wakeup((caddr_t)dptr);
                    954:        }
                    955:        if (dptr->hd_selr) {
                    956:                selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL);
                    957:                dptr->hd_selr = NULL;
                    958:                dptr->hd_flags &= ~HIL_SELCOLL;
                    959:        }
                    960: }
                    961: 
                    962: /*
                    963:  * Shared queue manipulation routines
                    964:  */
                    965: 
                    966: hilqalloc(qip)
                    967:        struct hilqinfo *qip;
                    968: {
                    969: #ifdef MAPMEM
                    970:        struct proc *p = u.u_procp;             /* XXX */
                    971:        register struct hilloop *hilp = &hil0;  /* XXX */
                    972:        register HILQ *hq;
                    973:        register int qnum;
                    974:        struct mapmem *mp;
                    975:        int error, hilqmapin();
                    976: 
                    977: #ifdef DEBUG
                    978:        if (hildebug & HDB_FOLLOW)
                    979:                printf("hilqalloc(%d): addr %x\n",
                    980:                       p->p_pid, qip->addr);
                    981: #endif
                    982:        /*
                    983:         * Find a free queue
                    984:         */
                    985:        for (qnum = 0; qnum < NHILQ; qnum++)
                    986:                if (hilp->hl_queue[qnum].hq_procp == NULL)
                    987:                        break;
                    988:        if (qnum == NHILQ)
                    989:                return(EMFILE);
                    990: 
                    991:        /*
                    992:         * Allocate and clear memory for the queue
                    993:         */
                    994:        if (hilp->hl_queue[qnum].hq_eventqueue)
                    995:                panic("hilqalloc");
                    996:        hq = (HILQ *) cialloc(sizeof(HILQ));
                    997:        if (hq == NULL)
                    998:                return(ENOMEM);
                    999:        bzero((caddr_t)hq, sizeof(HILQ));
                   1000:        hilp->hl_queue[qnum].hq_eventqueue = hq;
                   1001:        hq->hil_evqueue.size = HEVQSIZE;
                   1002: 
                   1003:        /*
                   1004:         * Map queue into user address space as instructed
                   1005:         */
                   1006:        error = mmalloc(p, qnum, &qip->addr, sizeof(HILQ), MM_RW|MM_CI,
                   1007:                        &hilqops, &mp);
                   1008:        if (error) {
                   1009:                cifree((caddr_t)hq, sizeof(HILQ));
                   1010:                hilp->hl_queue[qnum].hq_eventqueue = NULL;
                   1011:                return(error);
                   1012:        }
                   1013:        qip->qid = qnum;
                   1014:        if (error = mmmapin(p, mp, hilqmapin)) {
                   1015:                (void) mmfree(p, mp);
                   1016:                cifree((caddr_t)hq, sizeof(HILQ));
                   1017:                hilp->hl_queue[qnum].hq_eventqueue = NULL;
                   1018:                return(error);
                   1019:        }
                   1020:        hilp->hl_queue[qnum].hq_procp = p;
                   1021:        hilp->hl_queue[qnum].hq_devmask = 0;
                   1022:        return(0);
                   1023: #else
                   1024:        return(EINVAL);
                   1025: #endif
                   1026: }
                   1027: 
                   1028: hilqfree(qnum)
                   1029:        register int qnum;
                   1030: {
                   1031: #ifdef MAPMEM
                   1032:        struct proc *p = u.u_procp;             /* XXX */
                   1033:        register struct hilloop *hilp = &hil0;  /* XXX */
                   1034:        register struct mapmem *mp;
                   1035: 
                   1036: #ifdef DEBUG
                   1037:        if (hildebug & HDB_FOLLOW)
                   1038:                printf("hilqfree(%d): qnum %d\n",
                   1039:                       p->p_pid, qnum);
                   1040: #endif
                   1041:        if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
                   1042:                return(EINVAL);
                   1043:        for (mp = u.u_mmap; mp; mp = mp->mm_next)
                   1044:                if (qnum == mp->mm_id && mp->mm_ops == &hilqops) {
                   1045:                        (void) hilqexit(mp);
                   1046:                        return(0);
                   1047:                }
                   1048:        panic("hilqfree");
                   1049:        /* NOTREACHED */
                   1050: #else
                   1051:        return(EINVAL);
                   1052: #endif
                   1053: }
                   1054: 
                   1055: hilqmap(qnum, device)
                   1056:        register int qnum, device;
                   1057: {
                   1058:        struct proc *p = u.u_procp;             /* XXX */
                   1059:        register struct hilloop *hilp = &hil0;  /* XXX */
                   1060:        register struct hilloopdev *dptr = &hilp->hl_device[device];
                   1061:        int s;
                   1062: 
                   1063: #ifdef DEBUG
                   1064:        if (hildebug & HDB_FOLLOW)
                   1065:                printf("hilqmap(%d): qnum %d device %x\n",
                   1066:                       p->p_pid, qnum, device);
                   1067: #endif
                   1068:        if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
                   1069:                return(EINVAL);
                   1070:        if ((dptr->hd_flags & HIL_QUEUEIN) == 0)
                   1071:                return(EINVAL);
                   1072:        if (dptr->hd_qmask && u.u_uid && u.u_uid != dptr->hd_uid)
                   1073:                return(EPERM);
                   1074: 
                   1075:        hilp->hl_queue[qnum].hq_devmask |= hildevmask(device);
                   1076:        if (dptr->hd_qmask == 0)
                   1077:                dptr->hd_uid = u.u_uid;
                   1078:        s = splhil();
                   1079:        dptr->hd_qmask |= hilqmask(qnum);
                   1080:        splx(s);
                   1081: #ifdef DEBUG
                   1082:        if (hildebug & HDB_MASK)
                   1083:                printf("hilqmap(%d): devmask %x qmask %x\n",
                   1084:                       p->p_pid, hilp->hl_queue[qnum].hq_devmask,
                   1085:                       dptr->hd_qmask);
                   1086: #endif
                   1087:        return(0);
                   1088: }
                   1089: 
                   1090: hilqunmap(qnum, device)
                   1091:        register int qnum, device;
                   1092: {
                   1093:        struct proc *p = u.u_procp;             /* XXX */
                   1094:        register struct hilloop *hilp = &hil0;  /* XXX */
                   1095:        int s;
                   1096: 
                   1097: #ifdef DEBUG
                   1098:        if (hildebug & HDB_FOLLOW)
                   1099:                printf("hilqunmap(%d): qnum %d device %x\n",
                   1100:                       p->p_pid, qnum, device);
                   1101: #endif
                   1102: 
                   1103:        if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
                   1104:                return(EINVAL);
                   1105: 
                   1106:        hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device);
                   1107:        s = splhil();
                   1108:        hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum);
                   1109:        splx(s);
                   1110: #ifdef DEBUG
                   1111:        if (hildebug & HDB_MASK)
                   1112:                printf("hilqunmap(%d): devmask %x qmask %x\n",
                   1113:                       p->p_pid, hilp->hl_queue[qnum].hq_devmask,
                   1114:                       hilp->hl_device[device].hd_qmask);
                   1115: #endif
                   1116:        return(0);
                   1117: }
                   1118: 
                   1119: #ifdef MAPMEM
                   1120: hilqmapin(mp, off)
                   1121:        struct mapmem *mp;
                   1122: {
                   1123:        struct hilloop *hilp = &hil0;           /* XXX */
                   1124:        register HILQ *hq = hilp->hl_queue[mp->mm_id].hq_eventqueue;
                   1125: 
                   1126:        if (hq == NULL || off >= sizeof(HILQ))
                   1127:                return(-1);
                   1128:        return(kvtop((u_int)hq + off) >> PGSHIFT);
                   1129: }
                   1130: 
                   1131: /*
                   1132:  * Fork hook.
                   1133:  * Unmap queue from child's address space
                   1134:  */
                   1135: hilqfork(mp, ischild)
                   1136:        struct mapmem *mp;
                   1137: {
                   1138:        struct proc *p = u.u_procp;             /* XXX */
                   1139: #ifdef DEBUG
                   1140:        if (hildebug & HDB_MMAP)
                   1141:                printf("hilqfork(%d): %s qnum %d\n", p->p_pid,
                   1142:                       ischild ? "child" : "parent", mp->mm_id);
                   1143: #endif
                   1144:        if (ischild) {
                   1145:                mmmapout(p, mp);
                   1146:                (void) mmfree(p, mp);
                   1147:        }
                   1148: }
                   1149: 
                   1150: /*
                   1151:  * Vfork hook.
                   1152:  * Associate queue with child when VM resources are passed.
                   1153:  */
                   1154: hilqvfork(mp, fup, tup)
                   1155:        struct mapmem *mp;
                   1156:        struct user *fup, *tup;
                   1157: {
                   1158:        struct hilloop *hilp = &hil0;           /* XXX */
                   1159:        register struct hiliqueue *qp = &hilp->hl_queue[mp->mm_id];
                   1160: 
                   1161: #ifdef DEBUG
                   1162:        if (hildebug & HDB_MMAP)
                   1163:                printf("hilqvfork(%d): from %x to %x qnum %d, qprocp %x\n",
                   1164:                       u.u_procp->p_pid, fup->u_procp, tup->u_procp,
                   1165:                       mp->mm_id, qp->hq_procp);
                   1166: #endif
                   1167:        if (qp->hq_procp == fup->u_procp)
                   1168:                qp->hq_procp = tup->u_procp;
                   1169: }
                   1170: 
                   1171: /*
                   1172:  * Exit hook.
                   1173:  * Unmap all devices and free all queues.
                   1174:  */
                   1175: hilqexit(mp)
                   1176:        struct mapmem *mp;
                   1177: {
                   1178:        struct proc *p = u.u_procp;             /* XXX */
                   1179:        register struct hilloop *hilp = &hil0;  /* XXX */
                   1180:        register int mask, i;
                   1181:        int s;
                   1182: 
                   1183: #ifdef DEBUG
                   1184:        if (hildebug & HDB_MMAP)
                   1185:                printf("hilqexit(%d): qnum %d\n", p->p_pid, mp->mm_id);
                   1186: #endif
                   1187:        /*
                   1188:         * Atomically take all devices off the queue
                   1189:         */
                   1190:        mask = ~hilqmask(mp->mm_id);
                   1191:        s = splhil();
                   1192:        for (i = 0; i < NHILD; i++)
                   1193:                hilp->hl_device[i].hd_qmask &= mask;
                   1194:        splx(s);
                   1195:        /*
                   1196:         * Now unmap from user address space and free queue
                   1197:         */
                   1198:        i = mp->mm_id;
                   1199:        cifree((caddr_t)hilp->hl_queue[i].hq_eventqueue, sizeof(HILQ));
                   1200:        hilp->hl_queue[i].hq_eventqueue = NULL;
                   1201:        hilp->hl_queue[i].hq_procp = NULL;
                   1202:        return(mmfree(p, mp));
                   1203: }
                   1204: #endif
                   1205: 
                   1206: #include "clist.h"
                   1207: 
                   1208: /*
                   1209:  * This is just a copy of the virgin q_to_b routine with minor
                   1210:  * optimizations for HIL use.  It is used for two reasons:
                   1211:  * 1. If we have PAGE mode defined, the normal q_to_b processes
                   1212:  *    chars one at a time and breaks on newlines.
                   1213:  * 2. We don't have to raise the priority to spltty() for most
                   1214:  *    of the clist manipulations.
                   1215:  */
                   1216: hilq_to_b(q, cp, cc)
                   1217:        register struct clist *q;
                   1218:        register char *cp;
                   1219: {
                   1220:        register struct cblock *bp;
                   1221:        register int nc;
                   1222:        char *acp;
                   1223:        int s;
                   1224:        extern char cwaiting;
                   1225: 
                   1226:        if (cc <= 0)
                   1227:                return (0);
                   1228:        s = splhil();
                   1229:        if (q->c_cc <= 0) {
                   1230:                q->c_cc = 0;
                   1231:                q->c_cf = q->c_cl = NULL;
                   1232:                splx(s);
                   1233:                return (0);
                   1234:        }
                   1235:        acp = cp;
                   1236: 
                   1237:        while (cc) {
                   1238:                nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND);
                   1239:                nc = MIN(nc, cc);
                   1240:                nc = MIN(nc, q->c_cc);
                   1241:                (void) bcopy(q->c_cf, cp, (unsigned)nc);
                   1242:                q->c_cf += nc;
                   1243:                q->c_cc -= nc;
                   1244:                cc -= nc;
                   1245:                cp += nc;
                   1246:                if (q->c_cc <= 0) {
                   1247:                        bp = (struct cblock *)(q->c_cf - 1);
                   1248:                        bp = (struct cblock *)((int)bp & ~CROUND);
                   1249:                        q->c_cf = q->c_cl = NULL;
                   1250:                        spltty();
                   1251:                        bp->c_next = cfreelist;
                   1252:                        cfreelist = bp;
                   1253:                        cfreecount += CBSIZE;
                   1254:                        if (cwaiting) {
                   1255:                                wakeup(&cwaiting);
                   1256:                                cwaiting = 0;
                   1257:                        }
                   1258:                        break;
                   1259:                }
                   1260:                if (((int)q->c_cf & CROUND) == 0) {
                   1261:                        bp = (struct cblock *)(q->c_cf);
                   1262:                        bp--;
                   1263:                        q->c_cf = bp->c_next->c_info;
                   1264:                        spltty();
                   1265:                        bp->c_next = cfreelist;
                   1266:                        cfreelist = bp;
                   1267:                        cfreecount += CBSIZE;
                   1268:                        if (cwaiting) {
                   1269:                                wakeup(&cwaiting);
                   1270:                                cwaiting = 0;
                   1271:                        }
                   1272:                        splhil();
                   1273:                }
                   1274:        }
                   1275:        splx(s);
                   1276:        return (cp-acp);
                   1277: }
                   1278: 
                   1279: /*
                   1280:  * Cooked keyboard functions for ite driver.
                   1281:  * There is only one "cooked" ITE keyboard (the first keyboard found)
                   1282:  * per loop.  There may be other keyboards, but they will always be "raw".
                   1283:  */
                   1284: 
                   1285: kbdbell()
                   1286: {
                   1287:        struct hilloop *hilp = &hil0;           /* XXX */
                   1288: 
                   1289:        hilbeep(hilp, &default_bell);
                   1290: }
                   1291: 
                   1292: kbdenable()
                   1293: {
                   1294:        struct hilloop *hilp = &hil0;   /* XXX */
                   1295:        register struct hil_dev *hildevice = hilp->hl_addr;
                   1296:        char db;
                   1297: 
                   1298:        /* Set the autorepeat rate register */
                   1299:        db = ar_format(KBD_ARR);
                   1300:        send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL);
                   1301: 
                   1302:        /* Set the autorepeat delay register */
                   1303:        db = ar_format(KBD_ARD);
                   1304:        send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL);
                   1305: 
                   1306:        /* Enable interrupts */
                   1307:        send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
                   1308: }
                   1309: 
                   1310: kbddisable()
                   1311: {
                   1312: }
                   1313: 
                   1314: /*
                   1315:  * XXX: read keyboard directly and return code.
                   1316:  * Used by console getchar routine.  Could really screw up anybody
                   1317:  * reading from the keyboard in the normal, interrupt driven fashion.
                   1318:  */
                   1319: kbdgetc(statp)
                   1320:        int *statp;
                   1321: {
                   1322:        struct hilloop *hilp = &hil0;           /* XXX */
                   1323:        register struct hil_dev *hildevice = hilp->hl_addr;
                   1324:        register int c, stat;
                   1325:        int s;
                   1326: 
                   1327:        s = splhil();
                   1328:        while (((stat = hildevice->hil_stat) & HIL_DATA_RDY) == 0)
                   1329:                ;
                   1330:        c = hildevice->hil_data;
                   1331:        splx(s);
                   1332:        *statp = stat;
                   1333:        return(c);
                   1334: }
                   1335: 
                   1336: /*
                   1337:  * Recoginize and clear keyboard generated NMIs.
                   1338:  * Returns 1 if it was ours, 0 otherwise.  Note that we cannot use
                   1339:  * send_hil_cmd() to issue the clear NMI command as that would actually
                   1340:  * lower the priority to splimp() and it doesn't wait for the completion
                   1341:  * of the command.  Either of these conditions could result in the
                   1342:  * interrupt reoccuring.  Note that we issue the CNMT command twice.
                   1343:  * This seems to be needed, once is not always enough!?!
                   1344:  */
                   1345: kbdnmi()
                   1346: {
                   1347:        register struct hilloop *hilp = &hil0;          /* XXX */
                   1348: 
                   1349:        if ((*KBDNMISTAT & KBDNMI) == 0)
                   1350:                return(0);
                   1351:        HILWAIT(hilp->hl_addr);
                   1352:        hilp->hl_addr->hil_cmd = HIL_CNMT;
                   1353:        HILWAIT(hilp->hl_addr);
                   1354:        hilp->hl_addr->hil_cmd = HIL_CNMT;
                   1355:        HILWAIT(hilp->hl_addr);
                   1356:        return(1);
                   1357: }
                   1358: 
                   1359: #define HILSECURITY    0x33
                   1360: #define HILIDENTIFY    0x03
                   1361: #define HILSCBIT       0x04
                   1362: 
                   1363: /*
                   1364:  * Called at boot time to print out info about interesting devices
                   1365:  */
                   1366: hilinfo(hilp)
                   1367:        register struct hilloop *hilp;
                   1368: {
                   1369:        register int id, len;
                   1370:        register struct kbdmap *km;
                   1371: 
                   1372:        /*
                   1373:         * Keyboard info.
                   1374:         */
                   1375:        if (hilp->hl_kbddev) {
                   1376:                printf("hil%d: ", hilp->hl_kbddev);
                   1377:                for (km = kbd_map; km->kbd_code; km++)
                   1378:                        if (km->kbd_code == hilp->hl_kbdlang) {
                   1379:                                printf("%s ", km->kbd_desc);
                   1380:                                break;
                   1381:                        }
                   1382:                printf("keyboard\n");
                   1383:        }
                   1384:        /*
                   1385:         * ID module.
                   1386:         * Attempt to locate the first ID module and print out its
                   1387:         * security code.  Is this a good idea??
                   1388:         */
                   1389:        id = hiliddev(hilp);
                   1390:        if (id) {
                   1391:                hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1392:                hilp->hl_cmddev = id;
                   1393:                send_hildev_cmd(hilp, id, HILSECURITY);
                   1394:                len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
                   1395:                hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1396:                hilp->hl_cmddev = 0;
                   1397:                printf("hil%d: security code", id);
                   1398:                for (id = 0; id < len; id++)
                   1399:                        printf(" %x", hilp->hl_cmdbuf[id]);
                   1400:                while (id++ < 16)
                   1401:                        printf(" 0");
                   1402:                printf("\n");
                   1403:        }
                   1404: }
                   1405: 
                   1406: #define HILAR1 0x3E
                   1407: #define HILAR2 0x3F
                   1408: 
                   1409: /*
                   1410:  * Called after the loop has reconfigured.  Here we need to:
                   1411:  *     - determine how many devices are on the loop
                   1412:  *       (some may have been added or removed)
                   1413:  *     - locate the ITE keyboard (if any) and ensure
                   1414:  *       that it is in the proper state (raw or cooked)
                   1415:  *       and is set to use the proper language mapping table
                   1416:  *     - ensure all other keyboards are raw
                   1417:  * Note that our device state is now potentially invalid as
                   1418:  * devices may no longer be where they were.  What we should
                   1419:  * do here is either track where the devices went and move
                   1420:  * state around accordingly or, more simply, just mark all
                   1421:  * devices as HIL_DERROR and don't allow any further use until
                   1422:  * they are closed.  This is a little too brutal for my tastes,
                   1423:  * we prefer to just assume people won't move things around.
                   1424:  */
                   1425: hilconfig(hilp)
                   1426:        register struct hilloop *hilp;
                   1427: {
                   1428:        u_char db;
                   1429:        int s;
                   1430: 
                   1431:        s = splhil();
                   1432: #ifdef DEBUG
                   1433:        if (hildebug & HDB_CONFIG) {
                   1434:                printf("hilconfig: reconfigured: ");
                   1435:                send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db);
                   1436:                printf("LPSTAT %x, ", db);
                   1437:                send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &db);
                   1438:                printf("LPCTRL %x, ", db);
                   1439:                send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db);
                   1440:                printf("KBDSADR %x\n", db);
                   1441:                hilreport(hilp);
                   1442:        }
                   1443: #endif
                   1444:        /*
                   1445:         * Determine how many devices are on the loop.
                   1446:         * Mark those as alive and real, all others as dead.
                   1447:         */
                   1448:        db = 0;
                   1449:        send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db);
                   1450:        hilp->hl_maxdev = db & LPS_DEVMASK;
                   1451:        for (db = 1; db < NHILD; db++) {
                   1452:                if (db <= hilp->hl_maxdev)
                   1453:                        hilp->hl_device[db].hd_flags |= HIL_ALIVE;
                   1454:                else
                   1455:                        hilp->hl_device[db].hd_flags &= ~HIL_ALIVE;
                   1456:                hilp->hl_device[db].hd_flags &= ~HIL_PSEUDO;
                   1457:        }
                   1458: #ifdef DEBUG
                   1459:        if (hildebug & (HDB_CONFIG|HDB_KEYBOARD))
                   1460:                printf("hilconfig: max device %d\n", hilp->hl_maxdev);
                   1461: #endif
                   1462:        if (hilp->hl_maxdev == 0) {
                   1463:                hilp->hl_kbddev = 0;
                   1464:                splx(s);
                   1465:                return;
                   1466:        }
                   1467:        /*
                   1468:         * Find out where the keyboards are and record the ITE keyboard
                   1469:         * (first one found).  If no keyboards found, we are all done.
                   1470:         */
                   1471:        db = 0;
                   1472:        send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db);
                   1473: #ifdef DEBUG
                   1474:        if (hildebug & HDB_KEYBOARD)
                   1475:                printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n",
                   1476:                       db, hilp->hl_kbddev, ffs((int)db));
                   1477: #endif
                   1478:        hilp->hl_kbddev = ffs((int)db);
                   1479:        if (hilp->hl_kbddev == 0) {
                   1480:                splx(s);
                   1481:                return;
                   1482:        }
                   1483:        /*
                   1484:         * Determine if the keyboard should be cooked or raw and configure it.
                   1485:         */
                   1486:        db = (hilp->hl_kbdflags & KBD_RAW) ? 0 : 1 << (hilp->hl_kbddev - 1);
                   1487:        send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &db, 1, NULL);
                   1488:        /*
                   1489:         * Re-enable autorepeat in raw mode, cooked mode AR is not affected.
                   1490:         */
                   1491:        if (hilp->hl_kbdflags & (KBD_AR1|KBD_AR2)) {
                   1492:                db = (hilp->hl_kbdflags & KBD_AR1) ? HILAR1 : HILAR2;
                   1493:                hilp->hl_cmddev = hilp->hl_kbddev;
                   1494:                send_hildev_cmd(hilp, hilp->hl_kbddev, db);
                   1495:                hilp->hl_cmddev = 0;
                   1496:        }
                   1497:        /*
                   1498:         * Determine the keyboard language configuration, but don't
                   1499:         * override a user-specified setting.
                   1500:         */
                   1501:        db = 0;
                   1502:        send_hil_cmd(hilp->hl_addr, HIL_READKBDLANG, NULL, 0, &db);
                   1503: #ifdef DEBUG
                   1504:        if (hildebug & HDB_KEYBOARD)
                   1505:                printf("hilconfig: language: old %x new %x\n",
                   1506:                       hilp->hl_kbdlang, db);
                   1507: #endif
                   1508:        if (hilp->hl_kbdlang != KBD_SPECIAL) {
                   1509:                struct kbdmap *km;
                   1510: 
                   1511:                for (km = kbd_map; km->kbd_code; km++)
                   1512:                        if (km->kbd_code == db) {
                   1513:                                hilp->hl_kbdlang = db;
                   1514:                                /* XXX */
                   1515:                                kbd_keymap = km->kbd_keymap;
                   1516:                                kbd_shiftmap = km->kbd_shiftmap;
                   1517:                                kbd_ctrlmap = km->kbd_ctrlmap;
                   1518:                                kbd_ctrlshiftmap = km->kbd_ctrlshiftmap;
                   1519:                                kbd_stringmap = km->kbd_stringmap;
                   1520:                        }
                   1521:        }
                   1522:        splx(s);
                   1523: }
                   1524: 
                   1525: hilreset(hilp)
                   1526:        struct hilloop *hilp;
                   1527: {
                   1528:        register struct hil_dev *hildevice = hilp->hl_addr;
                   1529:        u_char db;
                   1530: 
                   1531:        /*
                   1532:         * Initialize the loop: reconfigure, don't report errors,
                   1533:         * cook keyboards, and enable autopolling.
                   1534:         */
                   1535:        db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL;
                   1536:        send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL);
                   1537:        /*
                   1538:         * Delay one second for reconfiguration and then read the the
                   1539:         * data register to clear the interrupt (if the loop reconfigured).
                   1540:         */
                   1541:        DELAY(1000000);
                   1542:        if (hildevice->hil_stat & HIL_DATA_RDY)
                   1543:                db = hildevice->hil_data;
                   1544:        /*
                   1545:         * The HIL loop may have reconfigured.  If so we proceed on,
                   1546:         * if not we loop until a successful reconfiguration is reported
                   1547:         * back to us.  The HIL loop will continue to attempt forever.
                   1548:         * Probably not very smart.
                   1549:         */
                   1550:        do {
                   1551:                send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db);
                   1552:         } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0);
                   1553:        /*
                   1554:         * At this point, the loop should have reconfigured.
                   1555:         * The reconfiguration interrupt has already called hilconfig()
                   1556:         * so the keyboard has been determined.
                   1557:         */
                   1558:        send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
                   1559: }
                   1560: 
                   1561: hilbeep(hilp, bp)
                   1562:        struct hilloop *hilp;
                   1563:        register struct _hilbell *bp;
                   1564: {
                   1565:        u_char buf[2];
                   1566: 
                   1567:        buf[0] = ~((bp->duration - 10) / 10);
                   1568:        buf[1] = bp->frequency;
                   1569:        send_hil_cmd(hilp->hl_addr, HIL_SETTONE, buf, 2, NULL);
                   1570: }
                   1571: 
                   1572: /*
                   1573:  * Locate and return the address of the first ID module, 0 if none present.
                   1574:  */
                   1575: hiliddev(hilp)
                   1576:        register struct hilloop *hilp;
                   1577: {
                   1578:        register int i, len;
                   1579: 
                   1580: #ifdef DEBUG
                   1581:        if (hildebug & HDB_IDMODULE)
                   1582:                printf("hiliddev(%x): looking for idmodule...", hilp);
                   1583: #endif
                   1584:        for (i = 1; i <= hilp->hl_maxdev; i++) {
                   1585:                hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1586:                hilp->hl_cmddev = i;
                   1587:                send_hildev_cmd(hilp, i, HILIDENTIFY);
                   1588:                /*
                   1589:                 * XXX: the final condition checks to ensure that the
                   1590:                 * device ID byte is in the range of the ID module (0x30-0x3F)
                   1591:                 */
                   1592:                len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
                   1593:                if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT) &&
                   1594:                    (hilp->hl_cmdbuf[0] & 0xF0) == 0x30) {
                   1595:                        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1596:                        hilp->hl_cmddev = i;
                   1597:                        send_hildev_cmd(hilp, i, HILSECURITY);
                   1598:                        break;
                   1599:                }
                   1600:        }               
                   1601:        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1602:        hilp->hl_cmddev = 0;
                   1603: #ifdef DEBUG
                   1604:        if (hildebug & HDB_IDMODULE)
                   1605:                if (i <= hilp->hl_maxdev)
                   1606:                        printf("found at %d\n", i);
                   1607:                else
                   1608:                        printf("not found\n");
                   1609: #endif
                   1610:        return(i <= hilp->hl_maxdev ? i : 0);
                   1611: }
                   1612: 
                   1613: /*
                   1614:  * Low level routines which actually talk to the 8042 chip.
                   1615:  */
                   1616: 
                   1617: /*
                   1618:  * Send a command to the 8042 with zero or more bytes of data.
                   1619:  * If rdata is non-null, wait for and return a byte of data.
                   1620:  * We run at splimp() to make the transaction as atomic as
                   1621:  * possible without blocking the clock (is this necessary?)
                   1622:  */
                   1623: send_hil_cmd(hildevice, cmd, data, dlen, rdata)
                   1624:        register struct hil_dev *hildevice;
                   1625:        u_char cmd, *data, dlen;
                   1626:        u_char *rdata;
                   1627: {
                   1628:        u_char status;
                   1629:        int s = splimp();
                   1630: 
                   1631:        HILWAIT(hildevice);
                   1632:        hildevice->hil_cmd = cmd;
                   1633:        while (dlen--) {
                   1634:                HILWAIT(hildevice);
                   1635:                hildevice->hil_data = *data++;
                   1636:        }
                   1637:        if (rdata) {
                   1638:                do {
                   1639:                        HILDATAWAIT(hildevice);
                   1640:                        status = hildevice->hil_stat;
                   1641:                        *rdata = hildevice->hil_data;
                   1642:                } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K);
                   1643:        }
                   1644:        splx(s);
                   1645: }
                   1646: 
                   1647: /*
                   1648:  * Send a command to a device on the loop.
                   1649:  * Since only one command can be active on the loop at any time,
                   1650:  * we must ensure that we are not interrupted during this process.
                   1651:  * Hence we mask interrupts to prevent potential access from most
                   1652:  * interrupt routines and turn off auto-polling to disable the
                   1653:  * internally generated poll commands.
                   1654:  *
                   1655:  * splhigh is extremely conservative but insures atomic operation,
                   1656:  * splimp (clock only interrupts) seems to be good enough in practice.
                   1657:  */
                   1658: send_hildev_cmd(hilp, device, cmd)
                   1659:        register struct hilloop *hilp;
                   1660:        char device, cmd;
                   1661: {
                   1662:        register struct hil_dev *hildevice = hilp->hl_addr;
                   1663:        u_char status, c;
                   1664:        int s = splimp();
                   1665: 
                   1666:        polloff(hildevice);
                   1667: 
                   1668:        /*
                   1669:         * Transfer the command and device info to the chip
                   1670:         */
                   1671:        HILWAIT(hildevice);
                   1672:        hildevice->hil_cmd = HIL_STARTCMD;
                   1673:        HILWAIT(hildevice);
                   1674:        hildevice->hil_data = 8 + device;
                   1675:        HILWAIT(hildevice);
                   1676:        hildevice->hil_data = cmd;
                   1677:        HILWAIT(hildevice);
                   1678:        hildevice->hil_data = HIL_TIMEOUT;
                   1679:        /*
                   1680:         * Trigger the command and wait for completion
                   1681:         */
                   1682:        HILWAIT(hildevice);
                   1683:        hildevice->hil_cmd = HIL_TRIGGER;
                   1684:        hilp->hl_cmddone = FALSE;
                   1685:        do {
                   1686:                HILDATAWAIT(hildevice);
                   1687:                status = hildevice->hil_stat;
                   1688:                c = hildevice->hil_data;
                   1689:                hil_process_int(status, c);
                   1690:        } while (!hilp->hl_cmddone);
                   1691: 
                   1692:        pollon(hildevice);
                   1693:        splx(s);
                   1694: }
                   1695: 
                   1696: /*
                   1697:  * Turn auto-polling off and on.
                   1698:  * Also disables and enable auto-repeat.  Why?
                   1699:  */
                   1700: polloff(hildevice)
                   1701:        register struct hil_dev *hildevice;
                   1702: {
                   1703:        register char db;
                   1704: 
                   1705:        /*
                   1706:         * Turn off auto repeat
                   1707:         */
                   1708:        HILWAIT(hildevice);
                   1709:        hildevice->hil_cmd = HIL_SETARR;
                   1710:        HILWAIT(hildevice);
                   1711:        hildevice->hil_data = 0;
                   1712:        /*
                   1713:         * Turn off auto-polling
                   1714:         */
                   1715:        HILWAIT(hildevice);
                   1716:        hildevice->hil_cmd = HIL_READLPCTRL;
                   1717:        HILDATAWAIT(hildevice);
                   1718:        db = hildevice->hil_data;
                   1719:        db &= ~LPC_AUTOPOLL;
                   1720:        HILWAIT(hildevice);
                   1721:        hildevice->hil_cmd = HIL_WRITELPCTRL;
                   1722:        HILWAIT(hildevice);
                   1723:        hildevice->hil_data = db;
                   1724:        /*
                   1725:         * Must wait til polling is really stopped
                   1726:         */
                   1727:        do {    
                   1728:                HILWAIT(hildevice);
                   1729:                hildevice->hil_cmd = HIL_READBUSY;
                   1730:                HILDATAWAIT(hildevice);
                   1731:                db = hildevice->hil_data;
                   1732:        } while (db & BSY_LOOPBUSY);
                   1733: }
                   1734: 
                   1735: pollon(hildevice)
                   1736:        register struct hil_dev *hildevice;
                   1737: {
                   1738:        register char db;
                   1739: 
                   1740:        /*
                   1741:         * Turn on auto polling
                   1742:         */
                   1743:        HILWAIT(hildevice);
                   1744:        hildevice->hil_cmd = HIL_READLPCTRL;
                   1745:        HILDATAWAIT(hildevice);
                   1746:        db = hildevice->hil_data;
                   1747:        db |= LPC_AUTOPOLL;
                   1748:        HILWAIT(hildevice);
                   1749:        hildevice->hil_cmd = HIL_WRITELPCTRL;
                   1750:        HILWAIT(hildevice);
                   1751:        hildevice->hil_data = db;
                   1752:        /*
                   1753:         * Turn on auto repeat
                   1754:         */
                   1755:        HILWAIT(hildevice);
                   1756:        hildevice->hil_cmd = HIL_SETARR;
                   1757:        HILWAIT(hildevice);
                   1758:        hildevice->hil_data = ar_format(KBD_ARR);
                   1759: }
                   1760: 
                   1761: #ifdef DEBUG
                   1762: printhilpollbuf(hilp)
                   1763:        register struct hilloop *hilp;
                   1764: {
                   1765:        register u_char *cp;
                   1766:        register int i, len;
                   1767: 
                   1768:        cp = hilp->hl_pollbuf;
                   1769:        len = hilp->hl_pollbp - cp;
                   1770:        for (i = 0; i < len; i++)
                   1771:                printf("%x ", hilp->hl_pollbuf[i]);
                   1772:        printf("\n");
                   1773: }
                   1774: 
                   1775: printhilcmdbuf(hilp)
                   1776:        register struct hilloop *hilp;
                   1777: {
                   1778:        register u_char *cp;
                   1779:        register int i, len;
                   1780: 
                   1781:        cp = hilp->hl_cmdbuf;
                   1782:        len = hilp->hl_cmdbp - cp;
                   1783:        for (i = 0; i < len; i++)
                   1784:                printf("%x ", hilp->hl_cmdbuf[i]);
                   1785:        printf("\n");
                   1786: }
                   1787: 
                   1788: hilreport(hilp)
                   1789:        register struct hilloop *hilp;
                   1790: {
                   1791:        register int i, len;
                   1792:        int s = splhil();
                   1793: 
                   1794:        for (i = 1; i <= hilp->hl_maxdev; i++) {
                   1795:                hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1796:                hilp->hl_cmddev = i;
                   1797:                send_hildev_cmd(hilp, i, HILIDENTIFY);
                   1798:                printf("hil%d: id: ", i);
                   1799:                printhilcmdbuf(hilp);
                   1800:                len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
                   1801:                if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT)) {
                   1802:                        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1803:                        hilp->hl_cmddev = i;
                   1804:                        send_hildev_cmd(hilp, i, HILSECURITY);
                   1805:                        printf("hil%d: sc: ", i);
                   1806:                        printhilcmdbuf(hilp);
                   1807:                }
                   1808:        }               
                   1809:        hilp->hl_cmdbp = hilp->hl_cmdbuf;
                   1810:        hilp->hl_cmddev = 0;
                   1811:        splx(s);
                   1812: }
                   1813: #endif

unix.superglobalmegacorp.com

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