xref: /csrg-svn/sys/hp/dev/hil.c (revision 43316)
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.3 (Berkeley) 06/20/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 	struct proc *p = u.u_procp;		/* XXX */
597 #ifdef MMAP
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 	struct proc *p = u.u_procp;		/* XXX */
957 #ifdef MAPMEM
958 	register struct hilloop *hilp = &hil0;	/* XXX */
959 	register HILQ *hq;
960 	register int qnum;
961 	struct mapmem *mp;
962 	int 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 	if (u.u_error = mmalloc(p, qnum, &qip->addr, sizeof(HILQ), MM_RW|MM_CI, &hilqops, &mp)) {
994 		cifree((caddr_t)hq, sizeof(HILQ));
995 		hilp->hl_queue[qnum].hq_eventqueue = NULL;
996 		return(u.u_error);
997 	}
998 	qip->qid = qnum;
999 	if (!mmmapin(p, mp, hilqmapin)) {
1000 		mmfree(p, mp);
1001 		cifree((caddr_t)hq, sizeof(HILQ));
1002 		hilp->hl_queue[qnum].hq_eventqueue = NULL;
1003 		return(u.u_error);
1004 	}
1005 	hilp->hl_queue[qnum].hq_procp = p;
1006 	hilp->hl_queue[qnum].hq_devmask = 0;
1007 	return(0);
1008 #else
1009 	return(EINVAL);
1010 #endif
1011 }
1012 
1013 hilqfree(qnum)
1014 	register int qnum;
1015 {
1016 	struct proc *p = u.u_procp;		/* XXX */
1017 #ifdef MAPMEM
1018 	register struct hilloop *hilp = &hil0;	/* XXX */
1019 	register struct mapmem *mp;
1020 
1021 #ifdef DEBUG
1022 	if (hildebug & HDB_FOLLOW)
1023 		printf("hilqfree(%d): qnum %d\n",
1024 		       p->p_pid, qnum);
1025 #endif
1026 	if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
1027 		return(EINVAL);
1028 	for (mp = u.u_mmap; mp; mp = mp->mm_next)
1029 		if (qnum == mp->mm_id && mp->mm_ops == &hilqops) {
1030 			hilqexit(mp);
1031 			return(0);
1032 		}
1033 	panic("hilqfree");
1034 	/* NOTREACHED */
1035 #else
1036 	return(EINVAL);
1037 #endif
1038 }
1039 
1040 hilqmap(qnum, device)
1041 	register int qnum, device;
1042 {
1043 	struct proc *p = u.u_procp;		/* XXX */
1044 	register struct hilloop *hilp = &hil0;	/* XXX */
1045 	register struct hilloopdev *dptr = &hilp->hl_device[device];
1046 	int s;
1047 
1048 #ifdef DEBUG
1049 	if (hildebug & HDB_FOLLOW)
1050 		printf("hilqmap(%d): qnum %d device %x\n",
1051 		       p->p_pid, qnum, device);
1052 #endif
1053 	if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
1054 		return(EINVAL);
1055 	if ((dptr->hd_flags & HIL_QUEUEIN) == 0)
1056 		return(EINVAL);
1057 	if (dptr->hd_qmask && u.u_uid && u.u_uid != dptr->hd_uid)
1058 		return(EPERM);
1059 
1060 	hilp->hl_queue[qnum].hq_devmask |= hildevmask(device);
1061 	if (dptr->hd_qmask == 0)
1062 		dptr->hd_uid = u.u_uid;
1063 	s = splhil();
1064 	dptr->hd_qmask |= hilqmask(qnum);
1065 	splx(s);
1066 #ifdef DEBUG
1067 	if (hildebug & HDB_MASK)
1068 		printf("hilqmap(%d): devmask %x qmask %x\n",
1069 		       p->p_pid, hilp->hl_queue[qnum].hq_devmask,
1070 		       dptr->hd_qmask);
1071 #endif
1072 	return(0);
1073 }
1074 
1075 hilqunmap(qnum, device)
1076 	register int qnum, device;
1077 {
1078 	struct proc *p = u.u_procp;		/* XXX */
1079 	register struct hilloop *hilp = &hil0;	/* XXX */
1080 	int s;
1081 
1082 #ifdef DEBUG
1083 	if (hildebug & HDB_FOLLOW)
1084 		printf("hilqunmap(%d): qnum %d device %x\n",
1085 		       p->p_pid, qnum, device);
1086 #endif
1087 
1088 	if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p)
1089 		return(EINVAL);
1090 
1091 	hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device);
1092 	s = splhil();
1093 	hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum);
1094 	splx(s);
1095 #ifdef DEBUG
1096 	if (hildebug & HDB_MASK)
1097 		printf("hilqunmap(%d): devmask %x qmask %x\n",
1098 		       p->p_pid, hilp->hl_queue[qnum].hq_devmask,
1099 		       hilp->hl_device[device].hd_qmask);
1100 #endif
1101 	return(0);
1102 }
1103 
1104 #ifdef MAPMEM
1105 hilqmapin(mp, off)
1106 	struct mapmem *mp;
1107 {
1108 	struct hilloop *hilp = &hil0;		/* XXX */
1109 	register HILQ *hq = hilp->hl_queue[mp->mm_id].hq_eventqueue;
1110 
1111 	if (hq == NULL || off >= sizeof(HILQ))
1112 		return(-1);
1113 	return(kvtop((u_int)hq + off) >> PGSHIFT);
1114 }
1115 
1116 /*
1117  * Fork hook.
1118  * Unmap queue from child's address space
1119  */
1120 hilqfork(mp, ischild)
1121 	struct mapmem *mp;
1122 {
1123 	struct proc *p = u.u_procp;		/* XXX */
1124 #ifdef DEBUG
1125 	if (hildebug & HDB_MMAP)
1126 		printf("hilqfork(%d): %s qnum %d\n", p->p_pid,
1127 		       ischild ? "child" : "parent", mp->mm_id);
1128 #endif
1129 	if (ischild) {
1130 		mmmapout(p, mp);
1131 		mmfree(p, mp);
1132 	}
1133 }
1134 
1135 /*
1136  * Vfork hook.
1137  * Associate queue with child when VM resources are passed.
1138  */
1139 hilqvfork(mp, fup, tup)
1140 	struct mapmem *mp;
1141 	struct user *fup, *tup;
1142 {
1143 	struct hilloop *hilp = &hil0;		/* XXX */
1144 	register struct hiliqueue *qp = &hilp->hl_queue[mp->mm_id];
1145 
1146 #ifdef DEBUG
1147 	if (hildebug & HDB_MMAP)
1148 		printf("hilqvfork(%d): from %x to %x qnum %d, qprocp %x\n",
1149 		       u.u_procp->p_pid, fup->u_procp, tup->u_procp,
1150 		       mp->mm_id, qp->hq_procp);
1151 #endif
1152 	if (qp->hq_procp == fup->u_procp)
1153 		qp->hq_procp = tup->u_procp;
1154 }
1155 
1156 /*
1157  * Exit hook.
1158  * Unmap all devices and free all queues.
1159  */
1160 hilqexit(mp)
1161 	struct mapmem *mp;
1162 {
1163 	struct proc *p = u.u_procp;		/* XXX */
1164 	register struct hilloop *hilp = &hil0;	/* XXX */
1165 	register int mask, i;
1166 	int s;
1167 
1168 #ifdef DEBUG
1169 	if (hildebug & HDB_MMAP)
1170 		printf("hilqexit(%d): qnum %d\n", p->p_pid, mp->mm_id);
1171 #endif
1172 	/*
1173 	 * Atomically take all devices off the queue
1174 	 */
1175 	mask = ~hilqmask(mp->mm_id);
1176 	s = splhil();
1177 	for (i = 0; i < NHILD; i++)
1178 		hilp->hl_device[i].hd_qmask &= mask;
1179 	splx(s);
1180 	/*
1181 	 * Now unmap from user address space and free queue
1182 	 */
1183 	i = mp->mm_id;
1184 	cifree((caddr_t)hilp->hl_queue[i].hq_eventqueue, sizeof(HILQ));
1185 	hilp->hl_queue[i].hq_eventqueue = NULL;
1186 	hilp->hl_queue[i].hq_procp = NULL;
1187 	mmfree(p, mp);
1188 }
1189 #endif
1190 
1191 #include "clist.h"
1192 
1193 /*
1194  * This is just a copy of the virgin q_to_b routine with minor
1195  * optimizations for HIL use.  It is used for two reasons:
1196  * 1. If we have PAGE mode defined, the normal q_to_b processes
1197  *    chars one at a time and breaks on newlines.
1198  * 2. We don't have to raise the priority to spltty() for most
1199  *    of the clist manipulations.
1200  */
1201 hilq_to_b(q, cp, cc)
1202 	register struct clist *q;
1203 	register char *cp;
1204 {
1205 	register struct cblock *bp;
1206 	register int nc;
1207 	char *acp;
1208 	int s;
1209 	extern char cwaiting;
1210 
1211 	if (cc <= 0)
1212 		return (0);
1213 	s = splhil();
1214 	if (q->c_cc <= 0) {
1215 		q->c_cc = 0;
1216 		q->c_cf = q->c_cl = NULL;
1217 		splx(s);
1218 		return (0);
1219 	}
1220 	acp = cp;
1221 
1222 	while (cc) {
1223 		nc = sizeof (struct cblock) - ((int)q->c_cf & CROUND);
1224 		nc = MIN(nc, cc);
1225 		nc = MIN(nc, q->c_cc);
1226 		(void) bcopy(q->c_cf, cp, (unsigned)nc);
1227 		q->c_cf += nc;
1228 		q->c_cc -= nc;
1229 		cc -= nc;
1230 		cp += nc;
1231 		if (q->c_cc <= 0) {
1232 			bp = (struct cblock *)(q->c_cf - 1);
1233 			bp = (struct cblock *)((int)bp & ~CROUND);
1234 			q->c_cf = q->c_cl = NULL;
1235 			spltty();
1236 			bp->c_next = cfreelist;
1237 			cfreelist = bp;
1238 			cfreecount += CBSIZE;
1239 			if (cwaiting) {
1240 				wakeup(&cwaiting);
1241 				cwaiting = 0;
1242 			}
1243 			break;
1244 		}
1245 		if (((int)q->c_cf & CROUND) == 0) {
1246 			bp = (struct cblock *)(q->c_cf);
1247 			bp--;
1248 			q->c_cf = bp->c_next->c_info;
1249 			spltty();
1250 			bp->c_next = cfreelist;
1251 			cfreelist = bp;
1252 			cfreecount += CBSIZE;
1253 			if (cwaiting) {
1254 				wakeup(&cwaiting);
1255 				cwaiting = 0;
1256 			}
1257 			splhil();
1258 		}
1259 	}
1260 	splx(s);
1261 	return (cp-acp);
1262 }
1263 
1264 /*
1265  * Cooked keyboard functions for ite driver.
1266  * There is only one "cooked" ITE keyboard (the first keyboard found)
1267  * per loop.  There may be other keyboards, but they will always be "raw".
1268  */
1269 
1270 kbdbell()
1271 {
1272 	struct hilloop *hilp = &hil0;		/* XXX */
1273 
1274 	hilbeep(hilp, &default_bell);
1275 }
1276 
1277 kbdenable()
1278 {
1279 	struct hilloop *hilp = &hil0;	/* XXX */
1280 	register struct hil_dev *hildevice = hilp->hl_addr;
1281 	char db;
1282 
1283 	/* Set the autorepeat rate register */
1284 	db = ar_format(KBD_ARR);
1285 	send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL);
1286 
1287 	/* Set the autorepeat delay register */
1288 	db = ar_format(KBD_ARD);
1289 	send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL);
1290 
1291 	/* Enable interrupts */
1292 	send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
1293 }
1294 
1295 kbddisable()
1296 {
1297 }
1298 
1299 /*
1300  * XXX: read keyboard directly and return code.
1301  * Used by console getchar routine.  Could really screw up anybody
1302  * reading from the keyboard in the normal, interrupt driven fashion.
1303  */
1304 kbdgetc(statp)
1305 	int *statp;
1306 {
1307 	struct hilloop *hilp = &hil0;		/* XXX */
1308 	register struct hil_dev *hildevice = hilp->hl_addr;
1309 	register int c, stat;
1310 	int s;
1311 
1312 	s = splhil();
1313 	while (((stat = hildevice->hil_stat) & HIL_DATA_RDY) == 0)
1314 		;
1315 	c = hildevice->hil_data;
1316 	splx(s);
1317 	*statp = stat;
1318 	return(c);
1319 }
1320 
1321 /*
1322  * Recoginize and clear keyboard generated NMIs.
1323  * Returns 1 if it was ours, 0 otherwise.  Note that we cannot use
1324  * send_hil_cmd() to issue the clear NMI command as that would actually
1325  * lower the priority to splimp() and it doesn't wait for the completion
1326  * of the command.  Either of these conditions could result in the
1327  * interrupt reoccuring.  Note that we issue the CNMT command twice.
1328  * This seems to be needed, once is not always enough!?!
1329  */
1330 kbdnmi()
1331 {
1332 	register struct hilloop *hilp = &hil0;		/* XXX */
1333 
1334 	if ((*KBDNMISTAT & KBDNMI) == 0)
1335 		return(0);
1336 	HILWAIT(hilp->hl_addr);
1337 	hilp->hl_addr->hil_cmd = HIL_CNMT;
1338 	HILWAIT(hilp->hl_addr);
1339 	hilp->hl_addr->hil_cmd = HIL_CNMT;
1340 	HILWAIT(hilp->hl_addr);
1341 	return(1);
1342 }
1343 
1344 #define HILSECURITY	0x33
1345 #define HILIDENTIFY	0x03
1346 #define HILSCBIT	0x04
1347 
1348 /*
1349  * Called at boot time to print out info about interesting devices
1350  */
1351 hilinfo(hilp)
1352 	register struct hilloop *hilp;
1353 {
1354 	register int id, len;
1355 	register struct kbdmap *km;
1356 
1357 	/*
1358 	 * Keyboard info.
1359 	 */
1360 	if (hilp->hl_kbddev) {
1361 		printf("hil%d: ", hilp->hl_kbddev);
1362 		for (km = kbd_map; km->kbd_code; km++)
1363 			if (km->kbd_code == hilp->hl_kbdlang) {
1364 				printf("%s ", km->kbd_desc);
1365 				break;
1366 			}
1367 		printf("keyboard\n");
1368 	}
1369 	/*
1370 	 * ID module.
1371 	 * Attempt to locate the first ID module and print out its
1372 	 * security code.  Is this a good idea??
1373 	 */
1374 	id = hiliddev(hilp);
1375 	if (id) {
1376 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1377 		hilp->hl_cmddev = id;
1378 		send_hildev_cmd(hilp, id, HILSECURITY);
1379 		len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
1380 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1381 		hilp->hl_cmddev = 0;
1382 		printf("hil%d: security code", id);
1383 		for (id = 0; id < len; id++)
1384 			printf(" %x", hilp->hl_cmdbuf[id]);
1385 		while (id++ < 16)
1386 			printf(" 0");
1387 		printf("\n");
1388 	}
1389 }
1390 
1391 #define HILAR1	0x3E
1392 #define HILAR2	0x3F
1393 
1394 /*
1395  * Called after the loop has reconfigured.  Here we need to:
1396  *	- determine how many devices are on the loop
1397  *	  (some may have been added or removed)
1398  *	- locate the ITE keyboard (if any) and ensure
1399  *	  that it is in the proper state (raw or cooked)
1400  *	  and is set to use the proper language mapping table
1401  *	- ensure all other keyboards are raw
1402  * Note that our device state is now potentially invalid as
1403  * devices may no longer be where they were.  What we should
1404  * do here is either track where the devices went and move
1405  * state around accordingly or, more simply, just mark all
1406  * devices as HIL_DERROR and don't allow any further use until
1407  * they are closed.  This is a little too brutal for my tastes,
1408  * we prefer to just assume people won't move things around.
1409  */
1410 hilconfig(hilp)
1411 	register struct hilloop *hilp;
1412 {
1413 	u_char db;
1414 	int s;
1415 
1416 	s = splhil();
1417 #ifdef DEBUG
1418 	if (hildebug & HDB_CONFIG) {
1419 		printf("hilconfig: reconfigured: ");
1420 		send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db);
1421 		printf("LPSTAT %x, ", db);
1422 		send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &db);
1423 		printf("LPCTRL %x, ", db);
1424 		send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db);
1425 		printf("KBDSADR %x\n", db);
1426 		hilreport(hilp);
1427 	}
1428 #endif
1429 	/*
1430 	 * Determine how many devices are on the loop.
1431 	 * Mark those as alive and real, all others as dead.
1432 	 */
1433 	db = 0;
1434 	send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db);
1435 	hilp->hl_maxdev = db & LPS_DEVMASK;
1436 	for (db = 1; db < NHILD; db++) {
1437 		if (db <= hilp->hl_maxdev)
1438 			hilp->hl_device[db].hd_flags |= HIL_ALIVE;
1439 		else
1440 			hilp->hl_device[db].hd_flags &= ~HIL_ALIVE;
1441 		hilp->hl_device[db].hd_flags &= ~HIL_PSEUDO;
1442 	}
1443 #ifdef DEBUG
1444 	if (hildebug & (HDB_CONFIG|HDB_KEYBOARD))
1445 		printf("hilconfig: max device %d\n", hilp->hl_maxdev);
1446 #endif
1447 	if (hilp->hl_maxdev == 0) {
1448 		hilp->hl_kbddev = 0;
1449 		splx(s);
1450 		return;
1451 	}
1452 	/*
1453 	 * Find out where the keyboards are and record the ITE keyboard
1454 	 * (first one found).  If no keyboards found, we are all done.
1455 	 */
1456 	db = 0;
1457 	send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db);
1458 #ifdef DEBUG
1459 	if (hildebug & HDB_KEYBOARD)
1460 		printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n",
1461 		       db, hilp->hl_kbddev, ffs((int)db));
1462 #endif
1463 	hilp->hl_kbddev = ffs((int)db);
1464 	if (hilp->hl_kbddev == 0) {
1465 		splx(s);
1466 		return;
1467 	}
1468 	/*
1469 	 * Determine if the keyboard should be cooked or raw and configure it.
1470 	 */
1471 	db = (hilp->hl_kbdflags & KBD_RAW) ? 0 : 1 << (hilp->hl_kbddev - 1);
1472 	send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &db, 1, NULL);
1473 	/*
1474 	 * Re-enable autorepeat in raw mode, cooked mode AR is not affected.
1475 	 */
1476 	if (hilp->hl_kbdflags & (KBD_AR1|KBD_AR2)) {
1477 		db = (hilp->hl_kbdflags & KBD_AR1) ? HILAR1 : HILAR2;
1478 		hilp->hl_cmddev = hilp->hl_kbddev;
1479 		send_hildev_cmd(hilp, hilp->hl_kbddev, db);
1480 		hilp->hl_cmddev = 0;
1481 	}
1482 	/*
1483 	 * Determine the keyboard language configuration, but don't
1484 	 * override a user-specified setting.
1485 	 */
1486 	db = 0;
1487 	send_hil_cmd(hilp->hl_addr, HIL_READKBDLANG, NULL, 0, &db);
1488 #ifdef DEBUG
1489 	if (hildebug & HDB_KEYBOARD)
1490 		printf("hilconfig: language: old %x new %x\n",
1491 		       hilp->hl_kbdlang, db);
1492 #endif
1493 	if (hilp->hl_kbdlang != KBD_SPECIAL) {
1494 		struct kbdmap *km;
1495 
1496 		for (km = kbd_map; km->kbd_code; km++)
1497 			if (km->kbd_code == db) {
1498 				hilp->hl_kbdlang = db;
1499 				/* XXX */
1500 				kbd_keymap = km->kbd_keymap;
1501 				kbd_shiftmap = km->kbd_shiftmap;
1502 				kbd_ctrlmap = km->kbd_ctrlmap;
1503 				kbd_ctrlshiftmap = km->kbd_ctrlshiftmap;
1504 				kbd_stringmap = km->kbd_stringmap;
1505 			}
1506 	}
1507 	splx(s);
1508 }
1509 
1510 hilreset(hilp)
1511 	struct hilloop *hilp;
1512 {
1513 	register struct hil_dev *hildevice = hilp->hl_addr;
1514 	u_char db;
1515 
1516 	/*
1517 	 * Initialize the loop: reconfigure, don't report errors,
1518 	 * cook keyboards, and enable autopolling.
1519 	 */
1520 	db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL;
1521 	send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL);
1522 	/*
1523 	 * Delay one second for reconfiguration and then read the the
1524 	 * data register to clear the interrupt (if the loop reconfigured).
1525 	 */
1526 	DELAY(1000000);
1527 	if (hildevice->hil_stat & HIL_DATA_RDY)
1528 		db = hildevice->hil_data;
1529 	/*
1530 	 * The HIL loop may have reconfigured.  If so we proceed on,
1531 	 * if not we loop until a successful reconfiguration is reported
1532 	 * back to us.  The HIL loop will continue to attempt forever.
1533 	 * Probably not very smart.
1534 	 */
1535 	do {
1536 		send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db);
1537         } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0);
1538 	/*
1539 	 * At this point, the loop should have reconfigured.
1540 	 * The reconfiguration interrupt has already called hilconfig()
1541 	 * so the keyboard has been determined.  All that is left is
1542 	 *
1543 	 */
1544 #if 0
1545 	hilconfig(hilp);
1546 #endif
1547 	send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL);
1548 }
1549 
1550 hilbeep(hilp, bp)
1551 	struct hilloop *hilp;
1552 	register struct _hilbell *bp;
1553 {
1554 	u_char buf[2];
1555 
1556 	buf[0] = ~((bp->duration - 10) / 10);
1557 	buf[1] = bp->frequency;
1558 	send_hil_cmd(hilp->hl_addr, HIL_SETTONE, buf, 2, NULL);
1559 }
1560 
1561 /*
1562  * Locate and return the address of the first ID module, 0 if none present.
1563  */
1564 hiliddev(hilp)
1565 	register struct hilloop *hilp;
1566 {
1567 	register int i, len;
1568 
1569 #ifdef DEBUG
1570 	if (hildebug & HDB_IDMODULE)
1571 		printf("hiliddev(%x): looking for idmodule...", hilp);
1572 #endif
1573 	for (i = 1; i <= hilp->hl_maxdev; i++) {
1574 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1575 		hilp->hl_cmddev = i;
1576 		send_hildev_cmd(hilp, i, HILIDENTIFY);
1577 		/*
1578 		 * XXX: the final condition checks to ensure that the
1579 		 * device ID byte is in the range of the ID module (0x30-0x3F)
1580 		 */
1581 		len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
1582 		if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT) &&
1583 		    (hilp->hl_cmdbuf[0] & 0xF0) == 0x30) {
1584 			hilp->hl_cmdbp = hilp->hl_cmdbuf;
1585 			hilp->hl_cmddev = i;
1586 			send_hildev_cmd(hilp, i, HILSECURITY);
1587 			break;
1588 		}
1589 	}
1590 	hilp->hl_cmdbp = hilp->hl_cmdbuf;
1591 	hilp->hl_cmddev = 0;
1592 #ifdef DEBUG
1593 	if (hildebug & HDB_IDMODULE)
1594 		if (i <= hilp->hl_maxdev)
1595 			printf("found at %d\n", i);
1596 		else
1597 			printf("not found\n");
1598 #endif
1599 	return(i <= hilp->hl_maxdev ? i : 0);
1600 }
1601 
1602 /*
1603  * Low level routines which actually talk to the 8042 chip.
1604  */
1605 
1606 /*
1607  * Send a command to the 8042 with zero or more bytes of data.
1608  * If rdata is non-null, wait for and return a byte of data.
1609  * We run at splimp() to make the transaction as atomic as
1610  * possible without blocking the clock (is this necessary?)
1611  */
1612 send_hil_cmd(hildevice, cmd, data, dlen, rdata)
1613 	register struct hil_dev *hildevice;
1614 	u_char cmd, *data, dlen;
1615 	u_char *rdata;
1616 {
1617 	u_char status;
1618 	int s = splimp();
1619 
1620 	HILWAIT(hildevice);
1621 	hildevice->hil_cmd = cmd;
1622 	while (dlen--) {
1623 	  	HILWAIT(hildevice);
1624 		hildevice->hil_data = *data++;
1625 	}
1626 	if (rdata) {
1627 		do {
1628 			HILDATAWAIT(hildevice);
1629 			status = hildevice->hil_stat;
1630 			*rdata = hildevice->hil_data;
1631 		} while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K);
1632 	}
1633 	splx(s);
1634 }
1635 
1636 /*
1637  * Send a command to a device on the loop.
1638  * Since only one command can be active on the loop at any time,
1639  * we must ensure that we are not interrupted during this process.
1640  * Hence we mask interrupts to prevent potential access from most
1641  * interrupt routines and turn off auto-polling to disable the
1642  * internally generated poll commands.
1643  *
1644  * splhigh is extremely conservative but insures atomic operation,
1645  * splimp (clock only interrupts) seems to be good enough in practice.
1646  */
1647 send_hildev_cmd(hilp, device, cmd)
1648 	register struct hilloop *hilp;
1649 	char device, cmd;
1650 {
1651 	register struct hil_dev *hildevice = hilp->hl_addr;
1652 	u_char status, c;
1653 	int s = splimp();
1654 
1655 	polloff(hildevice);
1656 
1657 	/*
1658 	 * Transfer the command and device info to the chip
1659 	 */
1660 	HILWAIT(hildevice);
1661 	hildevice->hil_cmd = HIL_STARTCMD;
1662   	HILWAIT(hildevice);
1663 	hildevice->hil_data = 8 + device;
1664   	HILWAIT(hildevice);
1665 	hildevice->hil_data = cmd;
1666   	HILWAIT(hildevice);
1667 	hildevice->hil_data = HIL_TIMEOUT;
1668 	/*
1669 	 * Trigger the command and wait for completion
1670 	 */
1671 	HILWAIT(hildevice);
1672 	hildevice->hil_cmd = HIL_TRIGGER;
1673 	hilp->hl_cmddone = FALSE;
1674 	do {
1675 		HILDATAWAIT(hildevice);
1676 		status = hildevice->hil_stat;
1677 		c = hildevice->hil_data;
1678 		hil_process_int(status, c);
1679 	} while (!hilp->hl_cmddone);
1680 
1681 	pollon(hildevice);
1682 	splx(s);
1683 }
1684 
1685 /*
1686  * Turn auto-polling off and on.
1687  * Also disables and enable auto-repeat.  Why?
1688  */
1689 polloff(hildevice)
1690 	register struct hil_dev *hildevice;
1691 {
1692 	register char db;
1693 
1694 	/*
1695 	 * Turn off auto repeat
1696 	 */
1697 	HILWAIT(hildevice);
1698 	hildevice->hil_cmd = HIL_SETARR;
1699 	HILWAIT(hildevice);
1700 	hildevice->hil_data = 0;
1701 	/*
1702 	 * Turn off auto-polling
1703 	 */
1704 	HILWAIT(hildevice);
1705 	hildevice->hil_cmd = HIL_READLPCTRL;
1706 	HILDATAWAIT(hildevice);
1707 	db = hildevice->hil_data;
1708 	db &= ~LPC_AUTOPOLL;
1709 	HILWAIT(hildevice);
1710 	hildevice->hil_cmd = HIL_WRITELPCTRL;
1711 	HILWAIT(hildevice);
1712 	hildevice->hil_data = db;
1713 	/*
1714 	 * Must wait til polling is really stopped
1715 	 */
1716 	do {
1717 		HILWAIT(hildevice);
1718 		hildevice->hil_cmd = HIL_READBUSY;
1719 		HILDATAWAIT(hildevice);
1720 		db = hildevice->hil_data;
1721 	} while (db & BSY_LOOPBUSY);
1722 }
1723 
1724 pollon(hildevice)
1725 	register struct hil_dev *hildevice;
1726 {
1727 	register char db;
1728 
1729 	/*
1730 	 * Turn on auto polling
1731 	 */
1732 	HILWAIT(hildevice);
1733 	hildevice->hil_cmd = HIL_READLPCTRL;
1734 	HILDATAWAIT(hildevice);
1735 	db = hildevice->hil_data;
1736 	db |= LPC_AUTOPOLL;
1737 	HILWAIT(hildevice);
1738 	hildevice->hil_cmd = HIL_WRITELPCTRL;
1739 	HILWAIT(hildevice);
1740 	hildevice->hil_data = db;
1741 	/*
1742 	 * Turn on auto repeat
1743 	 */
1744 	HILWAIT(hildevice);
1745 	hildevice->hil_cmd = HIL_SETARR;
1746 	HILWAIT(hildevice);
1747 	hildevice->hil_data = ar_format(KBD_ARR);
1748 }
1749 
1750 #ifdef DEBUG
1751 printhilpollbuf(hilp)
1752 	register struct hilloop *hilp;
1753 {
1754   	register u_char *cp;
1755 	register int i, len;
1756 
1757 	cp = hilp->hl_pollbuf;
1758 	len = hilp->hl_pollbp - cp;
1759 	for (i = 0; i < len; i++)
1760 		printf("%x ", hilp->hl_pollbuf[i]);
1761 	printf("\n");
1762 }
1763 
1764 printhilcmdbuf(hilp)
1765 	register struct hilloop *hilp;
1766 {
1767   	register u_char *cp;
1768 	register int i, len;
1769 
1770 	cp = hilp->hl_cmdbuf;
1771 	len = hilp->hl_cmdbp - cp;
1772 	for (i = 0; i < len; i++)
1773 		printf("%x ", hilp->hl_cmdbuf[i]);
1774 	printf("\n");
1775 }
1776 
1777 hilreport(hilp)
1778 	register struct hilloop *hilp;
1779 {
1780 	register int i, len;
1781 	int s = splhil();
1782 
1783 	for (i = 1; i <= hilp->hl_maxdev; i++) {
1784 		hilp->hl_cmdbp = hilp->hl_cmdbuf;
1785 		hilp->hl_cmddev = i;
1786 		send_hildev_cmd(hilp, i, HILIDENTIFY);
1787 		printf("hil%d: id: ", i);
1788 		printhilcmdbuf(hilp);
1789 		len = hilp->hl_cmdbp - hilp->hl_cmdbuf;
1790 		if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT)) {
1791 			hilp->hl_cmdbp = hilp->hl_cmdbuf;
1792 			hilp->hl_cmddev = i;
1793 			send_hildev_cmd(hilp, i, HILSECURITY);
1794 			printf("hil%d: sc: ", i);
1795 			printhilcmdbuf(hilp);
1796 		}
1797 	}
1798 	hilp->hl_cmdbp = hilp->hl_cmdbuf;
1799 	hilp->hl_cmddev = 0;
1800 	splx(s);
1801 }
1802 #endif
1803