home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / dev / hil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-29  |  38.4 KB  |  1,620 lines

  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
  1620.