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