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