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