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