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