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