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

Cache object: 98e989794ae218f26ea613848cd47702


[ 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.