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

unix.superglobalmegacorp.com

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