]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/kbd/atkbdc.c
This commit was generated by cvs2svn to compensate for changes in r147072,
[FreeBSD/FreeBSD.git] / sys / dev / kbd / atkbdc.c
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$");
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  */
86 static atkbdc_softc_t default_kbdc;
87 static atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc };
88
89 static int verbose = KBDIO_DEBUG;
90
91 /* function prototypes */
92
93 static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
94                         bus_space_handle_t h0, bus_space_handle_t h1);
95 static int addq(kqueue *q, int c);
96 static int removeq(kqueue *q);
97 static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
98 static int wait_for_data(atkbdc_softc_t *kbdc);
99 static int wait_for_kbd_data(atkbdc_softc_t *kbdc);
100 static int wait_for_kbd_ack(atkbdc_softc_t *kbdc);
101 static int wait_for_aux_data(atkbdc_softc_t *kbdc);
102 static int wait_for_aux_ack(atkbdc_softc_t *kbdc);
103
104 atkbdc_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
121 int
122 atkbdc_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
131 int
132 atkbdc_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 */
141 int
142 atkbdc_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
180 static int
181 atkbdc_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 */
204 KBDC 
205 atkbdc_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 */
256 int 
257 kbdc_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 */
268 int
269 kbdc_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
277 static int
278 addq(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
294 static int
295 removeq(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  */
313 static int
314 wait_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  */
339 static int
340 wait_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 */
356 static int
357 wait_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  */
381 static int
382 wait_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 */
408 static int
409 wait_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  */
433 static int
434 wait_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 */
460 int
461 write_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 */
470 int
471 write_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 */
480 int
481 write_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 */
490 int
491 write_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 */
499 int
500 send_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 */
516 int
517 send_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 */
543 int
544 send_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 */
572 int
573 send_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  */
605 int
606 read_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
618 static int call = 0;
619 #endif
620
621 /* read one byte from the keyboard */
622 int
623 read_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  */
645 int
646 read_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 */
676 int
677 read_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  */
689 int
690 read_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 */
710 void
711 empty_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 */
749 void
750 empty_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 */
788 void
789 empty_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  */
829 int
830 reset_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  */
867 int
868 reset_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
915 int
916 test_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
943 int
944 test_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
969 int
970 test_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
995 int
996 kbdc_get_device_mask(KBDC p)
997 {
998     return kbdcp(p)->command_mask;
999 }
1000
1001 void
1002 kbdc_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
1008 int
1009 get_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
1020 int
1021 set_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 }