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