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