xref: /openbsd-src/sys/dev/ic/pckbc.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /* $OpenBSD: pckbc.c,v 1.38 2014/07/07 18:20:15 shadchin Exp $ */
2 /* $NetBSD: pckbc.c,v 1.5 2000/06/09 04:58:35 soda Exp $ */
3 
4 /*
5  * Copyright (c) 1998
6  *	Matthias Drochner.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/timeout.h>
32 #include <sys/kernel.h>
33 #include <sys/proc.h>
34 #include <sys/device.h>
35 #include <sys/malloc.h>
36 #include <sys/errno.h>
37 #include <sys/queue.h>
38 #include <sys/lock.h>
39 
40 #include <machine/bus.h>
41 
42 #include <dev/ic/i8042reg.h>
43 #include <dev/ic/pckbcvar.h>
44 
45 #include "pckbd.h"
46 
47 #if NPCKBD > 0
48 #include <dev/pckbc/pckbdvar.h>
49 #endif
50 
51 #ifdef PCKBCDEBUG
52 #define DPRINTF(x...)	do { printf(x); } while (0);
53 #else
54 #define DPRINTF(x...)
55 #endif
56 
57 /* descriptor for one device command */
58 struct pckbc_devcmd {
59 	TAILQ_ENTRY(pckbc_devcmd) next;
60 	int flags;
61 #define KBC_CMDFLAG_SYNC 1 /* give descriptor back to caller */
62 #define KBC_CMDFLAG_SLOW 2
63 	u_char cmd[4];
64 	int cmdlen, cmdidx, retries;
65 	u_char response[4];
66 	int status, responselen, responseidx;
67 };
68 
69 /* data per slave device */
70 struct pckbc_slotdata {
71 	int polling; /* don't read data port in interrupt handler */
72 	TAILQ_HEAD(, pckbc_devcmd) cmdqueue; /* active commands */
73 	TAILQ_HEAD(, pckbc_devcmd) freequeue; /* free commands */
74 #define NCMD 5
75 	struct pckbc_devcmd cmds[NCMD];
76 };
77 
78 #define CMD_IN_QUEUE(q) (!TAILQ_EMPTY(&(q)->cmdqueue))
79 
80 void pckbc_init_slotdata(struct pckbc_slotdata *);
81 int pckbc_attach_slot(struct pckbc_softc *, pckbc_slot_t, int);
82 int pckbc_submatch_locators(struct device *, void *, void *);
83 int pckbc_submatch(struct device *, void *, void *);
84 int pckbcprint(void *, const char *);
85 void pckbc_release_console(void);
86 
87 struct pckbc_internal pckbc_consdata;
88 int pckbc_console_attached;
89 
90 static int pckbc_console;
91 static struct pckbc_slotdata pckbc_cons_slotdata;
92 
93 static int pckbc_wait_output(bus_space_tag_t, bus_space_handle_t);
94 
95 static int pckbc_get8042cmd(struct pckbc_internal *);
96 static int pckbc_put8042cmd(struct pckbc_internal *);
97 static int pckbc_send_devcmd(struct pckbc_internal *, pckbc_slot_t,
98 				  u_char);
99 static void pckbc_poll_cmd1(struct pckbc_internal *, pckbc_slot_t,
100 				 struct pckbc_devcmd *);
101 
102 void pckbc_cleanqueues(struct pckbc_internal *);
103 void pckbc_cleanqueue(struct pckbc_slotdata *);
104 void pckbc_cleanup(void *);
105 void pckbc_poll(void *);
106 int pckbc_cmdresponse(struct pckbc_internal *, pckbc_slot_t, u_char);
107 void pckbc_start(struct pckbc_internal *, pckbc_slot_t);
108 int pckbcintr_internal(struct pckbc_internal *, struct pckbc_softc *);
109 
110 const char *pckbc_slot_names[] = { "kbd", "aux" };
111 
112 #define KBC_DEVCMD_ACK		0xfa
113 #define KBC_DEVCMD_RESEND	0xfe
114 #define KBC_DEVCMD_BAT_DONE	0xaa
115 #define KBC_DEVCMD_BAT_FAIL	0xfc
116 
117 #define	KBD_DELAY	DELAY(8)
118 
119 static inline int
120 pckbc_wait_output(bus_space_tag_t iot, bus_space_handle_t ioh_c)
121 {
122 	u_int i;
123 
124 	for (i = 100000; i; i--)
125 		if (!(bus_space_read_1(iot, ioh_c, 0) & KBS_IBF)) {
126 			KBD_DELAY;
127 			return (1);
128 		}
129 	return (0);
130 }
131 
132 int
133 pckbc_send_cmd(bus_space_tag_t iot, bus_space_handle_t ioh_c, u_char val)
134 {
135 	if (!pckbc_wait_output(iot, ioh_c))
136 		return (0);
137 	bus_space_write_1(iot, ioh_c, 0, val);
138 	return (1);
139 }
140 
141 int
142 pckbc_poll_data1(bus_space_tag_t iot, bus_space_handle_t ioh_d,
143     bus_space_handle_t ioh_c, pckbc_slot_t slot, int checkaux)
144 {
145 	int i;
146 	u_char stat;
147 
148 	/* polls for ~100ms */
149 	for (i = 100; i; i--, delay(1000)) {
150 		stat = bus_space_read_1(iot, ioh_c, 0);
151 		if (stat & KBS_DIB) {
152 			register u_char c;
153 
154 			KBD_DELAY;
155 			c = bus_space_read_1(iot, ioh_d, 0);
156 			if (checkaux && (stat & 0x20)) { /* aux data */
157 				if (slot != PCKBC_AUX_SLOT) {
158 					DPRINTF("lost aux 0x%x\n", c);
159 					continue;
160 				}
161 			} else {
162 				if (slot == PCKBC_AUX_SLOT) {
163 					DPRINTF("lost kbd 0x%x\n", c);
164 					continue;
165 				}
166 			}
167 			return (c);
168 		}
169 	}
170 	return (-1);
171 }
172 
173 /*
174  * Get the current command byte.
175  */
176 static int
177 pckbc_get8042cmd(struct pckbc_internal *t)
178 {
179 	bus_space_tag_t iot = t->t_iot;
180 	bus_space_handle_t ioh_d = t->t_ioh_d;
181 	bus_space_handle_t ioh_c = t->t_ioh_c;
182 	int data;
183 
184 	if (!pckbc_send_cmd(iot, ioh_c, K_RDCMDBYTE))
185 		return (0);
186 	data = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT,
187 				t->t_haveaux);
188 	if (data == -1)
189 		return (0);
190 	t->t_cmdbyte = data;
191 	return (1);
192 }
193 
194 /*
195  * Pass command byte to keyboard controller (8042).
196  */
197 static int
198 pckbc_put8042cmd(struct pckbc_internal *t)
199 {
200 	bus_space_tag_t iot = t->t_iot;
201 	bus_space_handle_t ioh_d = t->t_ioh_d;
202 	bus_space_handle_t ioh_c = t->t_ioh_c;
203 
204 	if (!pckbc_send_cmd(iot, ioh_c, K_LDCMDBYTE))
205 		return (0);
206 	if (!pckbc_wait_output(iot, ioh_c))
207 		return (0);
208 	bus_space_write_1(iot, ioh_d, 0, t->t_cmdbyte);
209 	return (1);
210 }
211 
212 static int
213 pckbc_send_devcmd(struct pckbc_internal *t, pckbc_slot_t slot, u_char val)
214 {
215 	bus_space_tag_t iot = t->t_iot;
216 	bus_space_handle_t ioh_d = t->t_ioh_d;
217 	bus_space_handle_t ioh_c = t->t_ioh_c;
218 
219 	if (slot == PCKBC_AUX_SLOT) {
220 		if (!pckbc_send_cmd(iot, ioh_c, KBC_AUXWRITE))
221 			return (0);
222 	}
223 	if (!pckbc_wait_output(iot, ioh_c))
224 		return (0);
225 	bus_space_write_1(iot, ioh_d, 0, val);
226 	return (1);
227 }
228 
229 int
230 pckbc_is_console(bus_space_tag_t iot, bus_addr_t addr)
231 {
232 	if (pckbc_console && !pckbc_console_attached &&
233 	    pckbc_consdata.t_iot == iot &&
234 	    pckbc_consdata.t_addr == addr)
235 		return (1);
236 	return (0);
237 }
238 
239 int
240 pckbc_submatch_locators(struct device *parent, void *match, void *aux)
241 {
242 	struct cfdata *cf = match;
243 	struct pckbc_attach_args *pa = aux;
244 
245 	if (cf->cf_loc[PCKBCCF_SLOT] != PCKBCCF_SLOT_DEFAULT &&
246 	    cf->cf_loc[PCKBCCF_SLOT] != pa->pa_slot)
247 		return (0);
248 	return (1);
249 }
250 
251 int
252 pckbc_submatch(struct device *parent, void *match, void *aux)
253 {
254 	struct cfdata *cf = match;
255 
256 	if (pckbc_submatch_locators(parent, match, aux) == 0)
257 		return (0);
258 	return ((*cf->cf_attach->ca_match)(parent, cf, aux));
259 }
260 
261 int
262 pckbc_attach_slot(struct pckbc_softc *sc, pckbc_slot_t slot, int force)
263 {
264 	struct pckbc_internal *t = sc->id;
265 	struct pckbc_attach_args pa;
266 	int found;
267 
268 	pa.pa_tag = t;
269 	pa.pa_slot = slot;
270 	found = (config_found_sm((struct device *)sc, &pa, pckbcprint,
271 	    force ? pckbc_submatch_locators : pckbc_submatch) != NULL);
272 
273 	if (found && !t->t_slotdata[slot]) {
274 		t->t_slotdata[slot] = malloc(sizeof(struct pckbc_slotdata),
275 					     M_DEVBUF, M_NOWAIT);
276 		if (t->t_slotdata[slot] == NULL)
277 			return 0;
278 		pckbc_init_slotdata(t->t_slotdata[slot]);
279 	}
280 	return (found);
281 }
282 
283 void
284 pckbc_attach(struct pckbc_softc *sc, int flags)
285 {
286 	struct pckbc_internal *t;
287 	bus_space_tag_t iot;
288 	bus_space_handle_t ioh_d, ioh_c;
289 	int haskbd = 0, res;
290 	u_char cmdbits = 0;
291 
292 	t = sc->id;
293 	iot = t->t_iot;
294 	ioh_d = t->t_ioh_d;
295 	ioh_c = t->t_ioh_c;
296 
297 	if (pckbc_console == 0) {
298 		timeout_set(&t->t_cleanup, pckbc_cleanup, t);
299 		timeout_set(&t->t_poll, pckbc_poll, t);
300 	}
301 
302 	/* flush */
303 	(void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
304 
305 	/* set initial cmd byte */
306 	if (!pckbc_put8042cmd(t)) {
307 #if defined(__i386__) || defined(__amd64__)
308 		if (!ISSET(flags, PCKBCF_FORCE_KEYBOARD_PRESENT)) {
309 			pckbc_release_console();
310 			return;
311 		}
312 #endif
313 		printf("kbc: cmd word write error\n");
314 		return;
315 	}
316 
317 /*
318  * XXX Don't check the keyboard port. There are broken keyboard controllers
319  * which don't pass the test but work normally otherwise.
320  */
321 #if 0
322 	/*
323 	 * check kbd port ok
324 	 */
325 	if (!pckbc_send_cmd(iot, ioh_c, KBC_KBDTEST))
326 		return;
327 	res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
328 
329 	/*
330 	 * Normally, we should get a "0" here.
331 	 * But there are keyboard controllers behaving differently.
332 	 */
333 	if (res == 0 || res == 0xfa || res == 0x01 || res == 0xab) {
334 #ifdef PCKBCDEBUG
335 		if (res != 0)
336 			printf("kbc: returned %x on kbd slot test\n", res);
337 #endif
338 		if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT, 0)) {
339 			cmdbits |= KC8_KENABLE;
340 			haskbd = 1;
341 		}
342 	} else {
343 		printf("kbc: kbd port test: %x\n", res);
344 		return;
345 	}
346 #else
347 	if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT, 0)) {
348 		cmdbits |= KC8_KENABLE;
349 		haskbd = 1;
350 	}
351 #endif /* 0 */
352 
353 	/*
354 	 * Check aux port ok.
355 	 * Avoid KBC_AUXTEST because it hangs some older controllers
356 	 * (eg UMC880?).
357 	 */
358 	if (!pckbc_send_cmd(iot, ioh_c, KBC_AUXECHO)) {
359 		printf("kbc: aux echo error 1\n");
360 		goto nomouse;
361 	}
362 	if (!pckbc_wait_output(iot, ioh_c)) {
363 		printf("kbc: aux echo error 2\n");
364 		goto nomouse;
365 	}
366 	bus_space_write_1(iot, ioh_d, 0, 0x5a);	/* a random value */
367 	res = pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_AUX_SLOT, 1);
368 
369 	if (ISSET(t->t_flags, PCKBC_NEED_AUXWRITE)) {
370 		/*
371 		 * The following code is necessary to find the aux port on the
372 		 * oqo-1 machine, among others.  However if confuses old
373 		 * (non-ps/2) keyboard controllers (at least UMC880x again).
374 		 */
375 		if (res == -1) {
376 			/* Read of aux echo timed out, try again */
377 			if (!pckbc_send_cmd(iot, ioh_c, KBC_AUXWRITE))
378 				goto nomouse;
379 			if (!pckbc_wait_output(iot, ioh_c))
380 				goto nomouse;
381 			bus_space_write_1(iot, ioh_d, 0, 0x5a);
382 			res = pckbc_poll_data1(iot, ioh_d, ioh_c,
383 			    PCKBC_AUX_SLOT, 1);
384 			DPRINTF("kbc: aux echo: %x\n", res);
385 		}
386 	}
387 
388 	if (res != -1) {
389 		/*
390 		 * In most cases, the 0x5a gets echoed.
391 		 * Some old controllers (Gateway 2000 circa 1993)
392 		 * return 0xfe here.
393 		 * We are satisfied if there is anything in the
394 		 * aux output buffer.
395 		 */
396 		DPRINTF("kbc: aux echo: %x\n", res);
397 		t->t_haveaux = 1;
398 		if (pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0))
399 			cmdbits |= KC8_MENABLE;
400 	}
401 #ifdef PCKBCDEBUG
402 	else
403 		printf("kbc: aux echo test failed\n");
404 #endif
405 
406 #if defined(__i386__) || defined(__amd64__)
407 	if (haskbd == 0 && !ISSET(flags, PCKBCF_FORCE_KEYBOARD_PRESENT)) {
408 		if (t->t_haveaux) {
409 			if (pckbc_attach_slot(sc, PCKBC_KBD_SLOT, 1))
410 				cmdbits |= KC8_KENABLE;
411 		} else {
412 			pckbc_release_console();
413 		}
414 	}
415 #endif
416 
417 nomouse:
418 	/* enable needed interrupts */
419 	t->t_cmdbyte |= cmdbits;
420 	if (!pckbc_put8042cmd(t))
421 		printf("kbc: cmd word write error\n");
422 }
423 
424 int
425 pckbcprint(void *aux, const char *pnp)
426 {
427 	struct pckbc_attach_args *pa = aux;
428 
429 	if (!pnp)
430 		printf(" (%s slot)", pckbc_slot_names[pa->pa_slot]);
431 	return (QUIET);
432 }
433 
434 void
435 pckbc_release_console(void)
436 {
437 #if defined(__i386__) || defined(__amd64__)
438 	/*
439 	 * If there is no keyboard present, yet we are the console,
440 	 * we might be on a legacy-free PC where the PS/2 emulated
441 	 * keyboard was elected as console, but went away as soon
442 	 * as the USB controller drivers attached.
443 	 *
444 	 * In that case, we want to release ourselves from console
445 	 * duties, unless we have been able to attach a mouse,
446 	 * which would mean this is a real PS/2 controller
447 	 * afterwards.
448 	 */
449 	if (pckbc_console != 0) {
450 		extern void wscn_input_init(int);
451 
452 		pckbc_console = 0;
453 		wscn_input_init(1);
454 	}
455 #endif
456 }
457 
458 void
459 pckbc_init_slotdata(struct pckbc_slotdata *q)
460 {
461 	int i;
462 	TAILQ_INIT(&q->cmdqueue);
463 	TAILQ_INIT(&q->freequeue);
464 
465 	for (i = 0; i < NCMD; i++) {
466 		TAILQ_INSERT_TAIL(&q->freequeue, &(q->cmds[i]), next);
467 	}
468 	q->polling = 0;
469 }
470 
471 void
472 pckbc_flush(pckbc_tag_t self, pckbc_slot_t slot)
473 {
474 	struct pckbc_internal *t = self;
475 
476 	(void) pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c,
477 	    slot, t->t_haveaux);
478 }
479 
480 int
481 pckbc_poll_data(pckbc_tag_t self, pckbc_slot_t slot)
482 {
483 	struct pckbc_internal *t = self;
484 	struct pckbc_slotdata *q = t->t_slotdata[slot];
485 	int c;
486 
487 	c = pckbc_poll_data1(t->t_iot, t->t_ioh_d, t->t_ioh_c,
488 			     slot, t->t_haveaux);
489 	if (c != -1 && q && CMD_IN_QUEUE(q)) {
490 		/* we jumped into a running command - try to
491 		 deliver the response */
492 		if (pckbc_cmdresponse(t, slot, c))
493 			return (-1);
494 	}
495 	return (c);
496 }
497 
498 /*
499  * set scancode translation on
500  */
501 int
502 pckbc_xt_translation(pckbc_tag_t self)
503 {
504 	struct pckbc_internal *t = self;
505 
506 	if (ISSET(t->t_flags, PCKBC_CANT_TRANSLATE))
507 		return (-1);
508 
509 	if (t->t_cmdbyte & KC8_TRANS)
510 		return (0);
511 
512 	t->t_cmdbyte |= KC8_TRANS;
513 	if (!pckbc_put8042cmd(t))
514 		return (-1);
515 
516 	/* read back to be sure */
517 	if (!pckbc_get8042cmd(t))
518 		return (-1);
519 
520 	return (t->t_cmdbyte & KC8_TRANS) ? (0) : (-1);
521 }
522 
523 static struct pckbc_portcmd {
524 	u_char cmd_en, cmd_dis;
525 } pckbc_portcmd[2] = {
526 	{
527 		KBC_KBDENABLE, KBC_KBDDISABLE,
528 	}, {
529 		KBC_AUXENABLE, KBC_AUXDISABLE,
530 	}
531 };
532 
533 void
534 pckbc_slot_enable(pckbc_tag_t self, pckbc_slot_t slot, int on)
535 {
536 	struct pckbc_internal *t = (struct pckbc_internal *)self;
537 	struct pckbc_portcmd *cmd;
538 
539 	cmd = &pckbc_portcmd[slot];
540 
541 	if (!pckbc_send_cmd(t->t_iot, t->t_ioh_c,
542 			    on ? cmd->cmd_en : cmd->cmd_dis))
543 		printf("pckbc_slot_enable(%d) failed\n", on);
544 
545 	if (slot == PCKBC_KBD_SLOT) {
546 		if (on)
547 			timeout_add_sec(&t->t_poll, 1);
548 		else
549 			timeout_del(&t->t_poll);
550 	}
551 }
552 
553 void
554 pckbc_set_poll(pckbc_tag_t self, pckbc_slot_t slot, int on)
555 {
556 	struct pckbc_internal *t = (struct pckbc_internal *)self;
557 
558 	t->t_slotdata[slot]->polling = on;
559 
560 	if (!on) {
561                 int s;
562 
563                 /*
564                  * If disabling polling on a device that's been configured,
565                  * make sure there are no bytes left in the FIFO, holding up
566                  * the interrupt line.  Otherwise we won't get any further
567                  * interrupts.
568                  */
569 		if (t->t_sc) {
570 			s = spltty();
571 			pckbcintr_internal(t, t->t_sc);
572 			splx(s);
573 		}
574 	}
575 }
576 
577 /*
578  * Pass command to device, poll for ACK and data.
579  * to be called at spltty()
580  */
581 static void
582 pckbc_poll_cmd1(struct pckbc_internal *t, pckbc_slot_t slot,
583     struct pckbc_devcmd *cmd)
584 {
585 	bus_space_tag_t iot = t->t_iot;
586 	bus_space_handle_t ioh_d = t->t_ioh_d;
587 	bus_space_handle_t ioh_c = t->t_ioh_c;
588 	int i, c = 0;
589 
590 	while (cmd->cmdidx < cmd->cmdlen) {
591 		if (!pckbc_send_devcmd(t, slot, cmd->cmd[cmd->cmdidx])) {
592 			printf("pckbc_cmd: send error\n");
593 			cmd->status = EIO;
594 			return;
595 		}
596 		for (i = 10; i; i--) { /* 1s ??? */
597 			c = pckbc_poll_data1(iot, ioh_d, ioh_c, slot,
598 					     t->t_haveaux);
599 			if (c != -1)
600 				break;
601 		}
602 
603 		switch (c) {
604 		case KBC_DEVCMD_ACK:
605 			cmd->cmdidx++;
606 			continue;
607 		/*
608 		 * Some legacy free PCs keep returning Basic Assurance Test
609 		 * (BAT) instead of something usable, so fail gracefully.
610 		 */
611 		case KBC_DEVCMD_RESEND:
612 		case KBC_DEVCMD_BAT_DONE:
613 		case KBC_DEVCMD_BAT_FAIL:
614 			DPRINTF("pckbc_cmd: %s\n",
615 			    c == KBC_DEVCMD_RESEND ? "RESEND": "BAT");
616 			if (cmd->retries++ < 5)
617 				continue;
618 
619 			DPRINTF("pckbc_cmd: cmd failed\n");
620 			cmd->status = ENXIO;
621 			return;
622 		case -1:
623 			DPRINTF("pckbc_cmd: timeout\n");
624 			cmd->status = EIO;
625 			return;
626 		default:
627 			DPRINTF("pckbc_cmd: lost 0x%x\n", c);
628 		}
629 	}
630 
631 	while (cmd->responseidx < cmd->responselen) {
632 		if (cmd->flags & KBC_CMDFLAG_SLOW)
633 			i = 100; /* 10s ??? */
634 		else
635 			i = 10; /* 1s ??? */
636 		while (i--) {
637 			c = pckbc_poll_data1(iot, ioh_d, ioh_c, slot,
638 					     t->t_haveaux);
639 			if (c != -1)
640 				break;
641 		}
642 		if (c == -1) {
643 			DPRINTF("pckbc_cmd: no data\n");
644 			cmd->status = ETIMEDOUT;
645 			return;
646 		} else
647 			cmd->response[cmd->responseidx++] = c;
648 	}
649 }
650 
651 /* for use in autoconfiguration */
652 int
653 pckbc_poll_cmd(pckbc_tag_t self, pckbc_slot_t slot, u_char *cmd, int len,
654     int responselen, u_char *respbuf, int slow)
655 {
656 	struct pckbc_devcmd nc;
657 
658 	if ((len > 4) || (responselen > 4))
659 		return (EINVAL);
660 
661 	bzero(&nc, sizeof(nc));
662 	bcopy(cmd, nc.cmd, len);
663 	nc.cmdlen = len;
664 	nc.responselen = responselen;
665 	nc.flags = (slow ? KBC_CMDFLAG_SLOW : 0);
666 
667 	pckbc_poll_cmd1(self, slot, &nc);
668 
669 	if (nc.status == 0 && respbuf)
670 		bcopy(nc.response, respbuf, responselen);
671 
672 	return (nc.status);
673 }
674 
675 /*
676  * Clean up a command queue, throw away everything.
677  */
678 void
679 pckbc_cleanqueue(struct pckbc_slotdata *q)
680 {
681 	struct pckbc_devcmd *cmd;
682 #ifdef PCKBCDEBUG
683 	int i;
684 #endif
685 
686 	while ((cmd = TAILQ_FIRST(&q->cmdqueue))) {
687 		TAILQ_REMOVE(&q->cmdqueue, cmd, next);
688 #ifdef PCKBCDEBUG
689 		printf("pckbc_cleanqueue: removing");
690 		for (i = 0; i < cmd->cmdlen; i++)
691 			printf(" %02x", cmd->cmd[i]);
692 		printf("\n");
693 #endif
694 		TAILQ_INSERT_TAIL(&q->freequeue, cmd, next);
695 	}
696 }
697 
698 void
699 pckbc_cleanqueues(struct pckbc_internal *t)
700 {
701 	if (t->t_slotdata[PCKBC_KBD_SLOT])
702 		pckbc_cleanqueue(t->t_slotdata[PCKBC_KBD_SLOT]);
703 	if (t->t_slotdata[PCKBC_AUX_SLOT])
704 		pckbc_cleanqueue(t->t_slotdata[PCKBC_AUX_SLOT]);
705 }
706 
707 /*
708  * Timeout error handler: clean queues and data port.
709  * XXX could be less invasive.
710  */
711 void
712 pckbc_cleanup(void *self)
713 {
714 	struct pckbc_internal *t = self;
715 	int s;
716 
717 	printf("pckbc: command timeout\n");
718 
719 	s = spltty();
720 
721 	pckbc_cleanqueues(t);
722 
723 	while (bus_space_read_1(t->t_iot, t->t_ioh_c, 0) & KBS_DIB) {
724 		KBD_DELAY;
725 		(void) bus_space_read_1(t->t_iot, t->t_ioh_d, 0);
726 	}
727 
728 	/* reset KBC? */
729 
730 	splx(s);
731 }
732 
733 /*
734  * Stop the keyboard controller when we are going to suspend
735  */
736 void
737 pckbc_stop(struct pckbc_softc *sc)
738 {
739 	struct pckbc_internal *t = sc->id;
740 
741 	timeout_del(&t->t_poll);
742 	pckbc_cleanqueues(t);
743 	timeout_del(&t->t_cleanup);
744 }
745 
746 /*
747  * Reset the keyboard controller in a violent fashion; normally done
748  * after suspend/resume when we do not trust the machine.
749  */
750 void
751 pckbc_reset(struct pckbc_softc *sc)
752 {
753 	struct pckbc_internal *t = sc->id;
754 	bus_space_tag_t iot = t->t_iot;
755 	bus_space_handle_t ioh_d = t->t_ioh_d, ioh_c = t->t_ioh_c;
756 
757 	pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
758 	/* KBC selftest */
759 	if (pckbc_send_cmd(iot, ioh_c, KBC_SELFTEST) == 0)
760 		return;
761 	pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
762 	(void)pckbc_put8042cmd(t);
763 	pckbcintr_internal(t->t_sc->id, t->t_sc);
764 }
765 
766 /*
767  * Pass command to device during normal operation.
768  * to be called at spltty()
769  */
770 void
771 pckbc_start(struct pckbc_internal *t, pckbc_slot_t slot)
772 {
773 	struct pckbc_slotdata *q = t->t_slotdata[slot];
774 	struct pckbc_devcmd *cmd = TAILQ_FIRST(&q->cmdqueue);
775 
776 	if (q->polling) {
777 		do {
778 			pckbc_poll_cmd1(t, slot, cmd);
779 			if (cmd->status)
780 				printf("pckbc_start: command error\n");
781 
782 			if (cmd->flags & KBC_CMDFLAG_SYNC) {
783 				wakeup(cmd);
784 				cmd = TAILQ_NEXT(cmd, next);
785 			} else {
786 				TAILQ_REMOVE(&q->cmdqueue, cmd, next);
787 				timeout_del(&t->t_cleanup);
788 				TAILQ_INSERT_TAIL(&q->freequeue, cmd, next);
789 				cmd = TAILQ_FIRST(&q->cmdqueue);
790 			}
791 		} while (cmd);
792 		return;
793 	}
794 
795 	if (!pckbc_send_devcmd(t, slot, cmd->cmd[cmd->cmdidx])) {
796 		printf("pckbc_start: send error\n");
797 		/* XXX what now? */
798 		return;
799 	}
800 }
801 
802 /*
803  * Handle command responses coming in asynchronously,
804  * return nonzero if valid response.
805  * to be called at spltty()
806  */
807 int
808 pckbc_cmdresponse(struct pckbc_internal *t, pckbc_slot_t slot, u_char data)
809 {
810 	struct pckbc_slotdata *q = t->t_slotdata[slot];
811 	struct pckbc_devcmd *cmd = TAILQ_FIRST(&q->cmdqueue);
812 #ifdef DIAGNOSTIC
813 	if (!cmd)
814 		panic("pckbc_cmdresponse: no active command");
815 #endif
816 	if (cmd->cmdidx < cmd->cmdlen) {
817 		if (data != KBC_DEVCMD_ACK && data != KBC_DEVCMD_RESEND)
818 			return (0);
819 
820 		if (data == KBC_DEVCMD_RESEND) {
821 			if (cmd->retries++ < 5) {
822 				/* try again last command */
823 				goto restart;
824 			} else {
825 				DPRINTF("pckbc: cmd failed\n");
826 				cmd->status = ENXIO;
827 				/* dequeue */
828 			}
829 		} else {
830 			if (++cmd->cmdidx < cmd->cmdlen)
831 				goto restart;
832 			if (cmd->responselen)
833 				return (1);
834 			/* else dequeue */
835 		}
836 	} else if (cmd->responseidx < cmd->responselen) {
837 		cmd->response[cmd->responseidx++] = data;
838 		if (cmd->responseidx < cmd->responselen)
839 			return (1);
840 		/* else dequeue */
841 	} else
842 		return (0);
843 
844 	/* dequeue: */
845 	if (cmd->flags & KBC_CMDFLAG_SYNC) {
846 		wakeup(cmd);
847 		cmd = TAILQ_NEXT(cmd, next);
848 	} else {
849 		TAILQ_REMOVE(&q->cmdqueue, cmd, next);
850 		timeout_del(&t->t_cleanup);
851 		TAILQ_INSERT_TAIL(&q->freequeue, cmd, next);
852 		cmd = TAILQ_FIRST(&q->cmdqueue);
853 	}
854 	if (cmd == NULL)
855 		return (1);
856 restart:
857 	pckbc_start(t, slot);
858 	return (1);
859 }
860 
861 /*
862  * Put command into the device's command queue, return zero or errno.
863  */
864 int
865 pckbc_enqueue_cmd(pckbc_tag_t self, pckbc_slot_t slot, u_char *cmd, int len,
866     int responselen, int sync, u_char *respbuf)
867 {
868 	struct pckbc_internal *t = self;
869 	struct pckbc_slotdata *q = t->t_slotdata[slot];
870 	struct pckbc_devcmd *nc;
871 	int s, isactive, res = 0;
872 
873 	if ((len > 4) || (responselen > 4))
874 		return (EINVAL);
875 	s = spltty();
876 	nc = TAILQ_FIRST(&q->freequeue);
877 	if (nc) {
878 		TAILQ_REMOVE(&q->freequeue, nc, next);
879 	}
880 	splx(s);
881 	if (!nc)
882 		return (ENOMEM);
883 
884 	bzero(nc, sizeof(*nc));
885 	bcopy(cmd, nc->cmd, len);
886 	nc->cmdlen = len;
887 	nc->responselen = responselen;
888 	nc->flags = (sync ? KBC_CMDFLAG_SYNC : 0);
889 
890 	s = spltty();
891 
892 	if (q->polling && sync) {
893 		/*
894 		 * XXX We should poll until the queue is empty.
895 		 * But we don't come here normally, so make
896 		 * it simple and throw away everything.
897 		 */
898 		pckbc_cleanqueue(q);
899 	}
900 
901 	isactive = CMD_IN_QUEUE(q);
902 	TAILQ_INSERT_TAIL(&q->cmdqueue, nc, next);
903 	if (!isactive)
904 		pckbc_start(t, slot);
905 
906 	if (q->polling)
907 		res = (sync ? nc->status : 0);
908 	else if (sync) {
909 		if ((res = tsleep(nc, 0, "kbccmd", 1*hz))) {
910 			TAILQ_REMOVE(&q->cmdqueue, nc, next);
911 			pckbc_cleanup(t);
912 		} else {
913 			TAILQ_REMOVE(&q->cmdqueue, nc, next);
914 			res = nc->status;
915 		}
916 	} else
917 		timeout_add_sec(&t->t_cleanup, 1);
918 
919 	if (sync) {
920 		if (respbuf)
921 			bcopy(nc->response, respbuf, responselen);
922 		TAILQ_INSERT_TAIL(&q->freequeue, nc, next);
923 	}
924 
925 	splx(s);
926 
927 	return (res);
928 }
929 
930 void
931 pckbc_set_inputhandler(pckbc_tag_t self, pckbc_slot_t slot, pckbc_inputfcn func,
932     void *arg, char *name)
933 {
934 	struct pckbc_internal *t = (struct pckbc_internal *)self;
935 	struct pckbc_softc *sc = t->t_sc;
936 
937 	if (slot >= PCKBC_NSLOTS)
938 		panic("pckbc_set_inputhandler: bad slot %d", slot);
939 
940 	(*sc->intr_establish)(sc, slot);
941 
942 	sc->inputhandler[slot] = func;
943 	sc->inputarg[slot] = arg;
944 	sc->subname[slot] = name;
945 
946 	if (pckbc_console && slot == PCKBC_KBD_SLOT)
947 		timeout_add_sec(&t->t_poll, 1);
948 }
949 
950 void
951 pckbc_poll(void *v)
952 {
953 	struct pckbc_internal *t = v;
954 	int s;
955 
956 	s = spltty();
957 	(void)pckbcintr_internal(t, t->t_sc);
958 	timeout_add_sec(&t->t_poll, 1);
959 	splx(s);
960 }
961 
962 int
963 pckbcintr(void *vsc)
964 {
965 	struct pckbc_softc *sc = (struct pckbc_softc *)vsc;
966 
967 	return (pckbcintr_internal(sc->id, sc));
968 }
969 
970 int
971 pckbcintr_internal(struct pckbc_internal *t, struct pckbc_softc *sc)
972 {
973 	u_char stat;
974 	pckbc_slot_t slot;
975 	struct pckbc_slotdata *q;
976 	int served = 0, data;
977 
978 	/* reschedule timeout further into the idle times */
979 	if (timeout_pending(&t->t_poll))
980 		timeout_add_sec(&t->t_poll, 1);
981 
982 	for(;;) {
983 		stat = bus_space_read_1(t->t_iot, t->t_ioh_c, 0);
984 		if (!(stat & KBS_DIB))
985 			break;
986 
987 		served = 1;
988 
989 		slot = (t->t_haveaux && (stat & 0x20)) ?
990 		    PCKBC_AUX_SLOT : PCKBC_KBD_SLOT;
991 		q = t->t_slotdata[slot];
992 
993 		if (!q) {
994 			/* XXX do something for live insertion? */
995 #ifdef PCKBCDEBUG
996 			printf("pckbcintr: no dev for slot %d\n", slot);
997 #endif
998 			KBD_DELAY;
999 			(void) bus_space_read_1(t->t_iot, t->t_ioh_d, 0);
1000 			continue;
1001 		}
1002 
1003 		if (q->polling)
1004 			break; /* pckbc_poll_data() will get it */
1005 
1006 		KBD_DELAY;
1007 		data = bus_space_read_1(t->t_iot, t->t_ioh_d, 0);
1008 
1009 		if (CMD_IN_QUEUE(q) && pckbc_cmdresponse(t, slot, data))
1010 			continue;
1011 
1012 		if (sc != NULL) {
1013 			if (sc->inputhandler[slot])
1014 				(*sc->inputhandler[slot])(sc->inputarg[slot],
1015 				    data);
1016 #ifdef PCKBCDEBUG
1017 			else
1018 				printf("pckbcintr: slot %d lost %d\n",
1019 				    slot, data);
1020 #endif
1021 		}
1022 	}
1023 
1024 	return (served);
1025 }
1026 
1027 int
1028 pckbc_cnattach(bus_space_tag_t iot, bus_addr_t addr, bus_size_t cmd_offset,
1029     int flags)
1030 {
1031 	bus_space_handle_t ioh_d, ioh_c;
1032 	int res = 0;
1033 
1034 	if (bus_space_map(iot, addr + KBDATAP, 1, 0, &ioh_d))
1035                 return (ENXIO);
1036 	if (bus_space_map(iot, addr + cmd_offset, 1, 0, &ioh_c)) {
1037 		bus_space_unmap(iot, ioh_d, 1);
1038                 return (ENXIO);
1039 	}
1040 
1041 	pckbc_consdata.t_iot = iot;
1042 	pckbc_consdata.t_ioh_d = ioh_d;
1043 	pckbc_consdata.t_ioh_c = ioh_c;
1044 	pckbc_consdata.t_addr = addr;
1045 	pckbc_consdata.t_flags = flags;
1046 	timeout_set(&pckbc_consdata.t_cleanup, pckbc_cleanup, &pckbc_consdata);
1047 	timeout_set(&pckbc_consdata.t_poll, pckbc_poll, &pckbc_consdata);
1048 
1049 	/* flush */
1050 	(void) pckbc_poll_data1(iot, ioh_d, ioh_c, PCKBC_KBD_SLOT, 0);
1051 
1052 	/* selftest? */
1053 
1054 	/* init cmd byte, enable ports */
1055 	pckbc_consdata.t_cmdbyte = KC8_CPU;
1056 	if (!pckbc_put8042cmd(&pckbc_consdata)) {
1057 		printf("kbc: cmd word write error\n");
1058 		res = EIO;
1059 	}
1060 
1061 	if (!res) {
1062 #if (NPCKBD > 0)
1063 		res = pckbd_cnattach(&pckbc_consdata);
1064 #else
1065 		res = ENXIO;
1066 #endif /* NPCKBD > 0 */
1067 	}
1068 
1069 	if (res) {
1070 		bus_space_unmap(iot, pckbc_consdata.t_ioh_d, 1);
1071 		bus_space_unmap(iot, pckbc_consdata.t_ioh_c, 1);
1072 	} else {
1073 		pckbc_consdata.t_slotdata[PCKBC_KBD_SLOT] = &pckbc_cons_slotdata;
1074 		pckbc_init_slotdata(&pckbc_cons_slotdata);
1075 		pckbc_console = 1;
1076 	}
1077 
1078 	return (res);
1079 }
1080 
1081 struct cfdriver pckbc_cd = {
1082 	NULL, "pckbc", DV_DULL
1083 };
1084