No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / hp300 / dev / hil.c
blob72b71e9e5b76d7f60a8ca97f02e3f496b14b9d22
1 /* $NetBSD: hil.c,v 1.82 2008/06/13 09:41:15 cegger Exp $ */
3 /*
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * the Systems Programming Group of the University of Utah Computer
9 * Science Department.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 * from: Utah $Hdr: hil.c 1.38 92/01/21$
37 * @(#)hil.c 8.2 (Berkeley) 1/12/94
40 * Copyright (c) 1988 University of Utah.
42 * This code is derived from software contributed to Berkeley by
43 * the Systems Programming Group of the University of Utah Computer
44 * Science Department.
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. All advertising materials mentioning features or use of this software
55 * must display the following acknowledgement:
56 * This product includes software developed by the University of
57 * California, Berkeley and its contributors.
58 * 4. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 * SUCH DAMAGE.
74 * from: Utah $Hdr: hil.c 1.38 92/01/21$
76 * @(#)hil.c 8.2 (Berkeley) 1/12/94
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: hil.c,v 1.82 2008/06/13 09:41:15 cegger Exp $");
82 #include "ite.h"
83 #include "rnd.h"
85 #include <sys/param.h>
86 #include <sys/systm.h>
87 #include <sys/conf.h>
88 #include <sys/device.h>
89 #include <sys/file.h>
90 #include <sys/ioctl.h>
91 #include <sys/kernel.h>
92 #include <sys/poll.h>
93 #include <sys/proc.h>
94 #include <sys/tty.h>
95 #include <sys/uio.h>
96 #include <sys/kauth.h>
98 #include <uvm/uvm_extern.h>
100 #if NRND > 0
101 #include <sys/rnd.h>
102 #endif
104 #include <hp300/dev/intiovar.h>
106 #include <hp300/dev/hilreg.h>
107 #include <hp300/dev/hilioctl.h>
108 #include <hp300/dev/hilvar.h>
109 #include <hp300/dev/itevar.h>
110 #include <hp300/dev/kbdmap.h>
112 #include <machine/bus.h>
113 #include <machine/cpu.h>
115 #include "ioconf.h"
117 static int hilmatch(device_t, cfdata_t, void *);
118 static void hilattach(device_t, device_t, void *);
120 CFATTACH_DECL_NEW(hil, sizeof(struct hil_softc),
121 hilmatch, hilattach, NULL, NULL);
123 static struct _hilbell default_bell = { BELLDUR, BELLFREQ };
125 #ifdef DEBUG
126 int hildebug = 0;
127 #define HDB_FOLLOW 0x01
128 #define HDB_MMAP 0x02
129 #define HDB_MASK 0x04
130 #define HDB_CONFIG 0x08
131 #define HDB_KEYBOARD 0x10
132 #define HDB_IDMODULE 0x20
133 #define HDB_EVENTS 0x80
134 #endif
136 extern struct kbdmap kbd_map[];
138 /* symbolic sleep message strings */
139 static const char hilin[] = "hilin";
141 static dev_type_open(hilopen);
142 static dev_type_close(hilclose);
143 static dev_type_read(hilread);
144 static dev_type_ioctl(hilioctl);
145 static dev_type_poll(hilpoll);
146 static dev_type_kqfilter(hilkqfilter);
148 const struct cdevsw hil_cdevsw = {
149 hilopen, hilclose, hilread, nullwrite, hilioctl,
150 nostop, notty, hilpoll, nommap, hilkqfilter,
153 static void hilattach_deferred(device_t);
155 static void hilinfo(struct hil_softc *);
156 static void hilconfig(struct hil_softc *);
157 static void hilreset(struct hil_softc *);
158 static void hilbeep(struct hil_softc *, const struct _hilbell *);
159 static int hiliddev(struct hil_softc *);
161 static int hilint(void *);
162 static void hil_process_int(struct hil_softc *, uint8_t, uint8_t);
163 static void hilevent(struct hil_softc *);
164 static void hpuxhilevent(struct hil_softc *, struct hilloopdev *);
166 static int hilqalloc(struct hil_softc *, struct hilqinfo *, struct proc *);
167 static int hilqfree(struct hil_softc *, int, struct proc *);
168 static int hilqmap(struct hil_softc *, int, int, struct lwp *);
169 static int hilqunmap(struct hil_softc *, int, int, struct proc *);
171 #ifdef DEBUG
172 static void printhilpollbuf(struct hil_softc *);
173 static void printhilcmdbuf(struct hil_softc *);
174 static void hilreport(struct hil_softc *);
175 #endif /* DEBUG */
177 static int
178 hilmatch(device_t parent, cfdata_t cf, void *aux)
180 struct intio_attach_args *ia = aux;
182 if (strcmp("hil", ia->ia_modname) != 0)
183 return 0;
185 return 1;
188 static void
189 hilattach(device_t parent, device_t self, void *aux)
191 struct hil_softc *sc = device_private(self);
192 struct intio_attach_args *ia = aux;
193 int i;
195 sc->sc_dev = self;
196 aprint_normal("\n");
198 #ifdef DEBUG
199 if (hildebug & HDB_FOLLOW)
200 aprint_debug("hilsoftinit(%p, %p)\n", sc,
201 (void *)ia->ia_addr);
202 #endif
204 * Initialize loop information
206 sc->sc_addr = (struct hil_dev *)ia->ia_addr;
207 sc->sc_cmdending = false;
208 sc->sc_actdev = sc->sc_cmddev = 0;
209 sc->sc_cmddone = false;
210 sc->sc_cmdbp = sc->sc_cmdbuf;
211 sc->sc_pollbp = sc->sc_pollbuf;
212 sc->sc_kbddev = 0;
213 sc->sc_kbdflags = 0;
215 * Clear all queues and device associations with queues
217 for (i = 0; i < NHILQ; i++) {
218 sc->sc_queue[i].hq_eventqueue = NULL;
219 sc->sc_queue[i].hq_procp = NULL;
220 sc->sc_queue[i].hq_devmask = 0;
222 for (i = 0; i < NHILD; i++) {
223 selinit(&sc->sc_device[i].hd_selr);
224 sc->sc_device[i].hd_qmask = 0;
226 sc->sc_device[HILLOOPDEV].hd_flags = (HIL_ALIVE|HIL_PSEUDO);
229 * Set up default keyboard language. We always default
230 * to US ASCII - it seems to work OK for non-recognized
231 * keyboards.
234 sc->sc_kbdlang = KBD_DEFAULT;
235 #if NITE > 0
237 struct kbdmap *km;
238 for (km = kbd_map; km->kbd_code; km++) {
239 if (km->kbd_code == KBD_US)
240 iteinstallkeymap(km);
243 #endif
245 (void)intio_intr_establish(hilint, sc, ia->ia_ipl, IPL_TTY);
247 config_interrupts(self, hilattach_deferred);
250 static void
251 hilattach_deferred(device_t self)
253 struct hil_softc *sc = device_private(self);
255 #ifdef DEBUG
256 if (hildebug & HDB_FOLLOW)
257 aprint_debug("hilinit(%p, %p)\n", sc, sc->sc_addr);
258 #endif
260 * Initialize hardware.
261 * Reset the loop hardware, and collect keyboard/id info
263 hilreset(sc);
264 hilinfo(sc);
265 hilkbdenable(sc);
268 /* ARGSUSED */
269 static int
270 hilopen(dev_t dev, int flags, int mode, struct lwp *l)
272 struct hil_softc *sc;
273 struct hilloopdev *dptr;
274 int s;
275 #ifdef DEBUG
276 struct proc *p = l->l_proc;
277 #endif
279 sc = device_lookup_private(&hil_cd, HILLOOP(dev));
281 #ifdef DEBUG
282 if (hildebug & HDB_FOLLOW)
283 printf("hilopen(%d): loop %x device %x\n",
284 p->p_pid, HILLOOP(dev), HILUNIT(dev));
285 #endif
287 if ((sc->sc_device[HILLOOPDEV].hd_flags & HIL_ALIVE) == 0)
288 return ENXIO;
290 dptr = &sc->sc_device[HILUNIT(dev)];
291 if ((dptr->hd_flags & HIL_ALIVE) == 0)
292 return ENODEV;
295 * Pseudo-devices cannot be read, nothing more to do.
297 if (dptr->hd_flags & HIL_PSEUDO)
298 return 0;
301 * Open semantics:
302 * 1. Open devices have only one of HIL_READIN/HIL_QUEUEIN.
303 * 2. HPUX processes always get read syscall interface and
304 * must have exclusive use of the device.
305 * 3. BSD processes default to shared queue interface.
306 * Multiple processes can open the device.
308 if (dptr->hd_flags & HIL_READIN)
309 return EBUSY;
310 dptr->hd_flags |= HIL_QUEUEIN;
311 if (flags & FNONBLOCK)
312 dptr->hd_flags |= HIL_NOBLOCK;
314 * It is safe to flush the read buffer as we are guaranteed
315 * that no one else is using it.
317 if ((dptr->hd_flags & HIL_OPENED) == 0) {
318 dptr->hd_flags |= HIL_OPENED;
319 clalloc(&dptr->hd_queue, HILMAXCLIST, 0);
322 send_hil_cmd(sc->sc_addr, HIL_INTON, NULL, 0, NULL);
324 * Opened the keyboard, put in raw mode.
326 s = splhil();
327 if (HILUNIT(dev) == sc->sc_kbddev) {
328 uint8_t mask = 0;
329 send_hil_cmd(sc->sc_addr, HIL_WRITEKBDSADR, &mask, 1, NULL);
330 sc->sc_kbdflags |= KBD_RAW;
331 #ifdef DEBUG
332 if (hildebug & HDB_KEYBOARD)
333 printf("hilopen: keyboard %d raw\n", sc->sc_kbddev);
334 #endif
336 splx(s);
337 return 0;
340 /* ARGSUSED */
341 static int
342 hilclose(dev_t dev, int flags, int mode, struct lwp *l)
344 struct hil_softc *sc;
345 struct hilloopdev *dptr;
346 int i;
347 char mask, lpctrl;
348 int s;
349 extern struct emul emul_netbsd;
350 #ifdef DEBUG
351 struct proc *p = l->l_proc;
352 #endif
354 sc = device_lookup_private(&hil_cd, HILLOOP(dev));
356 #ifdef DEBUG
357 if (hildebug & HDB_FOLLOW)
358 printf("hilclose(%d): device %x\n", p->p_pid, HILUNIT(dev));
359 #endif
361 dptr = &sc->sc_device[HILUNIT(dev)];
362 if (HILUNIT(dev) && (dptr->hd_flags & HIL_PSEUDO))
363 return 0;
365 if (l && l->l_proc->p_emul == &emul_netbsd) {
367 * If this is the loop device,
368 * free up all queues belonging to this process.
370 if (HILUNIT(dev) == 0) {
371 for (i = 0; i < NHILQ; i++)
372 if (sc->sc_queue[i].hq_procp == l->l_proc)
373 (void) hilqfree(sc, i, l->l_proc);
374 } else {
375 mask = ~hildevmask(HILUNIT(dev));
376 s = splhil();
377 for (i = 0; i < NHILQ; i++)
378 if (sc->sc_queue[i].hq_procp == l->l_proc) {
379 dptr->hd_qmask &= ~hilqmask(i);
380 sc->sc_queue[i].hq_devmask &= mask;
382 splx(s);
386 * The read buffer can go away.
388 dptr->hd_flags &= ~(HIL_QUEUEIN|HIL_READIN|HIL_NOBLOCK|HIL_OPENED);
389 clfree(&dptr->hd_queue);
391 * Set keyboard back to cooked mode when closed.
393 s = splhil();
394 if (HILUNIT(dev) && HILUNIT(dev) == sc->sc_kbddev) {
395 mask = 1 << (sc->sc_kbddev - 1);
396 send_hil_cmd(sc->sc_addr, HIL_WRITEKBDSADR, &mask, 1, NULL);
397 sc->sc_kbdflags &= ~(KBD_RAW|KBD_AR1|KBD_AR2);
399 * XXX: We have had trouble with keyboards remaining raw
400 * after close due to the LPC_KBDCOOK bit getting cleared
401 * somewhere along the line. Hence we check and reset
402 * LPCTRL if necessary.
404 send_hil_cmd(sc->sc_addr, HIL_READLPCTRL, NULL, 0, &lpctrl);
405 if ((lpctrl & LPC_KBDCOOK) == 0) {
406 printf("hilclose: bad LPCTRL %x, reset to %x\n",
407 lpctrl, lpctrl|LPC_KBDCOOK);
408 lpctrl |= LPC_KBDCOOK;
409 send_hil_cmd(sc->sc_addr, HIL_WRITELPCTRL,
410 &lpctrl, 1, NULL);
412 #ifdef DEBUG
413 if (hildebug & HDB_KEYBOARD)
414 printf("hilclose: keyboard %d cooked\n",
415 sc->sc_kbddev);
416 #endif
417 hilkbdenable(sc);
419 splx(s);
420 return 0;
424 * Read interface to HIL device.
426 /* ARGSUSED */
427 static int
428 hilread(dev_t dev, struct uio *uio, int flag)
430 struct hil_softc *sc;
431 struct hilloopdev *dptr;
432 int cc;
433 uint8_t buf[HILBUFSIZE];
434 int error, s;
436 sc = device_lookup_private(&hil_cd, HILLOOP(dev));
438 #if 0
440 * XXX: Don't do this since HP-UX doesn't.
442 * Check device number.
443 * This check is necessary since loop can reconfigure.
445 if (HILUNIT(dev) > sc->sc_maxdev)
446 return ENODEV;
447 #endif
449 dptr = &sc->sc_device[HILUNIT(dev)];
450 if ((dptr->hd_flags & HIL_READIN) == 0)
451 return ENODEV;
453 s = splhil();
454 while (dptr->hd_queue.c_cc == 0) {
455 if (dptr->hd_flags & HIL_NOBLOCK) {
456 spl0();
457 return EWOULDBLOCK;
459 dptr->hd_flags |= HIL_ASLEEP;
460 if ((error = tsleep((void *)dptr,
461 TTIPRI | PCATCH, hilin, 0))) {
462 (void)spl0();
463 return error;
466 splx(s);
468 error = 0;
469 while (uio->uio_resid > 0 && error == 0) {
470 cc = q_to_b(&dptr->hd_queue, buf,
471 min(uio->uio_resid, HILBUFSIZE));
472 if (cc <= 0)
473 break;
474 error = uiomove(buf, cc, uio);
476 return error;
479 static int
480 hilioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
482 struct hil_softc *sc;
483 struct hilloopdev *dptr;
484 uint8_t *buf;
485 int i;
486 uint8_t hold;
487 int error;
489 sc = device_lookup_private(&hil_cd, HILLOOP(dev));
491 #ifdef DEBUG
492 if (hildebug & HDB_FOLLOW)
493 printf("hilioctl(%d): dev %x cmd %lx\n",
494 l->l_proc->p_pid, HILUNIT(dev), cmd);
495 #endif
497 dptr = &sc->sc_device[HILUNIT(dev)];
498 if ((dptr->hd_flags & HIL_ALIVE) == 0)
499 return ENODEV;
502 * Don't allow hardware ioctls on virtual devices.
503 * Note that though these are the BSD names, they have the same
504 * values as the HP-UX equivalents so we catch them as well.
506 if (dptr->hd_flags & HIL_PSEUDO) {
507 switch (cmd) {
508 case HILIOCSC:
509 case HILIOCID:
510 case OHILIOCID:
511 case HILIOCRN:
512 case HILIOCRS:
513 case HILIOCED:
514 return ENODEV;
517 * XXX: should also return ENODEV but HP-UX compat
518 * breaks if we do. They work ok right now because
519 * we only recognize one keyboard on the loop. This
520 * will have to change if we remove that restriction.
522 case HILIOCAROFF:
523 case HILIOCAR1:
524 case HILIOCAR2:
525 break;
527 default:
528 break;
532 sc->sc_cmdbp = sc->sc_cmdbuf;
533 memset((void *)sc->sc_cmdbuf, 0, HILBUFSIZE);
534 sc->sc_cmddev = HILUNIT(dev);
535 error = 0;
536 switch (cmd) {
538 case HILIOCSBP:
539 /* Send four data bytes to the tone gererator. */
540 send_hil_cmd(sc->sc_addr, HIL_STARTCMD, data, 4, NULL);
541 /* Send the trigger beeper command to the 8042. */
542 send_hil_cmd(sc->sc_addr, (cmd & 0xFF), NULL, 0, NULL);
543 break;
545 case OHILIOCRRT:
546 case HILIOCRRT:
547 /* Transfer the real time to the 8042 data buffer */
548 send_hil_cmd(sc->sc_addr, (cmd & 0xFF), NULL, 0, NULL);
549 /* Read each byte of the real time */
550 buf = data;
551 for (i = 0; i < 5; i++) {
552 send_hil_cmd(sc->sc_addr, HIL_READTIME + i, NULL,
553 0, &hold);
554 buf[4 - i] = hold;
556 break;
558 case HILIOCRT:
559 buf = data;
560 for (i = 0; i < 4; i++) {
561 send_hil_cmd(sc->sc_addr, (cmd & 0xFF) + i,
562 NULL, 0, &hold);
563 buf[i] = hold;
565 break;
567 case HILIOCID:
568 case OHILIOCID:
569 case HILIOCSC:
570 case HILIOCRN:
571 case HILIOCRS:
572 case HILIOCED:
573 send_hildev_cmd(sc, HILUNIT(dev), (cmd & 0xFF));
574 memcpy(data, sc->sc_cmdbuf, sc->sc_cmdbp - sc->sc_cmdbuf);
575 break;
577 case HILIOCAROFF:
578 case HILIOCAR1:
579 case HILIOCAR2:
580 if (sc->sc_kbddev) {
581 sc->sc_cmddev = sc->sc_kbddev;
582 send_hildev_cmd(sc, sc->sc_kbddev, (cmd & 0xFF));
583 sc->sc_kbdflags &= ~(KBD_AR1|KBD_AR2);
584 if (cmd == HILIOCAR1)
585 sc->sc_kbdflags |= KBD_AR1;
586 else if (cmd == HILIOCAR2)
587 sc->sc_kbdflags |= KBD_AR2;
589 break;
591 case HILIOCBEEP:
592 hilbeep(sc, (struct _hilbell *)data);
593 break;
595 case FIONBIO:
596 dptr = &sc->sc_device[HILUNIT(dev)];
597 if (*(int *)data)
598 dptr->hd_flags |= HIL_NOBLOCK;
599 else
600 dptr->hd_flags &= ~HIL_NOBLOCK;
601 break;
604 * FIOASYNC must be present for FIONBIO above to work!
605 * (See fcntl in kern_descrip.c).
607 case FIOASYNC:
608 break;
610 case HILIOCALLOCQ:
611 error = hilqalloc(sc, (struct hilqinfo *)data, l->l_proc);
612 break;
614 case HILIOCFREEQ:
615 error = hilqfree(sc, ((struct hilqinfo *)data)->qid, l->l_proc);
616 break;
618 case HILIOCMAPQ:
619 error = hilqmap(sc, *(int *)data, HILUNIT(dev), l);
620 break;
622 case HILIOCUNMAPQ:
623 error = hilqunmap(sc, *(int *)data, HILUNIT(dev), l->l_proc);
624 break;
626 case HILIOCHPUX:
627 dptr = &sc->sc_device[HILUNIT(dev)];
628 dptr->hd_flags |= HIL_READIN;
629 dptr->hd_flags &= ~HIL_QUEUEIN;
630 break;
632 case HILIOCRESET:
633 hilreset(sc);
634 break;
636 #ifdef DEBUG
637 case HILIOCTEST:
638 hildebug = *(int *)data;
639 break;
640 #endif
642 default:
643 error = EINVAL;
644 break;
647 sc->sc_cmddev = 0;
648 return error;
651 /*ARGSUSED*/
652 static int
653 hilpoll(dev_t dev, int events, struct lwp *l)
655 struct hil_softc *sc;
656 struct hilloopdev *dptr;
657 struct hiliqueue *qp;
658 int mask;
659 int s, revents;
661 sc = device_lookup_private(&hil_cd, HILLOOP(dev));
663 revents = events & (POLLOUT | POLLWRNORM);
665 /* Attempt to save some work. */
666 if ((events & (POLLIN | POLLRDNORM)) == 0)
667 return revents;
670 * Read interface.
671 * Return 1 if there is something in the queue, 0 ow.
673 dptr = &sc->sc_device[HILUNIT(dev)];
674 if (dptr->hd_flags & HIL_READIN) {
675 s = splhil();
676 if (dptr->hd_queue.c_cc > 0)
677 revents |= events & (POLLIN | POLLRDNORM);
678 else
679 selrecord(l, &dptr->hd_selr);
680 splx(s);
681 return revents;
685 * Make sure device is alive and real (or the loop device).
686 * Note that we do not do this for the read interface.
687 * This is primarily to be consistant with HP-UX.
689 if (HILUNIT(dev) &&
690 (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE)
691 return revents | (events & (POLLIN | POLLRDNORM));
694 * Select on loop device is special.
695 * Check to see if there are any data for any loop device
696 * provided it is associated with a queue belonging to this user.
698 if (HILUNIT(dev) == 0)
699 mask = -1;
700 else
701 mask = hildevmask(HILUNIT(dev));
703 * Must check everybody with interrupts blocked to prevent races.
705 s = splhil();
706 for (qp = sc->sc_queue; qp < &sc->sc_queue[NHILQ]; qp++)
707 if (qp->hq_procp == l->l_proc && (mask & qp->hq_devmask) &&
708 qp->hq_eventqueue->hil_evqueue.head !=
709 qp->hq_eventqueue->hil_evqueue.tail) {
710 splx(s);
711 return revents | (events & (POLLIN | POLLRDNORM));
714 selrecord(l, &dptr->hd_selr);
715 splx(s);
716 return revents;
719 static void
720 filt_hilrdetach(struct knote *kn)
722 dev_t dev = (intptr_t) kn->kn_hook;
723 struct hil_softc *sc = device_lookup_private(&hil_cd,HILLOOP(dev));
724 struct hilloopdev *dptr = &sc->sc_device[HILUNIT(dev)];
725 int s;
727 s = splhil();
728 SLIST_REMOVE(&dptr->hd_selr.sel_klist, kn, knote, kn_selnext);
729 splx(s);
732 static int
733 filt_hilread(struct knote *kn, long hint)
735 dev_t dev = (intptr_t) kn->kn_hook;
736 int device = HILUNIT(dev);
737 struct hil_softc *sc = device_lookup_private(&hil_cd,HILLOOP(dev));
738 struct hilloopdev *dptr = &sc->sc_device[device];
739 struct hiliqueue *qp;
740 int mask;
742 if (dptr->hd_flags & HIL_READIN) {
743 kn->kn_data = dptr->hd_queue.c_cc;
744 return kn->kn_data > 0;
748 * Make sure device is alive and real (or the loop device).
749 * Note that we do not do this for the read interface.
750 * This is primarily to be consistant with HP-UX.
752 if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE) {
753 kn->kn_data = 0; /* XXXLUKEM (thorpej): what to put here? */
754 return 1;
758 * Select on loop device is special.
759 * Check to see if there are any data for any loop device
760 * provided it is associated with a queue belonging to this user.
762 if (device == 0)
763 mask = -1;
764 else
765 mask = hildevmask(device);
767 * Must check everybody with interrupts blocked to prevent races.
768 * (Interrupts are already blocked.)
770 for (qp = sc->sc_queue; qp < &sc->sc_queue[NHILQ]; qp++) {
771 /* XXXLUKEM (thorpej): PROCESS CHECK! */
772 if (/*qp->hq_procp == l->l_proc &&*/ (mask & qp->hq_devmask) &&
773 qp->hq_eventqueue->hil_evqueue.head !=
774 qp->hq_eventqueue->hil_evqueue.tail) {
775 /* XXXLUKEM (thorpej): what to put here? */
776 kn->kn_data = 0;
777 return 1;
781 return 0;
784 static const struct filterops hilread_filtops =
785 { 1, NULL, filt_hilrdetach, filt_hilread };
787 static const struct filterops hil_seltrue_filtops =
788 { 1, NULL, filt_hilrdetach, filt_seltrue };
790 static int
791 hilkqfilter(dev_t dev, struct knote *kn)
793 struct hil_softc *sc = device_lookup_private(&hil_cd,HILLOOP(dev));
794 struct hilloopdev *dptr = &sc->sc_device[HILUNIT(dev)];
795 struct klist *klist;
796 int s;
798 switch (kn->kn_filter) {
799 case EVFILT_READ:
800 klist = &dptr->hd_selr.sel_klist;
801 kn->kn_fop = &hilread_filtops;
802 break;
804 case EVFILT_WRITE:
805 klist = &dptr->hd_selr.sel_klist;
806 kn->kn_fop = &hil_seltrue_filtops;
807 break;
809 default:
810 return 1;
813 kn->kn_hook = (void *)(intptr_t) dev; /* XXX yuck */
815 s = splhil();
816 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
817 splx(s);
819 return 0;
822 /*ARGSUSED*/
823 static int
824 hilint(void *v)
826 struct hil_softc *sc = v;
827 struct hil_dev *hildevice = sc->sc_addr;
828 uint8_t c, stat;
830 stat = READHILSTAT(hildevice);
831 c = READHILDATA(hildevice); /* clears interrupt */
832 hil_process_int(sc, stat, c);
833 #if NRND > 0
834 rnd_add_uint32(&sc->rnd_source, (stat<<8)|c);
835 #endif
836 return 1;
839 static void
840 hil_process_int(struct hil_softc *sc, uint8_t stat, uint8_t c)
842 #ifdef DEBUG
843 if (hildebug & HDB_EVENTS)
844 printf("hilint: %x %x\n", stat, c);
845 #endif
847 /* the shift enables the compiler to generate a jump table */
848 switch ((stat>>HIL_SSHIFT) & HIL_SMASK) {
850 #if NITE > 0
851 case HIL_KEY:
852 case HIL_SHIFT:
853 case HIL_CTRL:
854 case HIL_CTRLSHIFT:
855 itefilter(stat, c);
856 return;
857 #endif
859 case HIL_STATUS: /* The status info. */
860 if (c & HIL_ERROR) {
861 sc->sc_cmddone = true;
862 if (c == HIL_RECONFIG)
863 hilconfig(sc);
864 break;
866 if (c & HIL_COMMAND) {
867 if (c & HIL_POLLDATA) /* End of data */
868 hilevent(sc);
869 else /* End of command */
870 sc->sc_cmdending = true;
871 sc->sc_actdev = 0;
872 } else {
873 if (c & HIL_POLLDATA) { /* Start of polled data */
874 if (sc->sc_actdev != 0)
875 hilevent(sc);
876 sc->sc_actdev = (c & HIL_DEVMASK);
877 sc->sc_pollbp = sc->sc_pollbuf;
878 } else { /* Start of command */
879 if (sc->sc_cmddev == (c & HIL_DEVMASK)) {
880 sc->sc_cmdbp = sc->sc_cmdbuf;
881 sc->sc_actdev = 0;
885 return;
887 case HIL_DATA:
888 if (sc->sc_actdev != 0) /* Collecting poll data */
889 *sc->sc_pollbp++ = c;
890 else {
891 if (sc->sc_cmddev != 0) { /* Collecting cmd data */
892 if (sc->sc_cmdending) {
893 sc->sc_cmddone = true;
894 sc->sc_cmdending = false;
895 } else
896 *sc->sc_cmdbp++ = c;
899 return;
901 case 0: /* force full jump table */
902 default:
903 return;
909 * Optimized macro to compute:
910 * eq->head == (eq->tail + 1) % eq->size
911 * i.e. has tail caught up with head. We do this because 32 bit long
912 * remaidering is expensive (a function call with our compiler).
914 #define HQFULL(eq) (((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1)
915 #define HQVALID(eq) \
916 ((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE)
918 static void
919 hilevent(struct hil_softc *sc)
921 struct hilloopdev *dptr = &sc->sc_device[sc->sc_actdev];
922 int len, mask, qnum;
923 uint8_t *cp, *pp;
924 HILQ *hq;
925 struct timeval ourtime;
926 hil_packet *proto;
927 int len0;
928 long tenths;
930 #ifdef DEBUG
931 if (hildebug & HDB_EVENTS) {
932 printf("hilevent: dev %d pollbuf: ", sc->sc_actdev);
933 printhilpollbuf(sc);
934 printf("\n");
936 #endif
939 * Note that HIL_READIN effectively "shuts off" any queues
940 * that may have been in use at the time of an HILIOCHPUX call.
942 if (dptr->hd_flags & HIL_READIN) {
943 hpuxhilevent(sc, dptr);
944 return;
948 * If this device isn't on any queue or there are no data
949 * in the packet (can this happen?) do nothing.
951 if (dptr->hd_qmask == 0 ||
952 (len0 = sc->sc_pollbp - sc->sc_pollbuf) <= 0)
953 return;
956 * Everybody gets the same time stamp
958 microtime(&ourtime);
959 tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);
961 proto = NULL;
962 mask = dptr->hd_qmask;
963 for (qnum = 0; mask; qnum++) {
964 if ((mask & hilqmask(qnum)) == 0)
965 continue;
966 mask &= ~hilqmask(qnum);
967 hq = sc->sc_queue[qnum].hq_eventqueue;
970 * Ensure that queue fields that we rely on are valid
971 * and that there is space in the queue. If either
972 * test fails, we just skip this queue.
974 if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue))
975 continue;
978 * Copy data to queue.
979 * If this is the first queue we construct the packet
980 * with length, timestamp and poll buffer data.
981 * For second and successive packets we just duplicate
982 * the first packet.
984 pp = (uint8_t *)&hq->hil_event[hq->hil_evqueue.tail];
985 if (proto == NULL) {
986 proto = (hil_packet *)pp;
987 cp = sc->sc_pollbuf;
988 len = len0;
989 *pp++ = len + 6;
990 *pp++ = sc->sc_actdev;
991 *(long *)pp = tenths;
992 pp += sizeof(long);
993 do *pp++ = *cp++; while (--len);
994 } else
995 *(hil_packet *)pp = *proto;
997 if (++hq->hil_evqueue.tail == hq->hil_evqueue.size)
998 hq->hil_evqueue.tail = 0;
1002 * Wake up anyone selecting on this device or the loop itself
1004 selnotify(&dptr->hd_selr, 0, 0);
1005 dptr = &sc->sc_device[HILLOOPDEV];
1006 selnotify(&dptr->hd_selr, 0, 0);
1009 #undef HQFULL
1011 static void
1012 hpuxhilevent(struct hil_softc *sc, struct hilloopdev *dptr)
1014 int len;
1015 struct timeval ourtime;
1016 long tstamp;
1019 * Everybody gets the same time stamp
1021 microtime(&ourtime);
1022 tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);
1025 * Each packet that goes into the buffer must be preceded by the
1026 * number of bytes in the packet, and the timestamp of the packet.
1027 * This adds 5 bytes to the packet size. Make sure there is enough
1028 * room in the buffer for it, and if not, toss the packet.
1030 len = sc->sc_pollbp - sc->sc_pollbuf;
1031 if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len + 5))) {
1032 putc(len+5, &dptr->hd_queue);
1033 (void)b_to_q((uint8_t *)&tstamp, sizeof tstamp,
1034 &dptr->hd_queue);
1035 (void)b_to_q((uint8_t *)sc->sc_pollbuf, len, &dptr->hd_queue);
1039 * Wake up any one blocked on a read or select
1041 if (dptr->hd_flags & HIL_ASLEEP) {
1042 dptr->hd_flags &= ~HIL_ASLEEP;
1043 wakeup((void *)dptr);
1045 selnotify(&dptr->hd_selr, 0, 0);
1049 * Shared queue manipulation routines
1052 static int
1053 hilqalloc(struct hil_softc *sc, struct hilqinfo *qip, struct proc *p)
1056 #ifdef DEBUG
1057 if (hildebug & HDB_FOLLOW)
1058 printf("hilqalloc(%d): addr %p\n", p->p_pid, qip->addr);
1059 #endif
1060 return EINVAL;
1063 static int
1064 hilqfree(struct hil_softc *sc, int qnum, struct proc *p)
1067 #ifdef DEBUG
1068 if (hildebug & HDB_FOLLOW)
1069 printf("hilqfree(%d): qnum %d\n", p->p_pid, qnum);
1070 #endif
1071 return EINVAL;
1074 static int
1075 hilqmap(struct hil_softc *sc, int qnum, int device, struct lwp *l)
1077 struct hilloopdev *dptr = &sc->sc_device[device];
1078 int s;
1080 #ifdef DEBUG
1081 if (hildebug & HDB_FOLLOW)
1082 printf("hilqmap(%d): qnum %d device %x\n",
1083 l->l_proc->p_pid, qnum, device);
1084 #endif
1085 if (qnum >= NHILQ || sc->sc_queue[qnum].hq_procp != l->l_proc)
1086 return EINVAL;
1087 if ((dptr->hd_flags & HIL_QUEUEIN) == 0)
1088 return EINVAL;
1089 if (dptr->hd_qmask && kauth_cred_geteuid(l->l_cred) &&
1090 kauth_cred_geteuid(l->l_cred) != dptr->hd_uid)
1091 return EPERM;
1093 sc->sc_queue[qnum].hq_devmask |= hildevmask(device);
1094 if (dptr->hd_qmask == 0)
1095 dptr->hd_uid = kauth_cred_geteuid(l->l_cred);
1096 s = splhil();
1097 dptr->hd_qmask |= hilqmask(qnum);
1098 splx(s);
1099 #ifdef DEBUG
1100 if (hildebug & HDB_MASK)
1101 printf("hilqmap(%d): devmask %x qmask %x\n",
1102 l->l_proc->p_pid, sc->sc_queue[qnum].hq_devmask,
1103 dptr->hd_qmask);
1104 #endif
1105 return 0;
1108 static int
1109 hilqunmap(struct hil_softc *sc, int qnum, int device, struct proc *p)
1111 int s;
1113 #ifdef DEBUG
1114 if (hildebug & HDB_FOLLOW)
1115 printf("hilqunmap(%d): qnum %d device %x\n",
1116 p->p_pid, qnum, device);
1117 #endif
1119 if (qnum >= NHILQ || sc->sc_queue[qnum].hq_procp != p)
1120 return EINVAL;
1122 sc->sc_queue[qnum].hq_devmask &= ~hildevmask(device);
1123 s = splhil();
1124 sc->sc_device[device].hd_qmask &= ~hilqmask(qnum);
1125 splx(s);
1126 #ifdef DEBUG
1127 if (hildebug & HDB_MASK)
1128 printf("hilqunmap(%d): devmask %x qmask %x\n",
1129 p->p_pid, sc->sc_queue[qnum].hq_devmask,
1130 sc->sc_device[device].hd_qmask);
1131 #endif
1132 return 0;
1136 * Cooked keyboard functions for ite driver.
1137 * There is only one "cooked" ITE keyboard (the first keyboard found)
1138 * per loop. There may be other keyboards, but they will always be "raw".
1141 void
1142 hilkbdbell(void *v)
1144 hilbeep(v, &default_bell);
1147 void
1148 hilkbdenable(void *v)
1150 struct hil_softc *sc = v;
1151 struct hil_dev *hildevice = HILADDR;
1152 char db;
1154 if (sc != NULL)
1155 hildevice = sc->sc_addr;
1157 /* Set the autorepeat rate */
1158 db = ar_format(KBD_ARR);
1159 send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL);
1161 /* Set the autorepeat delay */
1162 db = ar_format(KBD_ARD);
1163 send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL);
1165 /* Enable interrupts */
1166 send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
1169 void
1170 hilkbddisable(void *v)
1174 #if NITE > 0
1176 * The following chunk of code implements HIL console keyboard
1177 * support.
1180 static struct hil_dev *hilkbd_cn_device;
1181 static struct ite_kbdmap hilkbd_cn_map;
1182 static struct ite_kbdops hilkbd_cn_ops = {
1183 hilkbdcngetc,
1184 hilkbdenable,
1185 hilkbdbell,
1186 NULL,
1189 extern char us_keymap[], us_shiftmap[], us_ctrlmap[];
1192 * XXX: read keyboard directly and return code.
1193 * Used by console getchar routine. Could really screw up anybody
1194 * reading from the keyboard in the normal, interrupt driven fashion.
1197 hilkbdcngetc(int *statp)
1199 int c, stat;
1200 int s;
1202 if (hilkbd_cn_device == NULL)
1203 return 0;
1206 * XXX needs to be splraise because we could be called
1207 * XXX at splhigh, e.g. in DDB.
1209 s = splhil();
1210 while (((stat = READHILSTAT(hilkbd_cn_device)) & HIL_DATA_RDY) == 0)
1212 c = READHILDATA(hilkbd_cn_device);
1213 splx(s);
1214 *statp = stat;
1215 return c;
1219 * Perform basic initialization of the HIL keyboard, suitable
1220 * for early console use.
1223 hilkbdcnattach(bus_space_tag_t bst, bus_addr_t addr)
1225 void *va;
1226 struct kbdmap *km;
1227 bus_space_handle_t bsh;
1228 u_char lang;
1230 if (bus_space_map(bst, addr, PAGE_SIZE, 0, &bsh))
1231 return 1;
1233 va = bus_space_vaddr(bst, bsh);
1234 hilkbd_cn_device = (struct hil_dev *)va;
1236 /* Default to US-ASCII keyboard. */
1237 hilkbd_cn_map.keymap = us_keymap;
1238 hilkbd_cn_map.shiftmap = us_shiftmap;
1239 hilkbd_cn_map.ctrlmap = us_ctrlmap;
1241 HILWAIT(hilkbd_cn_device);
1242 WRITEHILCMD(hilkbd_cn_device, HIL_SETARR);
1243 HILWAIT(hilkbd_cn_device);
1244 WRITEHILDATA(hilkbd_cn_device, ar_format(KBD_ARR));
1245 HILWAIT(hilkbd_cn_device);
1246 WRITEHILCMD(hilkbd_cn_device, HIL_READKBDLANG);
1247 HILDATAWAIT(hilkbd_cn_device);
1248 lang = READHILDATA(hilkbd_cn_device);
1249 for (km = kbd_map; km->kbd_code; km++) {
1250 if (km->kbd_code == lang) {
1251 hilkbd_cn_map.keymap = km->kbd_keymap;
1252 hilkbd_cn_map.shiftmap = km->kbd_shiftmap;
1253 hilkbd_cn_map.ctrlmap = km->kbd_ctrlmap;
1256 HILWAIT(hilkbd_cn_device);
1257 WRITEHILCMD(hilkbd_cn_device, HIL_INTON);
1259 hilkbd_cn_ops.arg = NULL;
1260 itekbdcnattach(&hilkbd_cn_ops, &hilkbd_cn_map);
1262 return 0;
1265 #endif /* End of HIL console keyboard code. */
1268 * Recognize and clear keyboard generated NMIs.
1269 * Returns 1 if it was ours, 0 otherwise. Note that we cannot use
1270 * send_hil_cmd() to issue the clear NMI command as that would actually
1271 * lower the priority to splvm() and it doesn't wait for the completion
1272 * of the command. Either of these conditions could result in the
1273 * interrupt reoccuring. Note that we issue the CNMT command twice.
1274 * This seems to be needed, once is not always enough!?!
1277 kbdnmi(void)
1279 struct hil_dev *hl_addr = HILADDR;
1281 if ((*KBDNMISTAT & KBDNMI) == 0)
1282 return 0;
1284 HILWAIT(hl_addr);
1285 WRITEHILCMD(hl_addr, HIL_CNMT);
1286 HILWAIT(hl_addr);
1287 WRITEHILCMD(hl_addr, HIL_CNMT);
1288 HILWAIT(hl_addr);
1289 return 1;
1292 #define HILSECURITY 0x33
1293 #define HILIDENTIFY 0x03
1294 #define HILSCBIT 0x04
1297 * Called at boot time to print out info about interesting devices
1299 void
1300 hilinfo(struct hil_softc *sc)
1302 int id, len;
1303 struct kbdmap *km;
1306 * Keyboard info.
1308 if (sc->sc_kbddev) {
1309 aprint_normal("%s device %d: ", device_xname(sc->sc_dev),
1310 sc->sc_kbddev);
1311 for (km = kbd_map; km->kbd_code; km++)
1312 if (km->kbd_code == sc->sc_kbdlang) {
1313 aprint_normal("%s ", km->kbd_desc);
1314 break;
1316 aprint_normal("keyboard\n");
1319 * ID module.
1320 * Attempt to locate the first ID module and print out its
1321 * security code. Is this a good idea??
1323 id = hiliddev(sc);
1324 if (id) {
1325 sc->sc_cmdbp = sc->sc_cmdbuf;
1326 sc->sc_cmddev = id;
1327 send_hildev_cmd(sc, id, HILSECURITY);
1328 len = sc->sc_cmdbp - sc->sc_cmdbuf;
1329 sc->sc_cmdbp = sc->sc_cmdbuf;
1330 sc->sc_cmddev = 0;
1331 aprint_normal_dev(sc->sc_dev, "security code");
1332 for (id = 0; id < len; id++)
1333 aprint_normal(" %x", sc->sc_cmdbuf[id]);
1334 while (id++ < 16)
1335 aprint_normal(" 0");
1336 aprint_normal("\n");
1338 #if NRND > 0
1340 * attach the device into the random source list
1341 * except from ID module (no point)
1343 if (!id) {
1344 char buf[10];
1345 sprintf(buf, "%s", device_xname(sc->sc_dev));
1346 rnd_attach_source(&sc->rnd_source, buf, RND_TYPE_TTY, 0);
1348 #endif
1351 #define HILAR1 0x3E
1352 #define HILAR2 0x3F
1355 * Called after the loop has reconfigured. Here we need to:
1356 * - determine how many devices are on the loop
1357 * (some may have been added or removed)
1358 * - locate the ITE keyboard (if any) and ensure
1359 * that it is in the proper state (raw or cooked)
1360 * and is set to use the proper language mapping table
1361 * - ensure all other keyboards are raw
1362 * Note that our device state is now potentially invalid as
1363 * devices may no longer be where they were. What we should
1364 * do here is either track where the devices went and move
1365 * state around accordingly or, more simply, just mark all
1366 * devices as HIL_DERROR and don't allow any further use until
1367 * they are closed. This is a little too brutal for my tastes,
1368 * we prefer to just assume people won't move things around.
1370 void
1371 hilconfig(struct hil_softc *sc)
1373 u_char db;
1374 int s;
1376 s = splhil();
1377 #ifdef DEBUG
1378 if (hildebug & HDB_CONFIG) {
1379 printf("hilconfig: reconfigured: ");
1380 send_hil_cmd(sc->sc_addr, HIL_READLPSTAT, NULL, 0, &db);
1381 printf("LPSTAT %x, ", db);
1382 send_hil_cmd(sc->sc_addr, HIL_READLPCTRL, NULL, 0, &db);
1383 printf("LPCTRL %x, ", db);
1384 send_hil_cmd(sc->sc_addr, HIL_READKBDSADR, NULL, 0, &db);
1385 printf("KBDSADR %x\n", db);
1386 hilreport(sc);
1388 #endif
1390 * Determine how many devices are on the loop.
1391 * Mark those as alive and real, all others as dead.
1393 db = 0;
1394 send_hil_cmd(sc->sc_addr, HIL_READLPSTAT, NULL, 0, &db);
1395 sc->sc_maxdev = db & LPS_DEVMASK;
1396 #ifdef DEBUG
1397 if (hildebug & HDB_CONFIG)
1398 printf("hilconfig: %d devices found\n", sc->sc_maxdev);
1399 #endif
1400 for (db = 1; db < NHILD; db++) {
1401 if (db <= sc->sc_maxdev)
1402 sc->sc_device[db].hd_flags |= HIL_ALIVE;
1403 else
1404 sc->sc_device[db].hd_flags &= ~HIL_ALIVE;
1405 sc->sc_device[db].hd_flags &= ~HIL_PSEUDO;
1407 #ifdef DEBUG
1408 if (hildebug & (HDB_CONFIG|HDB_KEYBOARD))
1409 printf("hilconfig: max device %d\n", sc->sc_maxdev);
1410 #endif
1411 if (sc->sc_maxdev == 0) {
1412 sc->sc_kbddev = 0;
1413 splx(s);
1414 return;
1417 * Find out where the keyboards are and record the ITE keyboard
1418 * (first one found). If no keyboards found, we are all done.
1420 db = 0;
1421 send_hil_cmd(sc->sc_addr, HIL_READKBDSADR, NULL, 0, &db);
1422 #ifdef DEBUG
1423 if (hildebug & HDB_KEYBOARD)
1424 printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n",
1425 db, sc->sc_kbddev, ffs((int)db));
1426 #endif
1427 sc->sc_kbddev = ffs((int)db);
1428 if (sc->sc_kbddev == 0) {
1429 splx(s);
1430 return;
1433 * Determine if the keyboard should be cooked or raw and configure it.
1435 db = (sc->sc_kbdflags & KBD_RAW) ? 0 : 1 << (sc->sc_kbddev - 1);
1436 send_hil_cmd(sc->sc_addr, HIL_WRITEKBDSADR, &db, 1, NULL);
1438 * Re-enable autorepeat in raw mode, cooked mode AR is not affected.
1440 if (sc->sc_kbdflags & (KBD_AR1|KBD_AR2)) {
1441 db = (sc->sc_kbdflags & KBD_AR1) ? HILAR1 : HILAR2;
1442 sc->sc_cmddev = sc->sc_kbddev;
1443 send_hildev_cmd(sc, sc->sc_kbddev, db);
1444 sc->sc_cmddev = 0;
1447 * Determine the keyboard language configuration, but don't
1448 * override a user-specified setting.
1450 db = 0;
1451 send_hil_cmd(sc->sc_addr, HIL_READKBDLANG, NULL, 0, &db);
1452 #ifdef DEBUG
1453 if (hildebug & HDB_KEYBOARD)
1454 printf("hilconfig: language: old %x new %x\n",
1455 sc->sc_kbdlang, db);
1456 #endif
1457 if (sc->sc_kbdlang != KBD_SPECIAL) {
1458 struct kbdmap *km;
1460 #if NITE > 0
1461 for (km = kbd_map; km->kbd_code; km++) {
1462 if (km->kbd_code == db) {
1463 sc->sc_kbdlang = db;
1464 iteinstallkeymap(km);
1465 break;
1468 #endif
1469 if (km->kbd_code == 0) {
1470 printf("hilconfig: unknown keyboard type 0x%x, "
1471 "using default\n", db);
1474 splx(s);
1477 void
1478 hilreset(struct hil_softc *sc)
1480 struct hil_dev *hildevice = sc->sc_addr;
1481 u_char db;
1483 #ifdef DEBUG
1484 if (hildebug & HDB_FOLLOW)
1485 printf("hilreset(%p)\n", sc);
1486 #endif
1488 * Initialize the loop: reconfigure, don't report errors,
1489 * cook keyboards, and enable autopolling.
1491 db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL;
1492 send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL);
1494 * Delay one second for reconfiguration and then read the
1495 * data to clear the interrupt (if the loop reconfigured).
1497 DELAY(1000000);
1498 if (READHILSTAT(hildevice) & HIL_DATA_RDY)
1499 db = READHILDATA(hildevice);
1501 * The HIL loop may have reconfigured. If so we proceed on,
1502 * if not we loop until a successful reconfiguration is reported
1503 * back to us. The HIL loop will continue to attempt forever.
1504 * Probably not very smart.
1506 do {
1507 send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db);
1508 } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0);
1510 * At this point, the loop should have reconfigured.
1511 * The reconfiguration interrupt has already called hilconfig()
1512 * so the keyboard has been determined.
1514 send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
1517 void
1518 hilbeep(struct hil_softc *sc, const struct _hilbell *bp)
1520 struct hil_dev *hl_addr = HILADDR;
1521 u_char buf[2];
1523 if (sc != NULL)
1524 hl_addr = sc->sc_addr;
1526 buf[0] = ~((bp->duration - 10) / 10);
1527 buf[1] = bp->frequency;
1528 send_hil_cmd(hl_addr, HIL_SETTONE, buf, 2, NULL);
1532 * Locate and return the address of the first ID module, 0 if none present.
1535 hiliddev(struct hil_softc *sc)
1537 int i, len;
1539 #ifdef DEBUG
1540 if (hildebug & HDB_IDMODULE)
1541 printf("hiliddev(%p): max %d, looking for idmodule...",
1542 sc, sc->sc_maxdev);
1543 #endif
1544 for (i = 1; i <= sc->sc_maxdev; i++) {
1545 sc->sc_cmdbp = sc->sc_cmdbuf;
1546 sc->sc_cmddev = i;
1547 send_hildev_cmd(sc, i, HILIDENTIFY);
1549 * XXX: the final condition checks to ensure that the
1550 * device ID byte is in the range of the ID module (0x30-0x3F)
1552 len = sc->sc_cmdbp - sc->sc_cmdbuf;
1553 if (len > 1 && (sc->sc_cmdbuf[1] & HILSCBIT) &&
1554 (sc->sc_cmdbuf[0] & 0xF0) == 0x30) {
1555 sc->sc_cmdbp = sc->sc_cmdbuf;
1556 sc->sc_cmddev = i;
1557 send_hildev_cmd(sc, i, HILSECURITY);
1558 break;
1561 sc->sc_cmdbp = sc->sc_cmdbuf;
1562 sc->sc_cmddev = 0;
1563 #ifdef DEBUG
1564 if (hildebug & HDB_IDMODULE) {
1565 if (i <= sc->sc_maxdev)
1566 printf("found at %d\n", i);
1567 else
1568 printf("not found\n");
1570 #endif
1571 return i <= sc->sc_maxdev ? i : 0;
1575 * Low level routines which actually talk to the 8042 chip.
1579 * Send a command to the 8042 with zero or more bytes of data.
1580 * If rdata is non-null, wait for and return a byte of data.
1581 * We run at splvm() to make the transaction as atomic as
1582 * possible without blocking the clock (is this necessary?)
1584 void
1585 send_hil_cmd(struct hil_dev *hildevice, u_char cmd, u_char *data, u_char dlen,
1586 u_char *rdata)
1588 u_char status;
1589 int s = splvm();
1591 HILWAIT(hildevice);
1592 WRITEHILCMD(hildevice, cmd);
1593 while (dlen--) {
1594 HILWAIT(hildevice);
1595 WRITEHILDATA(hildevice, *data++);
1597 if (rdata) {
1598 do {
1599 HILDATAWAIT(hildevice);
1600 status = READHILSTAT(hildevice);
1601 *rdata = READHILDATA(hildevice);
1602 } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K);
1604 splx(s);
1608 * Send a command to a device on the loop.
1609 * Since only one command can be active on the loop at any time,
1610 * we must ensure that we are not interrupted during this process.
1611 * Hence we mask interrupts to prevent potential access from most
1612 * interrupt routines and turn off auto-polling to disable the
1613 * internally generated poll commands.
1615 * splhigh is extremely conservative but insures atomic operation,
1616 * splvm (clock only interrupts) seems to be good enough in practice.
1618 void
1619 send_hildev_cmd(struct hil_softc *sc, char device, char cmd)
1621 struct hil_dev *hildevice = sc->sc_addr;
1622 uint8_t status, c;
1623 int s = splvm();
1625 polloff(hildevice);
1628 * Transfer the command and device info to the chip
1630 HILWAIT(hildevice);
1631 WRITEHILCMD(hildevice, HIL_STARTCMD);
1632 HILWAIT(hildevice);
1633 WRITEHILDATA(hildevice, 8 + device);
1634 HILWAIT(hildevice);
1635 WRITEHILDATA(hildevice, cmd);
1636 HILWAIT(hildevice);
1637 WRITEHILDATA(hildevice, HIL_TIMEOUT);
1639 * Trigger the command and wait for completion
1641 HILWAIT(hildevice);
1642 WRITEHILCMD(hildevice, HIL_TRIGGER);
1643 sc->sc_cmddone = false;
1644 do {
1645 HILDATAWAIT(hildevice);
1646 status = READHILSTAT(hildevice);
1647 c = READHILDATA(hildevice);
1648 hil_process_int(sc, status, c);
1649 } while (!sc->sc_cmddone);
1651 pollon(hildevice);
1652 splx(s);
1656 * Turn auto-polling off and on.
1657 * Also disables and enable auto-repeat. Why?
1659 void
1660 polloff(struct hil_dev *hildevice)
1662 char db;
1665 * Turn off auto repeat
1667 HILWAIT(hildevice);
1668 WRITEHILCMD(hildevice, HIL_SETARR);
1669 HILWAIT(hildevice);
1670 WRITEHILDATA(hildevice, 0);
1672 * Turn off auto-polling
1674 HILWAIT(hildevice);
1675 WRITEHILCMD(hildevice, HIL_READLPCTRL);
1676 HILDATAWAIT(hildevice);
1677 db = READHILDATA(hildevice);
1678 db &= ~LPC_AUTOPOLL;
1679 HILWAIT(hildevice);
1680 WRITEHILCMD(hildevice, HIL_WRITELPCTRL);
1681 HILWAIT(hildevice);
1682 WRITEHILDATA(hildevice, db);
1684 * Must wait til polling is really stopped
1686 do {
1687 HILWAIT(hildevice);
1688 WRITEHILCMD(hildevice, HIL_READBUSY);
1689 HILDATAWAIT(hildevice);
1690 db = READHILDATA(hildevice);
1691 } while (db & BSY_LOOPBUSY);
1694 void
1695 pollon(struct hil_dev *hildevice)
1697 char db;
1700 * Turn on auto polling
1702 HILWAIT(hildevice);
1703 WRITEHILCMD(hildevice, HIL_READLPCTRL);
1704 HILDATAWAIT(hildevice);
1705 db = READHILDATA(hildevice);
1706 db |= LPC_AUTOPOLL;
1707 HILWAIT(hildevice);
1708 WRITEHILCMD(hildevice, HIL_WRITELPCTRL);
1709 HILWAIT(hildevice);
1710 WRITEHILDATA(hildevice, db);
1712 * Turn on auto repeat
1714 HILWAIT(hildevice);
1715 WRITEHILCMD(hildevice, HIL_SETARR);
1716 HILWAIT(hildevice);
1717 WRITEHILDATA(hildevice, ar_format(KBD_ARR));
1720 #ifdef DEBUG
1721 static void
1722 printhilpollbuf(struct hil_softc *sc)
1724 u_char *cp;
1725 int i, len;
1727 cp = sc->sc_pollbuf;
1728 len = sc->sc_pollbp - cp;
1729 for (i = 0; i < len; i++)
1730 printf("%x ", sc->sc_pollbuf[i]);
1731 printf("\n");
1734 static void
1735 printhilcmdbuf(struct hil_softc *sc)
1737 u_char *cp;
1738 int i, len;
1740 cp = sc->sc_cmdbuf;
1741 len = sc->sc_cmdbp - cp;
1742 for (i = 0; i < len; i++)
1743 printf("%x ", sc->sc_cmdbuf[i]);
1744 printf("\n");
1747 static void
1748 hilreport(struct hil_softc *sc)
1750 int i, len;
1751 int s = splhil();
1753 for (i = 1; i <= sc->sc_maxdev; i++) {
1754 sc->sc_cmdbp = sc->sc_cmdbuf;
1755 sc->sc_cmddev = i;
1756 send_hildev_cmd(sc, i, HILIDENTIFY);
1757 printf("hil%d: id: ", i);
1758 printhilcmdbuf(sc);
1759 len = sc->sc_cmdbp - sc->sc_cmdbuf;
1760 if (len > 1 && (sc->sc_cmdbuf[1] & HILSCBIT)) {
1761 sc->sc_cmdbp = sc->sc_cmdbuf;
1762 sc->sc_cmddev = i;
1763 send_hildev_cmd(sc, i, HILSECURITY);
1764 printf("hil%d: sc: ", i);
1765 printhilcmdbuf(sc);
1768 sc->sc_cmdbp = sc->sc_cmdbuf;
1769 sc->sc_cmddev = 0;
1770 splx(s);
1772 #endif