1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/ddi.h> 28 #include <sys/inline.h> 29 #include <sys/conf.h> 30 #include <sys/sunddi.h> 31 #include <sys/sunndi.h> 32 #include <sys/i8042.h> 33 #include <sys/kmem.h> 34 #include <sys/promif.h> /* for prom_printf */ 35 #include <sys/note.h> 36 37 /* 38 * Note: For x86, this driver is used to create keyboard/mouse nodes when 39 * booting with ACPI enumeration turned off (acpi-enum=off). 40 */ 41 42 /* 43 * Unfortunately, soft interrupts are implemented poorly. Each additional 44 * soft interrupt user impacts the performance of all existing soft interrupt 45 * users. This is not the case on SPARC, however. 46 */ 47 #ifdef __sparc 48 #define USE_SOFT_INTRS 49 #else 50 #undef USE_SOFT_INTRS 51 #endif 52 53 /* 54 * The command bytes are different for x86 and for SPARC because on x86, 55 * all modern 8042s can properly translate scan code set 2 codes to 56 * scan code set 1. On SPARC systems that have 8042s (e.g. Tadpole laptops), 57 * setting the "translation" bit in the command byte has no effect. 58 * This is potentially dangerous if, in the future, new SPARC systems uses 8042s 59 * that implement the scan code translation when the translation bit is set. 60 * 61 * On SPARC, kb8042 will attempt to detect which scan code set the keyboard 62 * is using. In order for that code to work, the real scan code set must be the 63 * set that is returned by the keyboard (and not a different set that is 64 * translated by the 8042). (e.g. If the translation bit were enabled here, 65 * and the keyboard returned scan code set 2 when kb8042 queried it, kb8042 66 * would not be able to know with certainty that the scan codes it will receive 67 * are set 2 scancodes, or set 1 translations made by the 8042). 68 */ 69 70 /* 71 * 8042 Command Byte Layout: 72 * 73 * 0x80: 0 = Reserved, must be zero. 74 * 0x40: 1 = Translate to XT codes. (0=No translation) 75 * 0x20: 1 = Disable aux (mouse) port. (0=Enable port) 76 * 0x10: 1 = Disable main (keyboard) port. (0=Enable port) 77 * 0x08: 0 = Reserved, must be zero. 78 * 0x04: 1 = System flag, 1 means passed self-test. 79 * Caution: setting this bit to zero causes some 80 * systems (HP Kayak XA) to fail to reboot without 81 * a hard reset. 82 * 0x02: 0 = Disable aux port interrupts. (1=Enable aux port interrupts) 83 * 0x01: 0 = Disable main port interrupts. (1=Enable main port interrupts) 84 * 85 */ 86 #if defined(__sparc) 87 #define I8042_CMD_DISABLE_ALL 0x34 88 #define I8042_CMD_ENABLE_ALL 0x07 89 #elif defined(__i386) || defined(__amd64) 90 #define I8042_CMD_DISABLE_ALL 0x74 91 #define I8042_CMD_ENABLE_ALL 0x47 92 #endif 93 94 #define BUFSIZ 64 95 96 /* 97 * Child nodes, used to determine which to create at bus_config time 98 */ 99 #define I8042_KEYBOARD 2 100 #define I8042_MOUSE 1 101 102 enum i8042_ports { 103 MAIN_PORT = 0, 104 AUX_PORT 105 }; 106 107 #define NUM_PORTS 2 108 109 /* 110 * Only register at most MAX_INTERRUPTS interrupt handlers, 111 * regardless of the number of interrupts in the prom node. 112 * This is important, as registering for all interrupts on 113 * some systems (e.g. Tadpole laptops) results in a flood 114 * of spurious interrupts (for Tadpole, the first 2 interrupts 115 * are for the keyboard and mouse, respectively, and the 116 * third is for a proprietary device that is also accessed 117 * via the same I/O addresses.) 118 */ 119 #define MAX_INTERRUPTS 2 120 121 /* 122 * One of these for each port - main (keyboard) and aux (mouse). 123 */ 124 struct i8042_port { 125 boolean_t initialized; 126 dev_info_t *dip; 127 int inumber; 128 enum i8042_ports which; /* main or aux port */ 129 #if defined(USE_SOFT_INTRS) 130 ddi_softint_handle_t soft_hdl; 131 boolean_t soft_intr_enabled; 132 #else 133 kmutex_t intr_mutex; 134 #endif 135 uint_t (*intr_func)(caddr_t arg1, caddr_t arg2); 136 caddr_t intr_arg1; 137 caddr_t intr_arg2; 138 struct i8042 *i8042_global; 139 /* 140 * wptr is next byte to write 141 */ 142 int wptr; 143 /* 144 * rptr is next byte to read, == wptr means empty 145 * NB: At full, one byte is unused. 146 */ 147 int rptr; 148 int overruns; 149 unsigned char buf[BUFSIZ]; 150 /* 151 * has_glock is 1 if this child has the [put8] exclusive-access lock. 152 */ 153 volatile boolean_t has_glock; 154 }; 155 156 /* 157 * Describes entire 8042 device. 158 */ 159 struct i8042 { 160 dev_info_t *dip; 161 struct i8042_port i8042_ports[NUM_PORTS]; 162 kmutex_t i8042_mutex; 163 kmutex_t i8042_out_mutex; 164 boolean_t initialized; 165 ddi_acc_handle_t io_handle; 166 uint8_t *io_addr; 167 int nintrs; 168 ddi_iblock_cookie_t *iblock_cookies; 169 uint_t init_state; 170 /* Initialization states: */ 171 #define I8042_INIT_BASIC 0x00000001 172 #define I8042_INIT_REGS_MAPPED 0x00000002 173 #define I8042_INIT_MUTEXES 0x00000004 174 #define I8042_INIT_INTRS_ENABLED 0x00000010 175 uint_t intrs_added; 176 #ifdef __sparc 177 timeout_id_t timeout_id; 178 #endif 179 /* 180 * glock is 1 if any child has the [put8] exclusive-access lock 181 * glock_cv is associated with the condition `glock == 0' 182 */ 183 volatile int glock; 184 /* 185 * Callers awaiting exclusive access in i8042_put8 sleep on glock_cv 186 * and are signaled when another child relinquishes exclusive access. 187 */ 188 kcondvar_t glock_cv; 189 }; 190 191 /* 192 * i8042 hardware register definitions 193 */ 194 195 /* 196 * These are I/O registers, relative to the device's base (normally 0x60). 197 */ 198 #define I8042_DATA 0x00 /* read/write data here */ 199 #define I8042_STAT 0x04 /* read status here */ 200 #define I8042_CMD 0x04 /* write commands here */ 201 202 /* 203 * These are bits in I8042_STAT. 204 */ 205 #define I8042_STAT_OUTBF 0x01 /* Output (to host) buffer full */ 206 #define I8042_STAT_INBF 0x02 /* Input (from host) buffer full */ 207 #define I8042_STAT_AUXBF 0x20 /* Output buffer data is from aux */ 208 209 /* 210 * These are commands to the i8042 itself (as distinct from the devices 211 * attached to it). 212 */ 213 #define I8042_CMD_RCB 0x20 /* Read command byte (we don't use) */ 214 #define I8042_CMD_WCB 0x60 /* Write command byte */ 215 #define I8042_CMD_WRITE_AUX 0xD4 /* Send next data byte to aux port */ 216 217 /* 218 * Maximum number of times to loop while clearing pending data from the 219 * keyboard controller. 220 */ 221 #define MAX_JUNK_ITERATIONS 1000 222 223 /* 224 * Maximum time to wait for the keyboard to become ready to accept data 225 * (maximum time = MAX_WAIT_ITERATIONS * USECS_PER_WAIT (default is 250ms)) 226 */ 227 #define MAX_WAIT_ITERATIONS 25000 228 #define USECS_PER_WAIT 10 229 230 231 #ifdef __sparc 232 233 #define PLATFORM_MATCH(s) (strncmp(ddi_get_name(ddi_root_node()), \ 234 (s), strlen(s)) == 0) 235 236 /* 237 * On some older SPARC platforms that have problems with the 238 * interrupt line attached to the PS/2 keyboard/mouse, it 239 * may be necessary to change the operating mode of the nexus 240 * to a polling-based (instead of interrupt-based) method. 241 * this variable is present to enable a worst-case workaround so 242 * owners of these systems can still retain a working keyboard. 243 * 244 * The `i8042_polled_mode' variable can be used to force polled 245 * mode for platforms that have this issue, but for which 246 * automatic relief is not implemented. 247 * 248 * In the off chance that one of the platforms is misidentified 249 * as requiried polling mode, `i8042_force_interrupt_mode' can 250 * be set to force the nexus to use interrupts. 251 */ 252 #define I8042_MIN_POLL_INTERVAL 1000 /* usecs */ 253 int i8042_poll_interval = 8000; /* usecs */ 254 int i8042_fast_poll_interval; /* usecs */ 255 int i8042_slow_poll_interval; /* usecs */ 256 257 boolean_t i8042_polled_mode = B_FALSE; 258 boolean_t i8042_force_interrupt_mode = B_FALSE; 259 #endif /* __sparc */ 260 261 int max_wait_iterations = MAX_WAIT_ITERATIONS; 262 263 #ifdef DEBUG 264 int i8042_debug = 0; 265 #endif 266 267 /* 268 * function prototypes for bus ops routines: 269 */ 270 static int i8042_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 271 off_t offset, off_t len, caddr_t *addrp); 272 static int i8042_ctlops(dev_info_t *dip, dev_info_t *rdip, 273 ddi_ctl_enum_t op, void *arg, void *result); 274 275 /* 276 * function prototypes for dev ops routines: 277 */ 278 static int i8042_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 279 static int i8042_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 280 static int i8042_intr_ops(dev_info_t *dip, dev_info_t *rdip, 281 ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result); 282 static int i8042_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t, 283 void *, dev_info_t **); 284 static int i8042_bus_unconfig(dev_info_t *, uint_t, 285 ddi_bus_config_op_t, void *); 286 #ifdef __sparc 287 static int i8042_build_interrupts_property(dev_info_t *dip); 288 static boolean_t i8042_is_polling_platform(void); 289 #endif 290 291 /* 292 * bus ops and dev ops structures: 293 */ 294 static struct bus_ops i8042_bus_ops = { 295 BUSO_REV, 296 i8042_map, 297 NULL, 298 NULL, 299 NULL, 300 NULL, /* ddi_map_fault */ 301 NULL, /* ddi_dma_map */ 302 NULL, /* ddi_dma_allochdl */ 303 NULL, /* ddi_dma_freehdl */ 304 NULL, /* ddi_dma_bindhdl */ 305 NULL, /* ddi_dma_unbindhdl */ 306 NULL, /* ddi_dma_flush */ 307 NULL, /* ddi_dma_win */ 308 NULL, /* ddi_dma_mctl */ 309 i8042_ctlops, 310 ddi_bus_prop_op, 311 NULL, /* (*bus_get_eventcookie)(); */ 312 NULL, /* (*bus_add_eventcall)(); */ 313 NULL, /* (*bus_remove_eventcall)(); */ 314 NULL, /* (*bus_post_event)(); */ 315 NULL, /* bus_intr_ctl */ 316 i8042_bus_config, /* bus_config */ 317 i8042_bus_unconfig, /* bus_unconfig */ 318 NULL, /* bus_fm_init */ 319 NULL, /* bus_fm_fini */ 320 NULL, /* bus_fm_access_enter */ 321 NULL, /* bus_fm_access_exit */ 322 NULL, /* bus_power */ 323 i8042_intr_ops /* bus_intr_op */ 324 }; 325 326 static struct dev_ops i8042_ops = { 327 DEVO_REV, 328 0, 329 ddi_no_info, 330 nulldev, 331 0, 332 i8042_attach, 333 i8042_detach, 334 nodev, 335 (struct cb_ops *)0, 336 &i8042_bus_ops, 337 NULL, 338 ddi_quiesce_not_needed, 339 }; 340 341 342 /* 343 * module definitions: 344 */ 345 #include <sys/modctl.h> 346 extern struct mod_ops mod_driverops; 347 348 static struct modldrv modldrv = { 349 &mod_driverops, /* Type of module. This one is a driver */ 350 "i8042 nexus driver", /* Name of module. */ 351 &i8042_ops, /* driver ops */ 352 }; 353 354 static struct modlinkage modlinkage = { 355 MODREV_1, (void *)&modldrv, NULL 356 }; 357 358 int 359 _init(void) 360 { 361 int e; 362 363 /* 364 * Install the module. 365 */ 366 e = mod_install(&modlinkage); 367 return (e); 368 } 369 370 int 371 _fini(void) 372 { 373 int e; 374 375 /* 376 * Remove the module. 377 */ 378 e = mod_remove(&modlinkage); 379 if (e != 0) 380 return (e); 381 382 return (e); 383 } 384 385 int 386 _info(struct modinfo *modinfop) 387 { 388 return (mod_info(&modlinkage, modinfop)); 389 } 390 391 #define DRIVER_NAME(dip) ddi_driver_name(dip) 392 393 static void i8042_timeout(void *arg); 394 static unsigned int i8042_intr(caddr_t arg); 395 static void i8042_write_command_byte(struct i8042 *, unsigned char); 396 static uint8_t i8042_get8(ddi_acc_impl_t *handlep, uint8_t *addr); 397 static void i8042_put8(ddi_acc_impl_t *handlep, uint8_t *addr, 398 uint8_t value); 399 static void i8042_send(struct i8042 *global, int reg, unsigned char cmd); 400 static uint8_t i8042_get8(ddi_acc_impl_t *handlep, uint8_t *addr); 401 402 unsigned int i8042_unclaimed_interrupts = 0; 403 404 static void 405 i8042_discard_junk_data(struct i8042 *global) 406 { 407 /* Discard any junk data that may have been left around */ 408 for (;;) { 409 unsigned char stat; 410 411 stat = ddi_get8(global->io_handle, 412 global->io_addr + I8042_STAT); 413 if (! (stat & I8042_STAT_OUTBF)) 414 break; 415 (void) ddi_get8(global->io_handle, 416 global->io_addr + I8042_DATA); 417 418 } 419 } 420 421 static int 422 i8042_cleanup(struct i8042 *global) 423 { 424 int which_port, i; 425 struct i8042_port *port; 426 427 ASSERT(global != NULL); 428 429 if (global->initialized == B_TRUE) { 430 /* 431 * If any children still have regs mapped or interrupts 432 * registered, return immediate failure (and do nothing). 433 */ 434 mutex_enter(&global->i8042_mutex); 435 436 for (which_port = 0; which_port < NUM_PORTS; which_port++) { 437 port = &global->i8042_ports[which_port]; 438 439 if (port->initialized == B_TRUE) { 440 mutex_exit(&global->i8042_mutex); 441 return (DDI_FAILURE); 442 } 443 #if defined(USE_SOFT_INTRS) 444 if (port->soft_hdl != 0) { 445 mutex_exit(&global->i8042_mutex); 446 return (DDI_FAILURE); 447 } 448 #else 449 mutex_enter(&port->intr_mutex); 450 if (port->intr_func != NULL) { 451 mutex_exit(&port->intr_mutex); 452 mutex_exit(&global->i8042_mutex); 453 return (DDI_FAILURE); 454 } 455 mutex_exit(&port->intr_mutex); 456 #endif 457 } 458 global->initialized = B_FALSE; 459 460 mutex_exit(&global->i8042_mutex); 461 } 462 463 #ifdef __sparc 464 /* If there may be an outstanding timeout, cancel it */ 465 if (global->timeout_id != 0) { 466 (void) untimeout(global->timeout_id); 467 } 468 #endif 469 470 /* Stop the controller from generating interrupts */ 471 if (global->init_state & I8042_INIT_INTRS_ENABLED) 472 i8042_write_command_byte(global, I8042_CMD_DISABLE_ALL); 473 474 if (global->intrs_added) { 475 /* 476 * Remove the interrupts in the reverse order in 477 * which they were added 478 */ 479 for (i = global->nintrs - 1; i >= 0; i--) { 480 if (global->intrs_added & (1 << i)) 481 ddi_remove_intr(global->dip, i, 482 global->iblock_cookies[i]); 483 } 484 } 485 486 487 if (global->init_state & I8042_INIT_MUTEXES) { 488 for (which_port = 0; which_port < NUM_PORTS; which_port++) { 489 #ifndef USE_SOFT_INTRS 490 port = &global->i8042_ports[which_port]; 491 mutex_destroy(&port->intr_mutex); 492 #endif 493 } 494 cv_destroy(&global->glock_cv); 495 mutex_destroy(&global->i8042_out_mutex); 496 mutex_destroy(&global->i8042_mutex); 497 } 498 499 if (global->init_state & I8042_INIT_REGS_MAPPED) 500 ddi_regs_map_free(&global->io_handle); 501 502 if (global->init_state & I8042_INIT_BASIC) { 503 ddi_set_driver_private(global->dip, (caddr_t)NULL); 504 if (global->nintrs > 0) { 505 kmem_free(global->iblock_cookies, global->nintrs * 506 sizeof (ddi_iblock_cookie_t)); 507 } 508 kmem_free(global, sizeof (struct i8042)); 509 } 510 511 return (DDI_SUCCESS); 512 } 513 514 #define OBF_WAIT_COUNT 1000 /* in granules of 10uS */ 515 516 /* 517 * Wait for the 8042 to fill the 'output' (from 8042 to host) 518 * buffer. If 8042 fails to fill the output buffer within an 519 * allowed time, return 1 (which means there is no data available), 520 * otherwise return 0 521 */ 522 static int 523 i8042_wait_obf(struct i8042 *global) 524 { 525 int timer = 0; 526 527 while (!(ddi_get8(global->io_handle, global->io_addr + I8042_STAT) & 528 I8042_STAT_OUTBF)) { 529 if (++timer > OBF_WAIT_COUNT) 530 return (1); 531 drv_usecwait(10); 532 } 533 return (0); 534 } 535 536 537 /* 538 * Drain all queued bytes from the 8042. 539 * Return 0 for no error, <> 0 if there was an error. 540 */ 541 static int 542 i8042_purge_outbuf(struct i8042 *global) 543 { 544 int i; 545 546 for (i = 0; i < MAX_JUNK_ITERATIONS; i++) { 547 if (i8042_wait_obf(global)) 548 break; 549 (void) ddi_get8(global->io_handle, 550 global->io_addr + I8042_DATA); 551 } 552 553 /* 554 * If we hit the maximum number of iterations, then there 555 * was a serious problem (e.g. our hardware may not be 556 * present or working properly). 557 */ 558 return (i == MAX_JUNK_ITERATIONS); 559 } 560 561 static int 562 i8042_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 563 { 564 struct i8042_port *port; 565 enum i8042_ports which_port; 566 int i; 567 #if !defined(USE_SOFT_INTRS) 568 ddi_iblock_cookie_t cookie; 569 #endif 570 static ddi_device_acc_attr_t attr = { 571 DDI_DEVICE_ATTR_V0, 572 DDI_NEVERSWAP_ACC, 573 DDI_STRICTORDER_ACC, 574 }; 575 struct i8042 *global; 576 #ifdef __sparc 577 int interval; 578 #endif 579 580 switch (cmd) { 581 case DDI_RESUME: 582 global = (struct i8042 *)ddi_get_driver_private(dip); 583 i8042_discard_junk_data(global); 584 i8042_write_command_byte(global, I8042_CMD_ENABLE_ALL); 585 return (DDI_SUCCESS); 586 587 case DDI_ATTACH: 588 /* Handled in the main function block */ 589 break; 590 591 default: 592 return (DDI_FAILURE); 593 } 594 595 /* 596 * DDI_ATTACH processing 597 */ 598 599 global = (struct i8042 *)kmem_zalloc(sizeof (struct i8042), KM_SLEEP); 600 ddi_set_driver_private(dip, (caddr_t)global); 601 global->dip = dip; 602 global->initialized = B_FALSE; 603 604 global->init_state |= I8042_INIT_BASIC; 605 606 if (ddi_regs_map_setup(dip, 0, (caddr_t *)&global->io_addr, 607 (offset_t)0, (offset_t)0, &attr, &global->io_handle) 608 != DDI_SUCCESS) 609 goto fail; 610 611 global->init_state |= I8042_INIT_REGS_MAPPED; 612 613 /* 614 * Get the number of interrupts for this nexus 615 */ 616 if (ddi_dev_nintrs(dip, &global->nintrs) == DDI_FAILURE) 617 goto fail; 618 619 #ifdef __sparc 620 if ((i8042_polled_mode || i8042_is_polling_platform()) && 621 !i8042_force_interrupt_mode) { 622 /* 623 * If we're on a platform that has known 624 * interrupt issues with the keyboard/mouse, 625 * use polled mode. 626 */ 627 i8042_polled_mode = B_TRUE; 628 global->nintrs = 0; 629 } else if (global->nintrs == 0) { 630 /* 631 * If there are no interrupts on the i8042 node, 632 * we may be on a brain-dead platform that only 633 * has interrupts properties on i8042's children 634 * (e.g. some UltraII-based boards) 635 * In this case, scan first-level children, and 636 * build a list of interrupts that each child uses, 637 * then create an `interrupts' property on the nexus node 638 * that contains the interrupts used by all children 639 */ 640 if (i8042_build_interrupts_property(dip) == DDI_FAILURE || 641 ddi_dev_nintrs(dip, &global->nintrs) == DDI_FAILURE || 642 global->nintrs == 0) { 643 cmn_err(CE_WARN, "i8042#%d: No interrupts defined!", 644 ddi_get_instance(global->dip)); 645 goto fail; 646 } 647 } 648 #else 649 if (global->nintrs == 0) { 650 cmn_err(CE_WARN, "i8042#%d: No interrupts defined!", 651 ddi_get_instance(global->dip)); 652 goto fail; 653 } 654 #endif 655 656 if (global->nintrs > MAX_INTERRUPTS) 657 global->nintrs = MAX_INTERRUPTS; 658 659 if (global->nintrs > 0) { 660 global->iblock_cookies = kmem_zalloc(global->nintrs * 661 sizeof (ddi_iblock_cookie_t), KM_NOSLEEP); 662 663 for (i = 0; i < global->nintrs; i++) { 664 if (ddi_get_iblock_cookie(dip, i, 665 &global->iblock_cookies[i]) != DDI_SUCCESS) 666 goto fail; 667 } 668 } else 669 global->iblock_cookies = NULL; 670 671 mutex_init(&global->i8042_mutex, NULL, MUTEX_DRIVER, 672 (global->nintrs > 0) ? global->iblock_cookies[0] : NULL); 673 674 mutex_init(&global->i8042_out_mutex, NULL, MUTEX_DRIVER, NULL); 675 676 cv_init(&global->glock_cv, NULL, CV_DRIVER, NULL); 677 678 for (which_port = 0; which_port < NUM_PORTS; ++which_port) { 679 port = &global->i8042_ports[which_port]; 680 port->initialized = B_FALSE; 681 port->i8042_global = global; 682 port->which = which_port; 683 #if defined(USE_SOFT_INTRS) 684 port->soft_hdl = 0; 685 #else 686 687 /* 688 * Assume that the interrupt block cookie for port <n> 689 * is iblock_cookies[<n>] (a 1:1 mapping). If there are not 690 * enough interrupts to cover the number of ports, use 691 * the cookie from interrupt 0. 692 */ 693 if (global->nintrs > 0) { 694 cookie = global->iblock_cookies[ 695 (which_port < global->nintrs) ? which_port : 0]; 696 697 mutex_init(&port->intr_mutex, NULL, MUTEX_DRIVER, 698 cookie); 699 700 } else { 701 mutex_init(&port->intr_mutex, NULL, MUTEX_DRIVER, NULL); 702 } 703 704 #endif 705 } 706 707 global->init_state |= I8042_INIT_MUTEXES; 708 709 /* 710 * Disable input and interrupts from both the main and aux ports. 711 * 712 * It is difficult if not impossible to read the command byte in 713 * a completely clean way. Reading the command byte may cause 714 * an interrupt, and there is no way to suppress interrupts without 715 * writing the command byte. On a PC we might rely on the fact 716 * that IRQ 1 is disabled and guaranteed not shared, but on 717 * other platforms the interrupt line might be shared and so 718 * causing an interrupt could be bad. 719 * 720 * Since we can't read the command byte and update it, we 721 * just set it to static values. 722 */ 723 i8042_write_command_byte(global, I8042_CMD_DISABLE_ALL); 724 725 global->init_state &= ~I8042_INIT_INTRS_ENABLED; 726 727 /* Discard any junk data that may have been left around */ 728 if (i8042_purge_outbuf(global) != 0) 729 goto fail; 730 731 732 /* 733 * Assume the number of interrupts is less that the number of 734 * bits in the variable used to keep track of which interrupt 735 * was added. 736 */ 737 ASSERT(global->nintrs <= (sizeof (global->intrs_added) * NBBY)); 738 739 for (i = 0; i < global->nintrs; i++) { 740 /* 741 * The 8042 handles all interrupts, because all 742 * device access goes through the same I/O addresses. 743 */ 744 if (ddi_add_intr(dip, i, 745 (ddi_iblock_cookie_t *)NULL, 746 (ddi_idevice_cookie_t *)NULL, 747 i8042_intr, (caddr_t)global) != DDI_SUCCESS) 748 goto fail; 749 750 global->intrs_added |= (1 << i); 751 } 752 753 global->initialized = B_TRUE; 754 755 /* 756 * Enable the main and aux data ports and interrupts 757 */ 758 i8042_write_command_byte(global, I8042_CMD_ENABLE_ALL); 759 global->init_state |= I8042_INIT_INTRS_ENABLED; 760 761 #ifdef __sparc 762 if (i8042_polled_mode) { 763 /* 764 * Do not allow anyone to set the polling interval 765 * to an interval more frequent than I8042_MIN_POLL_INTERVAL -- 766 * it could hose the system. 767 */ 768 interval = i8042_poll_interval; 769 if (interval < I8042_MIN_POLL_INTERVAL) 770 interval = I8042_MIN_POLL_INTERVAL; 771 i8042_fast_poll_interval = interval; 772 i8042_slow_poll_interval = interval << 3; 773 774 global->timeout_id = timeout(i8042_timeout, global, 775 drv_usectohz(i8042_slow_poll_interval)); 776 } 777 #endif 778 779 return (DDI_SUCCESS); 780 781 fail: 782 /* cleanup will succeed because no children have attached yet */ 783 (void) i8042_cleanup(global); 784 return (DDI_FAILURE); 785 } 786 787 /*ARGSUSED*/ 788 static int 789 i8042_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 790 { 791 struct i8042 *global = (struct i8042 *)ddi_get_driver_private(dip); 792 793 ASSERT(global != NULL); 794 795 switch (cmd) { 796 case DDI_SUSPEND: 797 /* 798 * Do not disable the keyboard controller for x86 suspend, as 799 * the keyboard can be used to bring the system out of 800 * suspend. 801 */ 802 #ifdef __sparc 803 /* Disable interrupts and controller devices before suspend */ 804 i8042_write_command_byte(global, I8042_CMD_DISABLE_ALL); 805 #endif 806 return (DDI_SUCCESS); 807 808 case DDI_DETACH: 809 /* DETACH can only succeed if cleanup succeeds */ 810 return (i8042_cleanup(global)); 811 812 default: 813 return (DDI_FAILURE); 814 } 815 } 816 817 /* 818 * The primary interface to us from our children is via virtual registers. 819 * This is the entry point that allows our children to "map" these 820 * virtual registers. 821 */ 822 static int 823 i8042_map( 824 dev_info_t *dip, 825 dev_info_t *rdip, 826 ddi_map_req_t *mp, 827 off_t offset, 828 off_t len, 829 caddr_t *addrp) 830 { 831 struct i8042_port *port; 832 struct i8042 *global; 833 enum i8042_ports which_port; 834 int *iprop; 835 unsigned int iprop_len; 836 int rnumber; 837 ddi_acc_hdl_t *handle; 838 ddi_acc_impl_t *ap; 839 840 global = ddi_get_driver_private(dip); 841 842 switch (mp->map_type) { 843 case DDI_MT_REGSPEC: 844 which_port = *(int *)mp->map_obj.rp; 845 break; 846 847 case DDI_MT_RNUMBER: 848 rnumber = mp->map_obj.rnumber; 849 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip, 850 DDI_PROP_DONTPASS, "reg", &iprop, &iprop_len) != 851 DDI_SUCCESS) { 852 #if defined(DEBUG) 853 cmn_err(CE_WARN, "%s #%d: Missing 'reg' on %s@%s", 854 DRIVER_NAME(dip), ddi_get_instance(dip), 855 ddi_node_name(rdip), ddi_get_name_addr(rdip)); 856 #endif 857 return (DDI_FAILURE); 858 } 859 #if defined(DEBUG) 860 if (iprop_len != 1) { 861 cmn_err(CE_WARN, "%s #%d: Malformed 'reg' on %s@%s", 862 DRIVER_NAME(dip), ddi_get_instance(dip), 863 ddi_node_name(rdip), ddi_get_name_addr(rdip)); 864 return (DDI_FAILURE); 865 } 866 if (rnumber < 0 || rnumber >= iprop_len) { 867 cmn_err(CE_WARN, "%s #%d: bad map request for %s@%s", 868 DRIVER_NAME(dip), ddi_get_instance(dip), 869 ddi_node_name(rdip), ddi_get_name_addr(rdip)); 870 return (DDI_FAILURE); 871 } 872 #endif 873 which_port = iprop[rnumber]; 874 ddi_prop_free((void *)iprop); 875 #if defined(DEBUG) 876 if (which_port != MAIN_PORT && which_port != AUX_PORT) { 877 cmn_err(CE_WARN, 878 "%s #%d: bad 'reg' value %d on %s@%s", 879 DRIVER_NAME(dip), ddi_get_instance(dip), 880 which_port, 881 ddi_node_name(rdip), ddi_get_name_addr(rdip)); 882 return (DDI_FAILURE); 883 } 884 #endif 885 break; 886 887 default: 888 #if defined(DEBUG) 889 cmn_err(CE_WARN, "%s #%d: unknown map type %d for %s@%s", 890 DRIVER_NAME(dip), ddi_get_instance(dip), 891 mp->map_type, 892 ddi_node_name(rdip), ddi_get_name_addr(rdip)); 893 #endif 894 return (DDI_FAILURE); 895 } 896 897 #if defined(DEBUG) 898 if (offset != 0 || len != 0) { 899 cmn_err(CE_WARN, 900 "%s #%d: partial mapping attempt for %s@%s ignored", 901 DRIVER_NAME(dip), ddi_get_instance(dip), 902 ddi_node_name(rdip), ddi_get_name_addr(rdip)); 903 } 904 #endif 905 906 port = &global->i8042_ports[which_port]; 907 908 switch (mp->map_op) { 909 case DDI_MO_MAP_LOCKED: 910 #if defined(USE_SOFT_INTRS) 911 port->soft_intr_enabled = B_FALSE; 912 #else 913 port->intr_func = NULL; 914 #endif 915 port->wptr = 0; 916 port->rptr = 0; 917 port->dip = dip; 918 port->inumber = 0; 919 port->has_glock = B_FALSE; 920 port->initialized = B_TRUE; 921 922 handle = mp->map_handlep; 923 handle->ah_bus_private = port; 924 handle->ah_addr = 0; 925 ap = (ddi_acc_impl_t *)handle->ah_platform_private; 926 /* 927 * Support get8, put8 and _rep_put8 928 */ 929 ap->ahi_put8 = i8042_put8; 930 ap->ahi_get8 = i8042_get8; 931 ap->ahi_put16 = NULL; 932 ap->ahi_get16 = NULL; 933 ap->ahi_put32 = NULL; 934 ap->ahi_get32 = NULL; 935 ap->ahi_put64 = NULL; 936 ap->ahi_get64 = NULL; 937 ap->ahi_rep_put8 = NULL; 938 ap->ahi_rep_get8 = NULL; 939 ap->ahi_rep_put16 = NULL; 940 ap->ahi_rep_get16 = NULL; 941 ap->ahi_rep_put32 = NULL; 942 ap->ahi_rep_get32 = NULL; 943 ap->ahi_rep_put64 = NULL; 944 ap->ahi_rep_get64 = NULL; 945 *addrp = 0; 946 return (DDI_SUCCESS); 947 948 case DDI_MO_UNMAP: 949 port->initialized = B_FALSE; 950 return (DDI_SUCCESS); 951 952 default: 953 cmn_err(CE_WARN, "%s: map operation %d not supported", 954 DRIVER_NAME(dip), mp->map_op); 955 return (DDI_FAILURE); 956 } 957 } 958 959 #ifdef __sparc 960 static void 961 i8042_timeout(void *arg) 962 { 963 struct i8042 *i8042_p = (struct i8042 *)arg; 964 int interval; 965 966 /* 967 * Allow the polling speed to be changed on the fly -- 968 * catch it here and update the intervals used. 969 */ 970 if (i8042_fast_poll_interval != i8042_poll_interval) { 971 interval = i8042_poll_interval; 972 if (interval < I8042_MIN_POLL_INTERVAL) 973 interval = I8042_MIN_POLL_INTERVAL; 974 i8042_fast_poll_interval = interval; 975 i8042_slow_poll_interval = interval << 3; 976 } 977 978 /* 979 * If the ISR returned true, start polling at a faster rate to 980 * increate responsiveness. Once the keyboard or mouse go idle, 981 * the ISR will return UNCLAIMED, and we'll go back to the slower 982 * polling rate. This gives some positive hysteresis (but not 983 * negative, since we go back to the slower polling interval after 984 * only one UNCLAIMED). This has shown to be responsive enough, 985 * even for fast typers. 986 */ 987 interval = (i8042_intr((caddr_t)i8042_p) == DDI_INTR_CLAIMED) ? 988 i8042_fast_poll_interval : i8042_slow_poll_interval; 989 990 if (i8042_polled_mode) 991 i8042_p->timeout_id = timeout(i8042_timeout, arg, 992 drv_usectohz(interval)); 993 else 994 i8042_p->timeout_id = 0; 995 } 996 #endif 997 998 /* 999 * i8042 hardware interrupt routine. Called for both main and aux port 1000 * interrupts. 1001 */ 1002 static unsigned int 1003 i8042_intr(caddr_t arg) 1004 { 1005 struct i8042 *global = (struct i8042 *)arg; 1006 enum i8042_ports which_port; 1007 unsigned char stat; 1008 unsigned char byte; 1009 int new_wptr; 1010 struct i8042_port *port; 1011 1012 mutex_enter(&global->i8042_mutex); 1013 1014 stat = ddi_get8(global->io_handle, global->io_addr + I8042_STAT); 1015 1016 if (! (stat & I8042_STAT_OUTBF)) { 1017 ++i8042_unclaimed_interrupts; 1018 mutex_exit(&global->i8042_mutex); 1019 return (DDI_INTR_UNCLAIMED); 1020 } 1021 1022 byte = ddi_get8(global->io_handle, global->io_addr + I8042_DATA); 1023 1024 which_port = (stat & I8042_STAT_AUXBF) ? AUX_PORT : MAIN_PORT; 1025 1026 port = &global->i8042_ports[which_port]; 1027 1028 if (! port->initialized) { 1029 mutex_exit(&global->i8042_mutex); 1030 return (DDI_INTR_CLAIMED); 1031 } 1032 1033 new_wptr = (port->wptr + 1) % BUFSIZ; 1034 if (new_wptr == port->rptr) { 1035 port->overruns++; 1036 #if defined(DEBUG) 1037 if (port->overruns % 50 == 1) { 1038 cmn_err(CE_WARN, "i8042/%d: %d overruns\n", 1039 which_port, port->overruns); 1040 } 1041 #endif 1042 1043 mutex_exit(&global->i8042_mutex); 1044 return (DDI_INTR_CLAIMED); 1045 } 1046 1047 port->buf[port->wptr] = byte; 1048 port->wptr = new_wptr; 1049 1050 #if defined(USE_SOFT_INTRS) 1051 if (port->soft_intr_enabled) 1052 (void) ddi_intr_trigger_softint(port->soft_hdl, 1053 port->intr_arg2); 1054 #endif 1055 1056 mutex_exit(&global->i8042_mutex); 1057 1058 #if !defined(USE_SOFT_INTRS) 1059 mutex_enter(&port->intr_mutex); 1060 if (port->intr_func != NULL) 1061 port->intr_func(port->intr_arg1, NULL); 1062 mutex_exit(&port->intr_mutex); 1063 #endif 1064 1065 return (DDI_INTR_CLAIMED); 1066 } 1067 1068 static void 1069 i8042_write_command_byte(struct i8042 *global, unsigned char cb) 1070 { 1071 mutex_enter(&global->i8042_out_mutex); 1072 i8042_send(global, I8042_CMD, I8042_CMD_WCB); 1073 i8042_send(global, I8042_DATA, cb); 1074 mutex_exit(&global->i8042_out_mutex); 1075 } 1076 1077 /* 1078 * Send a byte to either the i8042 command or data register, depending on 1079 * the argument. 1080 */ 1081 static void 1082 i8042_send(struct i8042 *global, int reg, unsigned char val) 1083 { 1084 uint8_t stat; 1085 int tries = 0; 1086 1087 /* 1088 * First, wait for the i8042 to be ready to accept data. 1089 */ 1090 /*CONSTANTCONDITION*/ 1091 while (1) { 1092 stat = ddi_get8(global->io_handle, 1093 global->io_addr + I8042_STAT); 1094 1095 if ((stat & I8042_STAT_INBF) == 0) { 1096 ddi_put8(global->io_handle, global->io_addr+reg, val); 1097 break; 1098 } 1099 1100 /* Don't wait unless we're going to check again */ 1101 if (++tries >= max_wait_iterations) 1102 break; 1103 else 1104 drv_usecwait(USECS_PER_WAIT); 1105 } 1106 1107 #ifdef DEBUG 1108 if (tries >= MAX_WAIT_ITERATIONS) 1109 cmn_err(CE_WARN, "i8042_send: timeout!"); 1110 #endif 1111 } 1112 1113 /* 1114 * Here's the interface to the virtual registers on the device. 1115 * 1116 * Normal interrupt-driven I/O: 1117 * 1118 * I8042_INT_INPUT_AVAIL (r/o) 1119 * Interrupt mode input bytes available? Zero = No. 1120 * I8042_INT_INPUT_DATA (r/o) 1121 * Fetch interrupt mode input byte. 1122 * I8042_INT_OUTPUT_DATA (w/o) 1123 * Interrupt mode output byte. 1124 * 1125 * Polled I/O, used by (e.g.) kmdb, when normal system services are 1126 * unavailable: 1127 * 1128 * I8042_POLL_INPUT_AVAIL (r/o) 1129 * Polled mode input bytes available? Zero = No. 1130 * I8042_POLL_INPUT_DATA (r/o) 1131 * Polled mode input byte. 1132 * I8042_POLL_OUTPUT_DATA (w/o) 1133 * Polled mode output byte. 1134 * 1135 * Note that in polled mode we cannot use cmn_err; only prom_printf is safe. 1136 */ 1137 static uint8_t 1138 i8042_get8(ddi_acc_impl_t *handlep, uint8_t *addr) 1139 { 1140 struct i8042_port *port; 1141 struct i8042 *global; 1142 uint8_t ret; 1143 ddi_acc_hdl_t *h; 1144 uint8_t stat; 1145 1146 h = (ddi_acc_hdl_t *)handlep; 1147 1148 port = (struct i8042_port *)h->ah_bus_private; 1149 global = port->i8042_global; 1150 1151 switch ((uintptr_t)addr) { 1152 case I8042_LOCK: 1153 ASSERT(port->has_glock != B_TRUE); /* No reentrancy */ 1154 mutex_enter(&global->i8042_out_mutex); 1155 /* 1156 * Block other children requesting exclusive access here until 1157 * the child possessing it relinquishes the lock. 1158 */ 1159 while (global->glock) { 1160 cv_wait(&global->glock_cv, &global->i8042_out_mutex); 1161 } 1162 port->has_glock = B_TRUE; 1163 global->glock = 1; 1164 mutex_exit(&global->i8042_out_mutex); 1165 ret = 0; 1166 break; 1167 1168 case I8042_UNLOCK: 1169 mutex_enter(&global->i8042_out_mutex); 1170 ASSERT(global->glock != 0); 1171 ASSERT(port->has_glock == B_TRUE); 1172 port->has_glock = B_FALSE; 1173 global->glock = 0; 1174 /* 1175 * Signal anyone waiting for exclusive access that it is now 1176 * available. 1177 */ 1178 cv_signal(&global->glock_cv); 1179 mutex_exit(&global->i8042_out_mutex); 1180 ret = 0; 1181 break; 1182 1183 case I8042_INT_INPUT_AVAIL: 1184 mutex_enter(&global->i8042_mutex); 1185 ret = port->rptr != port->wptr; 1186 mutex_exit(&global->i8042_mutex); 1187 return (ret); 1188 1189 case I8042_INT_INPUT_DATA: 1190 mutex_enter(&global->i8042_mutex); 1191 1192 if (port->rptr != port->wptr) { 1193 ret = port->buf[port->rptr]; 1194 port->rptr = (port->rptr + 1) % BUFSIZ; 1195 } else { 1196 #if defined(DEBUG) 1197 cmn_err(CE_WARN, 1198 "i8042: Tried to read from empty buffer"); 1199 #endif 1200 ret = 0; 1201 } 1202 1203 1204 mutex_exit(&global->i8042_mutex); 1205 1206 break; 1207 1208 #if defined(DEBUG) 1209 case I8042_INT_OUTPUT_DATA: 1210 case I8042_POLL_OUTPUT_DATA: 1211 cmn_err(CE_WARN, "i8042: read of write-only register 0x%p", 1212 (void *)addr); 1213 ret = 0; 1214 break; 1215 #endif 1216 1217 case I8042_POLL_INPUT_AVAIL: 1218 if (port->rptr != port->wptr) 1219 return (B_TRUE); 1220 for (;;) { 1221 stat = ddi_get8(global->io_handle, 1222 global->io_addr + I8042_STAT); 1223 if ((stat & I8042_STAT_OUTBF) == 0) 1224 return (B_FALSE); 1225 switch (port->which) { 1226 case MAIN_PORT: 1227 if ((stat & I8042_STAT_AUXBF) == 0) 1228 return (B_TRUE); 1229 break; 1230 case AUX_PORT: 1231 if ((stat & I8042_STAT_AUXBF) != 0) 1232 return (B_TRUE); 1233 break; 1234 default: 1235 cmn_err(CE_WARN, "data from unknown port: %d", 1236 port->which); 1237 } 1238 /* 1239 * Data for wrong port pending; discard it. 1240 */ 1241 (void) ddi_get8(global->io_handle, 1242 global->io_addr + I8042_DATA); 1243 } 1244 1245 /* NOTREACHED */ 1246 1247 case I8042_POLL_INPUT_DATA: 1248 if (port->rptr != port->wptr) { 1249 ret = port->buf[port->rptr]; 1250 port->rptr = (port->rptr + 1) % BUFSIZ; 1251 return (ret); 1252 } 1253 1254 stat = ddi_get8(global->io_handle, 1255 global->io_addr + I8042_STAT); 1256 if ((stat & I8042_STAT_OUTBF) == 0) { 1257 #if defined(DEBUG) 1258 prom_printf("I8042_POLL_INPUT_DATA: no data!\n"); 1259 #endif 1260 return (0); 1261 } 1262 ret = ddi_get8(global->io_handle, 1263 global->io_addr + I8042_DATA); 1264 switch (port->which) { 1265 case MAIN_PORT: 1266 if ((stat & I8042_STAT_AUXBF) == 0) 1267 return (ret); 1268 break; 1269 case AUX_PORT: 1270 if ((stat & I8042_STAT_AUXBF) != 0) 1271 return (ret); 1272 break; 1273 } 1274 #if defined(DEBUG) 1275 prom_printf("I8042_POLL_INPUT_DATA: data for wrong port!\n"); 1276 #endif 1277 return (0); 1278 1279 default: 1280 #if defined(DEBUG) 1281 cmn_err(CE_WARN, "i8042: read of undefined register 0x%p", 1282 (void *)addr); 1283 #endif 1284 ret = 0; 1285 break; 1286 } 1287 return (ret); 1288 } 1289 1290 static void 1291 i8042_put8(ddi_acc_impl_t *handlep, uint8_t *addr, uint8_t value) 1292 { 1293 struct i8042 *global; 1294 struct i8042_port *port; 1295 ddi_acc_hdl_t *h; 1296 1297 h = (ddi_acc_hdl_t *)handlep; 1298 port = (struct i8042_port *)h->ah_bus_private; 1299 global = port->i8042_global; 1300 1301 switch ((uintptr_t)addr) { 1302 case I8042_INT_OUTPUT_DATA: 1303 case I8042_POLL_OUTPUT_DATA: 1304 1305 if ((uintptr_t)addr == I8042_INT_OUTPUT_DATA) { 1306 mutex_enter(&global->i8042_out_mutex); 1307 1308 /* 1309 * If no child has exclusive access, then proceed with 1310 * the put8 below. If a child (not the one making the 1311 * call) has exclusive access, wait for it to be 1312 * relinquished. The use of i8042_out_mutex prevents 1313 * children seeking exclusive access from getting it 1314 * while a child is writing to the 8042. 1315 */ 1316 while (global->glock && !port->has_glock) { 1317 cv_wait(&global->glock_cv, 1318 &global->i8042_out_mutex); 1319 } 1320 } 1321 1322 if (port->which == AUX_PORT) 1323 i8042_send(global, I8042_CMD, I8042_CMD_WRITE_AUX); 1324 1325 i8042_send(global, I8042_DATA, value); 1326 1327 if ((uintptr_t)addr == I8042_INT_OUTPUT_DATA) 1328 mutex_exit(&global->i8042_out_mutex); 1329 1330 break; 1331 1332 #if defined(DEBUG) 1333 case I8042_INT_INPUT_AVAIL: 1334 case I8042_INT_INPUT_DATA: 1335 case I8042_POLL_INPUT_AVAIL: 1336 case I8042_POLL_INPUT_DATA: 1337 cmn_err(CE_WARN, "i8042: write of read-only register 0x%p", 1338 (void *)addr); 1339 break; 1340 1341 default: 1342 cmn_err(CE_WARN, "i8042: read of undefined register 0x%p", 1343 (void *)addr); 1344 break; 1345 #endif 1346 } 1347 } 1348 1349 1350 /* ARGSUSED */ 1351 static int 1352 i8042_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 1353 ddi_intr_handle_impl_t *hdlp, void *result) 1354 { 1355 struct i8042_port *port; 1356 #if defined(USE_SOFT_INTRS) 1357 struct i8042 *global; 1358 int ret; 1359 #endif 1360 1361 switch (intr_op) { 1362 case DDI_INTROP_SUPPORTED_TYPES: 1363 *(int *)result = DDI_INTR_TYPE_FIXED; 1364 break; 1365 case DDI_INTROP_GETCAP: 1366 if (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result) 1367 == DDI_FAILURE) 1368 *(int *)result = 0; 1369 break; 1370 case DDI_INTROP_NINTRS: 1371 case DDI_INTROP_NAVAIL: 1372 *(int *)result = 1; 1373 break; 1374 case DDI_INTROP_ALLOC: 1375 *(int *)result = hdlp->ih_scratch1; 1376 break; 1377 case DDI_INTROP_FREE: 1378 break; 1379 case DDI_INTROP_GETPRI: 1380 /* Hard coding it for x86 */ 1381 *(int *)result = 5; 1382 break; 1383 case DDI_INTROP_ADDISR: 1384 port = ddi_get_parent_data(rdip); 1385 1386 #if defined(USE_SOFT_INTRS) 1387 global = port->i8042_global; 1388 ret = ddi_intr_add_softint(rdip, &port->soft_hdl, 1389 I8042_SOFTINT_PRI, hdlp->ih_cb_func, hdlp->ih_cb_arg1); 1390 1391 if (ret != DDI_SUCCESS) { 1392 #if defined(DEBUG) 1393 cmn_err(CE_WARN, "%s #%d: " 1394 "Cannot add soft interrupt for %s #%d, ret=%d.", 1395 DRIVER_NAME(dip), ddi_get_instance(dip), 1396 DRIVER_NAME(rdip), ddi_get_instance(rdip), ret); 1397 #endif /* defined(DEBUG) */ 1398 return (ret); 1399 } 1400 1401 #else /* defined(USE_SOFT_INTRS) */ 1402 mutex_enter(&port->intr_mutex); 1403 port->intr_func = hdlp->ih_cb_func; 1404 port->intr_arg1 = hdlp->ih_cb_arg1; 1405 port->intr_arg2 = hdlp->ih_cb_arg2; 1406 mutex_exit(&port->intr_mutex); 1407 #endif /* defined(USE_SOFT_INTRS) */ 1408 break; 1409 case DDI_INTROP_REMISR: 1410 port = ddi_get_parent_data(rdip); 1411 1412 #if defined(USE_SOFT_INTRS) 1413 global = port->i8042_global; 1414 mutex_enter(&global->i8042_mutex); 1415 port->soft_hdl = 0; 1416 mutex_exit(&global->i8042_mutex); 1417 #else /* defined(USE_SOFT_INTRS) */ 1418 mutex_enter(&port->intr_mutex); 1419 port->intr_func = NULL; 1420 mutex_exit(&port->intr_mutex); 1421 #endif /* defined(USE_SOFT_INTRS) */ 1422 break; 1423 case DDI_INTROP_ENABLE: 1424 port = ddi_get_parent_data(rdip); 1425 #if defined(USE_SOFT_INTRS) 1426 global = port->i8042_global; 1427 mutex_enter(&global->i8042_mutex); 1428 port->soft_intr_enabled = B_TRUE; 1429 if (port->wptr != port->rptr) 1430 (void) ddi_intr_trigger_softint(port->soft_hdl, 1431 port->intr_arg2); 1432 mutex_exit(&global->i8042_mutex); 1433 #else /* defined(USE_SOFT_INTRS) */ 1434 mutex_enter(&port->intr_mutex); 1435 if (port->wptr != port->rptr) 1436 port->intr_func(port->intr_arg1, port->intr_arg2); 1437 mutex_exit(&port->intr_mutex); 1438 #endif /* defined(USE_SOFT_INTRS) */ 1439 break; 1440 case DDI_INTROP_DISABLE: 1441 #if defined(USE_SOFT_INTRS) 1442 port = ddi_get_parent_data(rdip); 1443 global = port->i8042_global; 1444 mutex_enter(&global->i8042_mutex); 1445 port->soft_intr_enabled = B_FALSE; 1446 (void) ddi_intr_remove_softint(port->soft_hdl); 1447 mutex_exit(&global->i8042_mutex); 1448 #endif /* defined(USE_SOFT_INTRS) */ 1449 break; 1450 default: 1451 return (DDI_FAILURE); 1452 } 1453 1454 return (DDI_SUCCESS); 1455 } 1456 1457 static int 1458 i8042_ctlops(dev_info_t *dip, dev_info_t *rdip, 1459 ddi_ctl_enum_t op, void *arg, void *result) 1460 { 1461 int *iprop; 1462 unsigned int iprop_len; 1463 int which_port; 1464 char name[16]; 1465 struct i8042 *global; 1466 dev_info_t *child; 1467 1468 global = ddi_get_driver_private(dip); 1469 1470 switch (op) { 1471 case DDI_CTLOPS_INITCHILD: 1472 child = (dev_info_t *)arg; 1473 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, 1474 DDI_PROP_DONTPASS, "reg", &iprop, &iprop_len) != 1475 DDI_SUCCESS) { 1476 #if defined(DEBUG) 1477 cmn_err(CE_WARN, "%s #%d: Missing 'reg' on %s@???", 1478 DRIVER_NAME(dip), ddi_get_instance(dip), 1479 ddi_node_name(child)); 1480 #endif 1481 return (DDI_FAILURE); 1482 } 1483 which_port = iprop[0]; 1484 ddi_prop_free((void *)iprop); 1485 1486 (void) sprintf(name, "%d", which_port); 1487 ddi_set_name_addr(child, name); 1488 ddi_set_parent_data(child, 1489 (caddr_t)&global->i8042_ports[which_port]); 1490 return (DDI_SUCCESS); 1491 1492 case DDI_CTLOPS_UNINITCHILD: 1493 child = (dev_info_t *)arg; 1494 ddi_set_name_addr(child, NULL); 1495 ddi_set_parent_data(child, NULL); 1496 return (DDI_SUCCESS); 1497 1498 case DDI_CTLOPS_REPORTDEV: 1499 cmn_err(CE_CONT, "?8042 device: %s@%s, %s # %d\n", 1500 ddi_node_name(rdip), ddi_get_name_addr(rdip), 1501 DRIVER_NAME(rdip), ddi_get_instance(rdip)); 1502 return (DDI_SUCCESS); 1503 1504 default: 1505 return (ddi_ctlops(dip, rdip, op, arg, result)); 1506 } 1507 /* NOTREACHED */ 1508 } 1509 1510 #if defined(__i386) || defined(__amd64) 1511 static dev_info_t * 1512 i8042_devi_findchild_by_node_name(dev_info_t *pdip, char *nodename) 1513 { 1514 dev_info_t *child; 1515 1516 ASSERT(DEVI_BUSY_OWNED(pdip)); 1517 1518 if (nodename == NULL) { 1519 return ((dev_info_t *)NULL); 1520 } 1521 1522 for (child = ddi_get_child(pdip); child != NULL; 1523 child = ddi_get_next_sibling(child)) { 1524 1525 if (strcmp(ddi_node_name(child), nodename) == 0) 1526 break; 1527 } 1528 return (child); 1529 } 1530 1531 static void 1532 alloc_kb_mouse(dev_info_t *i8042_dip, int nodes_needed) 1533 { 1534 dev_info_t *xdip; 1535 int acpi_off = 0; 1536 char *acpi_prop; 1537 1538 /* don't alloc unless acpi is off */ 1539 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), 1540 DDI_PROP_DONTPASS, "acpi-enum", &acpi_prop) == DDI_PROP_SUCCESS) { 1541 if (strcmp("off", acpi_prop) == 0) { 1542 acpi_off = 1; 1543 } 1544 ddi_prop_free(acpi_prop); 1545 } 1546 if (acpi_off == 0) { 1547 return; 1548 } 1549 1550 if (nodes_needed & I8042_MOUSE) { 1551 /* mouse */ 1552 ndi_devi_alloc_sleep(i8042_dip, "mouse", 1553 (pnode_t)DEVI_SID_NODEID, &xdip); 1554 (void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip, 1555 "reg", 1); 1556 (void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip, 1557 "interrupts", 2); 1558 (void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip, 1559 "compatible", "pnpPNP,f03"); 1560 /* 1561 * The device_type property does not matter on SPARC. Retain it 1562 * on x86 for compatibility with the previous pseudo-prom. 1563 */ 1564 (void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip, 1565 "device_type", "mouse"); 1566 (void) ndi_devi_bind_driver(xdip, 0); 1567 } 1568 1569 if (nodes_needed & I8042_KEYBOARD) { 1570 /* keyboard */ 1571 ndi_devi_alloc_sleep(i8042_dip, "keyboard", 1572 (pnode_t)DEVI_SID_NODEID, &xdip); 1573 (void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip, 1574 "reg", 0); 1575 (void) ndi_prop_update_int(DDI_DEV_T_NONE, xdip, 1576 "interrupts", 1); 1577 (void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip, 1578 "compatible", "pnpPNP,303"); 1579 (void) ndi_prop_update_string(DDI_DEV_T_NONE, xdip, 1580 "device_type", "keyboard"); 1581 (void) ndi_devi_bind_driver(xdip, 0); 1582 } 1583 } 1584 #endif 1585 1586 static int 1587 i8042_bus_config(dev_info_t *parent, uint_t flags, 1588 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 1589 { 1590 #if defined(__i386) || defined(__amd64) 1591 int nodes_needed = 0; 1592 int circ; 1593 1594 /* 1595 * On x86 systems, if ACPI is disabled, the only way the 1596 * keyboard and mouse can be enumerated is by creating them 1597 * manually. The following code searches for the existence of 1598 * the keyboard and mouse nodes and creates them if they are not 1599 * found. 1600 */ 1601 ndi_devi_enter(parent, &circ); 1602 if (i8042_devi_findchild_by_node_name(parent, "keyboard") == NULL) 1603 nodes_needed |= I8042_KEYBOARD; 1604 if (i8042_devi_findchild_by_node_name(parent, "mouse") == NULL) 1605 nodes_needed |= I8042_MOUSE; 1606 1607 /* If the mouse and keyboard nodes do not already exist, create them */ 1608 if (nodes_needed) 1609 alloc_kb_mouse(parent, nodes_needed); 1610 ndi_devi_exit(parent, circ); 1611 #endif 1612 return (ndi_busop_bus_config(parent, flags, op, arg, childp, 0)); 1613 } 1614 1615 static int 1616 i8042_bus_unconfig(dev_info_t *parent, uint_t flags, 1617 ddi_bus_config_op_t op, void *arg) 1618 { 1619 /* 1620 * The NDI_UNCONFIG flag allows the reference count on this nexus to be 1621 * decremented when children's drivers are unloaded, enabling the nexus 1622 * itself to be unloaded. 1623 */ 1624 return (ndi_busop_bus_unconfig(parent, flags | NDI_UNCONFIG, op, arg)); 1625 } 1626 1627 #ifdef __sparc 1628 static int 1629 i8042_build_interrupts_property(dev_info_t *dip) 1630 { 1631 dev_info_t *child = ddi_get_child(dip); 1632 uint_t nintr; 1633 int *intrs = NULL; 1634 int interrupts[MAX_INTERRUPTS]; 1635 int i = 0; 1636 1637 /* Walk the children of this node, scanning for interrupts properties */ 1638 while (child != NULL && i < MAX_INTERRUPTS) { 1639 1640 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, 1641 DDI_PROP_DONTPASS, "interrupts", &intrs, &nintr) 1642 == DDI_PROP_SUCCESS && intrs != NULL) { 1643 1644 while (nintr > 0 && i < MAX_INTERRUPTS) { 1645 interrupts[i++] = intrs[--nintr]; 1646 } 1647 ddi_prop_free(intrs); 1648 } 1649 1650 child = ddi_get_next_sibling(child); 1651 } 1652 1653 if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, "interrupts", 1654 interrupts, i) != DDI_PROP_SUCCESS) { 1655 1656 return (DDI_FAILURE); 1657 } 1658 1659 /* 1660 * Oh, the humanity. On the platforms on which we need to 1661 * synthesize an interrupts property, we ALSO need to update the 1662 * device_type property, and set it to "serial" in order for the 1663 * correct interrupt PIL to be chosen by the framework. 1664 */ 1665 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, "device_type", "serial") 1666 != DDI_PROP_SUCCESS) { 1667 1668 return (DDI_FAILURE); 1669 } 1670 1671 return (DDI_SUCCESS); 1672 } 1673 1674 static boolean_t 1675 i8042_is_polling_platform(void) 1676 { 1677 /* 1678 * Returns true if this platform is one of the platforms 1679 * that has interrupt issues with the PS/2 keyboard/mouse. 1680 */ 1681 if (PLATFORM_MATCH("SUNW,UltraAX-")) 1682 return (B_TRUE); 1683 else 1684 return (B_FALSE); 1685 } 1686 #endif