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