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