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