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