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