Annotation of Net2/arch/hp300/dev/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 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.