2 * Copyright (c) 1996-1999
3 * Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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
31 * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/syslog.h>
43 #include <machine/clock.h>
45 #include <dev/kbd/atkbdcreg.h>
47 #include <isa/isareg.h>
51 #define MAXKBDC MAX(NATKBDC, 1)
56 #define MAX(x, y) ((x) > (y) ? (x) : (y))
59 #define kbdcp(p) ((atkbdc_softc_t *)(p))
60 #define nextq(i) (((i) + 1) % KBDQ_BUFSIZE)
61 #define availq(q) ((q)->head != (q)->tail)
63 #define emptyq(q) ((q)->tail = (q)->head = (q)->qcount = 0)
65 #define emptyq(q) ((q)->tail = (q)->head = 0)
71 * We always need at least one copy of the kbdc_softc struct for the
72 * low-level console. As the low-level console accesses the keyboard
73 * controller before kbdc, and all other devices, is probed, we
74 * statically allocate one entry. XXX
76 static atkbdc_softc_t default_kbdc;
77 static atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc };
79 static int verbose = KBDIO_DEBUG;
81 /* function prototypes */
83 static int atkbdc_setup(atkbdc_softc_t *sc, int port);
84 static int addq(kqueue *q, int c);
85 static int removeq(kqueue *q);
86 static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
87 static int wait_for_data(atkbdc_softc_t *kbdc);
88 static int wait_for_kbd_data(atkbdc_softc_t *kbdc);
89 static int wait_for_kbd_ack(atkbdc_softc_t *kbdc);
90 static int wait_for_aux_data(atkbdc_softc_t *kbdc);
91 static int wait_for_aux_ack(atkbdc_softc_t *kbdc);
96 *atkbdc_get_softc(int unit)
100 if (unit >= sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0]))
102 sc = atkbdc_softc[unit];
104 sc = atkbdc_softc[unit]
105 = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
108 bzero(sc, sizeof(*sc));
109 sc->port = -1; /* XXX */
115 atkbdc_probe_unit(int unit, int port)
123 atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, int port)
125 return atkbdc_setup(sc, port);
128 #endif /* NATKBDC > 0 */
130 /* the backdoor to the keyboard controller! XXX */
132 atkbdc_configure(void)
134 return atkbdc_setup(atkbdc_softc[0], -1);
138 atkbdc_setup(atkbdc_softc_t *sc, int port)
144 sc->command_byte = -1;
145 sc->command_mask = 0;
147 sc->kbd.head = sc->kbd.tail = 0;
148 sc->aux.head = sc->aux.tail = 0;
150 sc->kbd.call_count = 0;
151 sc->kbd.qcount = sc->kbd.max_qcount = 0;
152 sc->aux.call_count = 0;
153 sc->aux.qcount = sc->aux.max_qcount = 0;
156 sc->port = port; /* may override the previous value */
160 /* associate a port number with a KBDC */
172 for (i = 0; i < sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0]); ++i) {
173 if (atkbdc_softc[i] == NULL)
175 if (atkbdc_softc[i]->port == port) {
177 return (KBDC)atkbdc_softc[i];
179 if (atkbdc_softc[i]->port <= 0) {
180 if (atkbdc_setup(atkbdc_softc[i], port))
183 return (KBDC)atkbdc_softc[i];
191 * I/O access arbitration in `kbdio'
193 * The `kbdio' module uses a simplistic convention to arbitrate
194 * I/O access to the controller/keyboard/mouse. The convention requires
195 * close cooperation of the calling device driver.
197 * The device driver which utilizes the `kbdio' module are assumed to
198 * have the following set of routines.
199 * a. An interrupt handler (the bottom half of the driver).
200 * b. Timeout routines which may briefly polls the keyboard controller.
201 * c. Routines outside interrupt context (the top half of the driver).
202 * They should follow the rules below:
203 * 1. The interrupt handler may assume that it always has full access
204 * to the controller/keyboard/mouse.
205 * 2. The other routines must issue `spltty()' if they wish to
206 * prevent the interrupt handler from accessing
207 * the controller/keyboard/mouse.
208 * 3. The timeout routines and the top half routines of the device driver
209 * arbitrate I/O access by observing the lock flag in `kbdio'.
210 * The flag is manipulated via `kbdc_lock()'; when one wants to
211 * perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if
212 * the call returns with TRUE. Otherwise the caller must back off.
213 * Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion
214 * is finished. This mechanism does not prevent the interrupt
215 * handler from being invoked at any time and carrying out I/O.
216 * Therefore, `spltty()' must be strategically placed in the device
217 * driver code. Also note that the timeout routine may interrupt
218 * `kbdc_lock()' called by the top half of the driver, but this
219 * interruption is OK so long as the timeout routine observes the
221 * 4. The interrupt and timeout routines should not extend I/O operation
222 * across more than one interrupt or timeout; they must complete
223 * necessary I/O operation within one invokation of the routine.
224 * This measns that if the timeout routine acquires the lock flag,
225 * it must reset the flag to FALSE before it returns.
228 /* set/reset polling lock */
230 kbdc_lock(KBDC p, int lock)
234 prevlock = kbdcp(p)->lock;
235 kbdcp(p)->lock = lock;
237 return (prevlock != lock);
240 /* check if any data is waiting to be processed */
242 kbdc_data_ready(KBDC p)
244 return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux)
245 || (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL));
248 /* queuing functions */
251 addq(kqueue *q, int c)
253 if (nextq(q->tail) != q->head) {
255 q->tail = nextq(q->tail);
259 if (q->qcount > q->max_qcount)
260 q->max_qcount = q->qcount;
272 if (q->tail != q->head) {
274 q->head = nextq(q->head);
284 * device I/O routines
287 wait_while_controller_busy(struct atkbdc_softc *kbdc)
289 /* CPU will stay inside the loop for 100msec at most */
291 int port = kbdc->port;
294 while ((f = inb(port + KBD_STATUS_PORT)) & KBDS_INPUT_BUFFER_FULL) {
295 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
296 DELAY(KBDD_DELAYTIME);
297 addq(&kbdc->kbd, inb(port + KBD_DATA_PORT));
298 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
299 DELAY(KBDD_DELAYTIME);
300 addq(&kbdc->aux, inb(port + KBD_DATA_PORT));
302 DELAY(KBDC_DELAYTIME);
310 * wait for any data; whether it's from the controller,
311 * the keyboard, or the aux device.
314 wait_for_data(struct atkbdc_softc *kbdc)
316 /* CPU will stay inside the loop for 200msec at most */
318 int port = kbdc->port;
321 while ((f = inb(port + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) == 0) {
322 DELAY(KBDC_DELAYTIME);
326 DELAY(KBDD_DELAYTIME);
330 /* wait for data from the keyboard */
332 wait_for_kbd_data(struct atkbdc_softc *kbdc)
334 /* CPU will stay inside the loop for 200msec at most */
336 int port = kbdc->port;
339 while ((f = inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
340 != KBDS_KBD_BUFFER_FULL) {
341 if (f == KBDS_AUX_BUFFER_FULL) {
342 DELAY(KBDD_DELAYTIME);
343 addq(&kbdc->aux, inb(port + KBD_DATA_PORT));
345 DELAY(KBDC_DELAYTIME);
349 DELAY(KBDD_DELAYTIME);
354 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard.
355 * queue anything else.
358 wait_for_kbd_ack(struct atkbdc_softc *kbdc)
360 /* CPU will stay inside the loop for 200msec at most */
362 int port = kbdc->port;
366 while (retry-- > 0) {
367 if ((f = inb(port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
368 DELAY(KBDD_DELAYTIME);
369 b = inb(port + KBD_DATA_PORT);
370 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
371 if ((b == KBD_ACK) || (b == KBD_RESEND)
372 || (b == KBD_RESET_FAIL))
375 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
379 DELAY(KBDC_DELAYTIME);
384 /* wait for data from the aux device */
386 wait_for_aux_data(struct atkbdc_softc *kbdc)
388 /* CPU will stay inside the loop for 200msec at most */
390 int port = kbdc->port;
393 while ((f = inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)
394 != KBDS_AUX_BUFFER_FULL) {
395 if (f == KBDS_KBD_BUFFER_FULL) {
396 DELAY(KBDD_DELAYTIME);
397 addq(&kbdc->kbd, inb(port + KBD_DATA_PORT));
399 DELAY(KBDC_DELAYTIME);
403 DELAY(KBDD_DELAYTIME);
408 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device.
409 * queue anything else.
412 wait_for_aux_ack(struct atkbdc_softc *kbdc)
414 /* CPU will stay inside the loop for 200msec at most */
416 int port = kbdc->port;
420 while (retry-- > 0) {
421 if ((f = inb(port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
422 DELAY(KBDD_DELAYTIME);
423 b = inb(port + KBD_DATA_PORT);
424 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
425 if ((b == PSM_ACK) || (b == PSM_RESEND)
426 || (b == PSM_RESET_FAIL))
429 } else if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
433 DELAY(KBDC_DELAYTIME);
438 /* write a one byte command to the controller */
440 write_controller_command(KBDC p, int c)
442 if (!wait_while_controller_busy(kbdcp(p)))
444 outb(kbdcp(p)->port + KBD_COMMAND_PORT, c);
448 /* write a one byte data to the controller */
450 write_controller_data(KBDC p, int c)
452 if (!wait_while_controller_busy(kbdcp(p)))
454 outb(kbdcp(p)->port + KBD_DATA_PORT, c);
458 /* write a one byte keyboard command */
460 write_kbd_command(KBDC p, int c)
462 if (!wait_while_controller_busy(kbdcp(p)))
464 outb(kbdcp(p)->port + KBD_DATA_PORT, c);
468 /* write a one byte auxiliary device command */
470 write_aux_command(KBDC p, int c)
472 if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
474 return write_controller_data(p, c);
477 /* send a command to the keyboard and wait for ACK */
479 send_kbd_command(KBDC p, int c)
481 int retry = KBD_MAXRETRY;
484 while (retry-- > 0) {
485 if (!write_kbd_command(p, c))
487 res = wait_for_kbd_ack(kbdcp(p));
494 /* send a command to the auxiliary device and wait for ACK */
496 send_aux_command(KBDC p, int c)
498 int retry = KBD_MAXRETRY;
501 while (retry-- > 0) {
502 if (!write_aux_command(p, c))
506 * The aux device may have already sent one or two bytes of
507 * status data, when a command is received. It will immediately
508 * stop data transmission, thus, leaving an incomplete data
509 * packet in our buffer. We have to discard any unprocessed
510 * data in order to remove such packets. Well, we may remove
511 * unprocessed, but necessary data byte as well...
513 emptyq(&kbdcp(p)->aux);
514 res = wait_for_aux_ack(kbdcp(p));
521 /* send a command and a data to the keyboard, wait for ACKs */
523 send_kbd_command_and_data(KBDC p, int c, int d)
528 for (retry = KBD_MAXRETRY; retry > 0; --retry) {
529 if (!write_kbd_command(p, c))
531 res = wait_for_kbd_ack(kbdcp(p));
534 else if (res != KBD_RESEND)
540 for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
541 if (!write_kbd_command(p, d))
543 res = wait_for_kbd_ack(kbdcp(p));
544 if (res != KBD_RESEND)
550 /* send a command and a data to the auxiliary device, wait for ACKs */
552 send_aux_command_and_data(KBDC p, int c, int d)
557 for (retry = KBD_MAXRETRY; retry > 0; --retry) {
558 if (!write_aux_command(p, c))
560 emptyq(&kbdcp(p)->aux);
561 res = wait_for_aux_ack(kbdcp(p));
564 else if (res != PSM_RESEND)
570 for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
571 if (!write_aux_command(p, d))
573 res = wait_for_aux_ack(kbdcp(p));
574 if (res != PSM_RESEND)
581 * read one byte from any source; whether from the controller,
582 * the keyboard, or the aux device
585 read_controller_data(KBDC p)
587 if (availq(&kbdcp(p)->kbd))
588 return removeq(&kbdcp(p)->kbd);
589 if (availq(&kbdcp(p)->aux))
590 return removeq(&kbdcp(p)->aux);
591 if (!wait_for_data(kbdcp(p)))
592 return -1; /* timeout */
593 return inb(kbdcp(p)->port + KBD_DATA_PORT);
600 /* read one byte from the keyboard */
602 read_kbd_data(KBDC p)
607 log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
608 "aux q: %d calls, max %d chars\n",
609 kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
610 kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
614 if (availq(&kbdcp(p)->kbd))
615 return removeq(&kbdcp(p)->kbd);
616 if (!wait_for_kbd_data(kbdcp(p)))
617 return -1; /* timeout */
618 return inb(kbdcp(p)->port + KBD_DATA_PORT);
621 /* read one byte from the keyboard, but return immediately if
625 read_kbd_data_no_wait(KBDC p)
632 log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
633 "aux q: %d calls, max %d chars\n",
634 kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
635 kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
639 if (availq(&kbdcp(p)->kbd))
640 return removeq(&kbdcp(p)->kbd);
641 f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
642 if (f == KBDS_AUX_BUFFER_FULL) {
643 DELAY(KBDD_DELAYTIME);
644 addq(&kbdcp(p)->aux, inb(kbdcp(p)->port + KBD_DATA_PORT));
645 f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
647 if (f == KBDS_KBD_BUFFER_FULL) {
648 DELAY(KBDD_DELAYTIME);
649 return inb(kbdcp(p)->port + KBD_DATA_PORT);
651 return -1; /* no data */
654 /* read one byte from the aux device */
656 read_aux_data(KBDC p)
658 if (availq(&kbdcp(p)->aux))
659 return removeq(&kbdcp(p)->aux);
660 if (!wait_for_aux_data(kbdcp(p)))
661 return -1; /* timeout */
662 return inb(kbdcp(p)->port + KBD_DATA_PORT);
665 /* read one byte from the aux device, but return immediately if
669 read_aux_data_no_wait(KBDC p)
673 if (availq(&kbdcp(p)->aux))
674 return removeq(&kbdcp(p)->aux);
675 f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
676 if (f == KBDS_KBD_BUFFER_FULL) {
677 DELAY(KBDD_DELAYTIME);
678 addq(&kbdcp(p)->kbd, inb(kbdcp(p)->port + KBD_DATA_PORT));
679 f = inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL;
681 if (f == KBDS_AUX_BUFFER_FULL) {
682 DELAY(KBDD_DELAYTIME);
683 return inb(kbdcp(p)->port + KBD_DATA_PORT);
685 return -1; /* no data */
688 /* discard data from the keyboard */
690 empty_kbd_buffer(KBDC p, int wait)
701 for (t = wait; t > 0; ) {
702 if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
703 DELAY(KBDD_DELAYTIME);
704 b = inb(kbdcp(p)->port + KBD_DATA_PORT);
705 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
706 addq(&kbdcp(p)->aux, b);
720 if ((c1 > 0) || (c2 > 0))
721 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_kbd_buffer)\n", c1, c2);
724 emptyq(&kbdcp(p)->kbd);
727 /* discard data from the aux device */
729 empty_aux_buffer(KBDC p, int wait)
740 for (t = wait; t > 0; ) {
741 if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
742 DELAY(KBDD_DELAYTIME);
743 b = inb(kbdcp(p)->port + KBD_DATA_PORT);
744 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
745 addq(&kbdcp(p)->kbd, b);
759 if ((c1 > 0) || (c2 > 0))
760 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_aux_buffer)\n", c1, c2);
763 emptyq(&kbdcp(p)->aux);
766 /* discard any data from the keyboard or the aux device */
768 empty_both_buffers(KBDC p, int wait)
778 for (t = wait; t > 0; ) {
779 if ((f = inb(kbdcp(p)->port + KBD_STATUS_PORT)) & KBDS_ANY_BUFFER_FULL) {
780 DELAY(KBDD_DELAYTIME);
781 (void)inb(kbdcp(p)->port + KBD_DATA_PORT);
783 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL)
795 if ((c1 > 0) || (c2 > 0))
796 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_both_buffers)\n", c1, c2);
799 emptyq(&kbdcp(p)->kbd);
800 emptyq(&kbdcp(p)->aux);
803 /* keyboard and mouse device control */
805 /* NOTE: enable the keyboard port but disable the keyboard
806 * interrupt before calling "reset_kbd()".
811 int retry = KBD_MAXRETRY;
812 int again = KBD_MAXWAIT;
813 int c = KBD_RESEND; /* keep the compiler happy */
815 while (retry-- > 0) {
816 empty_both_buffers(p, 10);
817 if (!write_kbd_command(p, KBDC_RESET_KBD))
819 emptyq(&kbdcp(p)->kbd);
820 c = read_controller_data(p);
821 if (verbose || bootverbose)
822 log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c);
823 if (c == KBD_ACK) /* keyboard has agreed to reset itself... */
829 while (again-- > 0) {
830 /* wait awhile, well, in fact we must wait quite loooooooooooong */
831 DELAY(KBD_RESETDELAY*1000);
832 c = read_controller_data(p); /* RESET_DONE/RESET_FAIL */
833 if (c != -1) /* wait again if the controller is not ready */
836 if (verbose || bootverbose)
837 log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c);
838 if (c != KBD_RESET_DONE)
843 /* NOTE: enable the aux port but disable the aux interrupt
844 * before calling `reset_aux_dev()'.
847 reset_aux_dev(KBDC p)
849 int retry = KBD_MAXRETRY;
850 int again = KBD_MAXWAIT;
851 int c = PSM_RESEND; /* keep the compiler happy */
853 while (retry-- > 0) {
854 empty_both_buffers(p, 10);
855 if (!write_aux_command(p, PSMC_RESET_DEV))
857 emptyq(&kbdcp(p)->aux);
858 /* NOTE: Compaq Armada laptops require extra delay here. XXX */
859 for (again = KBD_MAXWAIT; again > 0; --again) {
860 DELAY(KBD_RESETDELAY*1000);
861 c = read_aux_data_no_wait(p);
865 if (verbose || bootverbose)
866 log(LOG_DEBUG, "kbdc: RESET_AUX return code:%04x\n", c);
867 if (c == PSM_ACK) /* aux dev is about to reset... */
873 for (again = KBD_MAXWAIT; again > 0; --again) {
874 /* wait awhile, well, quite looooooooooooong */
875 DELAY(KBD_RESETDELAY*1000);
876 c = read_aux_data_no_wait(p); /* RESET_DONE/RESET_FAIL */
877 if (c != -1) /* wait again if the controller is not ready */
880 if (verbose || bootverbose)
881 log(LOG_DEBUG, "kbdc: RESET_AUX status:%04x\n", c);
882 if (c != PSM_RESET_DONE) /* reset status */
885 c = read_aux_data(p); /* device ID */
886 if (verbose || bootverbose)
887 log(LOG_DEBUG, "kbdc: RESET_AUX ID:%04x\n", c);
888 /* NOTE: we could check the device ID now, but leave it later... */
892 /* controller diagnostics and setup */
895 test_controller(KBDC p)
897 int retry = KBD_MAXRETRY;
898 int again = KBD_MAXWAIT;
899 int c = KBD_DIAG_FAIL;
901 while (retry-- > 0) {
902 empty_both_buffers(p, 10);
903 if (write_controller_command(p, KBDC_DIAGNOSE))
909 emptyq(&kbdcp(p)->kbd);
910 while (again-- > 0) {
912 DELAY(KBD_RESETDELAY*1000);
913 c = read_controller_data(p); /* DIAG_DONE/DIAG_FAIL */
914 if (c != -1) /* wait again if the controller is not ready */
917 if (verbose || bootverbose)
918 log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c);
919 return (c == KBD_DIAG_DONE);
923 test_kbd_port(KBDC p)
925 int retry = KBD_MAXRETRY;
926 int again = KBD_MAXWAIT;
929 while (retry-- > 0) {
930 empty_both_buffers(p, 10);
931 if (write_controller_command(p, KBDC_TEST_KBD_PORT))
937 emptyq(&kbdcp(p)->kbd);
938 while (again-- > 0) {
939 c = read_controller_data(p);
940 if (c != -1) /* try again if the controller is not ready */
943 if (verbose || bootverbose)
944 log(LOG_DEBUG, "kbdc: TEST_KBD_PORT status:%04x\n", c);
949 test_aux_port(KBDC p)
951 int retry = KBD_MAXRETRY;
952 int again = KBD_MAXWAIT;
955 while (retry-- > 0) {
956 empty_both_buffers(p, 10);
957 if (write_controller_command(p, KBDC_TEST_AUX_PORT))
963 emptyq(&kbdcp(p)->kbd);
964 while (again-- > 0) {
965 c = read_controller_data(p);
966 if (c != -1) /* try again if the controller is not ready */
969 if (verbose || bootverbose)
970 log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c);
975 kbdc_get_device_mask(KBDC p)
977 return kbdcp(p)->command_mask;
981 kbdc_set_device_mask(KBDC p, int mask)
983 kbdcp(p)->command_mask =
984 mask & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS);
988 get_controller_command_byte(KBDC p)
990 if (kbdcp(p)->command_byte != -1)
991 return kbdcp(p)->command_byte;
992 if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
994 emptyq(&kbdcp(p)->kbd);
995 kbdcp(p)->command_byte = read_controller_data(p);
996 return kbdcp(p)->command_byte;
1000 set_controller_command_byte(KBDC p, int mask, int command)
1002 if (get_controller_command_byte(p) == -1)
1005 command = (kbdcp(p)->command_byte & ~mask) | (command & mask);
1006 if (command & KBD_DISABLE_KBD_PORT) {
1007 if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT))
1010 if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE))
1012 if (!write_controller_data(p, command))
1014 kbdcp(p)->command_byte = command;
1017 log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n",