atkbdc.c revision 114930
142421Syokota/*- 242421Syokota * Copyright (c) 1996-1999 342421Syokota * Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp) 442421Syokota * All rights reserved. 542421Syokota * 642421Syokota * Redistribution and use in source and binary forms, with or without 742421Syokota * modification, are permitted provided that the following conditions 842421Syokota * are met: 942421Syokota * 1. Redistributions of source code must retain the above copyright 1042421Syokota * notice, this list of conditions and the following disclaimer. 1142421Syokota * 2. Redistributions in binary form must reproduce the above copyright 1242421Syokota * notice, this list of conditions and the following disclaimer in the 1342421Syokota * documentation and/or other materials provided with the distribution. 1442421Syokota * 3. The name of the author may not be used to endorse or promote 1542421Syokota * products derived from this software without specific prior written 1642421Syokota * permission. 1742421Syokota * 1842421Syokota * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1942421Syokota * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2042421Syokota * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2142421Syokota * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2242421Syokota * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2342421Syokota * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2442421Syokota * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2542421Syokota * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2642421Syokota * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2742421Syokota * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2842421Syokota * SUCH DAMAGE. 2942421Syokota * 3050477Speter * $FreeBSD: head/sys/dev/atkbdc/atkbdc.c 114930 2003-05-12 02:44:37Z peter $ 3142421Syokota * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp 3242421Syokota */ 3342421Syokota 3442421Syokota#include "opt_kbd.h" 3542421Syokota 3642421Syokota#include <sys/param.h> 3742421Syokota#include <sys/systm.h> 3858271Syokota#include <sys/bus.h> 3942421Syokota#include <sys/malloc.h> 4042421Syokota#include <sys/syslog.h> 4158271Syokota#include <machine/bus_pio.h> 4258271Syokota#include <machine/bus.h> 4358271Syokota#include <machine/resource.h> 4458271Syokota#include <sys/rman.h> 4542421Syokota 4642421Syokota 4742421Syokota#include <dev/kbd/atkbdcreg.h> 4842421Syokota 4942421Syokota#include <isa/isareg.h> 5042421Syokota 5142421Syokota/* constants */ 5242421Syokota 53102149Speter#define MAXKBDC 1 /* XXX */ 5442421Syokota 5542421Syokota/* macros */ 5642421Syokota 5742421Syokota#ifndef MAX 5842421Syokota#define MAX(x, y) ((x) > (y) ? (x) : (y)) 5942421Syokota#endif 6042421Syokota 6142421Syokota#define kbdcp(p) ((atkbdc_softc_t *)(p)) 6242421Syokota#define nextq(i) (((i) + 1) % KBDQ_BUFSIZE) 6342421Syokota#define availq(q) ((q)->head != (q)->tail) 6442421Syokota#if KBDIO_DEBUG >= 2 6542421Syokota#define emptyq(q) ((q)->tail = (q)->head = (q)->qcount = 0) 6642421Syokota#else 6742421Syokota#define emptyq(q) ((q)->tail = (q)->head = 0) 6842421Syokota#endif 6942421Syokota 7058271Syokota#define read_data(k) (bus_space_read_1((k)->iot, (k)->ioh0, 0)) 7158271Syokota#define read_status(k) (bus_space_read_1((k)->iot, (k)->ioh1, 0)) 7258271Syokota#define write_data(k, d) \ 7358271Syokota (bus_space_write_1((k)->iot, (k)->ioh0, 0, (d))) 7458271Syokota#define write_command(k, d) \ 7558271Syokota (bus_space_write_1((k)->iot, (k)->ioh1, 0, (d))) 7658271Syokota 7742421Syokota/* local variables */ 7842421Syokota 7942421Syokota/* 8042421Syokota * We always need at least one copy of the kbdc_softc struct for the 8142421Syokota * low-level console. As the low-level console accesses the keyboard 8242421Syokota * controller before kbdc, and all other devices, is probed, we 8342421Syokota * statically allocate one entry. XXX 8442421Syokota */ 8542421Syokotastatic atkbdc_softc_t default_kbdc; 8642421Syokotastatic atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc }; 8742421Syokota 8842421Syokotastatic int verbose = KBDIO_DEBUG; 8942421Syokota 9042421Syokota/* function prototypes */ 9142421Syokota 9258271Syokotastatic int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, 9358271Syokota bus_space_handle_t h0, bus_space_handle_t h1); 9442421Syokotastatic int addq(kqueue *q, int c); 9542421Syokotastatic int removeq(kqueue *q); 9642421Syokotastatic int wait_while_controller_busy(atkbdc_softc_t *kbdc); 9742421Syokotastatic int wait_for_data(atkbdc_softc_t *kbdc); 9842421Syokotastatic int wait_for_kbd_data(atkbdc_softc_t *kbdc); 9942421Syokotastatic int wait_for_kbd_ack(atkbdc_softc_t *kbdc); 10042421Syokotastatic int wait_for_aux_data(atkbdc_softc_t *kbdc); 10142421Syokotastatic int wait_for_aux_ack(atkbdc_softc_t *kbdc); 10242421Syokota 10342421Syokotaatkbdc_softc_t 10442421Syokota*atkbdc_get_softc(int unit) 10542421Syokota{ 10642421Syokota atkbdc_softc_t *sc; 10742421Syokota 10842421Syokota if (unit >= sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0])) 10942421Syokota return NULL; 11042421Syokota sc = atkbdc_softc[unit]; 11142421Syokota if (sc == NULL) { 11242421Syokota sc = atkbdc_softc[unit] 11369781Sdwmalone = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO); 11442421Syokota if (sc == NULL) 11542421Syokota return NULL; 11642421Syokota } 11742421Syokota return sc; 11842421Syokota} 11942421Syokota 12042421Syokotaint 12158271Syokotaatkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1) 12242421Syokota{ 12358271Syokota if (rman_get_start(port0) <= 0) 12447296Syokota return ENXIO; 12558271Syokota if (rman_get_start(port1) <= 0) 12658271Syokota return ENXIO; 12747296Syokota return 0; 12847296Syokota} 12947296Syokota 13047296Syokotaint 13158271Syokotaatkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0, 13258271Syokota struct resource *port1) 13347296Syokota{ 13458271Syokota return atkbdc_setup(sc, rman_get_bustag(port0), 13558271Syokota rman_get_bushandle(port0), 13658271Syokota rman_get_bushandle(port1)); 13742421Syokota} 13842421Syokota 13942421Syokota/* the backdoor to the keyboard controller! XXX */ 14042421Syokotaint 14142421Syokotaatkbdc_configure(void) 14242421Syokota{ 14358271Syokota bus_space_tag_t tag; 14458271Syokota bus_space_handle_t h0; 14558271Syokota bus_space_handle_t h1; 14658271Syokota int port0; 14758271Syokota int port1; 14858271Syokota 14958271Syokota port0 = IO_KBD; 15058271Syokota resource_int_value("atkbdc", 0, "port", &port0); 15158271Syokota port1 = IO_KBD + KBD_STATUS_PORT; 15258271Syokota#if 0 15358271Syokota resource_int_value("atkbdc", 0, "port", &port0); 15458271Syokota#endif 15558271Syokota 15658271Syokota /* XXX: tag should be passed from the caller */ 157114930Speter#if defined(__i386__) 15858271Syokota tag = I386_BUS_SPACE_IO; 159114930Speter#elif defined(__amd64__) 160114930Speter tag = AMD64_BUS_SPACE_IO; 16158271Syokota#elif defined(__alpha__) 16265176Sdfr tag = busspace_isa_io; 16392661Speter#elif defined(__ia64__) 16492661Speter tag = IA64_BUS_SPACE_IO; 16592661Speter#else 16692661Speter#error "define tag!" 16758271Syokota#endif 16858271Syokota 16958271Syokota#if notyet 17058271Syokota bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0); 17158271Syokota bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1); 17258271Syokota#else 17358271Syokota h0 = (bus_space_handle_t)port0; 17458271Syokota h1 = (bus_space_handle_t)port1; 17558271Syokota#endif 17658271Syokota return atkbdc_setup(atkbdc_softc[0], tag, h0, h1); 17742421Syokota} 17842421Syokota 17942421Syokotastatic int 18058271Syokotaatkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0, 18158271Syokota bus_space_handle_t h1) 18242421Syokota{ 18358271Syokota if (sc->ioh0 == 0) { /* XXX */ 18442421Syokota sc->command_byte = -1; 18542421Syokota sc->command_mask = 0; 18642421Syokota sc->lock = FALSE; 18742421Syokota sc->kbd.head = sc->kbd.tail = 0; 18842421Syokota sc->aux.head = sc->aux.tail = 0; 18942421Syokota#if KBDIO_DEBUG >= 2 19042421Syokota sc->kbd.call_count = 0; 19142421Syokota sc->kbd.qcount = sc->kbd.max_qcount = 0; 19242421Syokota sc->aux.call_count = 0; 19342421Syokota sc->aux.qcount = sc->aux.max_qcount = 0; 19442421Syokota#endif 19542421Syokota } 19658271Syokota sc->iot = tag; 19758271Syokota sc->ioh0 = h0; 19858271Syokota sc->ioh1 = h1; 19942421Syokota return 0; 20042421Syokota} 20142421Syokota 20258271Syokota/* open a keyboard controller */ 20342421SyokotaKBDC 20458271Syokotaatkbdc_open(int unit) 20542421Syokota{ 20658271Syokota if (unit <= 0) 20758271Syokota unit = 0; 20858271Syokota if (unit >= MAXKBDC) 20958271Syokota return NULL; 21058271Syokota if ((atkbdc_softc[unit]->port0 != NULL) 21158271Syokota || (atkbdc_softc[unit]->ioh0 != 0)) /* XXX */ 21258271Syokota return (KBDC)atkbdc_softc[unit]; 21342421Syokota return NULL; 21442421Syokota} 21542421Syokota 21642421Syokota/* 21742421Syokota * I/O access arbitration in `kbdio' 21842421Syokota * 21942421Syokota * The `kbdio' module uses a simplistic convention to arbitrate 22042421Syokota * I/O access to the controller/keyboard/mouse. The convention requires 22142421Syokota * close cooperation of the calling device driver. 22242421Syokota * 22393279Smurray * The device drivers which utilize the `kbdio' module are assumed to 22442421Syokota * have the following set of routines. 22542421Syokota * a. An interrupt handler (the bottom half of the driver). 22693279Smurray * b. Timeout routines which may briefly poll the keyboard controller. 22742421Syokota * c. Routines outside interrupt context (the top half of the driver). 22842421Syokota * They should follow the rules below: 22942421Syokota * 1. The interrupt handler may assume that it always has full access 23042421Syokota * to the controller/keyboard/mouse. 23142421Syokota * 2. The other routines must issue `spltty()' if they wish to 23242421Syokota * prevent the interrupt handler from accessing 23342421Syokota * the controller/keyboard/mouse. 23442421Syokota * 3. The timeout routines and the top half routines of the device driver 23542421Syokota * arbitrate I/O access by observing the lock flag in `kbdio'. 23642421Syokota * The flag is manipulated via `kbdc_lock()'; when one wants to 23742421Syokota * perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if 23842421Syokota * the call returns with TRUE. Otherwise the caller must back off. 23942421Syokota * Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion 24042421Syokota * is finished. This mechanism does not prevent the interrupt 24142421Syokota * handler from being invoked at any time and carrying out I/O. 24242421Syokota * Therefore, `spltty()' must be strategically placed in the device 24342421Syokota * driver code. Also note that the timeout routine may interrupt 24442421Syokota * `kbdc_lock()' called by the top half of the driver, but this 24593279Smurray * interruption is OK so long as the timeout routine observes 24693279Smurray * rule 4 below. 24742421Syokota * 4. The interrupt and timeout routines should not extend I/O operation 24893279Smurray * across more than one interrupt or timeout; they must complete any 24993279Smurray * necessary I/O operation within one invocation of the routine. 25093279Smurray * This means that if the timeout routine acquires the lock flag, 25142421Syokota * it must reset the flag to FALSE before it returns. 25242421Syokota */ 25342421Syokota 25442421Syokota/* set/reset polling lock */ 25542421Syokotaint 25642421Syokotakbdc_lock(KBDC p, int lock) 25742421Syokota{ 25842421Syokota int prevlock; 25942421Syokota 26042421Syokota prevlock = kbdcp(p)->lock; 26142421Syokota kbdcp(p)->lock = lock; 26242421Syokota 26342421Syokota return (prevlock != lock); 26442421Syokota} 26542421Syokota 26642421Syokota/* check if any data is waiting to be processed */ 26742421Syokotaint 26842421Syokotakbdc_data_ready(KBDC p) 26942421Syokota{ 27042421Syokota return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux) 27158271Syokota || (read_status(kbdcp(p)) & KBDS_ANY_BUFFER_FULL)); 27242421Syokota} 27342421Syokota 27442421Syokota/* queuing functions */ 27542421Syokota 27642421Syokotastatic int 27742421Syokotaaddq(kqueue *q, int c) 27842421Syokota{ 27942421Syokota if (nextq(q->tail) != q->head) { 28042421Syokota q->q[q->tail] = c; 28142421Syokota q->tail = nextq(q->tail); 28242421Syokota#if KBDIO_DEBUG >= 2 28342421Syokota ++q->call_count; 28442421Syokota ++q->qcount; 28542421Syokota if (q->qcount > q->max_qcount) 28642421Syokota q->max_qcount = q->qcount; 28742421Syokota#endif 28842421Syokota return TRUE; 28942421Syokota } 29042421Syokota return FALSE; 29142421Syokota} 29242421Syokota 29342421Syokotastatic int 29442421Syokotaremoveq(kqueue *q) 29542421Syokota{ 29642421Syokota int c; 29742421Syokota 29842421Syokota if (q->tail != q->head) { 29942421Syokota c = q->q[q->head]; 30042421Syokota q->head = nextq(q->head); 30142421Syokota#if KBDIO_DEBUG >= 2 30242421Syokota --q->qcount; 30342421Syokota#endif 30442421Syokota return c; 30542421Syokota } 30642421Syokota return -1; 30742421Syokota} 30842421Syokota 30942421Syokota/* 31042421Syokota * device I/O routines 31142421Syokota */ 31242421Syokotastatic int 31342421Syokotawait_while_controller_busy(struct atkbdc_softc *kbdc) 31442421Syokota{ 31542421Syokota /* CPU will stay inside the loop for 100msec at most */ 31642421Syokota int retry = 5000; 31742421Syokota int f; 31842421Syokota 31958271Syokota while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) { 32042421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 32142421Syokota DELAY(KBDD_DELAYTIME); 32258271Syokota addq(&kbdc->kbd, read_data(kbdc)); 32342421Syokota } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 32442421Syokota DELAY(KBDD_DELAYTIME); 32558271Syokota addq(&kbdc->aux, read_data(kbdc)); 32642421Syokota } 32742421Syokota DELAY(KBDC_DELAYTIME); 32842421Syokota if (--retry < 0) 32942421Syokota return FALSE; 33042421Syokota } 33142421Syokota return TRUE; 33242421Syokota} 33342421Syokota 33442421Syokota/* 33542421Syokota * wait for any data; whether it's from the controller, 33642421Syokota * the keyboard, or the aux device. 33742421Syokota */ 33842421Syokotastatic int 33942421Syokotawait_for_data(struct atkbdc_softc *kbdc) 34042421Syokota{ 34142421Syokota /* CPU will stay inside the loop for 200msec at most */ 34242421Syokota int retry = 10000; 34342421Syokota int f; 34442421Syokota 34558271Syokota while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) { 34642421Syokota DELAY(KBDC_DELAYTIME); 34742421Syokota if (--retry < 0) 34842421Syokota return 0; 34942421Syokota } 35042421Syokota DELAY(KBDD_DELAYTIME); 35142421Syokota return f; 35242421Syokota} 35342421Syokota 35442421Syokota/* wait for data from the keyboard */ 35542421Syokotastatic int 35642421Syokotawait_for_kbd_data(struct atkbdc_softc *kbdc) 35742421Syokota{ 35842421Syokota /* CPU will stay inside the loop for 200msec at most */ 35942421Syokota int retry = 10000; 36042421Syokota int f; 36142421Syokota 36258271Syokota while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 36342421Syokota != KBDS_KBD_BUFFER_FULL) { 36442421Syokota if (f == KBDS_AUX_BUFFER_FULL) { 36542421Syokota DELAY(KBDD_DELAYTIME); 36658271Syokota addq(&kbdc->aux, read_data(kbdc)); 36742421Syokota } 36842421Syokota DELAY(KBDC_DELAYTIME); 36942421Syokota if (--retry < 0) 37042421Syokota return 0; 37142421Syokota } 37242421Syokota DELAY(KBDD_DELAYTIME); 37342421Syokota return f; 37442421Syokota} 37542421Syokota 37642421Syokota/* 37742421Syokota * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard. 37842421Syokota * queue anything else. 37942421Syokota */ 38042421Syokotastatic int 38142421Syokotawait_for_kbd_ack(struct atkbdc_softc *kbdc) 38242421Syokota{ 38342421Syokota /* CPU will stay inside the loop for 200msec at most */ 38442421Syokota int retry = 10000; 38542421Syokota int f; 38642421Syokota int b; 38742421Syokota 38842421Syokota while (retry-- > 0) { 38958271Syokota if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 39042421Syokota DELAY(KBDD_DELAYTIME); 39158271Syokota b = read_data(kbdc); 39242421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 39342421Syokota if ((b == KBD_ACK) || (b == KBD_RESEND) 39442421Syokota || (b == KBD_RESET_FAIL)) 39542421Syokota return b; 39642421Syokota addq(&kbdc->kbd, b); 39742421Syokota } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 39842421Syokota addq(&kbdc->aux, b); 39942421Syokota } 40042421Syokota } 40142421Syokota DELAY(KBDC_DELAYTIME); 40242421Syokota } 40342421Syokota return -1; 40442421Syokota} 40542421Syokota 40642421Syokota/* wait for data from the aux device */ 40742421Syokotastatic int 40842421Syokotawait_for_aux_data(struct atkbdc_softc *kbdc) 40942421Syokota{ 41042421Syokota /* CPU will stay inside the loop for 200msec at most */ 41142421Syokota int retry = 10000; 41242421Syokota int f; 41342421Syokota 41458271Syokota while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 41542421Syokota != KBDS_AUX_BUFFER_FULL) { 41642421Syokota if (f == KBDS_KBD_BUFFER_FULL) { 41742421Syokota DELAY(KBDD_DELAYTIME); 41858271Syokota addq(&kbdc->kbd, read_data(kbdc)); 41942421Syokota } 42042421Syokota DELAY(KBDC_DELAYTIME); 42142421Syokota if (--retry < 0) 42242421Syokota return 0; 42342421Syokota } 42442421Syokota DELAY(KBDD_DELAYTIME); 42542421Syokota return f; 42642421Syokota} 42742421Syokota 42842421Syokota/* 42942421Syokota * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device. 43042421Syokota * queue anything else. 43142421Syokota */ 43242421Syokotastatic int 43342421Syokotawait_for_aux_ack(struct atkbdc_softc *kbdc) 43442421Syokota{ 43542421Syokota /* CPU will stay inside the loop for 200msec at most */ 43642421Syokota int retry = 10000; 43742421Syokota int f; 43842421Syokota int b; 43942421Syokota 44042421Syokota while (retry-- > 0) { 44158271Syokota if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 44242421Syokota DELAY(KBDD_DELAYTIME); 44358271Syokota b = read_data(kbdc); 44442421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 44542421Syokota if ((b == PSM_ACK) || (b == PSM_RESEND) 44642421Syokota || (b == PSM_RESET_FAIL)) 44742421Syokota return b; 44842421Syokota addq(&kbdc->aux, b); 44942421Syokota } else if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 45042421Syokota addq(&kbdc->kbd, b); 45142421Syokota } 45242421Syokota } 45342421Syokota DELAY(KBDC_DELAYTIME); 45442421Syokota } 45542421Syokota return -1; 45642421Syokota} 45742421Syokota 45842421Syokota/* write a one byte command to the controller */ 45942421Syokotaint 46042421Syokotawrite_controller_command(KBDC p, int c) 46142421Syokota{ 46242421Syokota if (!wait_while_controller_busy(kbdcp(p))) 46342421Syokota return FALSE; 46458271Syokota write_command(kbdcp(p), c); 46542421Syokota return TRUE; 46642421Syokota} 46742421Syokota 46842421Syokota/* write a one byte data to the controller */ 46942421Syokotaint 47042421Syokotawrite_controller_data(KBDC p, int c) 47142421Syokota{ 47242421Syokota if (!wait_while_controller_busy(kbdcp(p))) 47342421Syokota return FALSE; 47458271Syokota write_data(kbdcp(p), c); 47542421Syokota return TRUE; 47642421Syokota} 47742421Syokota 47842421Syokota/* write a one byte keyboard command */ 47942421Syokotaint 48042421Syokotawrite_kbd_command(KBDC p, int c) 48142421Syokota{ 48242421Syokota if (!wait_while_controller_busy(kbdcp(p))) 48342421Syokota return FALSE; 48458271Syokota write_data(kbdcp(p), c); 48542421Syokota return TRUE; 48642421Syokota} 48742421Syokota 48842421Syokota/* write a one byte auxiliary device command */ 48942421Syokotaint 49042421Syokotawrite_aux_command(KBDC p, int c) 49142421Syokota{ 49242421Syokota if (!write_controller_command(p, KBDC_WRITE_TO_AUX)) 49342421Syokota return FALSE; 49442421Syokota return write_controller_data(p, c); 49542421Syokota} 49642421Syokota 49742421Syokota/* send a command to the keyboard and wait for ACK */ 49842421Syokotaint 49942421Syokotasend_kbd_command(KBDC p, int c) 50042421Syokota{ 50142421Syokota int retry = KBD_MAXRETRY; 50242421Syokota int res = -1; 50342421Syokota 50442421Syokota while (retry-- > 0) { 50542421Syokota if (!write_kbd_command(p, c)) 50642421Syokota continue; 50742421Syokota res = wait_for_kbd_ack(kbdcp(p)); 50842421Syokota if (res == KBD_ACK) 50942421Syokota break; 51042421Syokota } 51142421Syokota return res; 51242421Syokota} 51342421Syokota 51442421Syokota/* send a command to the auxiliary device and wait for ACK */ 51542421Syokotaint 51642421Syokotasend_aux_command(KBDC p, int c) 51742421Syokota{ 51842421Syokota int retry = KBD_MAXRETRY; 51942421Syokota int res = -1; 52042421Syokota 52142421Syokota while (retry-- > 0) { 52242421Syokota if (!write_aux_command(p, c)) 52342421Syokota continue; 52442421Syokota /* 52542421Syokota * FIXME: XXX 52642421Syokota * The aux device may have already sent one or two bytes of 52742421Syokota * status data, when a command is received. It will immediately 52842421Syokota * stop data transmission, thus, leaving an incomplete data 52942421Syokota * packet in our buffer. We have to discard any unprocessed 53042421Syokota * data in order to remove such packets. Well, we may remove 53142421Syokota * unprocessed, but necessary data byte as well... 53242421Syokota */ 53342421Syokota emptyq(&kbdcp(p)->aux); 53442421Syokota res = wait_for_aux_ack(kbdcp(p)); 53542421Syokota if (res == PSM_ACK) 53642421Syokota break; 53742421Syokota } 53842421Syokota return res; 53942421Syokota} 54042421Syokota 54142421Syokota/* send a command and a data to the keyboard, wait for ACKs */ 54242421Syokotaint 54342421Syokotasend_kbd_command_and_data(KBDC p, int c, int d) 54442421Syokota{ 54542421Syokota int retry; 54642421Syokota int res = -1; 54742421Syokota 54842421Syokota for (retry = KBD_MAXRETRY; retry > 0; --retry) { 54942421Syokota if (!write_kbd_command(p, c)) 55042421Syokota continue; 55142421Syokota res = wait_for_kbd_ack(kbdcp(p)); 55242421Syokota if (res == KBD_ACK) 55342421Syokota break; 55442421Syokota else if (res != KBD_RESEND) 55542421Syokota return res; 55642421Syokota } 55742421Syokota if (retry <= 0) 55842421Syokota return res; 55942421Syokota 56042421Syokota for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) { 56142421Syokota if (!write_kbd_command(p, d)) 56242421Syokota continue; 56342421Syokota res = wait_for_kbd_ack(kbdcp(p)); 56442421Syokota if (res != KBD_RESEND) 56542421Syokota break; 56642421Syokota } 56742421Syokota return res; 56842421Syokota} 56942421Syokota 57042421Syokota/* send a command and a data to the auxiliary device, wait for ACKs */ 57142421Syokotaint 57242421Syokotasend_aux_command_and_data(KBDC p, int c, int d) 57342421Syokota{ 57442421Syokota int retry; 57542421Syokota int res = -1; 57642421Syokota 57742421Syokota for (retry = KBD_MAXRETRY; retry > 0; --retry) { 57842421Syokota if (!write_aux_command(p, c)) 57942421Syokota continue; 58042421Syokota emptyq(&kbdcp(p)->aux); 58142421Syokota res = wait_for_aux_ack(kbdcp(p)); 58242421Syokota if (res == PSM_ACK) 58342421Syokota break; 58442421Syokota else if (res != PSM_RESEND) 58542421Syokota return res; 58642421Syokota } 58742421Syokota if (retry <= 0) 58842421Syokota return res; 58942421Syokota 59042421Syokota for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) { 59142421Syokota if (!write_aux_command(p, d)) 59242421Syokota continue; 59342421Syokota res = wait_for_aux_ack(kbdcp(p)); 59442421Syokota if (res != PSM_RESEND) 59542421Syokota break; 59642421Syokota } 59742421Syokota return res; 59842421Syokota} 59942421Syokota 60042421Syokota/* 60142421Syokota * read one byte from any source; whether from the controller, 60242421Syokota * the keyboard, or the aux device 60342421Syokota */ 60442421Syokotaint 60542421Syokotaread_controller_data(KBDC p) 60642421Syokota{ 60742421Syokota if (availq(&kbdcp(p)->kbd)) 60842421Syokota return removeq(&kbdcp(p)->kbd); 60942421Syokota if (availq(&kbdcp(p)->aux)) 61042421Syokota return removeq(&kbdcp(p)->aux); 61142421Syokota if (!wait_for_data(kbdcp(p))) 61242421Syokota return -1; /* timeout */ 61358271Syokota return read_data(kbdcp(p)); 61442421Syokota} 61542421Syokota 61642421Syokota#if KBDIO_DEBUG >= 2 61742421Syokotastatic int call = 0; 61842421Syokota#endif 61942421Syokota 62042421Syokota/* read one byte from the keyboard */ 62142421Syokotaint 62242421Syokotaread_kbd_data(KBDC p) 62342421Syokota{ 62442421Syokota#if KBDIO_DEBUG >= 2 62542421Syokota if (++call > 2000) { 62642421Syokota call = 0; 62742421Syokota log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, " 62842421Syokota "aux q: %d calls, max %d chars\n", 62942421Syokota kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount, 63042421Syokota kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount); 63142421Syokota } 63242421Syokota#endif 63342421Syokota 63442421Syokota if (availq(&kbdcp(p)->kbd)) 63542421Syokota return removeq(&kbdcp(p)->kbd); 63642421Syokota if (!wait_for_kbd_data(kbdcp(p))) 63742421Syokota return -1; /* timeout */ 63858271Syokota return read_data(kbdcp(p)); 63942421Syokota} 64042421Syokota 64142421Syokota/* read one byte from the keyboard, but return immediately if 64242421Syokota * no data is waiting 64342421Syokota */ 64442421Syokotaint 64542421Syokotaread_kbd_data_no_wait(KBDC p) 64642421Syokota{ 64742421Syokota int f; 64842421Syokota 64942421Syokota#if KBDIO_DEBUG >= 2 65042421Syokota if (++call > 2000) { 65142421Syokota call = 0; 65242421Syokota log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, " 65342421Syokota "aux q: %d calls, max %d chars\n", 65442421Syokota kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount, 65542421Syokota kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount); 65642421Syokota } 65742421Syokota#endif 65842421Syokota 65942421Syokota if (availq(&kbdcp(p)->kbd)) 66042421Syokota return removeq(&kbdcp(p)->kbd); 66158271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 66242421Syokota if (f == KBDS_AUX_BUFFER_FULL) { 66342421Syokota DELAY(KBDD_DELAYTIME); 66458271Syokota addq(&kbdcp(p)->aux, read_data(kbdcp(p))); 66558271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 66642421Syokota } 66742421Syokota if (f == KBDS_KBD_BUFFER_FULL) { 66842421Syokota DELAY(KBDD_DELAYTIME); 66958271Syokota return read_data(kbdcp(p)); 67042421Syokota } 67142421Syokota return -1; /* no data */ 67242421Syokota} 67342421Syokota 67442421Syokota/* read one byte from the aux device */ 67542421Syokotaint 67642421Syokotaread_aux_data(KBDC p) 67742421Syokota{ 67842421Syokota if (availq(&kbdcp(p)->aux)) 67942421Syokota return removeq(&kbdcp(p)->aux); 68042421Syokota if (!wait_for_aux_data(kbdcp(p))) 68142421Syokota return -1; /* timeout */ 68258271Syokota return read_data(kbdcp(p)); 68342421Syokota} 68442421Syokota 68542421Syokota/* read one byte from the aux device, but return immediately if 68642421Syokota * no data is waiting 68742421Syokota */ 68842421Syokotaint 68942421Syokotaread_aux_data_no_wait(KBDC p) 69042421Syokota{ 69142421Syokota int f; 69242421Syokota 69342421Syokota if (availq(&kbdcp(p)->aux)) 69442421Syokota return removeq(&kbdcp(p)->aux); 69558271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 69642421Syokota if (f == KBDS_KBD_BUFFER_FULL) { 69742421Syokota DELAY(KBDD_DELAYTIME); 69858271Syokota addq(&kbdcp(p)->kbd, read_data(kbdcp(p))); 69958271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 70042421Syokota } 70142421Syokota if (f == KBDS_AUX_BUFFER_FULL) { 70242421Syokota DELAY(KBDD_DELAYTIME); 70358271Syokota return read_data(kbdcp(p)); 70442421Syokota } 70542421Syokota return -1; /* no data */ 70642421Syokota} 70742421Syokota 70842421Syokota/* discard data from the keyboard */ 70942421Syokotavoid 71042421Syokotaempty_kbd_buffer(KBDC p, int wait) 71142421Syokota{ 71242421Syokota int t; 71342421Syokota int b; 71442421Syokota int f; 71542421Syokota#if KBDIO_DEBUG >= 2 71642421Syokota int c1 = 0; 71742421Syokota int c2 = 0; 71842421Syokota#endif 71942421Syokota int delta = 2; 72042421Syokota 72142421Syokota for (t = wait; t > 0; ) { 72258271Syokota if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) { 72342421Syokota DELAY(KBDD_DELAYTIME); 72458271Syokota b = read_data(kbdcp(p)); 72542421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 72642421Syokota addq(&kbdcp(p)->aux, b); 72742421Syokota#if KBDIO_DEBUG >= 2 72842421Syokota ++c2; 72942421Syokota } else { 73042421Syokota ++c1; 73142421Syokota#endif 73242421Syokota } 73342421Syokota t = wait; 73442421Syokota } else { 73542421Syokota t -= delta; 73642421Syokota } 73742421Syokota DELAY(delta*1000); 73842421Syokota } 73942421Syokota#if KBDIO_DEBUG >= 2 74042421Syokota if ((c1 > 0) || (c2 > 0)) 74142421Syokota log(LOG_DEBUG, "kbdc: %d:%d char read (empty_kbd_buffer)\n", c1, c2); 74242421Syokota#endif 74342421Syokota 74442421Syokota emptyq(&kbdcp(p)->kbd); 74542421Syokota} 74642421Syokota 74742421Syokota/* discard data from the aux device */ 74842421Syokotavoid 74942421Syokotaempty_aux_buffer(KBDC p, int wait) 75042421Syokota{ 75142421Syokota int t; 75242421Syokota int b; 75342421Syokota int f; 75442421Syokota#if KBDIO_DEBUG >= 2 75542421Syokota int c1 = 0; 75642421Syokota int c2 = 0; 75742421Syokota#endif 75842421Syokota int delta = 2; 75942421Syokota 76042421Syokota for (t = wait; t > 0; ) { 76158271Syokota if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) { 76242421Syokota DELAY(KBDD_DELAYTIME); 76358271Syokota b = read_data(kbdcp(p)); 76442421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 76542421Syokota addq(&kbdcp(p)->kbd, b); 76642421Syokota#if KBDIO_DEBUG >= 2 76742421Syokota ++c1; 76842421Syokota } else { 76942421Syokota ++c2; 77042421Syokota#endif 77142421Syokota } 77242421Syokota t = wait; 77342421Syokota } else { 77442421Syokota t -= delta; 77542421Syokota } 77642421Syokota DELAY(delta*1000); 77742421Syokota } 77842421Syokota#if KBDIO_DEBUG >= 2 77942421Syokota if ((c1 > 0) || (c2 > 0)) 78042421Syokota log(LOG_DEBUG, "kbdc: %d:%d char read (empty_aux_buffer)\n", c1, c2); 78142421Syokota#endif 78242421Syokota 78342421Syokota emptyq(&kbdcp(p)->aux); 78442421Syokota} 78542421Syokota 78642421Syokota/* discard any data from the keyboard or the aux device */ 78742421Syokotavoid 78842421Syokotaempty_both_buffers(KBDC p, int wait) 78942421Syokota{ 79042421Syokota int t; 79142421Syokota int f; 79242421Syokota#if KBDIO_DEBUG >= 2 79342421Syokota int c1 = 0; 79442421Syokota int c2 = 0; 79542421Syokota#endif 79642421Syokota int delta = 2; 79742421Syokota 79842421Syokota for (t = wait; t > 0; ) { 79958271Syokota if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) { 80042421Syokota DELAY(KBDD_DELAYTIME); 80158271Syokota (void)read_data(kbdcp(p)); 80242421Syokota#if KBDIO_DEBUG >= 2 80342421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) 80442421Syokota ++c1; 80542421Syokota else 80642421Syokota ++c2; 80742421Syokota#endif 80842421Syokota t = wait; 80942421Syokota } else { 81042421Syokota t -= delta; 81142421Syokota } 81242421Syokota DELAY(delta*1000); 81342421Syokota } 81442421Syokota#if KBDIO_DEBUG >= 2 81542421Syokota if ((c1 > 0) || (c2 > 0)) 81642421Syokota log(LOG_DEBUG, "kbdc: %d:%d char read (empty_both_buffers)\n", c1, c2); 81742421Syokota#endif 81842421Syokota 81942421Syokota emptyq(&kbdcp(p)->kbd); 82042421Syokota emptyq(&kbdcp(p)->aux); 82142421Syokota} 82242421Syokota 82342421Syokota/* keyboard and mouse device control */ 82442421Syokota 82542421Syokota/* NOTE: enable the keyboard port but disable the keyboard 82642421Syokota * interrupt before calling "reset_kbd()". 82742421Syokota */ 82842421Syokotaint 82942421Syokotareset_kbd(KBDC p) 83042421Syokota{ 83142421Syokota int retry = KBD_MAXRETRY; 83242421Syokota int again = KBD_MAXWAIT; 83342421Syokota int c = KBD_RESEND; /* keep the compiler happy */ 83442421Syokota 83542421Syokota while (retry-- > 0) { 83642421Syokota empty_both_buffers(p, 10); 83742421Syokota if (!write_kbd_command(p, KBDC_RESET_KBD)) 83842421Syokota continue; 83942421Syokota emptyq(&kbdcp(p)->kbd); 84042421Syokota c = read_controller_data(p); 84142421Syokota if (verbose || bootverbose) 84242421Syokota log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c); 84342421Syokota if (c == KBD_ACK) /* keyboard has agreed to reset itself... */ 84442421Syokota break; 84542421Syokota } 84642421Syokota if (retry < 0) 84742421Syokota return FALSE; 84842421Syokota 84942421Syokota while (again-- > 0) { 85042421Syokota /* wait awhile, well, in fact we must wait quite loooooooooooong */ 85142421Syokota DELAY(KBD_RESETDELAY*1000); 85242421Syokota c = read_controller_data(p); /* RESET_DONE/RESET_FAIL */ 85342421Syokota if (c != -1) /* wait again if the controller is not ready */ 85442421Syokota break; 85542421Syokota } 85642421Syokota if (verbose || bootverbose) 85742421Syokota log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c); 85842421Syokota if (c != KBD_RESET_DONE) 85942421Syokota return FALSE; 86042421Syokota return TRUE; 86142421Syokota} 86242421Syokota 86342421Syokota/* NOTE: enable the aux port but disable the aux interrupt 86442421Syokota * before calling `reset_aux_dev()'. 86542421Syokota */ 86642421Syokotaint 86742421Syokotareset_aux_dev(KBDC p) 86842421Syokota{ 86942421Syokota int retry = KBD_MAXRETRY; 87042421Syokota int again = KBD_MAXWAIT; 87142421Syokota int c = PSM_RESEND; /* keep the compiler happy */ 87242421Syokota 87342421Syokota while (retry-- > 0) { 87442421Syokota empty_both_buffers(p, 10); 87542421Syokota if (!write_aux_command(p, PSMC_RESET_DEV)) 87642421Syokota continue; 87742421Syokota emptyq(&kbdcp(p)->aux); 87842421Syokota /* NOTE: Compaq Armada laptops require extra delay here. XXX */ 87942421Syokota for (again = KBD_MAXWAIT; again > 0; --again) { 88042421Syokota DELAY(KBD_RESETDELAY*1000); 88142421Syokota c = read_aux_data_no_wait(p); 88242421Syokota if (c != -1) 88342421Syokota break; 88442421Syokota } 88542421Syokota if (verbose || bootverbose) 88642421Syokota log(LOG_DEBUG, "kbdc: RESET_AUX return code:%04x\n", c); 88742421Syokota if (c == PSM_ACK) /* aux dev is about to reset... */ 88842421Syokota break; 88942421Syokota } 89042421Syokota if (retry < 0) 89142421Syokota return FALSE; 89242421Syokota 89342421Syokota for (again = KBD_MAXWAIT; again > 0; --again) { 89442421Syokota /* wait awhile, well, quite looooooooooooong */ 89542421Syokota DELAY(KBD_RESETDELAY*1000); 89642421Syokota c = read_aux_data_no_wait(p); /* RESET_DONE/RESET_FAIL */ 89742421Syokota if (c != -1) /* wait again if the controller is not ready */ 89842421Syokota break; 89942421Syokota } 90042421Syokota if (verbose || bootverbose) 90142421Syokota log(LOG_DEBUG, "kbdc: RESET_AUX status:%04x\n", c); 90242421Syokota if (c != PSM_RESET_DONE) /* reset status */ 90342421Syokota return FALSE; 90442421Syokota 90542421Syokota c = read_aux_data(p); /* device ID */ 90642421Syokota if (verbose || bootverbose) 90742421Syokota log(LOG_DEBUG, "kbdc: RESET_AUX ID:%04x\n", c); 90842421Syokota /* NOTE: we could check the device ID now, but leave it later... */ 90942421Syokota return TRUE; 91042421Syokota} 91142421Syokota 91242421Syokota/* controller diagnostics and setup */ 91342421Syokota 91442421Syokotaint 91542421Syokotatest_controller(KBDC p) 91642421Syokota{ 91742421Syokota int retry = KBD_MAXRETRY; 91842421Syokota int again = KBD_MAXWAIT; 91942421Syokota int c = KBD_DIAG_FAIL; 92042421Syokota 92142421Syokota while (retry-- > 0) { 92242421Syokota empty_both_buffers(p, 10); 92342421Syokota if (write_controller_command(p, KBDC_DIAGNOSE)) 92442421Syokota break; 92542421Syokota } 92642421Syokota if (retry < 0) 92742421Syokota return FALSE; 92842421Syokota 92942421Syokota emptyq(&kbdcp(p)->kbd); 93042421Syokota while (again-- > 0) { 93142421Syokota /* wait awhile */ 93242421Syokota DELAY(KBD_RESETDELAY*1000); 93342421Syokota c = read_controller_data(p); /* DIAG_DONE/DIAG_FAIL */ 93442421Syokota if (c != -1) /* wait again if the controller is not ready */ 93542421Syokota break; 93642421Syokota } 93742421Syokota if (verbose || bootverbose) 93842421Syokota log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c); 93942421Syokota return (c == KBD_DIAG_DONE); 94042421Syokota} 94142421Syokota 94242421Syokotaint 94342421Syokotatest_kbd_port(KBDC p) 94442421Syokota{ 94542421Syokota int retry = KBD_MAXRETRY; 94642421Syokota int again = KBD_MAXWAIT; 94742421Syokota int c = -1; 94842421Syokota 94942421Syokota while (retry-- > 0) { 95042421Syokota empty_both_buffers(p, 10); 95142421Syokota if (write_controller_command(p, KBDC_TEST_KBD_PORT)) 95242421Syokota break; 95342421Syokota } 95442421Syokota if (retry < 0) 95542421Syokota return FALSE; 95642421Syokota 95742421Syokota emptyq(&kbdcp(p)->kbd); 95842421Syokota while (again-- > 0) { 95942421Syokota c = read_controller_data(p); 96042421Syokota if (c != -1) /* try again if the controller is not ready */ 96142421Syokota break; 96242421Syokota } 96342421Syokota if (verbose || bootverbose) 96442421Syokota log(LOG_DEBUG, "kbdc: TEST_KBD_PORT status:%04x\n", c); 96542421Syokota return c; 96642421Syokota} 96742421Syokota 96842421Syokotaint 96942421Syokotatest_aux_port(KBDC p) 97042421Syokota{ 97142421Syokota int retry = KBD_MAXRETRY; 97242421Syokota int again = KBD_MAXWAIT; 97342421Syokota int c = -1; 97442421Syokota 97542421Syokota while (retry-- > 0) { 97642421Syokota empty_both_buffers(p, 10); 97742421Syokota if (write_controller_command(p, KBDC_TEST_AUX_PORT)) 97842421Syokota break; 97942421Syokota } 98042421Syokota if (retry < 0) 98142421Syokota return FALSE; 98242421Syokota 98342421Syokota emptyq(&kbdcp(p)->kbd); 98442421Syokota while (again-- > 0) { 98542421Syokota c = read_controller_data(p); 98642421Syokota if (c != -1) /* try again if the controller is not ready */ 98742421Syokota break; 98842421Syokota } 98942421Syokota if (verbose || bootverbose) 99042421Syokota log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c); 99142421Syokota return c; 99242421Syokota} 99342421Syokota 99442421Syokotaint 99542421Syokotakbdc_get_device_mask(KBDC p) 99642421Syokota{ 99742421Syokota return kbdcp(p)->command_mask; 99842421Syokota} 99942421Syokota 100042421Syokotavoid 100142421Syokotakbdc_set_device_mask(KBDC p, int mask) 100242421Syokota{ 100342421Syokota kbdcp(p)->command_mask = 100442421Syokota mask & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS); 100542421Syokota} 100642421Syokota 100742421Syokotaint 100842421Syokotaget_controller_command_byte(KBDC p) 100942421Syokota{ 101042421Syokota if (kbdcp(p)->command_byte != -1) 101142421Syokota return kbdcp(p)->command_byte; 101242421Syokota if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE)) 101342421Syokota return -1; 101442421Syokota emptyq(&kbdcp(p)->kbd); 101542421Syokota kbdcp(p)->command_byte = read_controller_data(p); 101642421Syokota return kbdcp(p)->command_byte; 101742421Syokota} 101842421Syokota 101942421Syokotaint 102042421Syokotaset_controller_command_byte(KBDC p, int mask, int command) 102142421Syokota{ 102242421Syokota if (get_controller_command_byte(p) == -1) 102342421Syokota return FALSE; 102442421Syokota 102542421Syokota command = (kbdcp(p)->command_byte & ~mask) | (command & mask); 102642421Syokota if (command & KBD_DISABLE_KBD_PORT) { 102742421Syokota if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT)) 102842421Syokota return FALSE; 102942421Syokota } 103042421Syokota if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE)) 103142421Syokota return FALSE; 103242421Syokota if (!write_controller_data(p, command)) 103342421Syokota return FALSE; 103442421Syokota kbdcp(p)->command_byte = command; 103542421Syokota 103642421Syokota if (verbose) 103742421Syokota log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n", 103842421Syokota command); 103942421Syokota 104042421Syokota return TRUE; 104142421Syokota} 1042