xref: /original-bsd/sys/hp/dev/hil.c (revision a91856c6)
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.7 (Berkeley) 05/04/91
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 & FNDELAY)
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)
167 	dev_t dev;
168 {
169 	struct proc *p = curproc;		/* XXX */
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_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 		if (dptr->hd_selr &&
649 		    dptr->hd_selr->p_wchan == (caddr_t)&selwait)
650 			dptr->hd_flags |= HIL_SELCOLL;
651 		else
652 			dptr->hd_selr = p;
653 		splx(s);
654 		return (0);
655 	}
656 
657 	/*
658 	 * Make sure device is alive and real (or the loop device).
659 	 * Note that we do not do this for the read interface.
660 	 * This is primarily to be consistant with HP-UX.
661 	 */
662 	if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE)
663 		return (1);
664 
665 	/*
666 	 * Select on loop device is special.
667 	 * Check to see if there are any data for any loop device
668 	 * provided it is associated with a queue belonging to this user.
669 	 */
670 	if (device == 0)
671 		mask = -1;
672 	else
673 		mask = hildevmask(device);
674 	/*
675 	 * Must check everybody with interrupts blocked to prevent races.
676 	 */
677 	s = splhil();
678 	for (qp = hilp->hl_queue; qp < &hilp->hl_queue[NHILQ]; qp++)
679 		if (qp->hq_procp == p && (mask & qp->hq_devmask) &&
680 		    qp->hq_eventqueue->hil_evqueue.head !=
681 		    qp->hq_eventqueue->hil_evqueue.tail) {
682 			splx(s);
683 			return (1);
684 		}
685 
686 	if (dptr->hd_selr && dptr->hd_selr->p_wchan == (caddr_t)&selwait)
687 		dptr->hd_flags |= HIL_SELCOLL;
688 	else
689 		dptr->hd_selr = p;
690 	splx(s);
691 	return (0);
692 }
693 
694 hilint()
695 {
696 	struct hilloop *hilp = &hil0;		/* XXX */
697 	register struct hil_dev *hildevice = hilp->hl_addr;
698 	u_char c, stat;
699 
700 	stat = hildevice->hil_stat;
701 	c = hildevice->hil_data;		/* clears interrupt */
702 	hil_process_int(stat, c);
703 }
704 
705 #include "ite.h"
706 
707 hil_process_int(stat, c)
708 	register u_char stat, c;
709 {
710   	register struct hilloop *hilp;
711 
712 #ifdef DEBUG
713 	if (hildebug & HDB_EVENTS)
714 		printf("hilint: %x %x\n", stat, c);
715 #endif
716 
717 	/* the shift enables the compiler to generate a jump table */
718 	switch ((stat>>HIL_SSHIFT) & HIL_SMASK) {
719 
720 #if NITE > 0
721 	case HIL_KEY:
722 	case HIL_SHIFT:
723 	case HIL_CTRL:
724 	case HIL_CTRLSHIFT:
725 		itefilter(stat, c);
726 		return;
727 #endif
728 
729 	case HIL_STATUS:			/* The status info. */
730 		hilp = &hil0;			/* XXX */
731 		if (c & HIL_ERROR) {
732 		  	hilp->hl_cmddone = TRUE;
733 			if (c == HIL_RECONFIG)
734 				hilconfig(hilp);
735 			break;
736 		}
737 		if (c & HIL_COMMAND) {
738 		  	if (c & HIL_POLLDATA)	/* End of data */
739 				hilevent(hilp);
740 			else			/* End of command */
741 			  	hilp->hl_cmdending = TRUE;
742 			hilp->hl_actdev = 0;
743 		} else {
744 		  	if (c & HIL_POLLDATA) {	/* Start of polled data */
745 			  	if (hilp->hl_actdev != 0)
746 					hilevent(hilp);
747 				hilp->hl_actdev = (c & HIL_DEVMASK);
748 				hilp->hl_pollbp = hilp->hl_pollbuf;
749 			} else {		/* Start of command */
750 				if (hilp->hl_cmddev == (c & HIL_DEVMASK)) {
751 					hilp->hl_cmdbp = hilp->hl_cmdbuf;
752 					hilp->hl_actdev = 0;
753 				}
754 			}
755 		}
756 	        return;
757 
758 	case HIL_DATA:
759 		hilp = &hil0;			/* XXX */
760 		if (hilp->hl_actdev != 0)	/* Collecting poll data */
761 			*hilp->hl_pollbp++ = c;
762 		else if (hilp->hl_cmddev != 0)  /* Collecting cmd data */
763 			if (hilp->hl_cmdending) {
764 				hilp->hl_cmddone = TRUE;
765 				hilp->hl_cmdending = FALSE;
766 			} else
767 				*hilp->hl_cmdbp++ = c;
768 		return;
769 
770 	case 0:		/* force full jump table */
771 	default:
772 		return;
773 	}
774 }
775 
776 #if defined(DEBUG) && !defined(PANICBUTTON)
777 #define PANICBUTTON
778 #endif
779 
780 /*
781  * Optimized macro to compute:
782  *	eq->head == (eq->tail + 1) % eq->size
783  * i.e. has tail caught up with head.  We do this because 32 bit long
784  * remaidering is expensive (a function call with our compiler).
785  */
786 #define HQFULL(eq)	(((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1)
787 #define HQVALID(eq) \
788 	((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE)
789 
790 hilevent(hilp)
791 	struct hilloop *hilp;
792 {
793 	register struct hilloopdev *dptr = &hilp->hl_device[hilp->hl_actdev];
794 	register int len, mask, qnum;
795 	register u_char *cp, *pp;
796 	register HILQ *hq;
797 	struct timeval ourtime;
798 	hil_packet *proto;
799 	int s, len0;
800 	long tenths;
801 
802 #ifdef PANICBUTTON
803 	static int first;
804 	extern int panicbutton;
805 
806 	cp = hilp->hl_pollbuf;
807 	if (panicbutton && (*cp & HIL_KBDDATA)) {
808 		if (*++cp == 0x4E)
809 			first = 1;
810 		else if (first && *cp == 0x46 && !panicstr)
811 			panic("are we having fun yet?");
812 		else
813 			first = 0;
814 	}
815 #endif
816 #ifdef DEBUG
817 	if (hildebug & HDB_EVENTS) {
818 		printf("hilevent: dev %d pollbuf: ", hilp->hl_actdev);
819 		printhilpollbuf(hilp);
820 		printf("\n");
821 	}
822 #endif
823 
824 	/*
825 	 * Note that HIL_READIN effectively "shuts off" any queues
826 	 * that may have been in use at the time of an HILIOCHPUX call.
827 	 */
828 	if (dptr->hd_flags & HIL_READIN) {
829 		hpuxhilevent(hilp, dptr);
830 		return;
831 	}
832 
833 	/*
834 	 * If this device isn't on any queue or there are no data
835 	 * in the packet (can this happen?) do nothing.
836 	 */
837 	if (dptr->hd_qmask == 0 ||
838 	    (len0 = hilp->hl_pollbp - hilp->hl_pollbuf) <= 0)
839 		return;
840 
841 	/*
842 	 * Everybody gets the same time stamp
843 	 */
844 	s = splclock();
845 	ourtime = time;
846 	splx(s);
847 	tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);
848 
849 	proto = NULL;
850 	mask = dptr->hd_qmask;
851 	for (qnum = 0; mask; qnum++) {
852 		if ((mask & hilqmask(qnum)) == 0)
853 			continue;
854 		mask &= ~hilqmask(qnum);
855 		hq = hilp->hl_queue[qnum].hq_eventqueue;
856 
857 		/*
858 		 * Ensure that queue fields that we rely on are valid
859 		 * and that there is space in the queue.  If either
860 		 * test fails, we just skip this queue.
861 		 */
862 		if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue))
863 			continue;
864 
865 		/*
866 		 * Copy data to queue.
867 		 * If this is the first queue we construct the packet
868 		 * with length, timestamp and poll buffer data.
869 		 * For second and sucessive packets we just duplicate
870 		 * the first packet.
871 		 */
872 		pp = (u_char *) &hq->hil_event[hq->hil_evqueue.tail];
873 		if (proto == NULL) {
874 			proto = (hil_packet *)pp;
875 			cp = hilp->hl_pollbuf;
876 			len = len0;
877 			*pp++ = len + 6;
878 			*pp++ = hilp->hl_actdev;
879 			*(long *)pp = tenths;
880 			pp += sizeof(long);
881 			do *pp++ = *cp++; while (--len);
882 		} else
883 			*(hil_packet *)pp = *proto;
884 
885 		if (++hq->hil_evqueue.tail == hq->hil_evqueue.size)
886 			hq->hil_evqueue.tail = 0;
887 	}
888 
889 	/*
890 	 * Wake up anyone selecting on this device or the loop itself
891 	 */
892 	if (dptr->hd_selr) {
893 		selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL);
894 		dptr->hd_selr = NULL;
895 		dptr->hd_flags &= ~HIL_SELCOLL;
896 	}
897 	dptr = &hilp->hl_device[HILLOOPDEV];
898 	if (dptr->hd_selr) {
899 		selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL);
900 		dptr->hd_selr = NULL;
901 		dptr->hd_flags &= ~HIL_SELCOLL;
902 	}
903 }
904 
905 #undef HQFULL
906 
907 hpuxhilevent(hilp, dptr)
908 	register struct hilloop *hilp;
909 	register struct hilloopdev *dptr;
910 {
911 	register int len;
912 	struct timeval ourtime;
913 	long tstamp;
914 	int s;
915 
916 	/*
917 	 * Everybody gets the same time stamp
918 	 */
919 	s = splclock();
920 	ourtime = time;
921 	splx(s);
922 	tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000);
923 
924 	/*
925 	 * Each packet that goes into the buffer must be preceded by the
926 	 * number of bytes in the packet, and the timestamp of the packet.
927 	 * This adds 5 bytes to the packet size. Make sure there is enough
928 	 * room in the buffer for it, and if not, toss the packet.
929 	 */
930 	len = hilp->hl_pollbp - hilp->hl_pollbuf;
931 	if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len+5))) {
932 		putc(len+5, &dptr->hd_queue);
933 		(void) b_to_q((char *)&tstamp, sizeof tstamp, &dptr->hd_queue);
934 		(void) b_to_q((char *)hilp->hl_pollbuf, len, &dptr->hd_queue);
935 	}
936 
937 	/*
938 	 * Wake up any one blocked on a read or select
939 	 */
940 	if (dptr->hd_flags & HIL_ASLEEP) {
941 		dptr->hd_flags &= ~HIL_ASLEEP;
942 		wakeup((caddr_t)dptr);
943 	}
944 	if (dptr->hd_selr) {
945 		selwakeup(dptr->hd_selr, dptr->hd_flags & HIL_SELCOLL);
946 		dptr->hd_selr = NULL;
947 		dptr->hd_flags &= ~HIL_SELCOLL;
948 	}
949 }
950 
951 /*
952  * Shared queue manipulation routines
953  */
954 
955 hilqalloc(qip)
956 	struct hilqinfo *qip;
957 {
958 	struct proc *p = curproc;		/* XXX */
959 
960 #ifdef DEBUG
961 	if (hildebug & HDB_FOLLOW)
962 		printf("hilqalloc(%d): addr %x\n", p->p_pid, qip->addr);
963 #endif
964 	return(EINVAL);
965 }
966 
967 hilqfree(qnum)
968 	register int qnum;
969 {
970 	struct proc *p = curproc;		/* XXX */
971 
972 #ifdef DEBUG
973 	if (hildebug & HDB_FOLLOW)
974 		printf("hilqfree(%d): qnum %d\n", p->p_pid, qnum);
975 #endif
976 	return(EINVAL);
977 }
978 
979 hilqmap(qnum, device)
980 	register int qnum, device;
981 {
982 	struct proc *p = curproc;		/* XXX */
983 	register struct hilloop *hilp = &hil0;	/* XXX */
984 	register struct hilloopdev *dptr = &hilp->hl_device[device];
985 	int s;
986 
987 #ifdef DEBUG
988 	if (hildebug & HDB_FOLLOW)
989 		printf("hilqmap(%d): qnum %d device %x\n",
990 		       p->p_pid, qnum, device);
991 #endif
992 	if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
993 		return(EINVAL);
994 	if ((dptr->hd_flags & HIL_QUEUEIN) == 0)
995 		return(EINVAL);
996 	if (dptr->hd_qmask && p->p_ucred->cr_uid &&
997 	    p->p_ucred->cr_uid != dptr->hd_uid)
998 		return(EPERM);
999 
1000 	hilp->hl_queue[qnum].hq_devmask |= hildevmask(device);
1001 	if (dptr->hd_qmask == 0)
1002 		dptr->hd_uid = p->p_ucred->cr_uid;
1003 	s = splhil();
1004 	dptr->hd_qmask |= hilqmask(qnum);
1005 	splx(s);
1006 #ifdef DEBUG
1007 	if (hildebug & HDB_MASK)
1008 		printf("hilqmap(%d): devmask %x qmask %x\n",
1009 		       p->p_pid, hilp->hl_queue[qnum].hq_devmask,
1010 		       dptr->hd_qmask);
1011 #endif
1012 	return(0);
1013 }
1014 
1015 hilqunmap(qnum, device)
1016 	register int qnum, device;
1017 {
1018 	struct proc *p = curproc;		/* XXX */
1019 	register struct hilloop *hilp = &hil0;	/* XXX */
1020 	int s;
1021 
1022 #ifdef DEBUG
1023 	if (hildebug & HDB_FOLLOW)
1024 		printf("hilqunmap(%d): qnum %d device %x\n",
1025 		       p->p_pid, qnum, device);
1026 #endif
1027 
1028 	if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
1029 		return(EINVAL);
1030 
1031 	hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device);
1032 	s = splhil();
1033 	hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum);
1034 	splx(s);
1035 #ifdef DEBUG
1036 	if (hildebug & HDB_MASK)
1037 		printf("hilqunmap(%d): devmask %x qmask %x\n",
1038 		       p->p_pid, hilp->hl_queue[qnum].hq_devmask,
1039 		       hilp->hl_device[device].hd_qmask);
1040 #endif
1041 	return(0);
1042 }
1043 
1044 #include "sys/clist.h"
1045 
1046 /*
1047  * This is just a copy of the virgin q_to_b routine with minor
1048  * optimizations for HIL use.  It is used for two reasons:
1049  * 1. If we have PAGE mode defined, the normal q_to_b processes
1050  *    chars one at a time and breaks on newlines.
1051  * 2. We don't have to raise the priority to spltty() for most
1052  *    of the clist manipulations.
1053  */
1054 hilq_to_b(q, cp, cc)
1055 	register struct clist *q;
1056 	register char *cp;
1057 {
1058 	register struct cblock *bp;
1059 	register int nc;
1060 	char *acp;
1061 	int s;
1062 	extern char cwaiting;
1063 
1064 	if (cc <= 0)
1065 		return (0);
1066 	s = splhil();
1067 	if (q->c_cc <= 0) {
1068 		q->c_cc = 0;
1069 		q->c_cf = q->c_cl = NULL;
1070 		splx(s);
1071 		return (0);
1072 	}
1073 	acp = cp;
1074 
1075 	while (cc) {
1076 		nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND);
1077 		nc = MIN(nc, cc);
1078 		nc = MIN(nc, q->c_cc);
1079 		(void) bcopy(q->c_cf, cp, (unsigned)nc);
1080 		q->c_cf += nc;
1081 		q->c_cc -= nc;
1082 		cc -= nc;
1083 		cp += nc;
1084 		if (q->c_cc <= 0) {
1085 			bp = (struct cblock *)(q->c_cf - 1);
1086 			bp = (struct cblock *)((int)bp & ~CROUND);
1087 			q->c_cf = q->c_cl = NULL;
1088 			spltty();
1089 			bp->c_next = cfreelist;
1090 			cfreelist = bp;
1091 			cfreecount += CBSIZE;
1092 			if (cwaiting) {
1093 				wakeup(&cwaiting);
1094 				cwaiting = 0;
1095 			}
1096 			break;
1097 		}
1098 		if (((int)q->c_cf & CROUND) == 0) {
1099 			bp = (struct cblock *)(q->c_cf);
1100 			bp--;
1101 			q->c_cf = bp->c_next->c_info;
1102 			spltty();
1103 			bp->c_next = cfreelist;
1104 			cfreelist = bp;
1105 			cfreecount += CBSIZE;
1106 			if (cwaiting) {
1107 				wakeup(&cwaiting);
1108 				cwaiting = 0;
1109 			}
1110 			splhil();
1111 		}
1112 	}
1113 	splx(s);
1114 	return (cp-acp);
1115 }
1116 
1117 /*
1118  * Cooked keyboard functions for ite driver.
1119  * There is only one "cooked" ITE keyboard (the first keyboard found)
1120  * per loop.  There may be other keyboards, but they will always be "raw".
1121  */
1122 
1123 kbdbell()
1124 {
1125 	struct hilloop *hilp = &hil0;		/* XXX */
1126 
1127 	hilbeep(hilp, &default_bell);
1128 }
1129 
1130 kbdenable()
1131 {
1132 	struct hilloop *hilp = &hil0;	/* XXX */
1133 	register struct hil_dev *hildevice = hilp->hl_addr;
1134 	char db;
1135 
1136 	/* Set the autorepeat rate register */
1137 	db = ar_format(KBD_ARR);
1138 	send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL);
1139 
1140 	/* Set the autorepeat delay register */
1141 	db = ar_format(KBD_ARD);
1142 	send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL);
1143 
1144 	/* Enable interrupts */
1145 	send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
1146 }
1147 
1148 kbddisable()
1149 {
1150 }
1151 
1152 /*
1153  * XXX: read keyboard directly and return code.
1154  * Used by console getchar routine.  Could really screw up anybody
1155  * reading from the keyboard in the normal, interrupt driven fashion.
1156  */
1157 kbdgetc(statp)
1158 	int *statp;
1159 {
1160 	struct hilloop *hilp = &hil0;		/* XXX */
1161 	register struct hil_dev *hildevice = hilp->hl_addr;
1162 	register int c, stat;
1163 	int s;
1164 
1165 	s = splhil();
1166 	while (((stat = hildevice->hil_stat) & HIL_DATA_RDY) == 0)
1167 		;
1168 	c = hildevice->hil_data;
1169 	splx(s);
1170 	*statp = stat;
1171 	return(c);
1172 }
1173 
1174 /*
1175  * Recoginize and clear keyboard generated NMIs.
1176  * Returns 1 if it was ours, 0 otherwise.  Note that we cannot use
1177  * send_hil_cmd() to issue the clear NMI command as that would actually
1178  * lower the priority to splimp() and it doesn't wait for the completion
1179  * of the command.  Either of these conditions could result in the
1180  * interrupt reoccuring.  Note that we issue the CNMT command twice.
1181  * This seems to be needed, once is not always enough!?!
1182  */
1183 kbdnmi()
1184 {
1185 	register struct hilloop *hilp = &hil0;		/* XXX */
1186 
1187 	if ((*KBDNMISTAT & KBDNMI) == 0)
1188 		return(0);
1189 	HILWAIT(hilp->hl_addr);
1190 	hilp->hl_addr->hil_cmd = HIL_CNMT;
1191 	HILWAIT(hilp->hl_addr);
1192 	hilp->hl_addr->hil_cmd = HIL_CNMT;
1193 	HILWAIT(hilp->hl_addr);
1194 	return(1);
1195 }
1196 
1197 #define HILSECURITY	0x33
1198 #define HILIDENTIFY	0x03
1199 #define HILSCBIT	0x04
1200 
1201 /*
1202  * Called at boot time to print out info about interesting devices
1203  */
1204 hilinfo(hilp)
1205 	register struct hilloop *hilp;
1206 {
1207 	register int id, len;
1208 	register struct kbdmap *km;
1209 
1210 	/*
1211 	 * Keyboard info.
1212 	 */
1213 	if (hilp->hl_kbddev) {
1214 		printf("hil%d: ", hilp->hl_kbddev);
1215 		for (km = kbd_map; km->kbd_code; km++)
1216 			if (km->kbd_code == hilp->hl_kbdlang) {
1217 				printf("%s ", km->kbd_desc);
1218 				break;
1219 			}
1220 		printf("keyboard\n");
1221 	}
1222 	/*
1223 	 * ID module.
1224 	 * Attempt to locate the first ID module and print out its
1225 	 * security code.  Is this a good idea??
1226 	 */
1227 	id = hiliddev(hilp);
1228 	if (id) {
1229 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1230 		hilp->hl_cmddev = id;
1231 		send_hildev_cmd(hilp, id, HILSECURITY);
1232 		len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
1233 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1234 		hilp->hl_cmddev = 0;
1235 		printf("hil%d: security code", id);
1236 		for (id = 0; id < len; id++)
1237 			printf(" %x", hilp->hl_cmdbuf[id]);
1238 		while (id++ < 16)
1239 			printf(" 0");
1240 		printf("\n");
1241 	}
1242 }
1243 
1244 #define HILAR1	0x3E
1245 #define HILAR2	0x3F
1246 
1247 /*
1248  * Called after the loop has reconfigured.  Here we need to:
1249  *	- determine how many devices are on the loop
1250  *	  (some may have been added or removed)
1251  *	- locate the ITE keyboard (if any) and ensure
1252  *	  that it is in the proper state (raw or cooked)
1253  *	  and is set to use the proper language mapping table
1254  *	- ensure all other keyboards are raw
1255  * Note that our device state is now potentially invalid as
1256  * devices may no longer be where they were.  What we should
1257  * do here is either track where the devices went and move
1258  * state around accordingly or, more simply, just mark all
1259  * devices as HIL_DERROR and don't allow any further use until
1260  * they are closed.  This is a little too brutal for my tastes,
1261  * we prefer to just assume people won't move things around.
1262  */
1263 hilconfig(hilp)
1264 	register struct hilloop *hilp;
1265 {
1266 	u_char db;
1267 	int s;
1268 
1269 	s = splhil();
1270 #ifdef DEBUG
1271 	if (hildebug & HDB_CONFIG) {
1272 		printf("hilconfig: reconfigured: ");
1273 		send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db);
1274 		printf("LPSTAT %x, ", db);
1275 		send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &db);
1276 		printf("LPCTRL %x, ", db);
1277 		send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db);
1278 		printf("KBDSADR %x\n", db);
1279 		hilreport(hilp);
1280 	}
1281 #endif
1282 	/*
1283 	 * Determine how many devices are on the loop.
1284 	 * Mark those as alive and real, all others as dead.
1285 	 */
1286 	db = 0;
1287 	send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db);
1288 	hilp->hl_maxdev = db & LPS_DEVMASK;
1289 	for (db = 1; db < NHILD; db++) {
1290 		if (db <= hilp->hl_maxdev)
1291 			hilp->hl_device[db].hd_flags |= HIL_ALIVE;
1292 		else
1293 			hilp->hl_device[db].hd_flags &= ~HIL_ALIVE;
1294 		hilp->hl_device[db].hd_flags &= ~HIL_PSEUDO;
1295 	}
1296 #ifdef DEBUG
1297 	if (hildebug & (HDB_CONFIG|HDB_KEYBOARD))
1298 		printf("hilconfig: max device %d\n", hilp->hl_maxdev);
1299 #endif
1300 	if (hilp->hl_maxdev == 0) {
1301 		hilp->hl_kbddev = 0;
1302 		splx(s);
1303 		return;
1304 	}
1305 	/*
1306 	 * Find out where the keyboards are and record the ITE keyboard
1307 	 * (first one found).  If no keyboards found, we are all done.
1308 	 */
1309 	db = 0;
1310 	send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db);
1311 #ifdef DEBUG
1312 	if (hildebug & HDB_KEYBOARD)
1313 		printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n",
1314 		       db, hilp->hl_kbddev, ffs((int)db));
1315 #endif
1316 	hilp->hl_kbddev = ffs((int)db);
1317 	if (hilp->hl_kbddev == 0) {
1318 		splx(s);
1319 		return;
1320 	}
1321 	/*
1322 	 * Determine if the keyboard should be cooked or raw and configure it.
1323 	 */
1324 	db = (hilp->hl_kbdflags & KBD_RAW) ? 0 : 1 << (hilp->hl_kbddev - 1);
1325 	send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &db, 1, NULL);
1326 	/*
1327 	 * Re-enable autorepeat in raw mode, cooked mode AR is not affected.
1328 	 */
1329 	if (hilp->hl_kbdflags & (KBD_AR1|KBD_AR2)) {
1330 		db = (hilp->hl_kbdflags & KBD_AR1) ? HILAR1 : HILAR2;
1331 		hilp->hl_cmddev = hilp->hl_kbddev;
1332 		send_hildev_cmd(hilp, hilp->hl_kbddev, db);
1333 		hilp->hl_cmddev = 0;
1334 	}
1335 	/*
1336 	 * Determine the keyboard language configuration, but don't
1337 	 * override a user-specified setting.
1338 	 */
1339 	db = 0;
1340 	send_hil_cmd(hilp->hl_addr, HIL_READKBDLANG, NULL, 0, &db);
1341 #ifdef DEBUG
1342 	if (hildebug & HDB_KEYBOARD)
1343 		printf("hilconfig: language: old %x new %x\n",
1344 		       hilp->hl_kbdlang, db);
1345 #endif
1346 	if (hilp->hl_kbdlang != KBD_SPECIAL) {
1347 		struct kbdmap *km;
1348 
1349 		for (km = kbd_map; km->kbd_code; km++)
1350 			if (km->kbd_code == db) {
1351 				hilp->hl_kbdlang = db;
1352 				/* XXX */
1353 				kbd_keymap = km->kbd_keymap;
1354 				kbd_shiftmap = km->kbd_shiftmap;
1355 				kbd_ctrlmap = km->kbd_ctrlmap;
1356 				kbd_ctrlshiftmap = km->kbd_ctrlshiftmap;
1357 				kbd_stringmap = km->kbd_stringmap;
1358 			}
1359 	}
1360 	splx(s);
1361 }
1362 
1363 hilreset(hilp)
1364 	struct hilloop *hilp;
1365 {
1366 	register struct hil_dev *hildevice = hilp->hl_addr;
1367 	u_char db;
1368 
1369 	/*
1370 	 * Initialize the loop: reconfigure, don't report errors,
1371 	 * cook keyboards, and enable autopolling.
1372 	 */
1373 	db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL;
1374 	send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL);
1375 	/*
1376 	 * Delay one second for reconfiguration and then read the the
1377 	 * data register to clear the interrupt (if the loop reconfigured).
1378 	 */
1379 	DELAY(1000000);
1380 	if (hildevice->hil_stat & HIL_DATA_RDY)
1381 		db = hildevice->hil_data;
1382 	/*
1383 	 * The HIL loop may have reconfigured.  If so we proceed on,
1384 	 * if not we loop until a successful reconfiguration is reported
1385 	 * back to us.  The HIL loop will continue to attempt forever.
1386 	 * Probably not very smart.
1387 	 */
1388 	do {
1389 		send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db);
1390         } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0);
1391 	/*
1392 	 * At this point, the loop should have reconfigured.
1393 	 * The reconfiguration interrupt has already called hilconfig()
1394 	 * so the keyboard has been determined.
1395 	 */
1396 	send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
1397 }
1398 
1399 hilbeep(hilp, bp)
1400 	struct hilloop *hilp;
1401 	register struct _hilbell *bp;
1402 {
1403 	u_char buf[2];
1404 
1405 	buf[0] = ~((bp->duration - 10) / 10);
1406 	buf[1] = bp->frequency;
1407 	send_hil_cmd(hilp->hl_addr, HIL_SETTONE, buf, 2, NULL);
1408 }
1409 
1410 /*
1411  * Locate and return the address of the first ID module, 0 if none present.
1412  */
1413 hiliddev(hilp)
1414 	register struct hilloop *hilp;
1415 {
1416 	register int i, len;
1417 
1418 #ifdef DEBUG
1419 	if (hildebug & HDB_IDMODULE)
1420 		printf("hiliddev(%x): looking for idmodule...", hilp);
1421 #endif
1422 	for (i = 1; i <= hilp->hl_maxdev; i++) {
1423 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1424 		hilp->hl_cmddev = i;
1425 		send_hildev_cmd(hilp, i, HILIDENTIFY);
1426 		/*
1427 		 * XXX: the final condition checks to ensure that the
1428 		 * device ID byte is in the range of the ID module (0x30-0x3F)
1429 		 */
1430 		len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
1431 		if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT) &&
1432 		    (hilp->hl_cmdbuf[0] & 0xF0) == 0x30) {
1433 			hilp->hl_cmdbp = hilp->hl_cmdbuf;
1434 			hilp->hl_cmddev = i;
1435 			send_hildev_cmd(hilp, i, HILSECURITY);
1436 			break;
1437 		}
1438 	}
1439 	hilp->hl_cmdbp = hilp->hl_cmdbuf;
1440 	hilp->hl_cmddev = 0;
1441 #ifdef DEBUG
1442 	if (hildebug & HDB_IDMODULE)
1443 		if (i <= hilp->hl_maxdev)
1444 			printf("found at %d\n", i);
1445 		else
1446 			printf("not found\n");
1447 #endif
1448 	return(i <= hilp->hl_maxdev ? i : 0);
1449 }
1450 
1451 /*
1452  * Low level routines which actually talk to the 8042 chip.
1453  */
1454 
1455 /*
1456  * Send a command to the 8042 with zero or more bytes of data.
1457  * If rdata is non-null, wait for and return a byte of data.
1458  * We run at splimp() to make the transaction as atomic as
1459  * possible without blocking the clock (is this necessary?)
1460  */
1461 send_hil_cmd(hildevice, cmd, data, dlen, rdata)
1462 	register struct hil_dev *hildevice;
1463 	u_char cmd, *data, dlen;
1464 	u_char *rdata;
1465 {
1466 	u_char status;
1467 	int s = splimp();
1468 
1469 	HILWAIT(hildevice);
1470 	hildevice->hil_cmd = cmd;
1471 	while (dlen--) {
1472 	  	HILWAIT(hildevice);
1473 		hildevice->hil_data = *data++;
1474 	}
1475 	if (rdata) {
1476 		do {
1477 			HILDATAWAIT(hildevice);
1478 			status = hildevice->hil_stat;
1479 			*rdata = hildevice->hil_data;
1480 		} while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K);
1481 	}
1482 	splx(s);
1483 }
1484 
1485 /*
1486  * Send a command to a device on the loop.
1487  * Since only one command can be active on the loop at any time,
1488  * we must ensure that we are not interrupted during this process.
1489  * Hence we mask interrupts to prevent potential access from most
1490  * interrupt routines and turn off auto-polling to disable the
1491  * internally generated poll commands.
1492  *
1493  * splhigh is extremely conservative but insures atomic operation,
1494  * splimp (clock only interrupts) seems to be good enough in practice.
1495  */
1496 send_hildev_cmd(hilp, device, cmd)
1497 	register struct hilloop *hilp;
1498 	char device, cmd;
1499 {
1500 	register struct hil_dev *hildevice = hilp->hl_addr;
1501 	u_char status, c;
1502 	int s = splimp();
1503 
1504 	polloff(hildevice);
1505 
1506 	/*
1507 	 * Transfer the command and device info to the chip
1508 	 */
1509 	HILWAIT(hildevice);
1510 	hildevice->hil_cmd = HIL_STARTCMD;
1511   	HILWAIT(hildevice);
1512 	hildevice->hil_data = 8 + device;
1513   	HILWAIT(hildevice);
1514 	hildevice->hil_data = cmd;
1515   	HILWAIT(hildevice);
1516 	hildevice->hil_data = HIL_TIMEOUT;
1517 	/*
1518 	 * Trigger the command and wait for completion
1519 	 */
1520 	HILWAIT(hildevice);
1521 	hildevice->hil_cmd = HIL_TRIGGER;
1522 	hilp->hl_cmddone = FALSE;
1523 	do {
1524 		HILDATAWAIT(hildevice);
1525 		status = hildevice->hil_stat;
1526 		c = hildevice->hil_data;
1527 		hil_process_int(status, c);
1528 	} while (!hilp->hl_cmddone);
1529 
1530 	pollon(hildevice);
1531 	splx(s);
1532 }
1533 
1534 /*
1535  * Turn auto-polling off and on.
1536  * Also disables and enable auto-repeat.  Why?
1537  */
1538 polloff(hildevice)
1539 	register struct hil_dev *hildevice;
1540 {
1541 	register char db;
1542 
1543 	/*
1544 	 * Turn off auto repeat
1545 	 */
1546 	HILWAIT(hildevice);
1547 	hildevice->hil_cmd = HIL_SETARR;
1548 	HILWAIT(hildevice);
1549 	hildevice->hil_data = 0;
1550 	/*
1551 	 * Turn off auto-polling
1552 	 */
1553 	HILWAIT(hildevice);
1554 	hildevice->hil_cmd = HIL_READLPCTRL;
1555 	HILDATAWAIT(hildevice);
1556 	db = hildevice->hil_data;
1557 	db &= ~LPC_AUTOPOLL;
1558 	HILWAIT(hildevice);
1559 	hildevice->hil_cmd = HIL_WRITELPCTRL;
1560 	HILWAIT(hildevice);
1561 	hildevice->hil_data = db;
1562 	/*
1563 	 * Must wait til polling is really stopped
1564 	 */
1565 	do {
1566 		HILWAIT(hildevice);
1567 		hildevice->hil_cmd = HIL_READBUSY;
1568 		HILDATAWAIT(hildevice);
1569 		db = hildevice->hil_data;
1570 	} while (db & BSY_LOOPBUSY);
1571 }
1572 
1573 pollon(hildevice)
1574 	register struct hil_dev *hildevice;
1575 {
1576 	register char db;
1577 
1578 	/*
1579 	 * Turn on auto polling
1580 	 */
1581 	HILWAIT(hildevice);
1582 	hildevice->hil_cmd = HIL_READLPCTRL;
1583 	HILDATAWAIT(hildevice);
1584 	db = hildevice->hil_data;
1585 	db |= LPC_AUTOPOLL;
1586 	HILWAIT(hildevice);
1587 	hildevice->hil_cmd = HIL_WRITELPCTRL;
1588 	HILWAIT(hildevice);
1589 	hildevice->hil_data = db;
1590 	/*
1591 	 * Turn on auto repeat
1592 	 */
1593 	HILWAIT(hildevice);
1594 	hildevice->hil_cmd = HIL_SETARR;
1595 	HILWAIT(hildevice);
1596 	hildevice->hil_data = ar_format(KBD_ARR);
1597 }
1598 
1599 #ifdef DEBUG
1600 printhilpollbuf(hilp)
1601 	register struct hilloop *hilp;
1602 {
1603   	register u_char *cp;
1604 	register int i, len;
1605 
1606 	cp = hilp->hl_pollbuf;
1607 	len = hilp->hl_pollbp - cp;
1608 	for (i = 0; i < len; i++)
1609 		printf("%x ", hilp->hl_pollbuf[i]);
1610 	printf("\n");
1611 }
1612 
1613 printhilcmdbuf(hilp)
1614 	register struct hilloop *hilp;
1615 {
1616   	register u_char *cp;
1617 	register int i, len;
1618 
1619 	cp = hilp->hl_cmdbuf;
1620 	len = hilp->hl_cmdbp - cp;
1621 	for (i = 0; i < len; i++)
1622 		printf("%x ", hilp->hl_cmdbuf[i]);
1623 	printf("\n");
1624 }
1625 
1626 hilreport(hilp)
1627 	register struct hilloop *hilp;
1628 {
1629 	register int i, len;
1630 	int s = splhil();
1631 
1632 	for (i = 1; i <= hilp->hl_maxdev; i++) {
1633 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1634 		hilp->hl_cmddev = i;
1635 		send_hildev_cmd(hilp, i, HILIDENTIFY);
1636 		printf("hil%d: id: ", i);
1637 		printhilcmdbuf(hilp);
1638 		len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
1639 		if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT)) {
1640 			hilp->hl_cmdbp = hilp->hl_cmdbuf;
1641 			hilp->hl_cmddev = i;
1642 			send_hildev_cmd(hilp, i, HILSECURITY);
1643 			printf("hil%d: sc: ", i);
1644 			printhilcmdbuf(hilp);
1645 		}
1646 	}
1647 	hilp->hl_cmdbp = hilp->hl_cmdbuf;
1648 	hilp->hl_cmddev = 0;
1649 	splx(s);
1650 }
1651 #endif
1652