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