This source file includes following definitions.
- hilwait
- hildatawait
- hil_attach
- hildevprint
- hilsubmatch
- hil_attach_deferred
- hil_intr
- hil_process_int
- hil_process_poll
- hil_thread
- hilconfig
- hilempty
- send_hil_cmd
- send_device_cmd
- send_hildev_cmd
- polloff
- pollon
- hil_set_poll
- hil_poll_data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/conf.h>
70 #include <sys/device.h>
71 #include <sys/file.h>
72 #include <sys/ioctl.h>
73 #include <sys/kernel.h>
74 #include <sys/proc.h>
75 #include <sys/kthread.h>
76
77 #include <machine/autoconf.h>
78 #include <machine/bus.h>
79 #include <machine/cpu.h>
80
81 #include <dev/hil/hilreg.h>
82 #include <dev/hil/hilvar.h>
83 #include <dev/hil/hildevs.h>
84 #include <dev/hil/hildevs_data.h>
85
86 #include "hilkbd.h"
87
88
89
90
91
92 #define splhil splvm
93
94 struct cfdriver hil_cd = {
95 NULL, "hil", DV_DULL
96 };
97
98 void hilconfig(struct hil_softc *, u_int);
99 void hilempty(struct hil_softc *);
100 int hilsubmatch(struct device *, void *, void *);
101 void hil_process_int(struct hil_softc *, u_int8_t, u_int8_t);
102 int hil_process_poll(struct hil_softc *, u_int8_t, u_int8_t);
103 void hil_thread(void *);
104 int send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd);
105 void polloff(struct hil_softc *);
106 void pollon(struct hil_softc *);
107
108 static int hilwait(struct hil_softc *);
109 static int hildatawait(struct hil_softc *);
110
111 #define hil_process_pending(sc) wakeup(&(sc)->sc_pending)
112
113 static __inline int
114 hilwait(struct hil_softc *sc)
115 {
116 int cnt;
117
118 for (cnt = 50000; cnt != 0; cnt--) {
119 DELAY(1);
120 if ((bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) &
121 HIL_BUSY) == 0)
122 break;
123 }
124
125 return (cnt);
126 }
127
128 static __inline int
129 hildatawait(struct hil_softc *sc)
130 {
131 int cnt;
132
133 for (cnt = 50000; cnt != 0; cnt--) {
134 DELAY(1);
135 if ((bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) &
136 HIL_DATA_RDY) != 0)
137 break;
138 }
139
140 return (cnt);
141 }
142
143
144
145
146
147 void
148 hil_attach(struct hil_softc *sc, int *hil_is_console)
149 {
150 printf("\n");
151
152
153
154
155 sc->sc_cmdending = 0;
156 sc->sc_actdev = sc->sc_cmddev = 0;
157 sc->sc_cmddone = 0;
158 sc->sc_cmdbp = sc->sc_cmdbuf;
159 sc->sc_pollbp = sc->sc_pollbuf;
160 sc->sc_console = hil_is_console;
161 }
162
163
164
165
166
167 int
168 hildevprint(void *aux, const char *pnp)
169 {
170 struct hil_attach_args *ha = aux;
171
172 if (pnp != NULL) {
173 printf("\"%s\" at %s id %x",
174 ha->ha_descr, pnp, ha->ha_id);
175 }
176 printf(" code %d", ha->ha_code);
177 if (pnp == NULL) {
178 printf(": %s", ha->ha_descr);
179 }
180
181 return (UNCONF);
182 }
183
184 int
185 hilsubmatch(struct device *parent, void *vcf, void *aux)
186 {
187 struct hil_attach_args *ha = aux;
188 struct cfdata *cf = vcf;
189
190 if (cf->cf_loc[0] != -1 &&
191 cf->cf_loc[0] != ha->ha_code)
192 return (0);
193
194 return ((*cf->cf_attach->ca_match)(parent, vcf, aux));
195 }
196
197 void
198 hil_attach_deferred(void *v)
199 {
200 struct hil_softc *sc = v;
201 int tries;
202 u_int8_t db;
203
204 sc->sc_status = HIL_STATUS_BUSY;
205
206
207
208
209
210 db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL;
211 send_hil_cmd(sc, HIL_WRITELPCTRL, &db, 1, NULL);
212
213
214
215
216
217 DELAY(1000000);
218 if (bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT) &
219 HIL_DATA_RDY) {
220 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
221 DELAY(1);
222 }
223
224
225
226
227
228
229
230 for (tries = 10; tries != 0; tries--) {
231 if (send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db) == 0) {
232 if (db & (LPS_CONFFAIL | LPS_CONFGOOD))
233 break;
234 }
235
236 #ifdef HILDEBUG
237 printf("%s: loop not ready, retrying...\n",
238 sc->sc_dev.dv_xname);
239 #endif
240
241 DELAY(1000000);
242 }
243
244 if (tries == 0 || (db & LPS_CONFFAIL)) {
245 printf("%s: no devices\n", sc->sc_dev.dv_xname);
246 sc->sc_pending = 0;
247 if (tries == 0)
248 return;
249 }
250
251
252
253
254 if (kthread_create(hil_thread, sc, &sc->sc_thread,
255 "%s", sc->sc_dev.dv_xname) != 0) {
256 printf("%s: unable to create event thread\n",
257 sc->sc_dev.dv_xname);
258 return;
259 }
260
261
262
263
264 send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL);
265
266
267
268
269 sc->sc_status = HIL_STATUS_READY;
270 hil_process_pending(sc);
271 }
272
273
274
275
276
277 int
278 hil_intr(void *v)
279 {
280 struct hil_softc *sc = v;
281 u_int8_t c, stat;
282
283 if (cold)
284 return (0);
285
286 stat = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT);
287
288
289
290
291
292 if ((stat & HIL_DATA_RDY) == 0)
293 return (0);
294
295 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
296 HILP_DATA);
297 DELAY(1);
298
299 hil_process_int(sc, stat, c);
300
301 if (sc->sc_status != HIL_STATUS_BUSY)
302 hil_process_pending(sc);
303
304 return (1);
305 }
306
307 void
308 hil_process_int(struct hil_softc *sc, u_int8_t stat, u_int8_t c)
309 {
310 struct hildev_softc *dev;
311
312 switch ((stat >> HIL_SSHIFT) & HIL_SMASK) {
313 case HIL_STATUS:
314 if (c & HIL_ERROR) {
315 sc->sc_cmddone = 1;
316 switch (c) {
317 case HIL_RECONFIG:
318 sc->sc_pending = HIL_PENDING_RECONFIG;
319 break;
320 case HIL_UNPLUGGED:
321 sc->sc_pending = HIL_PENDING_UNPLUGGED;
322 break;
323 }
324 break;
325 }
326 if (c & HIL_COMMAND) {
327 if (c & HIL_POLLDATA) {
328 dev = sc->sc_devices[sc->sc_actdev];
329 if (dev != NULL && dev->sc_fn != NULL)
330 dev->sc_fn(dev,
331 sc->sc_pollbp - sc->sc_pollbuf,
332 sc->sc_pollbuf);
333 } else {
334 sc->sc_cmdending = 1;
335 }
336 sc->sc_actdev = 0;
337 } else {
338 if (c & HIL_POLLDATA) {
339 sc->sc_actdev = (c & HIL_DEVMASK);
340 sc->sc_pollbp = sc->sc_pollbuf;
341 } else {
342 if (sc->sc_cmddev == (c & HIL_DEVMASK)) {
343 sc->sc_cmdbp = sc->sc_cmdbuf;
344 sc->sc_actdev = 0;
345 }
346 }
347 }
348 break;
349 case HIL_DATA:
350 if (sc->sc_actdev != 0)
351 *sc->sc_pollbp++ = c;
352 else {
353 if (sc->sc_cmddev != 0) {
354 if (sc->sc_cmdending) {
355 sc->sc_cmddone = 1;
356 sc->sc_cmdending = 0;
357 } else
358 *sc->sc_cmdbp++ = c;
359 }
360 }
361 break;
362 }
363 }
364
365
366
367
368
369 int
370 hil_process_poll(struct hil_softc *sc, u_int8_t stat, u_int8_t c)
371 {
372 u_int8_t db;
373
374 switch ((stat >> HIL_SSHIFT) & HIL_SMASK) {
375 case HIL_STATUS:
376 if (c & HIL_ERROR) {
377 sc->sc_cmddone = 1;
378 switch (c) {
379 case HIL_RECONFIG:
380
381
382
383
384
385 sc->sc_pending = HIL_PENDING_RECONFIG;
386
387
388
389
390
391
392 db = 0;
393 send_hil_cmd(sc, HIL_WRITEKBDSADR, &db,
394 1, NULL);
395 break;
396 case HIL_UNPLUGGED:
397
398
399
400
401
402 sc->sc_pending = HIL_PENDING_UNPLUGGED;
403 break;
404 }
405 break;
406 }
407 if (c & HIL_COMMAND) {
408 if (!(c & HIL_POLLDATA)) {
409
410 sc->sc_cmdending = 1;
411 }
412 sc->sc_actdev = 0;
413 } else {
414 if (c & HIL_POLLDATA) {
415
416 sc->sc_actdev = (c & HIL_DEVMASK);
417 sc->sc_pollbp = sc->sc_pollbuf;
418 } else {
419
420 if (sc->sc_cmddev == (c & HIL_DEVMASK)) {
421 sc->sc_cmdbp = sc->sc_cmdbuf;
422 sc->sc_actdev = 0;
423 }
424 }
425 }
426 break;
427 case HIL_DATA:
428 if (sc->sc_actdev != 0)
429 return 1;
430 else {
431 if (sc->sc_cmddev != 0) {
432 if (sc->sc_cmdending) {
433 sc->sc_cmddone = 1;
434 sc->sc_cmdending = 0;
435 }
436 }
437 }
438 break;
439 }
440
441 return 0;
442 }
443
444 void
445 hil_thread(void *arg)
446 {
447 struct hil_softc *sc = arg;
448 int s;
449
450 for (;;) {
451 s = splhil();
452 if (sc->sc_pending == 0) {
453 splx(s);
454 (void)tsleep(&sc->sc_pending, PWAIT, "hil_event", 0);
455 continue;
456 }
457
458 switch (sc->sc_pending) {
459 case HIL_PENDING_RECONFIG:
460 sc->sc_pending = 0;
461 hilconfig(sc, sc->sc_maxdev);
462 break;
463 case HIL_PENDING_UNPLUGGED:
464 sc->sc_pending = 0;
465 hilempty(sc);
466 break;
467 }
468 }
469 }
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487 void
488 hilconfig(struct hil_softc *sc, u_int knowndevs)
489 {
490 struct hil_attach_args ha;
491 u_int8_t db;
492 int id, s;
493
494 s = splhil();
495
496
497
498
499 db = 0;
500 send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db);
501 sc->sc_maxdev = db & LPS_DEVMASK;
502 #ifdef HILDEBUG
503 printf("%s: %d device(s)\n", sc->sc_dev.dv_xname, sc->sc_maxdev);
504 #endif
505
506
507
508
509 db = 0;
510 send_hil_cmd(sc, HIL_WRITEKBDSADR, &db, 1, NULL);
511
512
513
514
515 for (id = knowndevs + 1; id <= sc->sc_maxdev; id++) {
516 int len;
517 const struct hildevice *hd;
518
519 if (send_device_cmd(sc, id, HIL_IDENTIFY) != 0) {
520 printf("%s: no answer from device %d\n",
521 sc->sc_dev.dv_xname, id);
522 continue;
523 }
524
525 len = sc->sc_cmdbp - sc->sc_cmdbuf;
526 if (len == 0) {
527 #ifdef HILDEBUG
528 printf("%s: no device at code %d\n",
529 sc->sc_dev.dv_xname, id);
530 #endif
531 continue;
532 }
533
534
535 for (hd = hildevs; hd->minid >= 0; hd++)
536 if (sc->sc_cmdbuf[0] >= hd->minid &&
537 sc->sc_cmdbuf[0] <= hd->maxid) {
538
539 ha.ha_console = *sc->sc_console;
540 ha.ha_code = id;
541 ha.ha_type = hd->type;
542 ha.ha_descr = hd->descr;
543 ha.ha_infolen = len;
544 bcopy(sc->sc_cmdbuf, ha.ha_info, len);
545
546 sc->sc_devices[id] = (struct hildev_softc *)
547 config_found_sm(&sc->sc_dev, &ha, hildevprint,
548 hilsubmatch);
549
550 #if NHILKBD > 0
551
552
553
554
555 if (sc->sc_devices[id] != NULL &&
556 ha.ha_type == HIL_DEVICE_KEYBOARD &&
557 ha.ha_console != 0)
558 *sc->sc_console = 1;
559 #endif
560 }
561 }
562
563
564
565
566 for (id = sc->sc_maxdev + 1; id < NHILD; id++) {
567 if (sc->sc_devices[id] != NULL)
568 config_detach((struct device *)sc->sc_devices[id],
569 DETACH_FORCE);
570 sc->sc_devices[id] = NULL;
571 }
572
573 sc->sc_cmdbp = sc->sc_cmdbuf;
574
575 splx(s);
576 }
577
578
579
580
581
582 void
583 hilempty(struct hil_softc *sc)
584 {
585 u_int8_t db;
586 int id, s;
587 u_int oldmaxdev;
588
589 s = splhil();
590
591
592
593
594 for (;;) {
595 if (send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db) == 0) {
596 if (db & (LPS_CONFFAIL | LPS_CONFGOOD))
597 break;
598 } else {
599 db = LPS_CONFFAIL;
600 break;
601 }
602 }
603
604 if (db & LPS_CONFFAIL) {
605 sc->sc_maxdev = 0;
606 } else {
607 db = 0;
608 send_hil_cmd(sc, HIL_READLPSTAT, NULL, 0, &db);
609 oldmaxdev = sc->sc_maxdev;
610 sc->sc_maxdev = db & LPS_DEVMASK;
611
612 if (sc->sc_maxdev != 0) {
613
614
615
616
617 hilconfig(sc, oldmaxdev);
618 return;
619 }
620 }
621
622
623
624
625 for (id = sc->sc_maxdev + 1; id < NHILD; id++) {
626 if (sc->sc_devices[id] != NULL)
627 config_detach((struct device *)sc->sc_devices[id],
628 DETACH_FORCE);
629 sc->sc_devices[id] = NULL;
630 }
631
632 sc->sc_cmdbp = sc->sc_cmdbuf;
633
634 splx(s);
635 }
636
637
638
639
640
641
642
643
644
645 int
646 send_hil_cmd(struct hil_softc *sc, u_int cmd, u_int8_t *data, u_int dlen,
647 u_int8_t *rdata)
648 {
649 u_int8_t status;
650 int s;
651
652 s = splhil();
653
654 if (hilwait(sc) == 0) {
655 #ifdef HILDEBUG
656 printf("%s: no answer from the loop\n", sc->sc_dev.dv_xname);
657 #endif
658 splx(s);
659 return (EBUSY);
660 }
661
662 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, cmd);
663 while (dlen--) {
664 hilwait(sc);
665 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, *data++);
666 DELAY(1);
667 }
668 if (rdata) {
669 do {
670 if (hildatawait(sc) == 0) {
671 #ifdef HILDEBUG
672 printf("%s: no answer from the loop\n",
673 sc->sc_dev.dv_xname);
674 #endif
675 break;
676 }
677 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
678 HILP_STAT);
679 *rdata = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
680 HILP_DATA);
681 DELAY(1);
682 } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K);
683 }
684 splx(s);
685 return (0);
686 }
687
688
689
690
691
692
693
694
695
696
697 int
698 send_device_cmd(struct hil_softc *sc, u_int device, u_int cmd)
699 {
700 u_int8_t status, c;
701 int rc = 0;
702
703 polloff(sc);
704
705 sc->sc_cmdbp = sc->sc_cmdbuf;
706 sc->sc_cmddev = device;
707
708 if (hilwait(sc) == 0) {
709 #ifdef HILDEBUG
710 printf("%s: no answer from device %d\n",
711 sc->sc_dev.dv_xname, device);
712 #endif
713 rc = EBUSY;
714 goto out;
715 }
716
717
718
719
720 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_STARTCMD);
721 hilwait(sc);
722 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 8 + device);
723 hilwait(sc);
724 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, cmd);
725 hilwait(sc);
726 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, HIL_TIMEOUT);
727
728
729
730
731 hilwait(sc);
732 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_TRIGGER);
733 sc->sc_cmddone = 0;
734 do {
735 if (hildatawait(sc) == 0) {
736 #ifdef HILDEBUG
737 printf("%s: no answer from device %d\n",
738 sc->sc_dev.dv_xname, device);
739 #endif
740 rc = EBUSY;
741 break;
742 }
743 status = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT);
744 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
745 DELAY(1);
746 hil_process_int(sc, status, c);
747 } while (sc->sc_cmddone == 0);
748 out:
749 sc->sc_cmddev = 0;
750
751 pollon(sc);
752 return (rc);
753 }
754
755 int
756 send_hildev_cmd(struct hildev_softc *dev, u_int cmd,
757 u_int8_t *outbuf, u_int *outlen)
758 {
759 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent;
760 int s, rc;
761
762 s = splhil();
763
764 if ((rc = send_device_cmd(sc, dev->sc_code, cmd)) == 0) {
765
766
767
768 if (outbuf != NULL && outlen != NULL) {
769 *outlen = min(*outlen, sc->sc_cmdbp - sc->sc_cmdbuf);
770 bcopy(sc->sc_cmdbuf, outbuf, *outlen);
771 }
772 }
773
774 splx(s);
775 return (rc);
776 }
777
778
779
780
781 void
782 polloff(struct hil_softc *sc)
783 {
784 u_int8_t db;
785
786 if (hilwait(sc) == 0)
787 return;
788
789
790
791
792 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR);
793 hilwait(sc);
794 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0);
795
796
797
798
799 hilwait(sc);
800 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL);
801 hildatawait(sc);
802 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
803 db &= ~LPC_AUTOPOLL;
804 hilwait(sc);
805 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL);
806 hilwait(sc);
807 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db);
808
809
810
811
812 do {
813 hilwait(sc);
814 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READBUSY);
815 hildatawait(sc);
816 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
817 } while (db & BSY_LOOPBUSY);
818
819 sc->sc_cmddone = 0;
820 sc->sc_cmddev = 0;
821 }
822
823 void
824 pollon(struct hil_softc *sc)
825 {
826 u_int8_t db;
827
828 if (hilwait(sc) == 0)
829 return;
830
831
832
833
834 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_READLPCTRL);
835 hildatawait(sc);
836 db = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
837 db |= LPC_AUTOPOLL;
838 hilwait(sc);
839 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_WRITELPCTRL);
840 hilwait(sc);
841 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, db);
842
843
844
845
846 hilwait(sc);
847 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_CMD, HIL_SETARR);
848 hilwait(sc);
849 bus_space_write_1(sc->sc_bst, sc->sc_bsh, HILP_DATA, 0);
850 DELAY(1);
851 }
852
853 void
854 hil_set_poll(struct hil_softc *sc, int on)
855 {
856 if (on) {
857 pollon(sc);
858 } else {
859 hil_process_pending(sc);
860 send_hil_cmd(sc, HIL_INTON, NULL, 0, NULL);
861 }
862 }
863
864 int
865 hil_poll_data(struct hildev_softc *dev, u_int8_t *stat, u_int8_t *data)
866 {
867 struct hil_softc *sc = (struct hil_softc *)dev->sc_dev.dv_parent;
868 u_int8_t s, c;
869
870 s = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_STAT);
871 if ((s & HIL_DATA_RDY) == 0)
872 return -1;
873
874 c = bus_space_read_1(sc->sc_bst, sc->sc_bsh, HILP_DATA);
875 DELAY(1);
876
877 if (hil_process_poll(sc, s, c)) {
878
879 if (sc->sc_actdev == dev->sc_code) {
880 *stat = s;
881 *data = c;
882 return 0;
883 }
884 }
885
886 return -1;
887 }