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