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