atkbdc.c (161969) | atkbdc.c (207354) |
---|---|
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: --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp 31 */ 32 33#include <sys/cdefs.h> | 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: --- 17 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/atkbdc/atkbdc.c 161969 2006-09-04 00:19:31Z dwhite $"); | 34__FBSDID("$FreeBSD: head/sys/dev/atkbdc/atkbdc.c 207354 2010-04-29 06:16:00Z sobomax $"); |
35 36#include "opt_kbd.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/bus.h> 41#include <sys/malloc.h> 42#include <sys/syslog.h> 43#include <machine/bus.h> 44#include <machine/resource.h> 45#include <sys/rman.h> 46 | 35 36#include "opt_kbd.h" 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/bus.h> 41#include <sys/malloc.h> 42#include <sys/syslog.h> 43#include <machine/bus.h> 44#include <machine/resource.h> 45#include <sys/rman.h> 46 |
47#if defined(__amd64__) 48#include <machine/clock.h> 49#endif 50 |
|
47#include <dev/atkbdc/atkbdcreg.h> 48 49#ifdef __sparc64__ 50#include <dev/ofw/openfirm.h> 51#include <machine/bus_private.h> 52#include <machine/ofw_machdep.h> 53#else 54#include <isa/isareg.h> --- 93 unchanged lines hidden (view full) --- 148 149/* the backdoor to the keyboard controller! XXX */ 150int 151atkbdc_configure(void) 152{ 153 bus_space_tag_t tag; 154 bus_space_handle_t h0; 155 bus_space_handle_t h1; | 51#include <dev/atkbdc/atkbdcreg.h> 52 53#ifdef __sparc64__ 54#include <dev/ofw/openfirm.h> 55#include <machine/bus_private.h> 56#include <machine/ofw_machdep.h> 57#else 58#include <isa/isareg.h> --- 93 unchanged lines hidden (view full) --- 152 153/* the backdoor to the keyboard controller! XXX */ 154int 155atkbdc_configure(void) 156{ 157 bus_space_tag_t tag; 158 bus_space_handle_t h0; 159 bus_space_handle_t h1; |
156#if defined(__i386__) | 160#if defined(__i386__) || defined(__amd64__) |
157 volatile int i; 158 register_t flags; 159#endif 160#ifdef __sparc64__ 161 char name[32]; 162 phandle_t chosen, node; 163 ihandle_t stdin; 164 bus_addr_t port0; --- 52 unchanged lines hidden (view full) --- 217 bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0); 218 bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1); 219#else 220 h0 = (bus_space_handle_t)port0; 221 h1 = (bus_space_handle_t)port1; 222#endif 223#endif 224 | 161 volatile int i; 162 register_t flags; 163#endif 164#ifdef __sparc64__ 165 char name[32]; 166 phandle_t chosen, node; 167 ihandle_t stdin; 168 bus_addr_t port0; --- 52 unchanged lines hidden (view full) --- 221 bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0); 222 bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1); 223#else 224 h0 = (bus_space_handle_t)port0; 225 h1 = (bus_space_handle_t)port1; 226#endif 227#endif 228 |
225#if defined(__i386__) | 229#if defined(__i386__) || defined(__amd64__) |
226 /* 227 * Check if we really have AT keyboard controller. Poll status 228 * register until we get "all clear" indication. If no such 229 * indication comes, it probably means that there is no AT 230 * keyboard controller present. Give up in such case. Check relies 231 * on the fact that reading from non-existing in/out port returns 232 * 0xff on i386. May or may not be true on other platforms. 233 */ --- 9 unchanged lines hidden (view full) --- 243 244 return atkbdc_setup(atkbdc_softc[0], tag, h0, h1); 245} 246 247static int 248atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0, 249 bus_space_handle_t h1) 250{ | 230 /* 231 * Check if we really have AT keyboard controller. Poll status 232 * register until we get "all clear" indication. If no such 233 * indication comes, it probably means that there is no AT 234 * keyboard controller present. Give up in such case. Check relies 235 * on the fact that reading from non-existing in/out port returns 236 * 0xff on i386. May or may not be true on other platforms. 237 */ --- 9 unchanged lines hidden (view full) --- 247 248 return atkbdc_setup(atkbdc_softc[0], tag, h0, h1); 249} 250 251static int 252atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0, 253 bus_space_handle_t h1) 254{ |
255#if defined(__amd64__) 256 u_int64_t tscval[3], read_delay; 257 register_t flags; 258#endif 259 |
|
251 if (sc->ioh0 == 0) { /* XXX */ 252 sc->command_byte = -1; 253 sc->command_mask = 0; 254 sc->lock = FALSE; 255 sc->kbd.head = sc->kbd.tail = 0; 256 sc->aux.head = sc->aux.tail = 0; 257#if KBDIO_DEBUG >= 2 258 sc->kbd.call_count = 0; 259 sc->kbd.qcount = sc->kbd.max_qcount = 0; 260 sc->aux.call_count = 0; 261 sc->aux.qcount = sc->aux.max_qcount = 0; 262#endif 263 } 264 sc->iot = tag; 265 sc->ioh0 = h0; 266 sc->ioh1 = h1; | 260 if (sc->ioh0 == 0) { /* XXX */ 261 sc->command_byte = -1; 262 sc->command_mask = 0; 263 sc->lock = FALSE; 264 sc->kbd.head = sc->kbd.tail = 0; 265 sc->aux.head = sc->aux.tail = 0; 266#if KBDIO_DEBUG >= 2 267 sc->kbd.call_count = 0; 268 sc->kbd.qcount = sc->kbd.max_qcount = 0; 269 sc->aux.call_count = 0; 270 sc->aux.qcount = sc->aux.max_qcount = 0; 271#endif 272 } 273 sc->iot = tag; 274 sc->ioh0 = h0; 275 sc->ioh1 = h1; |
276 277#if defined(__amd64__) 278 /* 279 * On certain chipsets AT keyboard controller isn't present and is 280 * emulated by BIOS using SMI interrupt. On those chipsets reading 281 * from the status port may be thousand times slower than usually. 282 * Sometimes this emilation is not working properly resulting in 283 * commands timing our and since we assume that inb() operation 284 * takes very little time to complete we need to adjust number of 285 * retries to keep waiting time within a designed limits (100ms). 286 * Measure time it takes to make read_status() call and adjust 287 * number of retries accordingly. 288 */ 289 flags = intr_disable(); 290 tscval[0] = rdtsc(); 291 read_status(sc); 292 tscval[1] = rdtsc(); 293 DELAY(1000); 294 tscval[2] = rdtsc(); 295 intr_restore(flags); 296 read_delay = tscval[1] - tscval[0]; 297 read_delay /= (tscval[2] - tscval[1]) / 1000; 298 sc->retry = 100000 / ((KBDD_DELAYTIME * 2) + read_delay); 299#else 300 sc->retry = 5000; 301#endif 302 |
|
267 return 0; 268} 269 270/* open a keyboard controller */ 271KBDC 272atkbdc_open(int unit) 273{ 274 if (unit <= 0) --- 100 unchanged lines hidden (view full) --- 375} 376 377/* 378 * device I/O routines 379 */ 380static int 381wait_while_controller_busy(struct atkbdc_softc *kbdc) 382{ | 303 return 0; 304} 305 306/* open a keyboard controller */ 307KBDC 308atkbdc_open(int unit) 309{ 310 if (unit <= 0) --- 100 unchanged lines hidden (view full) --- 411} 412 413/* 414 * device I/O routines 415 */ 416static int 417wait_while_controller_busy(struct atkbdc_softc *kbdc) 418{ |
383 /* CPU will stay inside the loop for 100msec at most */ 384 int retry = 5000; | 419 int retry; |
385 int f; 386 | 420 int f; 421 |
422 /* CPU will stay inside the loop for 100msec at most */ 423 retry = kbdc->retry; 424 |
|
387 while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) { 388 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 389 DELAY(KBDD_DELAYTIME); 390 addq(&kbdc->kbd, read_data(kbdc)); 391 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 392 DELAY(KBDD_DELAYTIME); 393 addq(&kbdc->aux, read_data(kbdc)); 394 } --- 6 unchanged lines hidden (view full) --- 401 402/* 403 * wait for any data; whether it's from the controller, 404 * the keyboard, or the aux device. 405 */ 406static int 407wait_for_data(struct atkbdc_softc *kbdc) 408{ | 425 while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) { 426 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 427 DELAY(KBDD_DELAYTIME); 428 addq(&kbdc->kbd, read_data(kbdc)); 429 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 430 DELAY(KBDD_DELAYTIME); 431 addq(&kbdc->aux, read_data(kbdc)); 432 } --- 6 unchanged lines hidden (view full) --- 439 440/* 441 * wait for any data; whether it's from the controller, 442 * the keyboard, or the aux device. 443 */ 444static int 445wait_for_data(struct atkbdc_softc *kbdc) 446{ |
409 /* CPU will stay inside the loop for 200msec at most */ 410 int retry = 10000; | 447 int retry; |
411 int f; 412 | 448 int f; 449 |
450 /* CPU will stay inside the loop for 200msec at most */ 451 retry = kbdc->retry * 2; 452 |
|
413 while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) { 414 DELAY(KBDC_DELAYTIME); 415 if (--retry < 0) 416 return 0; 417 } 418 DELAY(KBDD_DELAYTIME); 419 return f; 420} 421 422/* wait for data from the keyboard */ 423static int 424wait_for_kbd_data(struct atkbdc_softc *kbdc) 425{ | 453 while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) { 454 DELAY(KBDC_DELAYTIME); 455 if (--retry < 0) 456 return 0; 457 } 458 DELAY(KBDD_DELAYTIME); 459 return f; 460} 461 462/* wait for data from the keyboard */ 463static int 464wait_for_kbd_data(struct atkbdc_softc *kbdc) 465{ |
426 /* CPU will stay inside the loop for 200msec at most */ 427 int retry = 10000; | 466 int retry; |
428 int f; 429 | 467 int f; 468 |
469 /* CPU will stay inside the loop for 200msec at most */ 470 retry = kbdc->retry * 2; 471 |
|
430 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 431 != KBDS_KBD_BUFFER_FULL) { 432 if (f == KBDS_AUX_BUFFER_FULL) { 433 DELAY(KBDD_DELAYTIME); 434 addq(&kbdc->aux, read_data(kbdc)); 435 } 436 DELAY(KBDC_DELAYTIME); 437 if (--retry < 0) --- 5 unchanged lines hidden (view full) --- 443 444/* 445 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard. 446 * queue anything else. 447 */ 448static int 449wait_for_kbd_ack(struct atkbdc_softc *kbdc) 450{ | 472 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 473 != KBDS_KBD_BUFFER_FULL) { 474 if (f == KBDS_AUX_BUFFER_FULL) { 475 DELAY(KBDD_DELAYTIME); 476 addq(&kbdc->aux, read_data(kbdc)); 477 } 478 DELAY(KBDC_DELAYTIME); 479 if (--retry < 0) --- 5 unchanged lines hidden (view full) --- 485 486/* 487 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard. 488 * queue anything else. 489 */ 490static int 491wait_for_kbd_ack(struct atkbdc_softc *kbdc) 492{ |
451 /* CPU will stay inside the loop for 200msec at most */ 452 int retry = 10000; | 493 int retry; |
453 int f; 454 int b; 455 | 494 int f; 495 int b; 496 |
497 /* CPU will stay inside the loop for 200msec at most */ 498 retry = kbdc->retry * 2; 499 |
|
456 while (retry-- > 0) { 457 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 458 DELAY(KBDD_DELAYTIME); 459 b = read_data(kbdc); 460 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 461 if ((b == KBD_ACK) || (b == KBD_RESEND) 462 || (b == KBD_RESET_FAIL)) 463 return b; --- 6 unchanged lines hidden (view full) --- 470 } 471 return -1; 472} 473 474/* wait for data from the aux device */ 475static int 476wait_for_aux_data(struct atkbdc_softc *kbdc) 477{ | 500 while (retry-- > 0) { 501 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 502 DELAY(KBDD_DELAYTIME); 503 b = read_data(kbdc); 504 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) { 505 if ((b == KBD_ACK) || (b == KBD_RESEND) 506 || (b == KBD_RESET_FAIL)) 507 return b; --- 6 unchanged lines hidden (view full) --- 514 } 515 return -1; 516} 517 518/* wait for data from the aux device */ 519static int 520wait_for_aux_data(struct atkbdc_softc *kbdc) 521{ |
478 /* CPU will stay inside the loop for 200msec at most */ 479 int retry = 10000; | 522 int retry; |
480 int f; 481 | 523 int f; 524 |
525 /* CPU will stay inside the loop for 200msec at most */ 526 retry = kbdc->retry * 2; 527 |
|
482 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 483 != KBDS_AUX_BUFFER_FULL) { 484 if (f == KBDS_KBD_BUFFER_FULL) { 485 DELAY(KBDD_DELAYTIME); 486 addq(&kbdc->kbd, read_data(kbdc)); 487 } 488 DELAY(KBDC_DELAYTIME); 489 if (--retry < 0) --- 5 unchanged lines hidden (view full) --- 495 496/* 497 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device. 498 * queue anything else. 499 */ 500static int 501wait_for_aux_ack(struct atkbdc_softc *kbdc) 502{ | 528 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL) 529 != KBDS_AUX_BUFFER_FULL) { 530 if (f == KBDS_KBD_BUFFER_FULL) { 531 DELAY(KBDD_DELAYTIME); 532 addq(&kbdc->kbd, read_data(kbdc)); 533 } 534 DELAY(KBDC_DELAYTIME); 535 if (--retry < 0) --- 5 unchanged lines hidden (view full) --- 541 542/* 543 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device. 544 * queue anything else. 545 */ 546static int 547wait_for_aux_ack(struct atkbdc_softc *kbdc) 548{ |
503 /* CPU will stay inside the loop for 200msec at most */ 504 int retry = 10000; | 549 int retry; |
505 int f; 506 int b; 507 | 550 int f; 551 int b; 552 |
553 /* CPU will stay inside the loop for 200msec at most */ 554 retry = kbdc->retry * 2; 555 |
|
508 while (retry-- > 0) { 509 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 510 DELAY(KBDD_DELAYTIME); 511 b = read_data(kbdc); 512 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 513 if ((b == PSM_ACK) || (b == PSM_RESEND) 514 || (b == PSM_RESET_FAIL)) 515 return b; --- 605 unchanged lines hidden --- | 556 while (retry-- > 0) { 557 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) { 558 DELAY(KBDD_DELAYTIME); 559 b = read_data(kbdc); 560 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) { 561 if ((b == PSM_ACK) || (b == PSM_RESEND) 562 || (b == PSM_RESET_FAIL)) 563 return b; --- 605 unchanged lines hidden --- |