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