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