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