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