i8042.c revision 7656:2621e50fdf4a
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
103enum 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 */
125struct 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 */
156struct 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 */
240int i8042_poll_interval = 8000;		/* usecs */
241int i8042_fast_poll_interval;		/* usecs */
242int i8042_slow_poll_interval;		/* usecs */
243
244boolean_t i8042_polled_mode = B_FALSE;
245boolean_t i8042_force_interrupt_mode = B_FALSE;
246#endif /* __sparc */
247
248int max_wait_iterations = MAX_WAIT_ITERATIONS;
249
250/*
251 * function prototypes for bus ops routines:
252 */
253static 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);
255static 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 */
261static int i8042_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
262static int i8042_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
263static	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);
265static int i8042_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t,
266    void *, dev_info_t **);
267static int i8042_bus_unconfig(dev_info_t *, uint_t,
268    ddi_bus_config_op_t, void *);
269#ifdef __sparc
270static int i8042_build_interrupts_property(dev_info_t *dip);
271static boolean_t i8042_is_polling_platform(void);
272#endif
273
274/*
275 * bus ops and dev ops structures:
276 */
277static 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
309static 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>
329extern struct mod_ops mod_driverops;
330
331static 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
337static struct modlinkage modlinkage = {
338	MODREV_1, (void *)&modldrv, NULL
339};
340
341int
342_init(void)
343{
344	int e;
345
346	/*
347	 * Install the module.
348	 */
349	e = mod_install(&modlinkage);
350	return (e);
351}
352
353int
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
368int
369_info(struct modinfo *modinfop)
370{
371	return (mod_info(&modlinkage, modinfop));
372}
373
374#define	DRIVER_NAME(dip)	ddi_driver_name(dip)
375
376static void i8042_timeout(void *arg);
377static unsigned int i8042_intr(caddr_t arg);
378static void i8042_write_command_byte(struct i8042 *, unsigned char);
379static uint8_t i8042_get8(ddi_acc_impl_t *handlep, uint8_t *addr);
380static void i8042_put8(ddi_acc_impl_t *handlep, uint8_t *addr,
381	uint8_t value);
382static void i8042_send(struct i8042 *global, int reg, unsigned char cmd);
383
384unsigned int i8042_unclaimed_interrupts = 0;
385
386static void
387i8042_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
403static int
404i8042_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 */
502static int
503i8042_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 */
520static int
521i8042_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
540static int
541i8042_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
749fail:
750	/* cleanup will succeed because no children have attached yet */
751	(void) i8042_cleanup(global);
752	return (DDI_FAILURE);
753}
754
755/*ARGSUSED*/
756static int
757i8042_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 */
790static int
791i8042_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
927static void
928i8042_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 */
969static unsigned int
970i8042_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
1034static void
1035i8042_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 */
1047static void
1048i8042_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 */
1103static uint8_t
1104i8042_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
1225static void
1226i8042_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 */
1273static int
1274i8042_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
1379static int
1380i8042_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)
1433static dev_info_t *
1434i8042_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
1453static void
1454alloc_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
1508static int
1509i8042_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
1537static int
1538i8042_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
1550static int
1551i8042_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
1596static boolean_t
1597i8042_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