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