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