atkbdc.c revision 92661
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 92661 2002-03-19 10:53:33Z peter $ 3142421Syokota * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp 3242421Syokota */ 3342421Syokota 3442421Syokota#include "atkbdc.h" 3542421Syokota#include "opt_kbd.h" 3642421Syokota 3742421Syokota#include <sys/param.h> 3842421Syokota#include <sys/systm.h> 3958271Syokota#include <sys/bus.h> 4042421Syokota#include <sys/malloc.h> 4142421Syokota#include <sys/syslog.h> 4258271Syokota#include <machine/bus_pio.h> 4358271Syokota#include <machine/bus.h> 4458271Syokota#include <machine/resource.h> 4558271Syokota#include <sys/rman.h> 4642421Syokota 4742421Syokota 4842421Syokota#include <dev/kbd/atkbdcreg.h> 4942421Syokota 5042421Syokota#include <isa/isareg.h> 5142421Syokota 5242421Syokota/* constants */ 5342421Syokota 5456836Speter#define MAXKBDC MAX(NATKBDC, 1) /* XXX */ 5542421Syokota 5642421Syokota/* macros */ 5742421Syokota 5842421Syokota#ifndef MAX 5942421Syokota#define MAX(x, y) ((x) > (y) ? (x) : (y)) 6042421Syokota#endif 6142421Syokota 6242421Syokota#define kbdcp(p) ((atkbdc_softc_t *)(p)) 6342421Syokota#define nextq(i) (((i) + 1) % KBDQ_BUFSIZE) 6442421Syokota#define availq(q) ((q)->head != (q)->tail) 6542421Syokota#if KBDIO_DEBUG >= 2 6642421Syokota#define emptyq(q) ((q)->tail = (q)->head = (q)->qcount = 0) 6742421Syokota#else 6842421Syokota#define emptyq(q) ((q)->tail = (q)->head = 0) 6942421Syokota#endif 7042421Syokota 7158271Syokota#define read_data(k) (bus_space_read_1((k)->iot, (k)->ioh0, 0)) 7258271Syokota#define read_status(k) (bus_space_read_1((k)->iot, (k)->ioh1, 0)) 7358271Syokota#define write_data(k, d) \ 7458271Syokota (bus_space_write_1((k)->iot, (k)->ioh0, 0, (d))) 7558271Syokota#define write_command(k, d) \ 7658271Syokota (bus_space_write_1((k)->iot, (k)->ioh1, 0, (d))) 7758271Syokota 7842421Syokota/* local variables */ 7942421Syokota 8042421Syokota/* 8142421Syokota * We always need at least one copy of the kbdc_softc struct for the 8242421Syokota * low-level console. As the low-level console accesses the keyboard 8342421Syokota * controller before kbdc, and all other devices, is probed, we 8442421Syokota * statically allocate one entry. XXX 8542421Syokota */ 8642421Syokotastatic atkbdc_softc_t default_kbdc; 8742421Syokotastatic atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc }; 8842421Syokota 8942421Syokotastatic int verbose = KBDIO_DEBUG; 9042421Syokota 9142421Syokota/* function prototypes */ 9242421Syokota 9358271Syokotastatic int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, 9458271Syokota bus_space_handle_t h0, bus_space_handle_t h1); 9542421Syokotastatic int addq(kqueue *q, int c); 9642421Syokotastatic int removeq(kqueue *q); 9742421Syokotastatic int wait_while_controller_busy(atkbdc_softc_t *kbdc); 9842421Syokotastatic int wait_for_data(atkbdc_softc_t *kbdc); 9942421Syokotastatic int wait_for_kbd_data(atkbdc_softc_t *kbdc); 10042421Syokotastatic int wait_for_kbd_ack(atkbdc_softc_t *kbdc); 10142421Syokotastatic int wait_for_aux_data(atkbdc_softc_t *kbdc); 10242421Syokotastatic int wait_for_aux_ack(atkbdc_softc_t *kbdc); 10342421Syokota 10442421Syokotaatkbdc_softc_t 10542421Syokota*atkbdc_get_softc(int unit) 10642421Syokota{ 10742421Syokota atkbdc_softc_t *sc; 10842421Syokota 10942421Syokota if (unit >= sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0])) 11042421Syokota return NULL; 11142421Syokota sc = atkbdc_softc[unit]; 11242421Syokota if (sc == NULL) { 11342421Syokota sc = atkbdc_softc[unit] 11469781Sdwmalone = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO); 11542421Syokota if (sc == NULL) 11642421Syokota return NULL; 11742421Syokota } 11842421Syokota return sc; 11942421Syokota} 12042421Syokota 12142421Syokotaint 12258271Syokotaatkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1) 12342421Syokota{ 12458271Syokota if (rman_get_start(port0) <= 0) 12547296Syokota return ENXIO; 12658271Syokota if (rman_get_start(port1) <= 0) 12758271Syokota return ENXIO; 12847296Syokota return 0; 12947296Syokota} 13047296Syokota 13147296Syokotaint 13258271Syokotaatkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0, 13358271Syokota struct resource *port1) 13447296Syokota{ 13558271Syokota return atkbdc_setup(sc, rman_get_bustag(port0), 13658271Syokota rman_get_bushandle(port0), 13758271Syokota rman_get_bushandle(port1)); 13842421Syokota} 13942421Syokota 14042421Syokota/* the backdoor to the keyboard controller! XXX */ 14142421Syokotaint 14242421Syokotaatkbdc_configure(void) 14342421Syokota{ 14458271Syokota bus_space_tag_t tag; 14558271Syokota bus_space_handle_t h0; 14658271Syokota bus_space_handle_t h1; 14758271Syokota int port0; 14858271Syokota int port1; 14958271Syokota 15058271Syokota port0 = IO_KBD; 15158271Syokota resource_int_value("atkbdc", 0, "port", &port0); 15258271Syokota port1 = IO_KBD + KBD_STATUS_PORT; 15358271Syokota#if 0 15458271Syokota resource_int_value("atkbdc", 0, "port", &port0); 15558271Syokota#endif 15658271Syokota 15758271Syokota /* XXX: tag should be passed from the caller */ 15858271Syokota#if defined(__i386__) 15958271Syokota tag = I386_BUS_SPACE_IO; 16058271Syokota#elif defined(__alpha__) 16165176Sdfr tag = busspace_isa_io; 16292661Speter#elif defined(__ia64__) 16392661Speter tag = IA64_BUS_SPACE_IO; 16492661Speter#else 16592661Speter#error "define tag!" 16658271Syokota#endif 16758271Syokota 16858271Syokota#if notyet 16958271Syokota bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0); 17058271Syokota bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1); 17158271Syokota#else 17258271Syokota h0 = (bus_space_handle_t)port0; 17358271Syokota h1 = (bus_space_handle_t)port1; 17458271Syokota#endif 17558271Syokota return atkbdc_setup(atkbdc_softc[0], tag, h0, h1); 17642421Syokota} 17742421Syokota 17842421Syokotastatic int 17958271Syokotaatkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0, 18058271Syokota bus_space_handle_t h1) 18142421Syokota{ 18258271Syokota if (sc->ioh0 == 0) { /* XXX */ 18342421Syokota sc->command_byte = -1; 18442421Syokota sc->command_mask = 0; 18542421Syokota sc->lock = FALSE; 18642421Syokota sc->kbd.head = sc->kbd.tail = 0; 18742421Syokota sc->aux.head = sc->aux.tail = 0; 18842421Syokota#if KBDIO_DEBUG >= 2 18942421Syokota sc->kbd.call_count = 0; 19042421Syokota sc->kbd.qcount = sc->kbd.max_qcount = 0; 19142421Syokota sc->aux.call_count = 0; 19242421Syokota sc->aux.qcount = sc->aux.max_qcount = 0; 19342421Syokota#endif 19442421Syokota } 19558271Syokota sc->iot = tag; 19658271Syokota sc->ioh0 = h0; 19758271Syokota sc->ioh1 = h1; 19842421Syokota return 0; 19942421Syokota} 20042421Syokota 20158271Syokota/* open a keyboard controller */ 20242421SyokotaKBDC 20358271Syokotaatkbdc_open(int unit) 20442421Syokota{ 20558271Syokota if (unit <= 0) 20658271Syokota unit = 0; 20758271Syokota if (unit >= MAXKBDC) 20858271Syokota return NULL; 20958271Syokota if ((atkbdc_softc[unit]->port0 != NULL) 21058271Syokota || (atkbdc_softc[unit]->ioh0 != 0)) /* XXX */ 21158271Syokota return (KBDC)atkbdc_softc[unit]; 21242421Syokota return NULL; 21342421Syokota} 21442421Syokota 21542421Syokota/* 21642421Syokota * I/O access arbitration in `kbdio' 21742421Syokota * 21842421Syokota * The `kbdio' module uses a simplistic convention to arbitrate 21942421Syokota * I/O access to the controller/keyboard/mouse. The convention requires 22042421Syokota * close cooperation of the calling device driver. 22142421Syokota * 22242421Syokota * The device driver which utilizes the `kbdio' module are assumed to 22342421Syokota * have the following set of routines. 22442421Syokota * a. An interrupt handler (the bottom half of the driver). 22542421Syokota * b. Timeout routines which may briefly polls the keyboard controller. 22642421Syokota * c. Routines outside interrupt context (the top half of the driver). 22742421Syokota * They should follow the rules below: 22842421Syokota * 1. The interrupt handler may assume that it always has full access 22942421Syokota * to the controller/keyboard/mouse. 23042421Syokota * 2. The other routines must issue `spltty()' if they wish to 23142421Syokota * prevent the interrupt handler from accessing 23242421Syokota * the controller/keyboard/mouse. 23342421Syokota * 3. The timeout routines and the top half routines of the device driver 23442421Syokota * arbitrate I/O access by observing the lock flag in `kbdio'. 23542421Syokota * The flag is manipulated via `kbdc_lock()'; when one wants to 23642421Syokota * perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if 23742421Syokota * the call returns with TRUE. Otherwise the caller must back off. 23842421Syokota * Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion 23942421Syokota * is finished. This mechanism does not prevent the interrupt 24042421Syokota * handler from being invoked at any time and carrying out I/O. 24142421Syokota * Therefore, `spltty()' must be strategically placed in the device 24242421Syokota * driver code. Also note that the timeout routine may interrupt 24342421Syokota * `kbdc_lock()' called by the top half of the driver, but this 24442421Syokota * interruption is OK so long as the timeout routine observes the 24542421Syokota * the rule 4 below. 24642421Syokota * 4. The interrupt and timeout routines should not extend I/O operation 24742421Syokota * across more than one interrupt or timeout; they must complete 24842421Syokota * necessary I/O operation within one invokation of the routine. 24942421Syokota * This measns that if the timeout routine acquires the lock flag, 25042421Syokota * it must reset the flag to FALSE before it returns. 25142421Syokota */ 25242421Syokota 25342421Syokota/* set/reset polling lock */ 25442421Syokotaint 25542421Syokotakbdc_lock(KBDC p, int lock) 25642421Syokota{ 25742421Syokota int prevlock; 25842421Syokota 25942421Syokota prevlock = kbdcp(p)->lock; 26042421Syokota kbdcp(p)->lock = lock; 26142421Syokota 26242421Syokota return (prevlock != lock); 26342421Syokota} 26442421Syokota 26542421Syokota/* check if any data is waiting to be processed */ 26642421Syokotaint 26742421Syokotakbdc_data_ready(KBDC p) 26842421Syokota{ 26942421Syokota return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux) 27058271Syokota || (read_status(kbdcp(p)) & KBDS_ANY_BUFFER_FULL)); 27142421Syokota} 27242421Syokota 27342421Syokota/* queuing functions */ 27442421Syokota 27542421Syokotastatic int 27642421Syokotaaddq(kqueue *q, int c) 27742421Syokota{ 27842421Syokota if (nextq(q->tail) != q->head) { 27942421Syokota q->q[q->tail] = c; 28042421Syokota q->tail = nextq(q->tail); 28142421Syokota#if KBDIO_DEBUG >= 2 28242421Syokota ++q->call_count; 28342421Syokota ++q->qcount; 28442421Syokota if (q->qcount > q->max_qcount) 28542421Syokota q->max_qcount = q->qcount; 28642421Syokota#endif 28742421Syokota return TRUE; 28842421Syokota } 28942421Syokota return FALSE; 29042421Syokota} 29142421Syokota 29242421Syokotastatic int 29342421Syokotaremoveq(kqueue *q) 29442421Syokota{ 29542421Syokota int c; 29642421Syokota 29742421Syokota if (q->tail != q->head) { 29842421Syokota c = q->q[q->head]; 29942421Syokota q->head = nextq(q->head); 30042421Syokota#if KBDIO_DEBUG >= 2 30142421Syokota --q->qcount; 30242421Syokota#endif 30342421Syokota return c; 30442421Syokota } 30542421Syokota return -1; 30642421Syokota} 30742421Syokota 30842421Syokota/* 30942421Syokota * device I/O routines 31042421Syokota */ 31142421Syokotastatic int 31242421Syokotawait_while_controller_busy(struct atkbdc_softc *kbdc) 31342421Syokota{ 31442421Syokota /* CPU will stay inside the loop for 100msec at most */ 31542421Syokota int retry = 5000; 31642421Syokota int f; 31742421Syokota 31858271Syokota while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) { 31942421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 32042421Syokota DELAY(KBDD_DELAYTIME); 32158271Syokota addq(&kbdc->kbd, read_data(kbdc)); 32242421Syokota } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 32342421Syokota DELAY(KBDD_DELAYTIME); 32458271Syokota addq(&kbdc->aux, read_data(kbdc)); 32542421Syokota } 32642421Syokota DELAY(KBDC_DELAYTIME); 32742421Syokota if (--retry < 0) 32842421Syokota return FALSE; 32942421Syokota } 33042421Syokota return TRUE; 33142421Syokota} 33242421Syokota 33342421Syokota/* 33442421Syokota * wait for any data; whether it's from the controller, 33542421Syokota * the keyboard, or the aux device. 33642421Syokota */ 33742421Syokotastatic int 33842421Syokotawait_for_data(struct atkbdc_softc *kbdc) 33942421Syokota{ 34042421Syokota /* CPU will stay inside the loop for 200msec at most */ 34142421Syokota int retry = 10000; 34242421Syokota int f; 34342421Syokota 34458271Syokota while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) { 34542421Syokota DELAY(KBDC_DELAYTIME); 34642421Syokota if (--retry < 0) 34742421Syokota return 0; 34842421Syokota } 34942421Syokota DELAY(KBDD_DELAYTIME); 35042421Syokota return f; 35142421Syokota} 35242421Syokota 35342421Syokota/* wait for data from the keyboard */ 35442421Syokotastatic int 35542421Syokotawait_for_kbd_data(struct atkbdc_softc *kbdc) 35642421Syokota{ 35742421Syokota /* CPU will stay inside the loop for 200msec at most */ 35842421Syokota int retry = 10000; 35942421Syokota int f; 36042421Syokota 36158271Syokota while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 36242421Syokota != KBDS_KBD_BUFFER_FULL) { 36342421Syokota if (f == KBDS_AUX_BUFFER_FULL) { 36442421Syokota DELAY(KBDD_DELAYTIME); 36558271Syokota addq(&kbdc->aux, read_data(kbdc)); 36642421Syokota } 36742421Syokota DELAY(KBDC_DELAYTIME); 36842421Syokota if (--retry < 0) 36942421Syokota return 0; 37042421Syokota } 37142421Syokota DELAY(KBDD_DELAYTIME); 37242421Syokota return f; 37342421Syokota} 37442421Syokota 37542421Syokota/* 37642421Syokota * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard. 37742421Syokota * queue anything else. 37842421Syokota */ 37942421Syokotastatic int 38042421Syokotawait_for_kbd_ack(struct atkbdc_softc *kbdc) 38142421Syokota{ 38242421Syokota /* CPU will stay inside the loop for 200msec at most */ 38342421Syokota int retry = 10000; 38442421Syokota int f; 38542421Syokota int b; 38642421Syokota 38742421Syokota while (retry-- > 0) { 38858271Syokota if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 38942421Syokota DELAY(KBDD_DELAYTIME); 39058271Syokota b = read_data(kbdc); 39142421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 39242421Syokota if ((b == KBD_ACK) || (b == KBD_RESEND) 39342421Syokota || (b == KBD_RESET_FAIL)) 39442421Syokota return b; 39542421Syokota addq(&kbdc->kbd, b); 39642421Syokota } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 39742421Syokota addq(&kbdc->aux, b); 39842421Syokota } 39942421Syokota } 40042421Syokota DELAY(KBDC_DELAYTIME); 40142421Syokota } 40242421Syokota return -1; 40342421Syokota} 40442421Syokota 40542421Syokota/* wait for data from the aux device */ 40642421Syokotastatic int 40742421Syokotawait_for_aux_data(struct atkbdc_softc *kbdc) 40842421Syokota{ 40942421Syokota /* CPU will stay inside the loop for 200msec at most */ 41042421Syokota int retry = 10000; 41142421Syokota int f; 41242421Syokota 41358271Syokota while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 41442421Syokota != KBDS_AUX_BUFFER_FULL) { 41542421Syokota if (f == KBDS_KBD_BUFFER_FULL) { 41642421Syokota DELAY(KBDD_DELAYTIME); 41758271Syokota addq(&kbdc->kbd, read_data(kbdc)); 41842421Syokota } 41942421Syokota DELAY(KBDC_DELAYTIME); 42042421Syokota if (--retry < 0) 42142421Syokota return 0; 42242421Syokota } 42342421Syokota DELAY(KBDD_DELAYTIME); 42442421Syokota return f; 42542421Syokota} 42642421Syokota 42742421Syokota/* 42842421Syokota * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device. 42942421Syokota * queue anything else. 43042421Syokota */ 43142421Syokotastatic int 43242421Syokotawait_for_aux_ack(struct atkbdc_softc *kbdc) 43342421Syokota{ 43442421Syokota /* CPU will stay inside the loop for 200msec at most */ 43542421Syokota int retry = 10000; 43642421Syokota int f; 43742421Syokota int b; 43842421Syokota 43942421Syokota while (retry-- > 0) { 44058271Syokota if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 44142421Syokota DELAY(KBDD_DELAYTIME); 44258271Syokota b = read_data(kbdc); 44342421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 44442421Syokota if ((b == PSM_ACK) || (b == PSM_RESEND) 44542421Syokota || (b == PSM_RESET_FAIL)) 44642421Syokota return b; 44742421Syokota addq(&kbdc->aux, b); 44842421Syokota } else if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 44942421Syokota addq(&kbdc->kbd, b); 45042421Syokota } 45142421Syokota } 45242421Syokota DELAY(KBDC_DELAYTIME); 45342421Syokota } 45442421Syokota return -1; 45542421Syokota} 45642421Syokota 45742421Syokota/* write a one byte command to the controller */ 45842421Syokotaint 45942421Syokotawrite_controller_command(KBDC p, int c) 46042421Syokota{ 46142421Syokota if (!wait_while_controller_busy(kbdcp(p))) 46242421Syokota return FALSE; 46358271Syokota write_command(kbdcp(p), c); 46442421Syokota return TRUE; 46542421Syokota} 46642421Syokota 46742421Syokota/* write a one byte data to the controller */ 46842421Syokotaint 46942421Syokotawrite_controller_data(KBDC p, int c) 47042421Syokota{ 47142421Syokota if (!wait_while_controller_busy(kbdcp(p))) 47242421Syokota return FALSE; 47358271Syokota write_data(kbdcp(p), c); 47442421Syokota return TRUE; 47542421Syokota} 47642421Syokota 47742421Syokota/* write a one byte keyboard command */ 47842421Syokotaint 47942421Syokotawrite_kbd_command(KBDC p, int c) 48042421Syokota{ 48142421Syokota if (!wait_while_controller_busy(kbdcp(p))) 48242421Syokota return FALSE; 48358271Syokota write_data(kbdcp(p), c); 48442421Syokota return TRUE; 48542421Syokota} 48642421Syokota 48742421Syokota/* write a one byte auxiliary device command */ 48842421Syokotaint 48942421Syokotawrite_aux_command(KBDC p, int c) 49042421Syokota{ 49142421Syokota if (!write_controller_command(p, KBDC_WRITE_TO_AUX)) 49242421Syokota return FALSE; 49342421Syokota return write_controller_data(p, c); 49442421Syokota} 49542421Syokota 49642421Syokota/* send a command to the keyboard and wait for ACK */ 49742421Syokotaint 49842421Syokotasend_kbd_command(KBDC p, int c) 49942421Syokota{ 50042421Syokota int retry = KBD_MAXRETRY; 50142421Syokota int res = -1; 50242421Syokota 50342421Syokota while (retry-- > 0) { 50442421Syokota if (!write_kbd_command(p, c)) 50542421Syokota continue; 50642421Syokota res = wait_for_kbd_ack(kbdcp(p)); 50742421Syokota if (res == KBD_ACK) 50842421Syokota break; 50942421Syokota } 51042421Syokota return res; 51142421Syokota} 51242421Syokota 51342421Syokota/* send a command to the auxiliary device and wait for ACK */ 51442421Syokotaint 51542421Syokotasend_aux_command(KBDC p, int c) 51642421Syokota{ 51742421Syokota int retry = KBD_MAXRETRY; 51842421Syokota int res = -1; 51942421Syokota 52042421Syokota while (retry-- > 0) { 52142421Syokota if (!write_aux_command(p, c)) 52242421Syokota continue; 52342421Syokota /* 52442421Syokota * FIXME: XXX 52542421Syokota * The aux device may have already sent one or two bytes of 52642421Syokota * status data, when a command is received. It will immediately 52742421Syokota * stop data transmission, thus, leaving an incomplete data 52842421Syokota * packet in our buffer. We have to discard any unprocessed 52942421Syokota * data in order to remove such packets. Well, we may remove 53042421Syokota * unprocessed, but necessary data byte as well... 53142421Syokota */ 53242421Syokota emptyq(&kbdcp(p)->aux); 53342421Syokota res = wait_for_aux_ack(kbdcp(p)); 53442421Syokota if (res == PSM_ACK) 53542421Syokota break; 53642421Syokota } 53742421Syokota return res; 53842421Syokota} 53942421Syokota 54042421Syokota/* send a command and a data to the keyboard, wait for ACKs */ 54142421Syokotaint 54242421Syokotasend_kbd_command_and_data(KBDC p, int c, int d) 54342421Syokota{ 54442421Syokota int retry; 54542421Syokota int res = -1; 54642421Syokota 54742421Syokota for (retry = KBD_MAXRETRY; retry > 0; --retry) { 54842421Syokota if (!write_kbd_command(p, c)) 54942421Syokota continue; 55042421Syokota res = wait_for_kbd_ack(kbdcp(p)); 55142421Syokota if (res == KBD_ACK) 55242421Syokota break; 55342421Syokota else if (res != KBD_RESEND) 55442421Syokota return res; 55542421Syokota } 55642421Syokota if (retry <= 0) 55742421Syokota return res; 55842421Syokota 55942421Syokota for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) { 56042421Syokota if (!write_kbd_command(p, d)) 56142421Syokota continue; 56242421Syokota res = wait_for_kbd_ack(kbdcp(p)); 56342421Syokota if (res != KBD_RESEND) 56442421Syokota break; 56542421Syokota } 56642421Syokota return res; 56742421Syokota} 56842421Syokota 56942421Syokota/* send a command and a data to the auxiliary device, wait for ACKs */ 57042421Syokotaint 57142421Syokotasend_aux_command_and_data(KBDC p, int c, int d) 57242421Syokota{ 57342421Syokota int retry; 57442421Syokota int res = -1; 57542421Syokota 57642421Syokota for (retry = KBD_MAXRETRY; retry > 0; --retry) { 57742421Syokota if (!write_aux_command(p, c)) 57842421Syokota continue; 57942421Syokota emptyq(&kbdcp(p)->aux); 58042421Syokota res = wait_for_aux_ack(kbdcp(p)); 58142421Syokota if (res == PSM_ACK) 58242421Syokota break; 58342421Syokota else if (res != PSM_RESEND) 58442421Syokota return res; 58542421Syokota } 58642421Syokota if (retry <= 0) 58742421Syokota return res; 58842421Syokota 58942421Syokota for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) { 59042421Syokota if (!write_aux_command(p, d)) 59142421Syokota continue; 59242421Syokota res = wait_for_aux_ack(kbdcp(p)); 59342421Syokota if (res != PSM_RESEND) 59442421Syokota break; 59542421Syokota } 59642421Syokota return res; 59742421Syokota} 59842421Syokota 59942421Syokota/* 60042421Syokota * read one byte from any source; whether from the controller, 60142421Syokota * the keyboard, or the aux device 60242421Syokota */ 60342421Syokotaint 60442421Syokotaread_controller_data(KBDC p) 60542421Syokota{ 60642421Syokota if (availq(&kbdcp(p)->kbd)) 60742421Syokota return removeq(&kbdcp(p)->kbd); 60842421Syokota if (availq(&kbdcp(p)->aux)) 60942421Syokota return removeq(&kbdcp(p)->aux); 61042421Syokota if (!wait_for_data(kbdcp(p))) 61142421Syokota return -1; /* timeout */ 61258271Syokota return read_data(kbdcp(p)); 61342421Syokota} 61442421Syokota 61542421Syokota#if KBDIO_DEBUG >= 2 61642421Syokotastatic int call = 0; 61742421Syokota#endif 61842421Syokota 61942421Syokota/* read one byte from the keyboard */ 62042421Syokotaint 62142421Syokotaread_kbd_data(KBDC p) 62242421Syokota{ 62342421Syokota#if KBDIO_DEBUG >= 2 62442421Syokota if (++call > 2000) { 62542421Syokota call = 0; 62642421Syokota log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, " 62742421Syokota "aux q: %d calls, max %d chars\n", 62842421Syokota kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount, 62942421Syokota kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount); 63042421Syokota } 63142421Syokota#endif 63242421Syokota 63342421Syokota if (availq(&kbdcp(p)->kbd)) 63442421Syokota return removeq(&kbdcp(p)->kbd); 63542421Syokota if (!wait_for_kbd_data(kbdcp(p))) 63642421Syokota return -1; /* timeout */ 63758271Syokota return read_data(kbdcp(p)); 63842421Syokota} 63942421Syokota 64042421Syokota/* read one byte from the keyboard, but return immediately if 64142421Syokota * no data is waiting 64242421Syokota */ 64342421Syokotaint 64442421Syokotaread_kbd_data_no_wait(KBDC p) 64542421Syokota{ 64642421Syokota int f; 64742421Syokota 64842421Syokota#if KBDIO_DEBUG >= 2 64942421Syokota if (++call > 2000) { 65042421Syokota call = 0; 65142421Syokota log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, " 65242421Syokota "aux q: %d calls, max %d chars\n", 65342421Syokota kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount, 65442421Syokota kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount); 65542421Syokota } 65642421Syokota#endif 65742421Syokota 65842421Syokota if (availq(&kbdcp(p)->kbd)) 65942421Syokota return removeq(&kbdcp(p)->kbd); 66058271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 66142421Syokota if (f == KBDS_AUX_BUFFER_FULL) { 66242421Syokota DELAY(KBDD_DELAYTIME); 66358271Syokota addq(&kbdcp(p)->aux, read_data(kbdcp(p))); 66458271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 66542421Syokota } 66642421Syokota if (f == KBDS_KBD_BUFFER_FULL) { 66742421Syokota DELAY(KBDD_DELAYTIME); 66858271Syokota return read_data(kbdcp(p)); 66942421Syokota } 67042421Syokota return -1; /* no data */ 67142421Syokota} 67242421Syokota 67342421Syokota/* read one byte from the aux device */ 67442421Syokotaint 67542421Syokotaread_aux_data(KBDC p) 67642421Syokota{ 67742421Syokota if (availq(&kbdcp(p)->aux)) 67842421Syokota return removeq(&kbdcp(p)->aux); 67942421Syokota if (!wait_for_aux_data(kbdcp(p))) 68042421Syokota return -1; /* timeout */ 68158271Syokota return read_data(kbdcp(p)); 68242421Syokota} 68342421Syokota 68442421Syokota/* read one byte from the aux device, but return immediately if 68542421Syokota * no data is waiting 68642421Syokota */ 68742421Syokotaint 68842421Syokotaread_aux_data_no_wait(KBDC p) 68942421Syokota{ 69042421Syokota int f; 69142421Syokota 69242421Syokota if (availq(&kbdcp(p)->aux)) 69342421Syokota return removeq(&kbdcp(p)->aux); 69458271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 69542421Syokota if (f == KBDS_KBD_BUFFER_FULL) { 69642421Syokota DELAY(KBDD_DELAYTIME); 69758271Syokota addq(&kbdcp(p)->kbd, read_data(kbdcp(p))); 69858271Syokota f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL; 69942421Syokota } 70042421Syokota if (f == KBDS_AUX_BUFFER_FULL) { 70142421Syokota DELAY(KBDD_DELAYTIME); 70258271Syokota return read_data(kbdcp(p)); 70342421Syokota } 70442421Syokota return -1; /* no data */ 70542421Syokota} 70642421Syokota 70742421Syokota/* discard data from the keyboard */ 70842421Syokotavoid 70942421Syokotaempty_kbd_buffer(KBDC p, int wait) 71042421Syokota{ 71142421Syokota int t; 71242421Syokota int b; 71342421Syokota int f; 71442421Syokota#if KBDIO_DEBUG >= 2 71542421Syokota int c1 = 0; 71642421Syokota int c2 = 0; 71742421Syokota#endif 71842421Syokota int delta = 2; 71942421Syokota 72042421Syokota for (t = wait; t > 0; ) { 72158271Syokota if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) { 72242421Syokota DELAY(KBDD_DELAYTIME); 72358271Syokota b = read_data(kbdcp(p)); 72442421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 72542421Syokota addq(&kbdcp(p)->aux, b); 72642421Syokota#if KBDIO_DEBUG >= 2 72742421Syokota ++c2; 72842421Syokota } else { 72942421Syokota ++c1; 73042421Syokota#endif 73142421Syokota } 73242421Syokota t = wait; 73342421Syokota } else { 73442421Syokota t -= delta; 73542421Syokota } 73642421Syokota DELAY(delta*1000); 73742421Syokota } 73842421Syokota#if KBDIO_DEBUG >= 2 73942421Syokota if ((c1 > 0) || (c2 > 0)) 74042421Syokota log(LOG_DEBUG, "kbdc: %d:%d char read (empty_kbd_buffer)\n", c1, c2); 74142421Syokota#endif 74242421Syokota 74342421Syokota emptyq(&kbdcp(p)->kbd); 74442421Syokota} 74542421Syokota 74642421Syokota/* discard data from the aux device */ 74742421Syokotavoid 74842421Syokotaempty_aux_buffer(KBDC p, int wait) 74942421Syokota{ 75042421Syokota int t; 75142421Syokota int b; 75242421Syokota int f; 75342421Syokota#if KBDIO_DEBUG >= 2 75442421Syokota int c1 = 0; 75542421Syokota int c2 = 0; 75642421Syokota#endif 75742421Syokota int delta = 2; 75842421Syokota 75942421Syokota for (t = wait; t > 0; ) { 76058271Syokota if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) { 76142421Syokota DELAY(KBDD_DELAYTIME); 76258271Syokota b = read_data(kbdcp(p)); 76342421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 76442421Syokota addq(&kbdcp(p)->kbd, b); 76542421Syokota#if KBDIO_DEBUG >= 2 76642421Syokota ++c1; 76742421Syokota } else { 76842421Syokota ++c2; 76942421Syokota#endif 77042421Syokota } 77142421Syokota t = wait; 77242421Syokota } else { 77342421Syokota t -= delta; 77442421Syokota } 77542421Syokota DELAY(delta*1000); 77642421Syokota } 77742421Syokota#if KBDIO_DEBUG >= 2 77842421Syokota if ((c1 > 0) || (c2 > 0)) 77942421Syokota log(LOG_DEBUG, "kbdc: %d:%d char read (empty_aux_buffer)\n", c1, c2); 78042421Syokota#endif 78142421Syokota 78242421Syokota emptyq(&kbdcp(p)->aux); 78342421Syokota} 78442421Syokota 78542421Syokota/* discard any data from the keyboard or the aux device */ 78642421Syokotavoid 78742421Syokotaempty_both_buffers(KBDC p, int wait) 78842421Syokota{ 78942421Syokota int t; 79042421Syokota int f; 79142421Syokota#if KBDIO_DEBUG >= 2 79242421Syokota int c1 = 0; 79342421Syokota int c2 = 0; 79442421Syokota#endif 79542421Syokota int delta = 2; 79642421Syokota 79742421Syokota for (t = wait; t > 0; ) { 79858271Syokota if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) { 79942421Syokota DELAY(KBDD_DELAYTIME); 80058271Syokota (void)read_data(kbdcp(p)); 80142421Syokota#if KBDIO_DEBUG >= 2 80242421Syokota if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) 80342421Syokota ++c1; 80442421Syokota else 80542421Syokota ++c2; 80642421Syokota#endif 80742421Syokota t = wait; 80842421Syokota } else { 80942421Syokota t -= delta; 81042421Syokota } 81142421Syokota DELAY(delta*1000); 81242421Syokota } 81342421Syokota#if KBDIO_DEBUG >= 2 81442421Syokota if ((c1 > 0) || (c2 > 0)) 81542421Syokota log(LOG_DEBUG, "kbdc: %d:%d char read (empty_both_buffers)\n", c1, c2); 81642421Syokota#endif 81742421Syokota 81842421Syokota emptyq(&kbdcp(p)->kbd); 81942421Syokota emptyq(&kbdcp(p)->aux); 82042421Syokota} 82142421Syokota 82242421Syokota/* keyboard and mouse device control */ 82342421Syokota 82442421Syokota/* NOTE: enable the keyboard port but disable the keyboard 82542421Syokota * interrupt before calling "reset_kbd()". 82642421Syokota */ 82742421Syokotaint 82842421Syokotareset_kbd(KBDC p) 82942421Syokota{ 83042421Syokota int retry = KBD_MAXRETRY; 83142421Syokota int again = KBD_MAXWAIT; 83242421Syokota int c = KBD_RESEND; /* keep the compiler happy */ 83342421Syokota 83442421Syokota while (retry-- > 0) { 83542421Syokota empty_both_buffers(p, 10); 83642421Syokota if (!write_kbd_command(p, KBDC_RESET_KBD)) 83742421Syokota continue; 83842421Syokota emptyq(&kbdcp(p)->kbd); 83942421Syokota c = read_controller_data(p); 84042421Syokota if (verbose || bootverbose) 84142421Syokota log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c); 84242421Syokota if (c == KBD_ACK) /* keyboard has agreed to reset itself... */ 84342421Syokota break; 84442421Syokota } 84542421Syokota if (retry < 0) 84642421Syokota return FALSE; 84742421Syokota 84842421Syokota while (again-- > 0) { 84942421Syokota /* wait awhile, well, in fact we must wait quite loooooooooooong */ 85042421Syokota DELAY(KBD_RESETDELAY*1000); 85142421Syokota c = read_controller_data(p); /* RESET_DONE/RESET_FAIL */ 85242421Syokota if (c != -1) /* wait again if the controller is not ready */ 85342421Syokota break; 85442421Syokota } 85542421Syokota if (verbose || bootverbose) 85642421Syokota log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c); 85742421Syokota if (c != KBD_RESET_DONE) 85842421Syokota return FALSE; 85942421Syokota return TRUE; 86042421Syokota} 86142421Syokota 86242421Syokota/* NOTE: enable the aux port but disable the aux interrupt 86342421Syokota * before calling `reset_aux_dev()'. 86442421Syokota */ 86542421Syokotaint 86642421Syokotareset_aux_dev(KBDC p) 86742421Syokota{ 86842421Syokota int retry = KBD_MAXRETRY; 86942421Syokota int again = KBD_MAXWAIT; 87042421Syokota int c = PSM_RESEND; /* keep the compiler happy */ 87142421Syokota 87242421Syokota while (retry-- > 0) { 87342421Syokota empty_both_buffers(p, 10); 87442421Syokota if (!write_aux_command(p, PSMC_RESET_DEV)) 87542421Syokota continue; 87642421Syokota emptyq(&kbdcp(p)->aux); 87742421Syokota /* NOTE: Compaq Armada laptops require extra delay here. XXX */ 87842421Syokota for (again = KBD_MAXWAIT; again > 0; --again) { 87942421Syokota DELAY(KBD_RESETDELAY*1000); 88042421Syokota c = read_aux_data_no_wait(p); 88142421Syokota if (c != -1) 88242421Syokota break; 88342421Syokota } 88442421Syokota if (verbose || bootverbose) 88542421Syokota log(LOG_DEBUG, "kbdc: RESET_AUX return code:%04x\n", c); 88642421Syokota if (c == PSM_ACK) /* aux dev is about to reset... */ 88742421Syokota break; 88842421Syokota } 88942421Syokota if (retry < 0) 89042421Syokota return FALSE; 89142421Syokota 89242421Syokota for (again = KBD_MAXWAIT; again > 0; --again) { 89342421Syokota /* wait awhile, well, quite looooooooooooong */ 89442421Syokota DELAY(KBD_RESETDELAY*1000); 89542421Syokota c = read_aux_data_no_wait(p); /* RESET_DONE/RESET_FAIL */ 89642421Syokota if (c != -1) /* wait again if the controller is not ready */ 89742421Syokota break; 89842421Syokota } 89942421Syokota if (verbose || bootverbose) 90042421Syokota log(LOG_DEBUG, "kbdc: RESET_AUX status:%04x\n", c); 90142421Syokota if (c != PSM_RESET_DONE) /* reset status */ 90242421Syokota return FALSE; 90342421Syokota 90442421Syokota c = read_aux_data(p); /* device ID */ 90542421Syokota if (verbose || bootverbose) 90642421Syokota log(LOG_DEBUG, "kbdc: RESET_AUX ID:%04x\n", c); 90742421Syokota /* NOTE: we could check the device ID now, but leave it later... */ 90842421Syokota return TRUE; 90942421Syokota} 91042421Syokota 91142421Syokota/* controller diagnostics and setup */ 91242421Syokota 91342421Syokotaint 91442421Syokotatest_controller(KBDC p) 91542421Syokota{ 91642421Syokota int retry = KBD_MAXRETRY; 91742421Syokota int again = KBD_MAXWAIT; 91842421Syokota int c = KBD_DIAG_FAIL; 91942421Syokota 92042421Syokota while (retry-- > 0) { 92142421Syokota empty_both_buffers(p, 10); 92242421Syokota if (write_controller_command(p, KBDC_DIAGNOSE)) 92342421Syokota break; 92442421Syokota } 92542421Syokota if (retry < 0) 92642421Syokota return FALSE; 92742421Syokota 92842421Syokota emptyq(&kbdcp(p)->kbd); 92942421Syokota while (again-- > 0) { 93042421Syokota /* wait awhile */ 93142421Syokota DELAY(KBD_RESETDELAY*1000); 93242421Syokota c = read_controller_data(p); /* DIAG_DONE/DIAG_FAIL */ 93342421Syokota if (c != -1) /* wait again if the controller is not ready */ 93442421Syokota break; 93542421Syokota } 93642421Syokota if (verbose || bootverbose) 93742421Syokota log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c); 93842421Syokota return (c == KBD_DIAG_DONE); 93942421Syokota} 94042421Syokota 94142421Syokotaint 94242421Syokotatest_kbd_port(KBDC p) 94342421Syokota{ 94442421Syokota int retry = KBD_MAXRETRY; 94542421Syokota int again = KBD_MAXWAIT; 94642421Syokota int c = -1; 94742421Syokota 94842421Syokota while (retry-- > 0) { 94942421Syokota empty_both_buffers(p, 10); 95042421Syokota if (write_controller_command(p, KBDC_TEST_KBD_PORT)) 95142421Syokota break; 95242421Syokota } 95342421Syokota if (retry < 0) 95442421Syokota return FALSE; 95542421Syokota 95642421Syokota emptyq(&kbdcp(p)->kbd); 95742421Syokota while (again-- > 0) { 95842421Syokota c = read_controller_data(p); 95942421Syokota if (c != -1) /* try again if the controller is not ready */ 96042421Syokota break; 96142421Syokota } 96242421Syokota if (verbose || bootverbose) 96342421Syokota log(LOG_DEBUG, "kbdc: TEST_KBD_PORT status:%04x\n", c); 96442421Syokota return c; 96542421Syokota} 96642421Syokota 96742421Syokotaint 96842421Syokotatest_aux_port(KBDC p) 96942421Syokota{ 97042421Syokota int retry = KBD_MAXRETRY; 97142421Syokota int again = KBD_MAXWAIT; 97242421Syokota int c = -1; 97342421Syokota 97442421Syokota while (retry-- > 0) { 97542421Syokota empty_both_buffers(p, 10); 97642421Syokota if (write_controller_command(p, KBDC_TEST_AUX_PORT)) 97742421Syokota break; 97842421Syokota } 97942421Syokota if (retry < 0) 98042421Syokota return FALSE; 98142421Syokota 98242421Syokota emptyq(&kbdcp(p)->kbd); 98342421Syokota while (again-- > 0) { 98442421Syokota c = read_controller_data(p); 98542421Syokota if (c != -1) /* try again if the controller is not ready */ 98642421Syokota break; 98742421Syokota } 98842421Syokota if (verbose || bootverbose) 98942421Syokota log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c); 99042421Syokota return c; 99142421Syokota} 99242421Syokota 99342421Syokotaint 99442421Syokotakbdc_get_device_mask(KBDC p) 99542421Syokota{ 99642421Syokota return kbdcp(p)->command_mask; 99742421Syokota} 99842421Syokota 99942421Syokotavoid 100042421Syokotakbdc_set_device_mask(KBDC p, int mask) 100142421Syokota{ 100242421Syokota kbdcp(p)->command_mask = 100342421Syokota mask & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS); 100442421Syokota} 100542421Syokota 100642421Syokotaint 100742421Syokotaget_controller_command_byte(KBDC p) 100842421Syokota{ 100942421Syokota if (kbdcp(p)->command_byte != -1) 101042421Syokota return kbdcp(p)->command_byte; 101142421Syokota if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE)) 101242421Syokota return -1; 101342421Syokota emptyq(&kbdcp(p)->kbd); 101442421Syokota kbdcp(p)->command_byte = read_controller_data(p); 101542421Syokota return kbdcp(p)->command_byte; 101642421Syokota} 101742421Syokota 101842421Syokotaint 101942421Syokotaset_controller_command_byte(KBDC p, int mask, int command) 102042421Syokota{ 102142421Syokota if (get_controller_command_byte(p) == -1) 102242421Syokota return FALSE; 102342421Syokota 102442421Syokota command = (kbdcp(p)->command_byte & ~mask) | (command & mask); 102542421Syokota if (command & KBD_DISABLE_KBD_PORT) { 102642421Syokota if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT)) 102742421Syokota return FALSE; 102842421Syokota } 102942421Syokota if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE)) 103042421Syokota return FALSE; 103142421Syokota if (!write_controller_data(p, command)) 103242421Syokota return FALSE; 103342421Syokota kbdcp(p)->command_byte = command; 103442421Syokota 103542421Syokota if (verbose) 103642421Syokota log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n", 103742421Syokota command); 103842421Syokota 103942421Syokota return TRUE; 104042421Syokota} 1041