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

Cache object: 536738a715feeda0b05e6be201f4b26d


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