The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/atkbdc/atkbdc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (c) 1996-1999
    5  * Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote 
   17  *    products derived from this software without specific prior written 
   18  *    permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp
   33  */
   34 
   35 #include <sys/cdefs.h>
   36 __FBSDID("$FreeBSD$");
   37 
   38 #include "opt_kbd.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/bus.h>
   43 #include <sys/malloc.h>
   44 #include <sys/syslog.h>
   45 #include <machine/bus.h>
   46 #include <machine/resource.h>
   47 #include <sys/rman.h>
   48 
   49 #if defined(__amd64__)
   50 #include <machine/clock.h>
   51 #endif
   52 
   53 #include <dev/atkbdc/atkbdcreg.h>
   54 
   55 #include <isa/isareg.h>
   56 
   57 /* constants */
   58 
   59 #define MAXKBDC         1               /* XXX */
   60 
   61 /* macros */
   62 
   63 #ifndef MAX
   64 #define MAX(x, y)       ((x) > (y) ? (x) : (y))
   65 #endif
   66 
   67 #define nextq(i)        (((i) + 1) % KBDQ_BUFSIZE)
   68 #define availq(q)       ((q)->head != (q)->tail)
   69 #if KBDIO_DEBUG >= 2
   70 #define emptyq(q)       ((q)->tail = (q)->head = (q)->qcount = 0)
   71 #else
   72 #define emptyq(q)       ((q)->tail = (q)->head = 0)
   73 #endif
   74 
   75 #define read_data(k)    (bus_space_read_1((k)->iot, (k)->ioh0, 0))
   76 #define read_status(k)  (bus_space_read_1((k)->iot, (k)->ioh1, 0))
   77 #define write_data(k, d)        \
   78                         (bus_space_write_1((k)->iot, (k)->ioh0, 0, (d)))
   79 #define write_command(k, d)     \
   80                         (bus_space_write_1((k)->iot, (k)->ioh1, 0, (d)))
   81 
   82 /* local variables */
   83 
   84 /*
   85  * We always need at least one copy of the kbdc_softc struct for the
   86  * low-level console.  As the low-level console accesses the keyboard
   87  * controller before kbdc, and all other devices, is probed, we
   88  * statically allocate one entry. XXX
   89  */
   90 static atkbdc_softc_t default_kbdc;
   91 static atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc };
   92 
   93 static int verbose = KBDIO_DEBUG;
   94 
   95 /* function prototypes */
   96 
   97 static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
   98                         bus_space_handle_t h0, bus_space_handle_t h1);
   99 static int addq(kqueue *q, int c);
  100 static int removeq(kqueue *q);
  101 static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
  102 static int wait_for_data(atkbdc_softc_t *kbdc);
  103 static int wait_for_kbd_data(atkbdc_softc_t *kbdc);
  104 static int wait_for_kbd_ack(atkbdc_softc_t *kbdc);
  105 static int wait_for_aux_data(atkbdc_softc_t *kbdc);
  106 static int wait_for_aux_ack(atkbdc_softc_t *kbdc);
  107 
  108 struct atkbdc_quirks {
  109     const char* bios_vendor;
  110     const char* maker;
  111     const char* product;
  112     int         quirk;
  113 };
  114 
  115 static struct atkbdc_quirks quirks[] = {
  116     {"coreboot", "System76", NULL, 0},
  117     {"coreboot", NULL, NULL,
  118         KBDC_QUIRK_KEEP_ACTIVATED | KBDC_QUIRK_IGNORE_PROBE_RESULT |
  119         KBDC_QUIRK_RESET_AFTER_PROBE | KBDC_QUIRK_SETLEDS_ON_INIT},
  120     /* KBDC hangs on Lenovo X120e and X121e after disabling AUX MUX */
  121     {NULL, "LENOVO", NULL, KBDC_QUIRK_DISABLE_MUX_PROBE},
  122 };
  123 
  124 #define QUIRK_STR_MATCH(s1, s2) (s1 == NULL || \
  125     (s2 != NULL && !strcmp(s1, s2)))
  126 
  127 static int
  128 atkbdc_getquirks(void)
  129 {
  130     int i;
  131     char* bios_vendor = kern_getenv("smbios.bios.vendor");
  132     char* maker = kern_getenv("smbios.system.maker");
  133     char* product = kern_getenv("smbios.system.product");
  134 
  135     for (i = 0; i < nitems(quirks); i++)
  136         if (QUIRK_STR_MATCH(quirks[i].bios_vendor, bios_vendor) &&
  137             QUIRK_STR_MATCH(quirks[i].maker, maker) &&
  138             QUIRK_STR_MATCH(quirks[i].product, product))
  139                 return (quirks[i].quirk);
  140 
  141     return (0);
  142 }
  143 
  144 atkbdc_softc_t
  145 *atkbdc_get_softc(int unit)
  146 {
  147         atkbdc_softc_t *sc;
  148 
  149         if (unit >= nitems(atkbdc_softc))
  150                 return NULL;
  151         sc = atkbdc_softc[unit];
  152         if (sc == NULL) {
  153                 sc = atkbdc_softc[unit]
  154                    = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO);
  155                 if (sc == NULL)
  156                         return NULL;
  157         }
  158         return sc;
  159 }
  160 
  161 int
  162 atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1)
  163 {
  164         if (rman_get_start(port0) <= 0)
  165                 return ENXIO;
  166         if (rman_get_start(port1) <= 0)
  167                 return ENXIO;
  168         return 0;
  169 }
  170 
  171 int
  172 atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
  173                    struct resource *port1)
  174 {
  175         return atkbdc_setup(sc, rman_get_bustag(port0),
  176                             rman_get_bushandle(port0),
  177                             rman_get_bushandle(port1));
  178 }
  179 
  180 /* the backdoor to the keyboard controller! XXX */
  181 int
  182 atkbdc_configure(void)
  183 {
  184         bus_space_tag_t tag;
  185         bus_space_handle_t h0;
  186         bus_space_handle_t h1;
  187 #if defined(__i386__) || defined(__amd64__)
  188         volatile int i;
  189         register_t flags;
  190 #endif
  191         int port0;
  192         int port1;
  193 
  194         /* XXX: tag should be passed from the caller */
  195 #if defined(__amd64__) || defined(__i386__)
  196         tag = X86_BUS_SPACE_IO;
  197 #else
  198 #error "define tag!"
  199 #endif
  200 
  201         port0 = IO_KBD;
  202         resource_int_value("atkbdc", 0, "port", &port0);
  203         port1 = IO_KBD + KBD_STATUS_PORT;
  204 #ifdef notyet
  205         bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
  206         bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
  207 #else
  208         h0 = (bus_space_handle_t)port0;
  209         h1 = (bus_space_handle_t)port1;
  210 #endif
  211 
  212 #if defined(__i386__) || defined(__amd64__)
  213         /*
  214          * Check if we really have AT keyboard controller. Poll status
  215          * register until we get "all clear" indication. If no such
  216          * indication comes, it probably means that there is no AT
  217          * keyboard controller present. Give up in such case. Check relies
  218          * on the fact that reading from non-existing in/out port returns
  219          * 0xff on i386. May or may not be true on other platforms.
  220          */
  221         flags = intr_disable();
  222         for (i = 0; i != 65535; i++) {
  223                 if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0)
  224                         break;
  225         }
  226         intr_restore(flags);
  227         if (i == 65535)
  228                 return ENXIO;
  229 #endif
  230 
  231         return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
  232 }
  233 
  234 static int
  235 atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0,
  236              bus_space_handle_t h1)
  237 {
  238 #if defined(__amd64__)
  239         u_int64_t tscval[3], read_delay;
  240         register_t flags;
  241 #endif
  242 
  243         if (sc->ioh0 == 0) {    /* XXX */
  244             sc->command_byte = -1;
  245             sc->command_mask = 0;
  246             sc->lock = FALSE;
  247             sc->kbd.head = sc->kbd.tail = 0;
  248             sc->aux.head = sc->aux.tail = 0;
  249             sc->aux_mux_enabled = FALSE;
  250 #if KBDIO_DEBUG >= 2
  251             sc->kbd.call_count = 0;
  252             sc->kbd.qcount = sc->kbd.max_qcount = 0;
  253             sc->aux.call_count = 0;
  254             sc->aux.qcount = sc->aux.max_qcount = 0;
  255 #endif
  256         }
  257         sc->iot = tag;
  258         sc->ioh0 = h0;
  259         sc->ioh1 = h1;
  260 
  261 #if defined(__amd64__)
  262         /*
  263          * On certain chipsets AT keyboard controller isn't present and is
  264          * emulated by BIOS using SMI interrupt. On those chipsets reading
  265          * from the status port may be thousand times slower than usually.
  266          * Sometimes this emilation is not working properly resulting in
  267          * commands timing our and since we assume that inb() operation 
  268          * takes very little time to complete we need to adjust number of
  269          * retries to keep waiting time within a designed limits (100ms).
  270          * Measure time it takes to make read_status() call and adjust
  271          * number of retries accordingly.
  272          */
  273         flags = intr_disable();
  274         tscval[0] = rdtsc();
  275         read_status(sc);
  276         tscval[1] = rdtsc();
  277         DELAY(1000);
  278         tscval[2] = rdtsc();
  279         intr_restore(flags);
  280         read_delay = tscval[1] - tscval[0];
  281         read_delay /= (tscval[2] - tscval[1]) / 1000;
  282         sc->retry = 100000 / ((KBDD_DELAYTIME * 2) + read_delay);
  283 #else
  284         sc->retry = 5000;
  285 #endif
  286         sc->quirks = atkbdc_getquirks();
  287 
  288         return 0;
  289 }
  290 
  291 /* open a keyboard controller */
  292 KBDC 
  293 atkbdc_open(int unit)
  294 {
  295     if (unit <= 0)
  296         unit = 0;
  297     if (unit >= MAXKBDC)
  298         return NULL;
  299     if ((atkbdc_softc[unit]->port0 != NULL)
  300         || (atkbdc_softc[unit]->ioh0 != 0))             /* XXX */
  301         return atkbdc_softc[unit];
  302     return NULL;
  303 }
  304 
  305 /*
  306  * I/O access arbitration in `kbdio'
  307  *
  308  * The `kbdio' module uses a simplistic convention to arbitrate
  309  * I/O access to the controller/keyboard/mouse. The convention requires
  310  * close cooperation of the calling device driver.
  311  *
  312  * The device drivers which utilize the `kbdio' module are assumed to
  313  * have the following set of routines.
  314  *    a. An interrupt handler (the bottom half of the driver).
  315  *    b. Timeout routines which may briefly poll the keyboard controller.
  316  *    c. Routines outside interrupt context (the top half of the driver).
  317  * They should follow the rules below:
  318  *    1. The interrupt handler may assume that it always has full access 
  319  *       to the controller/keyboard/mouse.
  320  *    2. The other routines must issue `spltty()' if they wish to 
  321  *       prevent the interrupt handler from accessing 
  322  *       the controller/keyboard/mouse.
  323  *    3. The timeout routines and the top half routines of the device driver
  324  *       arbitrate I/O access by observing the lock flag in `kbdio'.
  325  *       The flag is manipulated via `kbdc_lock()'; when one wants to
  326  *       perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if
  327  *       the call returns with TRUE. Otherwise the caller must back off.
  328  *       Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion
  329  *       is finished. This mechanism does not prevent the interrupt 
  330  *       handler from being invoked at any time and carrying out I/O.
  331  *       Therefore, `spltty()' must be strategically placed in the device
  332  *       driver code. Also note that the timeout routine may interrupt
  333  *       `kbdc_lock()' called by the top half of the driver, but this
  334  *       interruption is OK so long as the timeout routine observes
  335  *       rule 4 below.
  336  *    4. The interrupt and timeout routines should not extend I/O operation
  337  *       across more than one interrupt or timeout; they must complete any
  338  *       necessary I/O operation within one invocation of the routine.
  339  *       This means that if the timeout routine acquires the lock flag,
  340  *       it must reset the flag to FALSE before it returns.
  341  */
  342 
  343 /* set/reset polling lock */
  344 int 
  345 kbdc_lock(KBDC p, int lock)
  346 {
  347     int prevlock;
  348 
  349     prevlock = p->lock;
  350     p->lock = lock;
  351 
  352     return (prevlock != lock);
  353 }
  354 
  355 /* check if any data is waiting to be processed */
  356 int
  357 kbdc_data_ready(KBDC p)
  358 {
  359     return (availq(&p->kbd) || availq(&p->aux)
  360         || (read_status(p) & KBDS_ANY_BUFFER_FULL));
  361 }
  362 
  363 /* queuing functions */
  364 
  365 static int
  366 addq(kqueue *q, int c)
  367 {
  368     if (nextq(q->tail) != q->head) {
  369         q->q[q->tail] = c;
  370         q->tail = nextq(q->tail);
  371 #if KBDIO_DEBUG >= 2
  372         ++q->call_count;
  373         ++q->qcount;
  374         if (q->qcount > q->max_qcount)
  375             q->max_qcount = q->qcount;
  376 #endif
  377         return TRUE;
  378     }
  379     return FALSE;
  380 }
  381 
  382 static int
  383 removeq(kqueue *q)
  384 {
  385     int c;
  386 
  387     if (q->tail != q->head) {
  388         c = q->q[q->head];
  389         q->head = nextq(q->head);
  390 #if KBDIO_DEBUG >= 2
  391         --q->qcount;
  392 #endif
  393         return c;
  394     }
  395     return -1;
  396 }
  397 
  398 /* 
  399  * device I/O routines
  400  */
  401 static int
  402 wait_while_controller_busy(struct atkbdc_softc *kbdc)
  403 {
  404     int retry;
  405     int f;
  406 
  407     /* CPU will stay inside the loop for 100msec at most */
  408     retry = kbdc->retry;
  409 
  410     while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) {
  411         if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
  412             DELAY(KBDD_DELAYTIME);
  413             addq(&kbdc->kbd, read_data(kbdc));
  414         } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
  415             DELAY(KBDD_DELAYTIME);
  416             addq(&kbdc->aux, read_data(kbdc));
  417         }
  418         DELAY(KBDC_DELAYTIME);
  419         if (--retry < 0)
  420             return FALSE;
  421     }
  422     return TRUE;
  423 }
  424 
  425 /*
  426  * wait for any data; whether it's from the controller, 
  427  * the keyboard, or the aux device.
  428  */
  429 static int
  430 wait_for_data(struct atkbdc_softc *kbdc)
  431 {
  432     int retry;
  433     int f;
  434 
  435     /* CPU will stay inside the loop for 200msec at most */
  436     retry = kbdc->retry * 2;
  437 
  438     while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) {
  439         DELAY(KBDC_DELAYTIME);
  440         if (--retry < 0)
  441             return 0;
  442     }
  443     DELAY(KBDD_DELAYTIME);
  444     return f;
  445 }
  446 
  447 /* wait for data from the keyboard */
  448 static int
  449 wait_for_kbd_data(struct atkbdc_softc *kbdc)
  450 {
  451     int retry;
  452     int f;
  453 
  454     /* CPU will stay inside the loop for 200msec at most */
  455     retry = kbdc->retry * 2;
  456 
  457     while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
  458             != KBDS_KBD_BUFFER_FULL) {
  459         if (f == KBDS_AUX_BUFFER_FULL) {
  460             DELAY(KBDD_DELAYTIME);
  461             addq(&kbdc->aux, read_data(kbdc));
  462         }
  463         DELAY(KBDC_DELAYTIME);
  464         if (--retry < 0)
  465             return 0;
  466     }
  467     DELAY(KBDD_DELAYTIME);
  468     return f;
  469 }
  470 
  471 /* 
  472  * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard.
  473  * queue anything else.
  474  */
  475 static int
  476 wait_for_kbd_ack(struct atkbdc_softc *kbdc)
  477 {
  478     int retry;
  479     int f;
  480     int b;
  481 
  482     /* CPU will stay inside the loop for 200msec at most */
  483     retry = kbdc->retry * 2;
  484 
  485     while (retry-- > 0) {
  486         if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
  487             DELAY(KBDD_DELAYTIME);
  488             b = read_data(kbdc);
  489             if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
  490                 if ((b == KBD_ACK) || (b == KBD_RESEND) 
  491                     || (b == KBD_RESET_FAIL))
  492                     return b;
  493                 addq(&kbdc->kbd, b);
  494             } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
  495                 addq(&kbdc->aux, b);
  496             }
  497         }
  498         DELAY(KBDC_DELAYTIME);
  499     }
  500     return -1;
  501 }
  502 
  503 /* wait for data from the aux device */
  504 static int
  505 wait_for_aux_data(struct atkbdc_softc *kbdc)
  506 {
  507     int retry;
  508     int f;
  509 
  510     /* CPU will stay inside the loop for 200msec at most */
  511     retry = kbdc->retry * 2;
  512 
  513     while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
  514             != KBDS_AUX_BUFFER_FULL) {
  515         if (f == KBDS_KBD_BUFFER_FULL) {
  516             DELAY(KBDD_DELAYTIME);
  517             addq(&kbdc->kbd, read_data(kbdc));
  518         }
  519         DELAY(KBDC_DELAYTIME);
  520         if (--retry < 0)
  521             return 0;
  522     }
  523     DELAY(KBDD_DELAYTIME);
  524     return f;
  525 }
  526 
  527 /* 
  528  * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device.
  529  * queue anything else.
  530  */
  531 static int
  532 wait_for_aux_ack(struct atkbdc_softc *kbdc)
  533 {
  534     int retry;
  535     int f;
  536     int b;
  537 
  538     /* CPU will stay inside the loop for 200msec at most */
  539     retry = kbdc->retry * 2;
  540 
  541     while (retry-- > 0) {
  542         if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
  543             DELAY(KBDD_DELAYTIME);
  544             b = read_data(kbdc);
  545             if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
  546                 if ((b == PSM_ACK) || (b == PSM_RESEND) 
  547                     || (b == PSM_RESET_FAIL))
  548                     return b;
  549                 addq(&kbdc->aux, b);
  550             } else if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
  551                 addq(&kbdc->kbd, b);
  552             }
  553         }
  554         DELAY(KBDC_DELAYTIME);
  555     }
  556     return -1;
  557 }
  558 
  559 /* write a one byte command to the controller */
  560 int
  561 write_controller_command(KBDC p, int c)
  562 {
  563     if (!wait_while_controller_busy(p))
  564         return FALSE;
  565     write_command(p, c);
  566     return TRUE;
  567 }
  568 
  569 /* write a one byte data to the controller */
  570 int
  571 write_controller_data(KBDC p, int c)
  572 {
  573     if (!wait_while_controller_busy(p))
  574         return FALSE;
  575     write_data(p, c);
  576     return TRUE;
  577 }
  578 
  579 /* write a one byte keyboard command */
  580 int
  581 write_kbd_command(KBDC p, int c)
  582 {
  583     if (!wait_while_controller_busy(p))
  584         return FALSE;
  585     write_data(p, c);
  586     return TRUE;
  587 }
  588 
  589 /* write a one byte auxiliary device command */
  590 int
  591 write_aux_command(KBDC p, int c)
  592 {
  593     int f;
  594 
  595     f = aux_mux_is_enabled(p) ?
  596         KBDC_WRITE_TO_AUX_MUX + p->aux_mux_port : KBDC_WRITE_TO_AUX;
  597 
  598     if (!write_controller_command(p, f))
  599         return FALSE;
  600     return write_controller_data(p, c);
  601 }
  602 
  603 /* send a command to the keyboard and wait for ACK */
  604 int
  605 send_kbd_command(KBDC p, int c)
  606 {
  607     int retry = KBD_MAXRETRY;
  608     int res = -1;
  609 
  610     while (retry-- > 0) {
  611         if (!write_kbd_command(p, c))
  612             continue;
  613         res = wait_for_kbd_ack(p);
  614         if (res == KBD_ACK)
  615             break;
  616     }
  617     return res;
  618 }
  619 
  620 /* send a command to the auxiliary device and wait for ACK */
  621 int
  622 send_aux_command(KBDC p, int c)
  623 {
  624     int retry = KBD_MAXRETRY;
  625     int res = -1;
  626 
  627     while (retry-- > 0) {
  628         if (!write_aux_command(p, c))
  629             continue;
  630         /*
  631          * FIXME: XXX
  632          * The aux device may have already sent one or two bytes of 
  633          * status data, when a command is received. It will immediately 
  634          * stop data transmission, thus, leaving an incomplete data 
  635          * packet in our buffer. We have to discard any unprocessed
  636          * data in order to remove such packets. Well, we may remove 
  637          * unprocessed, but necessary data byte as well... 
  638          */
  639         emptyq(&p->aux);
  640         res = wait_for_aux_ack(p);
  641         if (res == PSM_ACK)
  642             break;
  643     }
  644     return res;
  645 }
  646 
  647 /* send a command and a data to the keyboard, wait for ACKs */
  648 int
  649 send_kbd_command_and_data(KBDC p, int c, int d)
  650 {
  651     int retry;
  652     int res = -1;
  653 
  654     for (retry = KBD_MAXRETRY; retry > 0; --retry) {
  655         if (!write_kbd_command(p, c))
  656             continue;
  657         res = wait_for_kbd_ack(p);
  658         if (res == KBD_ACK)
  659             break;
  660         else if (res != KBD_RESEND)
  661             return res;
  662     }
  663     if (retry <= 0)
  664         return res;
  665 
  666     for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
  667         if (!write_kbd_command(p, d))
  668             continue;
  669         res = wait_for_kbd_ack(p);
  670         if (res != KBD_RESEND)
  671             break;
  672     }
  673     return res;
  674 }
  675 
  676 /* send a command and a data to the auxiliary device, wait for ACKs */
  677 int
  678 send_aux_command_and_data(KBDC p, int c, int d)
  679 {
  680     int retry;
  681     int res = -1;
  682 
  683     for (retry = KBD_MAXRETRY; retry > 0; --retry) {
  684         if (!write_aux_command(p, c))
  685             continue;
  686         emptyq(&p->aux);
  687         res = wait_for_aux_ack(p);
  688         if (res == PSM_ACK)
  689             break;
  690         else if (res != PSM_RESEND)
  691             return res;
  692     }
  693     if (retry <= 0)
  694         return res;
  695 
  696     for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
  697         if (!write_aux_command(p, d))
  698             continue;
  699         res = wait_for_aux_ack(p);
  700         if (res != PSM_RESEND)
  701             break;
  702     }
  703     return res;
  704 }
  705 
  706 /* 
  707  * read one byte from any source; whether from the controller,
  708  * the keyboard, or the aux device
  709  */
  710 int
  711 read_controller_data(KBDC p)
  712 {
  713     if (availq(&p->kbd))
  714         return removeq(&p->kbd);
  715     if (availq(&p->aux))
  716         return removeq(&p->aux);
  717     if (!wait_for_data(p))
  718         return -1;              /* timeout */
  719     return read_data(p);
  720 }
  721 
  722 #if KBDIO_DEBUG >= 2
  723 static int call = 0;
  724 #endif
  725 
  726 /* read one byte from the keyboard */
  727 int
  728 read_kbd_data(KBDC p)
  729 {
  730 #if KBDIO_DEBUG >= 2
  731     if (++call > 2000) {
  732         call = 0;
  733         log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
  734                              "aux q: %d calls, max %d chars\n",
  735                        p->kbd.call_count, p->kbd.max_qcount,
  736                        p->aux.call_count, p->aux.max_qcount);
  737     }
  738 #endif
  739 
  740     if (availq(&p->kbd))
  741         return removeq(&p->kbd);
  742     if (!wait_for_kbd_data(p))
  743         return -1;              /* timeout */
  744     return read_data(p);
  745 }
  746 
  747 /* read one byte from the keyboard, but return immediately if 
  748  * no data is waiting
  749  */
  750 int
  751 read_kbd_data_no_wait(KBDC p)
  752 {
  753     int f;
  754 
  755 #if KBDIO_DEBUG >= 2
  756     if (++call > 2000) {
  757         call = 0;
  758         log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
  759                              "aux q: %d calls, max %d chars\n",
  760                        p->kbd.call_count, p->kbd.max_qcount,
  761                        p->aux.call_count, p->aux.max_qcount);
  762     }
  763 #endif
  764 
  765     if (availq(&p->kbd))
  766         return removeq(&p->kbd);
  767     f = read_status(p) & KBDS_BUFFER_FULL;
  768     if (f == KBDS_AUX_BUFFER_FULL) {
  769         DELAY(KBDD_DELAYTIME);
  770         addq(&p->aux, read_data(p));
  771         f = read_status(p) & KBDS_BUFFER_FULL;
  772     }
  773     if (f == KBDS_KBD_BUFFER_FULL) {
  774         DELAY(KBDD_DELAYTIME);
  775         return read_data(p);
  776     }
  777     return -1;          /* no data */
  778 }
  779 
  780 /* read one byte from the aux device */
  781 int
  782 read_aux_data(KBDC p)
  783 {
  784     if (availq(&p->aux))
  785         return removeq(&p->aux);
  786     if (!wait_for_aux_data(p))
  787         return -1;              /* timeout */
  788     return read_data(p);
  789 }
  790 
  791 /* read one byte from the aux device, but return immediately if 
  792  * no data is waiting
  793  */
  794 int
  795 read_aux_data_no_wait(KBDC p)
  796 {
  797     int f;
  798 
  799     if (availq(&p->aux))
  800         return removeq(&p->aux);
  801     f = read_status(p) & KBDS_BUFFER_FULL;
  802     if (f == KBDS_KBD_BUFFER_FULL) {
  803         DELAY(KBDD_DELAYTIME);
  804         addq(&p->kbd, read_data(p));
  805         f = read_status(p) & KBDS_BUFFER_FULL;
  806     }
  807     if (f == KBDS_AUX_BUFFER_FULL) {
  808         DELAY(KBDD_DELAYTIME);
  809         return read_data(p);
  810     }
  811     return -1;          /* no data */
  812 }
  813 
  814 /* discard data from the keyboard */
  815 void
  816 empty_kbd_buffer(KBDC p, int wait)
  817 {
  818     int t;
  819     int b;
  820     int f;
  821 #if KBDIO_DEBUG >= 2
  822     int c1 = 0;
  823     int c2 = 0;
  824 #endif
  825     int delta = 2;
  826 
  827     for (t = wait; t > 0; ) { 
  828         if ((f = read_status(p)) & KBDS_ANY_BUFFER_FULL) {
  829             DELAY(KBDD_DELAYTIME);
  830             b = read_data(p);
  831             if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
  832                 addq(&p->aux, b);
  833 #if KBDIO_DEBUG >= 2
  834                 ++c2;
  835             } else {
  836                 ++c1;
  837 #endif
  838             }
  839             t = wait;
  840         } else {
  841             t -= delta;
  842         }
  843         DELAY(delta*1000);
  844     }
  845 #if KBDIO_DEBUG >= 2
  846     if ((c1 > 0) || (c2 > 0))
  847         log(LOG_DEBUG, "kbdc: %d:%d char read (empty_kbd_buffer)\n", c1, c2);
  848 #endif
  849 
  850     emptyq(&p->kbd);
  851 }
  852 
  853 /* discard data from the aux device */
  854 void
  855 empty_aux_buffer(KBDC p, int wait)
  856 {
  857     int t;
  858     int b;
  859     int f;
  860 #if KBDIO_DEBUG >= 2
  861     int c1 = 0;
  862     int c2 = 0;
  863 #endif
  864     int delta = 2;
  865 
  866     for (t = wait; t > 0; ) { 
  867         if ((f = read_status(p)) & KBDS_ANY_BUFFER_FULL) {
  868             DELAY(KBDD_DELAYTIME);
  869             b = read_data(p);
  870             if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
  871                 addq(&p->kbd, b);
  872 #if KBDIO_DEBUG >= 2
  873                 ++c1;
  874             } else {
  875                 ++c2;
  876 #endif
  877             }
  878             t = wait;
  879         } else {
  880             t -= delta;
  881         }
  882         DELAY(delta*1000);
  883     }
  884 #if KBDIO_DEBUG >= 2
  885     if ((c1 > 0) || (c2 > 0))
  886         log(LOG_DEBUG, "kbdc: %d:%d char read (empty_aux_buffer)\n", c1, c2);
  887 #endif
  888 
  889     emptyq(&p->aux);
  890 }
  891 
  892 /* discard any data from the keyboard or the aux device */
  893 void
  894 empty_both_buffers(KBDC p, int wait)
  895 {
  896     int t;
  897     int f;
  898     int waited = 0;
  899 #if KBDIO_DEBUG >= 2
  900     int c1 = 0;
  901     int c2 = 0;
  902 #endif
  903     int delta = 2;
  904 
  905     for (t = wait; t > 0; ) { 
  906         if ((f = read_status(p)) & KBDS_ANY_BUFFER_FULL) {
  907             DELAY(KBDD_DELAYTIME);
  908             (void)read_data(p);
  909 #if KBDIO_DEBUG >= 2
  910             if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL)
  911                 ++c1;
  912             else
  913                 ++c2;
  914 #endif
  915             t = wait;
  916         } else {
  917             t -= delta;
  918         }
  919 
  920         /*
  921          * Some systems (Intel/IBM blades) do not have keyboard devices and
  922          * will thus hang in this procedure. Time out after delta seconds to
  923          * avoid this hang -- the keyboard attach will fail later on.
  924          */
  925         waited += (delta * 1000);
  926         if (waited == (delta * 1000000))
  927             return;
  928 
  929         DELAY(delta*1000);
  930     }
  931 #if KBDIO_DEBUG >= 2
  932     if ((c1 > 0) || (c2 > 0))
  933         log(LOG_DEBUG, "kbdc: %d:%d char read (empty_both_buffers)\n", c1, c2);
  934 #endif
  935 
  936     emptyq(&p->kbd);
  937     emptyq(&p->aux);
  938 }
  939 
  940 /* keyboard and mouse device control */
  941 
  942 /* NOTE: enable the keyboard port but disable the keyboard 
  943  * interrupt before calling "reset_kbd()".
  944  */
  945 int
  946 reset_kbd(KBDC p)
  947 {
  948     int retry = KBD_MAXRETRY;
  949     int again = KBD_MAXWAIT;
  950     int c = KBD_RESEND;         /* keep the compiler happy */
  951 
  952     while (retry-- > 0) {
  953         empty_both_buffers(p, 10);
  954         if (!write_kbd_command(p, KBDC_RESET_KBD))
  955             continue;
  956         emptyq(&p->kbd);
  957         c = read_controller_data(p);
  958         if (verbose || bootverbose)
  959             log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c);
  960         if (c == KBD_ACK)       /* keyboard has agreed to reset itself... */
  961             break;
  962     }
  963     if (retry < 0)
  964         return FALSE;
  965 
  966     while (again-- > 0) {
  967         /* wait awhile, well, in fact we must wait quite loooooooooooong */
  968         DELAY(KBD_RESETDELAY*1000);
  969         c = read_controller_data(p);    /* RESET_DONE/RESET_FAIL */
  970         if (c != -1)    /* wait again if the controller is not ready */
  971             break;
  972     }
  973     if (verbose || bootverbose)
  974         log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c);
  975     if (c != KBD_RESET_DONE)
  976         return FALSE;
  977     return TRUE;
  978 }
  979 
  980 /* NOTE: enable the aux port but disable the aux interrupt
  981  * before calling `reset_aux_dev()'.
  982  */
  983 int
  984 reset_aux_dev(KBDC p)
  985 {
  986     int retry = KBD_MAXRETRY;
  987     int again = KBD_MAXWAIT;
  988     int c = PSM_RESEND;         /* keep the compiler happy */
  989 
  990     while (retry-- > 0) {
  991         empty_both_buffers(p, 10);
  992         if (!write_aux_command(p, PSMC_RESET_DEV))
  993             continue;
  994         emptyq(&p->aux);
  995         /* NOTE: Compaq Armada laptops require extra delay here. XXX */
  996         for (again = KBD_MAXWAIT; again > 0; --again) {
  997             DELAY(KBD_RESETDELAY*1000);
  998             c = read_aux_data_no_wait(p);
  999             if (c != -1)
 1000                 break;
 1001         }
 1002         if (verbose || bootverbose)
 1003             log(LOG_DEBUG, "kbdc: RESET_AUX return code:%04x\n", c);
 1004         if (c == PSM_ACK)       /* aux dev is about to reset... */
 1005             break;
 1006     }
 1007     if (retry < 0)
 1008         return FALSE;
 1009 
 1010     for (again = KBD_MAXWAIT; again > 0; --again) {
 1011         /* wait awhile, well, quite looooooooooooong */
 1012         DELAY(KBD_RESETDELAY*1000);
 1013         c = read_aux_data_no_wait(p);   /* RESET_DONE/RESET_FAIL */
 1014         if (c != -1)    /* wait again if the controller is not ready */
 1015             break;
 1016     }
 1017     if (verbose || bootverbose)
 1018         log(LOG_DEBUG, "kbdc: RESET_AUX status:%04x\n", c);
 1019     if (c != PSM_RESET_DONE)    /* reset status */
 1020         return FALSE;
 1021 
 1022     c = read_aux_data(p);       /* device ID */
 1023     if (verbose || bootverbose)
 1024         log(LOG_DEBUG, "kbdc: RESET_AUX ID:%04x\n", c);
 1025     /* NOTE: we could check the device ID now, but leave it later... */
 1026     return TRUE;
 1027 }
 1028 
 1029 /* controller diagnostics and setup */
 1030 
 1031 int
 1032 test_controller(KBDC p)
 1033 {
 1034     int retry = KBD_MAXRETRY;
 1035     int again = KBD_MAXWAIT;
 1036     int c = KBD_DIAG_FAIL;
 1037 
 1038     while (retry-- > 0) {
 1039         empty_both_buffers(p, 10);
 1040         if (write_controller_command(p, KBDC_DIAGNOSE))
 1041             break;
 1042     }
 1043     if (retry < 0)
 1044         return FALSE;
 1045 
 1046     emptyq(&p->kbd);
 1047     while (again-- > 0) {
 1048         /* wait awhile */
 1049         DELAY(KBD_RESETDELAY*1000);
 1050         c = read_controller_data(p);    /* DIAG_DONE/DIAG_FAIL */
 1051         if (c != -1)    /* wait again if the controller is not ready */
 1052             break;
 1053     }
 1054     if (verbose || bootverbose)
 1055         log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c);
 1056     return (c == KBD_DIAG_DONE);
 1057 }
 1058 
 1059 int
 1060 test_kbd_port(KBDC p)
 1061 {
 1062     int retry = KBD_MAXRETRY;
 1063     int again = KBD_MAXWAIT;
 1064     int c = -1;
 1065 
 1066     while (retry-- > 0) {
 1067         empty_both_buffers(p, 10);
 1068         if (write_controller_command(p, KBDC_TEST_KBD_PORT))
 1069             break;
 1070     }
 1071     if (retry < 0)
 1072         return FALSE;
 1073 
 1074     emptyq(&p->kbd);
 1075     while (again-- > 0) {
 1076         c = read_controller_data(p);
 1077         if (c != -1)    /* try again if the controller is not ready */
 1078             break;
 1079     }
 1080     if (verbose || bootverbose)
 1081         log(LOG_DEBUG, "kbdc: TEST_KBD_PORT status:%04x\n", c);
 1082     return c;
 1083 }
 1084 
 1085 int
 1086 test_aux_port(KBDC p)
 1087 {
 1088     int retry = KBD_MAXRETRY;
 1089     int again = KBD_MAXWAIT;
 1090     int c = -1;
 1091 
 1092     while (retry-- > 0) {
 1093         empty_both_buffers(p, 10);
 1094         if (write_controller_command(p, KBDC_TEST_AUX_PORT))
 1095             break;
 1096     }
 1097     if (retry < 0)
 1098         return FALSE;
 1099 
 1100     emptyq(&p->kbd);
 1101     while (again-- > 0) {
 1102         c = read_controller_data(p);
 1103         if (c != -1)    /* try again if the controller is not ready */
 1104             break;
 1105     }
 1106     if (verbose || bootverbose)
 1107         log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c);
 1108     return c;
 1109 }
 1110 
 1111 int
 1112 kbdc_get_device_mask(KBDC p)
 1113 {
 1114     return p->command_mask;
 1115 }
 1116 
 1117 void
 1118 kbdc_set_device_mask(KBDC p, int mask)
 1119 {
 1120     p->command_mask =
 1121         mask & (((p->quirks & KBDC_QUIRK_KEEP_ACTIVATED)
 1122             ? 0 : KBD_KBD_CONTROL_BITS) | KBD_AUX_CONTROL_BITS);
 1123 }
 1124 
 1125 int
 1126 get_controller_command_byte(KBDC p)
 1127 {
 1128     if (p->command_byte != -1)
 1129         return p->command_byte;
 1130     if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
 1131         return -1;
 1132     emptyq(&p->kbd);
 1133     p->command_byte = read_controller_data(p);
 1134     return p->command_byte;
 1135 }
 1136 
 1137 int
 1138 set_controller_command_byte(KBDC p, int mask, int command)
 1139 {
 1140     if (get_controller_command_byte(p) == -1)
 1141         return FALSE;
 1142 
 1143     command = (p->command_byte & ~mask) | (command & mask);
 1144     if (command & KBD_DISABLE_KBD_PORT) {
 1145         if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT))
 1146             return FALSE;
 1147     }
 1148     if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE))
 1149         return FALSE;
 1150     if (!write_controller_data(p, command))
 1151         return FALSE;
 1152     p->command_byte = command;
 1153 
 1154     if (verbose)
 1155         log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n",
 1156             command);
 1157 
 1158     return TRUE;
 1159 }
 1160 
 1161 /*
 1162  * Rudimentary support for active PS/2 AUX port multiplexing.
 1163  * Only write commands can be routed to a selected AUX port.
 1164  * Source port of data processed by read commands is totally ignored.
 1165  */
 1166 static int
 1167 set_aux_mux_state(KBDC p, int enabled)
 1168 {
 1169         int command, version;
 1170 
 1171         if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
 1172             write_controller_data(p, 0xF0) == 0 ||
 1173             read_controller_data(p) != 0xF0)
 1174                 return (-1);
 1175 
 1176         if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
 1177             write_controller_data(p, 0x56) == 0 ||
 1178             read_controller_data(p) != 0x56)
 1179                 return (-1);
 1180 
 1181         command = enabled ? 0xa4 : 0xa5;
 1182         if (write_controller_command(p, KBDC_FORCE_AUX_OUTPUT) == 0 ||
 1183             write_controller_data(p, command) == 0 ||
 1184             (version = read_controller_data(p)) == command)
 1185                 return (-1);
 1186 
 1187         return (version);
 1188 }
 1189 
 1190 int
 1191 set_active_aux_mux_port(KBDC p, int port)
 1192 {
 1193 
 1194         if (!aux_mux_is_enabled(p))
 1195                 return (FALSE);
 1196 
 1197         if (port < 0 || port >= KBDC_AUX_MUX_NUM_PORTS)
 1198                 return (FALSE);
 1199 
 1200         p->aux_mux_port = port;
 1201 
 1202         return (TRUE);
 1203 }
 1204 
 1205 /* Checks for active multiplexing support and enables it */
 1206 int
 1207 enable_aux_mux(KBDC p)
 1208 {
 1209         int version;
 1210 
 1211         version = set_aux_mux_state(p, TRUE);
 1212         if (version >= 0) {
 1213                 p->aux_mux_enabled = TRUE;
 1214                 set_active_aux_mux_port(p, 0);
 1215         }
 1216 
 1217         return (version);
 1218 }
 1219 
 1220 int
 1221 disable_aux_mux(KBDC p)
 1222 {
 1223 
 1224         p->aux_mux_enabled = FALSE;
 1225 
 1226         return (set_aux_mux_state(p, FALSE));
 1227 }
 1228 
 1229 int
 1230 aux_mux_is_enabled(KBDC p)
 1231 {
 1232 
 1233         return (p->aux_mux_enabled);
 1234 }

Cache object: 7e22b1f7f3f2b5b55cb60a136b187ce3


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.