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