xref: /dragonfly/sys/dev/misc/kbd/atkbdc.c (revision 3851e4b8)
1 /*
2  * (MPSAFE)
3  *
4  * Copyright (c) 1996-1999
5  * Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote
17  *    products derived from this software without specific prior written
18  *    permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD: src/sys/dev/kbd/atkbdc.c,v 1.5.2.2 2002/03/31 11:02:02 murray Exp $
33  * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp
34  */
35 
36 #include "opt_kbd.h"
37 #include "use_atkbdc.h"
38 
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/bus.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/syslog.h>
45 #include <sys/rman.h>
46 #include <sys/kbio.h>
47 
48 #include <machine/clock.h>
49 
50 #include "atkbdcreg.h"
51 #include "kbdreg.h"
52 
53 #include <bus/isa/isareg.h>
54 
55 #if 0
56 #define lwkt_gettoken(x)
57 #define lwkt_reltoken(x)
58 #endif
59 
60 /* constants */
61 
62 #define MAXKBDC		MAX(NATKBDC, 1)		/* XXX */
63 
64 /* macros */
65 
66 #ifndef MAX
67 #define MAX(x, y)	((x) > (y) ? (x) : (y))
68 #endif
69 
70 #define kbdcp(p)	((atkbdc_softc_t *)(p))
71 #define nextq(i)	(((i) + 1) % KBDQ_BUFSIZE)
72 #define availq(q)	((q)->head != (q)->tail)
73 #if KBDIO_DEBUG >= 2
74 #define emptyq(q)	((q)->tail = (q)->head = (q)->qcount = 0)
75 #else
76 #define emptyq(q)	((q)->tail = (q)->head = 0)
77 #endif
78 
79 #define read_data(k)	(bus_space_read_1((k)->iot, (k)->ioh0, 0))
80 #define read_status(k)	(bus_space_read_1((k)->iot, (k)->ioh1, 0))
81 #define write_data(k, d)	\
82 			(bus_space_write_1((k)->iot, (k)->ioh0, 0, (d)))
83 #define write_command(k, d)	\
84 			(bus_space_write_1((k)->iot, (k)->ioh1, 0, (d)))
85 
86 /* local variables */
87 
88 /*
89  * We always need at least one copy of the kbdc_softc struct for the
90  * low-level console.  As the low-level console accesses the keyboard
91  * controller before kbdc, and all other devices, is probed, we
92  * statically allocate one entry. XXX
93  */
94 static atkbdc_softc_t default_kbdc;
95 static atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc };
96 
97 static int verbose = KBDIO_DEBUG;
98 
99 /* function prototypes */
100 
101 static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
102 			bus_space_handle_t h0, bus_space_handle_t h1);
103 static int addq(kbdkqueue *q, int c);
104 static int removeq(kbdkqueue *q);
105 static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
106 static int wait_for_data(atkbdc_softc_t *kbdc);
107 static int wait_for_kbd_data(atkbdc_softc_t *kbdc);
108 static int wait_for_kbd_ack(atkbdc_softc_t *kbdc);
109 static int wait_for_aux_data(atkbdc_softc_t *kbdc);
110 static int wait_for_aux_ack(atkbdc_softc_t *kbdc);
111 
112 atkbdc_softc_t *
113 atkbdc_get_softc(int unit)
114 {
115 	atkbdc_softc_t *sc;
116 
117 	if (unit >= NELEM(atkbdc_softc))
118 		return NULL;
119 	sc = atkbdc_softc[unit];
120 	if (sc == NULL) {
121 		sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
122 		atkbdc_softc[unit] = sc;
123 	}
124 	return sc;
125 }
126 
127 int
128 atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1)
129 {
130 	if (rman_get_start(port0) <= 0)
131 		return ENXIO;
132 	if (rman_get_start(port1) <= 0)
133 		return ENXIO;
134 	return 0;
135 }
136 
137 int
138 atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
139 		   struct resource *port1)
140 {
141 	return atkbdc_setup(sc, rman_get_bustag(port0),
142 			    rman_get_bushandle(port0),
143 			    rman_get_bushandle(port1));
144 }
145 
146 extern int acpi_fadt_8042_nolegacy;
147 int kicked_by_syscons = 0;
148 
149 static void
150 atkbdc_fadt_done(void)
151 {
152 	if (kicked_by_syscons) {
153 		/*
154 		 * Configuring all keyboards is fine, because only atkbd
155 		 * really does something here, anyway.
156 		 */
157 		kbd_configure(KB_CONF_PROBE_ONLY);
158 	}
159 }
160 
161 /* After fadt_probe in platform/pc64/acpica/acpi_fadt.c. */
162 SYSINIT(atkbdc_kick, SI_BOOT2_PRESMP, SI_ORDER_THIRD, atkbdc_fadt_done, 0);
163 
164 /* the backdoor to the keyboard controller! XXX */
165 int
166 atkbdc_configure(void)
167 {
168 	bus_space_tag_t tag;
169 	bus_space_handle_t h0;
170 	bus_space_handle_t h1;
171 	int port0;
172 	int port1;
173 #if defined(__x86_64__)
174 	int i;
175 #endif
176 
177 	kicked_by_syscons = 1;
178 	if (acpi_fadt_8042_nolegacy != 0)
179 		return ENXIO;
180 
181 	port0 = IO_KBD;
182 	resource_int_value("atkbdc", 0, "port", &port0);
183 	port1 = IO_KBD + KBD_STATUS_PORT;
184 #if 0
185 	resource_int_value("atkbdc", 0, "port", &port0);
186 #endif
187 
188 	/* XXX: tag should be passed from the caller */
189 #if defined(__x86_64__)
190 	tag = X86_64_BUS_SPACE_IO;
191 #else
192 	tag = 0;	/* XXX */
193 #endif
194 
195 #if 0 /* notyet */
196 	bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
197 	bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
198 #else
199 	h0 = (bus_space_handle_t)port0;
200 	h1 = (bus_space_handle_t)port1;
201 #endif
202 
203 #if defined(__x86_64__)
204 	/*
205 	 * Check if we really have AT keyboard controller. Poll status
206 	 * register until we get "all clear" indication. If no such
207 	 * indication comes, it probably means that there is no AT
208 	 * keyboard controller present. Give up in such case. Check relies
209 	 * on the fact that reading from non-existing in/out port returns
210 	 * 0xff on i386. May or may not be true on other platforms.
211 	 */
212 	for (i = 65536; i != 0; --i) {
213 		if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0)
214 			break;
215 		DELAY(16);
216 	}
217 	if (i == 0)
218                 return ENXIO;
219 #endif
220 
221 	return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
222 }
223 
224 static int
225 atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0,
226 	     bus_space_handle_t h1)
227 {
228 	if (sc->ioh0 == 0) {	/* XXX */
229 	    sc->command_byte = -1;
230 	    sc->lock = FALSE;
231 	    sc->kbd.head = sc->kbd.tail = 0;
232 	    sc->aux.head = sc->aux.tail = 0;
233 #if KBDIO_DEBUG >= 2
234 	    sc->kbd.call_count = 0;
235 	    sc->kbd.qcount = sc->kbd.max_qcount = 0;
236 	    sc->aux.call_count = 0;
237 	    sc->aux.qcount = sc->aux.max_qcount = 0;
238 #endif
239 	}
240 	sc->iot = tag;
241 	sc->ioh0 = h0;
242 	sc->ioh1 = h1;
243 	return 0;
244 }
245 
246 /* open a keyboard controller */
247 KBDC
248 atkbdc_open(int unit)
249 {
250     if (unit <= 0)
251 	unit = 0;
252     if (unit >= MAXKBDC)
253 	return NULL;
254     if ((atkbdc_softc[unit]->port0 != NULL)
255 	|| (atkbdc_softc[unit]->ioh0 != 0))		/* XXX */
256 	return (KBDC)atkbdc_softc[unit];
257     return NULL;
258 }
259 
260 /*
261  * I/O access arbitration in `kbdio'
262  *
263  * The `kbdio' module uses a simplistic convention to arbitrate
264  * I/O access to the controller/keyboard/mouse. The convention requires
265  * close cooperation of the calling device driver.
266  *
267  * The device drivers which utilize the `kbdio' module are assumed to
268  * have the following set of routines.
269  *    a. An interrupt handler (the bottom half of the driver).
270  *    b. Timeout routines which may briefly poll the keyboard controller.
271  *    c. Routines outside interrupt context (the top half of the driver).
272  * They should follow the rules below:
273  *    1. The interrupt handler may assume that it always has full access
274  *       to the controller/keyboard/mouse.
275  *    2. The other routines must issue `spltty()' if they wish to
276  *       prevent the interrupt handler from accessing
277  *       the controller/keyboard/mouse.
278  *    3. The timeout routines and the top half routines of the device driver
279  *       arbitrate I/O access by observing the lock flag in `kbdio'.
280  *       The flag is manipulated via `kbdc_lock()'; when one wants to
281  *       perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if
282  *       the call returns with TRUE. Otherwise the caller must back off.
283  *       Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion
284  *       is finished. This mechanism does not prevent the interrupt
285  *       handler from being invoked at any time and carrying out I/O.
286  *       Therefore, `spltty()' must be strategically placed in the device
287  *       driver code. Also note that the timeout routine may interrupt
288  *       `kbdc_lock()' called by the top half of the driver, but this
289  *       interruption is OK so long as the timeout routine observes
290  *       rule 4 below.
291  *    4. The interrupt and timeout routines should not extend I/O operation
292  *       across more than one interrupt or timeout; they must complete any
293  *       necessary I/O operation within one invocation of the routine.
294  *       This means that if the timeout routine acquires the lock flag,
295  *       it must reset the flag to FALSE before it returns.
296  */
297 
298 /* set/reset polling lock */
299 int
300 kbdc_lock(KBDC p, int lock)
301 {
302     int prevlock;
303 
304     prevlock = kbdcp(p)->lock;
305     kbdcp(p)->lock = lock;
306 
307     return (prevlock != lock);
308 }
309 
310 /* check if any data is waiting to be processed */
311 int
312 kbdc_data_ready(KBDC p)
313 {
314     return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux)
315 	|| (read_status(kbdcp(p)) & KBDS_ANY_BUFFER_FULL));
316 }
317 
318 /* queuing functions */
319 
320 static int
321 addq(kbdkqueue *q, int c)
322 {
323     if (nextq(q->tail) != q->head) {
324 	q->q[q->tail] = c;
325 	q->tail = nextq(q->tail);
326 #if KBDIO_DEBUG >= 2
327         ++q->call_count;
328         ++q->qcount;
329 	if (q->qcount > q->max_qcount)
330             q->max_qcount = q->qcount;
331 #endif
332 	return TRUE;
333     }
334     return FALSE;
335 }
336 
337 static int
338 removeq(kbdkqueue *q)
339 {
340     int c;
341 
342     if (q->tail != q->head) {
343 	c = q->q[q->head];
344 	q->head = nextq(q->head);
345 #if KBDIO_DEBUG >= 2
346         --q->qcount;
347 #endif
348 	return c;
349     }
350     return -1;
351 }
352 
353 /*
354  * device I/O routines
355  */
356 static int
357 wait_while_controller_busy(struct atkbdc_softc *kbdc)
358 {
359     /* CPU will stay inside the loop for 100msec at most */
360     TOTALDELAY retry = { .us = 70000, .last_clock =0 };	/* 70ms */
361     int f;
362     unsigned char c;
363 
364     while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) {
365 	if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
366 	    DELAY(KBDD_DELAYTIME);
367 	    c = read_data(kbdc);
368 	    addq(&kbdc->kbd, c);
369 	} else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
370 	    DELAY(KBDD_DELAYTIME);
371 	    c = read_data(kbdc);
372 	    addq(&kbdc->aux, c);
373 	}
374         DELAY(KBDC_DELAYTIME);
375 	if (CHECKTIMEOUT(&retry))
376     	    return FALSE;
377     }
378     return TRUE;
379 }
380 
381 /*
382  * wait for any data; whether it's from the controller,
383  * the keyboard, or the aux device.
384  */
385 static int
386 wait_for_data(struct atkbdc_softc *kbdc)
387 {
388     /* CPU will stay inside the loop for 200msec at most */
389     TOTALDELAY retry = { 200000, 0 };	/* 200ms */
390     int f;
391 
392     while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) {
393         DELAY(KBDC_DELAYTIME);
394 	if (CHECKTIMEOUT(&retry))
395     	    return 0;
396     }
397     DELAY(KBDD_DELAYTIME);
398     return f;
399 }
400 
401 /* wait for data from the keyboard */
402 static int
403 wait_for_kbd_data(struct atkbdc_softc *kbdc)
404 {
405     /* CPU will stay inside the loop for 200msec at most */
406     TOTALDELAY retry = { 200000, 0 };	/* 200ms */
407     int f;
408     unsigned char c;
409 
410     while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
411 	    != KBDS_KBD_BUFFER_FULL) {
412         if (f == KBDS_AUX_BUFFER_FULL) {
413 	    DELAY(KBDD_DELAYTIME);
414 	    c = read_data(kbdc);
415 	    addq(&kbdc->aux, c);
416 	}
417         DELAY(KBDC_DELAYTIME);
418         if (CHECKTIMEOUT(&retry))
419     	    return 0;
420     }
421     DELAY(KBDD_DELAYTIME);
422     return f;
423 }
424 
425 /*
426  * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard.
427  * queue anything else.
428  */
429 static int
430 wait_for_kbd_ack(struct atkbdc_softc *kbdc)
431 {
432     /* CPU will stay inside the loop for 200msec at most */
433     TOTALDELAY retry = { 200000, 0 };	/* 200ms */
434     int f;
435     int b;
436 
437     while (CHECKTIMEOUT(&retry) == 0) {
438         if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
439 	    DELAY(KBDD_DELAYTIME);
440             b = read_data(kbdc);
441 	    if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
442 		if ((b == KBD_ACK) || (b == KBD_RESEND)
443 		    || (b == KBD_RESET_FAIL))
444 		    return b;
445 		addq(&kbdc->kbd, b);
446 	    } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
447 		addq(&kbdc->aux, b);
448 	    }
449 	}
450         DELAY(KBDC_DELAYTIME);
451     }
452     return -1;
453 }
454 
455 /* wait for data from the aux device */
456 static int
457 wait_for_aux_data(struct atkbdc_softc *kbdc)
458 {
459     /* CPU will stay inside the loop for 200msec at most */
460     TOTALDELAY retry = { 200000, 0 };	/* 200ms */
461     int f;
462     unsigned char b;
463 
464     while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
465 	    != KBDS_AUX_BUFFER_FULL) {
466         if (f == KBDS_KBD_BUFFER_FULL) {
467 	    DELAY(KBDD_DELAYTIME);
468 	    b = read_data(kbdc);
469 	    addq(&kbdc->kbd, b);
470 	}
471         DELAY(KBDC_DELAYTIME);
472 	if (CHECKTIMEOUT(&retry))
473     	    return 0;
474     }
475     DELAY(KBDD_DELAYTIME);
476     return f;
477 }
478 
479 /*
480  * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device.
481  * queue anything else.
482  */
483 static int
484 wait_for_aux_ack(struct atkbdc_softc *kbdc)
485 {
486     /* CPU will stay inside the loop for 200msec at most */
487     TOTALDELAY retry = { 200000, 0 };	/* 200ms */
488     int f;
489     int b;
490 
491     while (CHECKTIMEOUT(&retry) == 0) {
492         if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
493 	    DELAY(KBDD_DELAYTIME);
494             b = read_data(kbdc);
495 	    if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
496 		if ((b == PSM_ACK) || (b == PSM_RESEND)
497 		    || (b == PSM_RESET_FAIL))
498 		    return b;
499 		addq(&kbdc->aux, b);
500 	    } else if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
501 		addq(&kbdc->kbd, b);
502 	    }
503 	}
504         DELAY(KBDC_DELAYTIME);
505     }
506     return -1;
507 }
508 
509 /*
510  * Returns read-back data or -1 on failure
511  */
512 int
513 write_controller_w1r1(KBDC p, int c, int d)
514 {
515     if (!write_controller_command(p, c))
516 	return(-1);
517     if (!write_controller_data(p, d))
518 	return(-1);
519     return (read_controller_data(p));
520 }
521 
522 /* write a one byte command to the controller */
523 int
524 write_controller_command(KBDC p, int c)
525 {
526     if (!wait_while_controller_busy(kbdcp(p)))
527 	return FALSE;
528     write_command(kbdcp(p), c);
529     return TRUE;
530 }
531 
532 /* write a one byte data to the controller */
533 int
534 write_controller_data(KBDC p, int c)
535 {
536     if (!wait_while_controller_busy(kbdcp(p)))
537 	return FALSE;
538     write_data(kbdcp(p), c);
539     return TRUE;
540 }
541 
542 /* write a one byte keyboard command */
543 int
544 write_kbd_command(KBDC p, int c)
545 {
546     if (!wait_while_controller_busy(kbdcp(p)))
547 	return FALSE;
548     write_data(kbdcp(p), c);
549     return TRUE;
550 }
551 
552 /* write a one byte auxiliary device command */
553 int
554 write_aux_command(KBDC p, int c)
555 {
556     if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
557 	return FALSE;
558     return write_controller_data(p, c);
559 }
560 
561 /* send a command to the keyboard and wait for ACK */
562 int
563 send_kbd_command(KBDC p, int c)
564 {
565     int retry = KBD_MAXRETRY;
566     int res = -1;
567 
568     while (retry-- > 0) {
569 	if (!write_kbd_command(p, c))
570 	    continue;
571         res = wait_for_kbd_ack(kbdcp(p));
572         if (res == KBD_ACK)
573     	    break;
574     }
575     return res;
576 }
577 
578 /* send a command to the auxiliary device and wait for ACK */
579 int
580 send_aux_command(KBDC p, int c)
581 {
582     int retry = KBD_MAXRETRY;
583     int res = -1;
584 
585     while (retry-- > 0) {
586 	if (!write_aux_command(p, c))
587 	    continue;
588 	/*
589 	 * FIXME: XXX
590 	 * The aux device may have already sent one or two bytes of
591 	 * status data, when a command is received. It will immediately
592 	 * stop data transmission, thus, leaving an incomplete data
593 	 * packet in our buffer. We have to discard any unprocessed
594 	 * data in order to remove such packets. Well, we may remove
595 	 * unprocessed, but necessary data byte as well...
596 	 */
597 	emptyq(&kbdcp(p)->aux);
598         res = wait_for_aux_ack(kbdcp(p));
599         if (res == PSM_ACK)
600     	    break;
601     }
602     return res;
603 }
604 
605 /* send a command and a data to the keyboard, wait for ACKs */
606 int
607 send_kbd_command_and_data(KBDC p, int c, int d)
608 {
609     int retry;
610     int res = -1;
611 
612     for (retry = KBD_MAXRETRY; retry > 0; --retry) {
613 	if (!write_kbd_command(p, c))
614 	    continue;
615         res = wait_for_kbd_ack(kbdcp(p));
616         if (res == KBD_ACK)
617     	    break;
618         else if (res != KBD_RESEND)
619     	    return res;
620     }
621     if (retry <= 0)
622 	return res;
623 
624     for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
625 	if (!write_kbd_command(p, d))
626 	    continue;
627         res = wait_for_kbd_ack(kbdcp(p));
628         if (res != KBD_RESEND)
629     	    break;
630     }
631     return res;
632 }
633 
634 /* send a command and a data to the auxiliary device, wait for ACKs */
635 int
636 send_aux_command_and_data(KBDC p, int c, int d)
637 {
638     int retry;
639     int res = -1;
640 
641     for (retry = KBD_MAXRETRY; retry > 0; --retry) {
642 	if (!write_aux_command(p, c))
643 	    continue;
644 	emptyq(&kbdcp(p)->aux);
645         res = wait_for_aux_ack(kbdcp(p));
646         if (res == PSM_ACK)
647     	    break;
648         else if (res != PSM_RESEND)
649     	    return res;
650     }
651     if (retry <= 0)
652 	return res;
653 
654     for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
655 	if (!write_aux_command(p, d))
656 	    continue;
657         res = wait_for_aux_ack(kbdcp(p));
658         if (res != PSM_RESEND)
659     	    break;
660     }
661     return res;
662 }
663 
664 /*
665  * read one byte from any source; whether from the controller,
666  * the keyboard, or the aux device
667  */
668 int
669 read_controller_data(KBDC p)
670 {
671     if (availq(&kbdcp(p)->kbd))
672         return removeq(&kbdcp(p)->kbd);
673     if (availq(&kbdcp(p)->aux))
674         return removeq(&kbdcp(p)->aux);
675     if (!wait_for_data(kbdcp(p)))
676         return -1;		/* timeout */
677     return read_data(kbdcp(p));
678 }
679 
680 #if KBDIO_DEBUG >= 2
681 static int call = 0;
682 #endif
683 
684 /* read one byte from the keyboard */
685 int
686 read_kbd_data(KBDC p)
687 {
688     unsigned char b;
689 
690 #if KBDIO_DEBUG >= 2
691     if (++call > 2000) {
692 	call = 0;
693 	log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
694 			     "aux q: %d calls, max %d chars\n",
695 		       kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
696 		       kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
697     }
698 #endif
699 
700     if (availq(&kbdcp(p)->kbd))
701         return removeq(&kbdcp(p)->kbd);
702     if (!wait_for_kbd_data(kbdcp(p)))
703         return -1;		/* timeout */
704     b = read_data(kbdcp(p));
705     return b;
706 }
707 
708 /* read one byte from the keyboard, but return immediately if
709  * no data is waiting
710  */
711 int
712 read_kbd_data_no_wait(KBDC p)
713 {
714     int f;
715     unsigned char b;
716 
717 #if KBDIO_DEBUG >= 2
718     if (++call > 2000) {
719 	call = 0;
720 	log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
721 			     "aux q: %d calls, max %d chars\n",
722 		       kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
723 		       kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
724     }
725 #endif
726 
727     if (availq(&kbdcp(p)->kbd))
728         return removeq(&kbdcp(p)->kbd);
729     f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
730     while (f == KBDS_AUX_BUFFER_FULL) {
731         DELAY(KBDD_DELAYTIME);
732 	b = read_data(kbdcp(p));
733         addq(&kbdcp(p)->aux, b);
734         f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
735     }
736     if (f == KBDS_KBD_BUFFER_FULL) {
737         DELAY(KBDD_DELAYTIME);
738 	b = read_data(kbdcp(p));
739         return (int)b;
740     }
741     return -1;		/* no data */
742 }
743 
744 /* read one byte from the aux device */
745 int
746 read_aux_data(KBDC p)
747 {
748     unsigned char b;
749     if (availq(&kbdcp(p)->aux))
750         return removeq(&kbdcp(p)->aux);
751     if (!wait_for_aux_data(kbdcp(p)))
752         return -1;		/* timeout */
753     b = read_data(kbdcp(p));
754     return b;
755 }
756 
757 /* read one byte from the aux device, but return immediately if
758  * no data is waiting
759  */
760 int
761 read_aux_data_no_wait(KBDC p)
762 {
763     unsigned char b;
764     int f;
765 
766     if (availq(&kbdcp(p)->aux))
767         return removeq(&kbdcp(p)->aux);
768     f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
769     while (f == KBDS_KBD_BUFFER_FULL) {
770         DELAY(KBDD_DELAYTIME);
771 	b = read_data(kbdcp(p));
772         addq(&kbdcp(p)->kbd, b);
773         f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
774     }
775     if (f == KBDS_AUX_BUFFER_FULL) {
776         DELAY(KBDD_DELAYTIME);
777 	b = read_data(kbdcp(p));
778         return b;
779     }
780     return -1;		/* no data */
781 }
782 
783 /* discard data from the keyboard */
784 void
785 empty_kbd_buffer(KBDC p, int wait)
786 {
787     int t;
788     int b;
789     int f;
790 #if KBDIO_DEBUG >= 2
791     int c1 = 0;
792     int c2 = 0;
793 #endif
794     int delta = 2;
795 
796     for (t = wait; t > 0; ) {
797         if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
798 	    DELAY(KBDD_DELAYTIME);
799             b = read_data(kbdcp(p));
800 	    if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
801 		addq(&kbdcp(p)->aux, b);
802 #if KBDIO_DEBUG >= 2
803 		++c2;
804             } else {
805 		++c1;
806 #endif
807 	    }
808 	    t = wait;
809 	} else {
810 	    t -= delta;
811 	}
812         DELAY(delta*1000);
813     }
814 #if KBDIO_DEBUG >= 2
815     if ((c1 > 0) || (c2 > 0))
816         log(LOG_DEBUG, "kbdc: %d:%d char read (empty_kbd_buffer)\n", c1, c2);
817 #endif
818 
819     emptyq(&kbdcp(p)->kbd);
820 }
821 
822 /* discard data from the aux device */
823 void
824 empty_aux_buffer(KBDC p, int wait)
825 {
826     int t;
827     int b;
828     int f;
829 #if KBDIO_DEBUG >= 2
830     int c1 = 0;
831     int c2 = 0;
832 #endif
833     int delta = 2;
834 
835     for (t = wait; t > 0; ) {
836         if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
837 	    DELAY(KBDD_DELAYTIME);
838             b = read_data(kbdcp(p));
839 	    if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
840 		addq(&kbdcp(p)->kbd, b);
841 #if KBDIO_DEBUG >= 2
842 		++c1;
843             } else {
844 		++c2;
845 #endif
846 	    }
847 	    t = wait;
848 	} else {
849 	    t -= delta;
850 	}
851 	DELAY(delta*1000);
852     }
853 #if KBDIO_DEBUG >= 2
854     if ((c1 > 0) || (c2 > 0))
855         log(LOG_DEBUG, "kbdc: %d:%d char read (empty_aux_buffer)\n", c1, c2);
856 #endif
857 
858     emptyq(&kbdcp(p)->aux);
859 }
860 
861 /* discard any data from the keyboard or the aux device */
862 void
863 empty_both_buffers(KBDC p, int wait)
864 {
865     int t;
866     int f;
867 #if KBDIO_DEBUG >= 2
868     int c1 = 0;
869     int c2 = 0;
870 #endif
871     int delta = 2;
872 
873     for (t = wait; t > 0; ) {
874         if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
875 	    DELAY(KBDD_DELAYTIME);
876             (void)read_data(kbdcp(p));
877 #if KBDIO_DEBUG >= 2
878 	    if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL)
879 		++c1;
880             else
881 		++c2;
882 #endif
883 	    t = wait;
884 	} else {
885 	    t -= delta;
886 	}
887 	DELAY(delta*1000);
888     }
889 #if KBDIO_DEBUG >= 2
890     if ((c1 > 0) || (c2 > 0))
891         log(LOG_DEBUG, "kbdc: %d:%d char read (empty_both_buffers)\n", c1, c2);
892 #endif
893 
894     emptyq(&kbdcp(p)->kbd);
895     emptyq(&kbdcp(p)->aux);
896 }
897 
898 /* keyboard and mouse device control */
899 
900 /* NOTE: enable the keyboard port but disable the keyboard
901  * interrupt before calling "reset_kbd()".
902  */
903 int
904 reset_kbd(KBDC p)
905 {
906     int retry = KBD_MAXRETRY;
907     int again = KBD_MAXWAIT;
908     int c = KBD_RESEND;		/* keep the compiler happy */
909 
910     while (retry-- > 0) {
911         empty_both_buffers(p, 10);
912         if (!write_kbd_command(p, KBDC_RESET_KBD))
913 	    continue;
914 	emptyq(&kbdcp(p)->kbd);
915         c = read_controller_data(p);
916 	if (verbose || bootverbose)
917             log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c);
918         if (c == KBD_ACK)	/* keyboard has agreed to reset itself... */
919     	    break;
920     }
921     if (retry < 0)
922         return FALSE;
923 
924     while (again-- > 0) {
925         /* wait awhile, well, in fact we must wait quite loooooooooooong */
926         DELAY(KBD_RESETDELAY*1000);
927         c = read_controller_data(p);	/* RESET_DONE/RESET_FAIL */
928         if (c != -1) 	/* wait again if the controller is not ready */
929     	    break;
930     }
931     if (verbose || bootverbose)
932         log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c);
933     if (c != KBD_RESET_DONE)
934         return FALSE;
935     return TRUE;
936 }
937 
938 /* NOTE: enable the aux port but disable the aux interrupt
939  * before calling `reset_aux_dev()'.
940  */
941 int
942 reset_aux_dev(KBDC p)
943 {
944     int retry = KBD_MAXRETRY;
945     int again = KBD_MAXWAIT;
946     int c = PSM_RESEND;		/* keep the compiler happy */
947 
948     while (retry-- > 0) {
949         empty_both_buffers(p, 10);
950         if (!write_aux_command(p, PSMC_RESET_DEV))
951 	    continue;
952 	emptyq(&kbdcp(p)->aux);
953 	/* NOTE: Compaq Armada laptops require extra delay here. XXX */
954 	for (again = KBD_MAXWAIT; again > 0; --again) {
955             DELAY(KBD_RESETDELAY*1000);
956             c = read_aux_data_no_wait(p);
957 	    if (c != -1)
958 		break;
959 	}
960         if (verbose || bootverbose)
961             log(LOG_DEBUG, "kbdc: RESET_AUX return code:%04x\n", c);
962         if (c == PSM_ACK)	/* aux dev is about to reset... */
963     	    break;
964     }
965     if (retry < 0)
966         return FALSE;
967 
968     for (again = KBD_MAXWAIT; again > 0; --again) {
969         /* wait awhile, well, quite looooooooooooong */
970         DELAY(KBD_RESETDELAY*1000);
971         c = read_aux_data_no_wait(p);	/* RESET_DONE/RESET_FAIL */
972         if (c != -1) 	/* wait again if the controller is not ready */
973     	    break;
974     }
975     if (verbose || bootverbose)
976         log(LOG_DEBUG, "kbdc: RESET_AUX status:%04x\n", c);
977     if (c != PSM_RESET_DONE)	/* reset status */
978         return FALSE;
979 
980     c = read_aux_data(p);	/* device ID */
981     if (verbose || bootverbose)
982         log(LOG_DEBUG, "kbdc: RESET_AUX ID:%04x\n", c);
983     /* NOTE: we could check the device ID now, but leave it later... */
984     return TRUE;
985 }
986 
987 /* controller diagnostics and setup */
988 
989 int
990 test_controller(KBDC p)
991 {
992     int retry = KBD_MAXRETRY;
993     int again = KBD_MAXWAIT;
994     int c = KBD_DIAG_FAIL;
995 
996     while (retry-- > 0) {
997         empty_both_buffers(p, 10);
998         if (write_controller_command(p, KBDC_DIAGNOSE))
999     	    break;
1000     }
1001     if (retry < 0)
1002         return FALSE;
1003 
1004     emptyq(&kbdcp(p)->kbd);
1005     while (again-- > 0) {
1006         /* wait awhile */
1007         DELAY(KBD_RESETDELAY*1000);
1008         c = read_controller_data(p);	/* DIAG_DONE/DIAG_FAIL */
1009         if (c != -1) 	/* wait again if the controller is not ready */
1010     	    break;
1011     }
1012     if (verbose || bootverbose)
1013         log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c);
1014     return (c == KBD_DIAG_DONE);
1015 }
1016 
1017 int
1018 test_kbd_port(KBDC p)
1019 {
1020     int retry = KBD_MAXRETRY;
1021     int again = KBD_MAXWAIT;
1022     int c = -1;
1023 
1024     while (retry-- > 0) {
1025         empty_both_buffers(p, 10);
1026         if (write_controller_command(p, KBDC_TEST_KBD_PORT))
1027     	    break;
1028     }
1029     if (retry < 0)
1030         return FALSE;
1031 
1032     emptyq(&kbdcp(p)->kbd);
1033     while (again-- > 0) {
1034         c = read_controller_data(p);
1035         if (c != -1) 	/* try again if the controller is not ready */
1036     	    break;
1037     }
1038     if (verbose || bootverbose)
1039         log(LOG_DEBUG, "kbdc: TEST_KBD_PORT status:%04x\n", c);
1040     return c;
1041 }
1042 
1043 int
1044 test_aux_port(KBDC p)
1045 {
1046     int retry = KBD_MAXRETRY;
1047     int again = KBD_MAXWAIT;
1048     int c = -1;
1049 
1050     while (retry-- > 0) {
1051         empty_both_buffers(p, 10);
1052         if (write_controller_command(p, KBDC_TEST_AUX_PORT))
1053     	    break;
1054     }
1055     if (retry < 0)
1056         return FALSE;
1057 
1058     emptyq(&kbdcp(p)->kbd);
1059     while (again-- > 0) {
1060         c = read_controller_data(p);
1061         if (c != -1) 	/* try again if the controller is not ready */
1062     	    break;
1063     }
1064     if (verbose || bootverbose)
1065         log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c);
1066     return c;
1067 }
1068 
1069 int
1070 get_controller_command_byte(KBDC p)
1071 {
1072     if (kbdcp(p)->command_byte != -1)
1073 	return kbdcp(p)->command_byte;
1074     if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
1075 	return -1;
1076     emptyq(&kbdcp(p)->kbd);
1077     kbdcp(p)->command_byte = read_controller_data(p);
1078     return kbdcp(p)->command_byte;
1079 }
1080 
1081 int
1082 set_controller_command_byte(KBDC p, int mask, int command)
1083 {
1084     if (get_controller_command_byte(p) == -1)
1085 	return FALSE;
1086 
1087     command = (kbdcp(p)->command_byte & ~mask) | (command & mask);
1088 #if 0
1089     if (mask & KBD_DISABLE_KBD_PORT) {
1090 	    if (command & KBD_DISABLE_KBD_PORT) {
1091 		if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT))
1092 		    return FALSE;
1093 	    }
1094     }
1095 #endif
1096     if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE))
1097 	return FALSE;
1098     if (!write_controller_data(p, command))
1099 	return FALSE;
1100 #if 0
1101     if (mask & KBD_DISABLE_KBD_PORT) {
1102 	    if ((command & KBD_DISABLE_KBD_PORT) == 0) {
1103 		if (!write_controller_command(p, KBDC_ENABLE_KBD_PORT))
1104 		    return FALSE;
1105 	    }
1106     }
1107 #endif
1108     kbdcp(p)->command_byte = command;
1109 
1110     if (verbose)
1111         log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n",
1112 	    command);
1113 
1114     return TRUE;
1115 }
1116