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