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