1/*
2 * vkbd.c
3 */
4
5/*-
6 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $Id: vkbd.c,v 1.20 2004/11/15 23:53:30 max Exp $
31 * $FreeBSD: releng/10.3/sys/dev/vkbd/vkbd.c 255359 2013-09-07 13:45:44Z davide $
32 */
33
34#include "opt_compat.h"
35#include "opt_kbd.h"
36
37#include <sys/param.h>
38#include <sys/conf.h>
39#include <sys/fcntl.h>
40#include <sys/kbio.h>
41#include <sys/kernel.h>
42#include <sys/limits.h>
43#include <sys/lock.h>
44#include <sys/malloc.h>
45#include <sys/module.h>
46#include <sys/mutex.h>
47#include <sys/poll.h>
48#include <sys/proc.h>
49#include <sys/queue.h>
50#include <sys/selinfo.h>
51#include <sys/systm.h>
52#include <sys/taskqueue.h>
53#include <sys/uio.h>
54#include <dev/kbd/kbdreg.h>
55#include <dev/kbd/kbdtables.h>
56#include <dev/vkbd/vkbd_var.h>
57
58#define DEVICE_NAME	"vkbdctl"
59#define KEYBOARD_NAME	"vkbd"
60
61MALLOC_DECLARE(M_VKBD);
62MALLOC_DEFINE(M_VKBD, KEYBOARD_NAME, "Virtual AT keyboard");
63
64/*****************************************************************************
65 *****************************************************************************
66 **                             Keyboard state
67 *****************************************************************************
68 *****************************************************************************/
69
70/*
71 * XXX
72 * For now rely on Giant mutex to protect our data structures.
73 * Just like the rest of keyboard drivers and syscons(4) do.
74 */
75
76#if 0 /* not yet */
77#define VKBD_LOCK_DECL		struct mtx ks_lock
78#define VKBD_LOCK_INIT(s)	mtx_init(&(s)->ks_lock, "vkbd_lock", NULL, MTX_DEF|MTX_RECURSE)
79#define VKBD_LOCK_DESTROY(s)	mtx_destroy(&(s)->ks_lock)
80#define VKBD_LOCK(s)		mtx_lock(&(s)->ks_lock)
81#define VKBD_UNLOCK(s)		mtx_unlock(&(s)->ks_lock)
82#define VKBD_LOCK_ASSERT(s, w)	mtx_assert(&(s)->ks_lock, w)
83#define VKBD_SLEEP(s, f, d, t) \
84	msleep(&(s)->f, &(s)->ks_lock, PCATCH | (PZERO + 1), d, t)
85#else
86#define VKBD_LOCK_DECL
87#define VKBD_LOCK_INIT(s)
88#define VKBD_LOCK_DESTROY(s)
89#define VKBD_LOCK(s)
90#define VKBD_UNLOCK(s)
91#define VKBD_LOCK_ASSERT(s, w)
92#define VKBD_SLEEP(s, f, d, t)	tsleep(&(s)->f, PCATCH | (PZERO + 1), d, t)
93#endif
94
95#define VKBD_KEYBOARD(d) \
96	kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, dev2unit(d)))
97
98/* vkbd queue */
99struct vkbd_queue
100{
101	int		q[VKBD_Q_SIZE]; /* queue */
102	int		head;		/* index of the first code */
103	int		tail;		/* index of the last code */
104	int		cc;		/* number of codes in queue */
105};
106
107typedef struct vkbd_queue	vkbd_queue_t;
108
109/* vkbd state */
110struct vkbd_state
111{
112	struct cdev	*ks_dev;	/* control device */
113
114	struct selinfo	 ks_rsel;	/* select(2) */
115	struct selinfo	 ks_wsel;
116
117	vkbd_queue_t	 ks_inq;	/* input key codes queue */
118	struct task	 ks_task;	/* interrupt task */
119
120	int		 ks_flags;	/* flags */
121#define OPEN		(1 << 0)	/* control device is open */
122#define COMPOSE		(1 << 1)	/* compose flag */
123#define STATUS		(1 << 2)	/* status has changed */
124#define TASK		(1 << 3)	/* interrupt task queued */
125#define READ		(1 << 4)	/* read pending */
126#define WRITE		(1 << 5)	/* write pending */
127
128	int		 ks_mode;	/* K_XLATE, K_RAW, K_CODE */
129	int		 ks_polling;	/* polling flag */
130	int		 ks_state;	/* shift/lock key state */
131	int		 ks_accents;	/* accent key index (> 0) */
132	u_int		 ks_composed_char; /* composed char code */
133	u_char		 ks_prefix;	/* AT scan code prefix */
134
135	VKBD_LOCK_DECL;
136};
137
138typedef struct vkbd_state	vkbd_state_t;
139
140/*****************************************************************************
141 *****************************************************************************
142 **                             Character device
143 *****************************************************************************
144 *****************************************************************************/
145
146static void		vkbd_dev_clone(void *, struct ucred *, char *, int,
147			    struct cdev **);
148static d_open_t		vkbd_dev_open;
149static d_close_t	vkbd_dev_close;
150static d_read_t		vkbd_dev_read;
151static d_write_t	vkbd_dev_write;
152static d_ioctl_t	vkbd_dev_ioctl;
153static d_poll_t		vkbd_dev_poll;
154static void		vkbd_dev_intr(void *, int);
155static void		vkbd_status_changed(vkbd_state_t *);
156static int		vkbd_data_ready(vkbd_state_t *);
157static int		vkbd_data_read(vkbd_state_t *, int);
158
159static struct cdevsw	vkbd_dev_cdevsw = {
160	.d_version =	D_VERSION,
161	.d_flags =	D_NEEDGIANT | D_NEEDMINOR,
162	.d_open =	vkbd_dev_open,
163	.d_close =	vkbd_dev_close,
164	.d_read =	vkbd_dev_read,
165	.d_write =	vkbd_dev_write,
166	.d_ioctl =	vkbd_dev_ioctl,
167	.d_poll =	vkbd_dev_poll,
168	.d_name =	DEVICE_NAME,
169};
170
171static struct clonedevs	*vkbd_dev_clones = NULL;
172
173/* Clone device */
174static void
175vkbd_dev_clone(void *arg, struct ucred *cred, char *name, int namelen,
176    struct cdev **dev)
177{
178	int	unit;
179
180	if (*dev != NULL)
181		return;
182
183	if (strcmp(name, DEVICE_NAME) == 0)
184		unit = -1;
185	else if (dev_stdclone(name, NULL, DEVICE_NAME, &unit) != 1)
186		return; /* don't recognize the name */
187
188	/* find any existing device, or allocate new unit number */
189	if (clone_create(&vkbd_dev_clones, &vkbd_dev_cdevsw, &unit, dev, 0))
190		*dev = make_dev_credf(MAKEDEV_REF, &vkbd_dev_cdevsw, unit,
191			cred, UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME "%d",
192			unit);
193}
194
195/* Open device */
196static int
197vkbd_dev_open(struct cdev *dev, int flag, int mode, struct thread *td)
198{
199	int			 unit = dev2unit(dev), error;
200	keyboard_switch_t	*sw = NULL;
201	keyboard_t		*kbd = NULL;
202	vkbd_state_t		*state = (vkbd_state_t *) dev->si_drv1;
203
204	/* XXX FIXME: dev->si_drv1 locking */
205	if (state == NULL) {
206		if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL)
207			return (ENXIO);
208
209		if ((error = (*sw->probe)(unit, NULL, 0)) != 0 ||
210		    (error = (*sw->init)(unit, &kbd, NULL, 0)) != 0)
211			return (error);
212
213		state = (vkbd_state_t *) kbd->kb_data;
214
215		if ((error = (*sw->enable)(kbd)) != 0) {
216			(*sw->term)(kbd);
217			return (error);
218		}
219
220#ifdef KBD_INSTALL_CDEV
221		if ((error = kbd_attach(kbd)) != 0) {
222			(*sw->disable)(kbd);
223			(*sw->term)(kbd);
224			return (error);
225		}
226#endif /* def KBD_INSTALL_CDEV */
227
228		dev->si_drv1 = kbd->kb_data;
229	}
230
231	VKBD_LOCK(state);
232
233	if (state->ks_flags & OPEN) {
234		VKBD_UNLOCK(state);
235		return (EBUSY);
236	}
237
238	state->ks_flags |= OPEN;
239	state->ks_dev = dev;
240
241	VKBD_UNLOCK(state);
242
243	return (0);
244}
245
246/* Close device */
247static int
248vkbd_dev_close(struct cdev *dev, int foo, int bar, struct thread *td)
249{
250	keyboard_t	*kbd = VKBD_KEYBOARD(dev);
251	vkbd_state_t	*state = NULL;
252
253	if (kbd == NULL)
254		return (ENXIO);
255
256	if (kbd->kb_data == NULL || kbd->kb_data != dev->si_drv1)
257		panic("%s: kbd->kb_data != dev->si_drv1\n", __func__);
258
259	state = (vkbd_state_t *) kbd->kb_data;
260
261	VKBD_LOCK(state);
262
263	/* wait for interrupt task */
264	while (state->ks_flags & TASK)
265		VKBD_SLEEP(state, ks_task, "vkbdc", 0);
266
267	/* wakeup poll()ers */
268	selwakeuppri(&state->ks_rsel, PZERO + 1);
269	selwakeuppri(&state->ks_wsel, PZERO + 1);
270
271	state->ks_flags &= ~OPEN;
272	state->ks_dev = NULL;
273	state->ks_inq.head = state->ks_inq.tail = state->ks_inq.cc = 0;
274
275	VKBD_UNLOCK(state);
276
277	kbdd_disable(kbd);
278#ifdef KBD_INSTALL_CDEV
279	kbd_detach(kbd);
280#endif /* def KBD_INSTALL_CDEV */
281	kbdd_term(kbd);
282
283	/* XXX FIXME: dev->si_drv1 locking */
284	dev->si_drv1 = NULL;
285
286	return (0);
287}
288
289/* Read status */
290static int
291vkbd_dev_read(struct cdev *dev, struct uio *uio, int flag)
292{
293	keyboard_t	*kbd = VKBD_KEYBOARD(dev);
294	vkbd_state_t	*state = NULL;
295	vkbd_status_t	 status;
296	int		 error;
297
298	if (kbd == NULL)
299		return (ENXIO);
300
301	if (uio->uio_resid != sizeof(status))
302		return (EINVAL);
303
304	if (kbd->kb_data == NULL || kbd->kb_data != dev->si_drv1)
305		panic("%s: kbd->kb_data != dev->si_drv1\n", __func__);
306
307	state = (vkbd_state_t *) kbd->kb_data;
308
309	VKBD_LOCK(state);
310
311	if (state->ks_flags & READ) {
312		VKBD_UNLOCK(state);
313		return (EALREADY);
314	}
315
316	state->ks_flags |= READ;
317again:
318	if (state->ks_flags & STATUS) {
319		state->ks_flags &= ~STATUS;
320
321		status.mode = state->ks_mode;
322		status.leds = KBD_LED_VAL(kbd);
323		status.lock = state->ks_state & LOCK_MASK;
324		status.delay = kbd->kb_delay1;
325		status.rate = kbd->kb_delay2;
326		bzero(status.reserved, sizeof(status.reserved));
327
328		error = uiomove(&status, sizeof(status), uio);
329	} else {
330		if (flag & O_NONBLOCK) {
331			error = EWOULDBLOCK;
332			goto done;
333		}
334
335		error = VKBD_SLEEP(state, ks_flags, "vkbdr", 0);
336		if (error != 0)
337			goto done;
338
339		goto again;
340	}
341done:
342	state->ks_flags &= ~READ;
343
344	VKBD_UNLOCK(state);
345
346	return (error);
347}
348
349/* Write scancodes */
350static int
351vkbd_dev_write(struct cdev *dev, struct uio *uio, int flag)
352{
353	keyboard_t	*kbd = VKBD_KEYBOARD(dev);
354	vkbd_state_t	*state = NULL;
355	vkbd_queue_t	*q = NULL;
356	int		 error, avail, bytes;
357
358	if (kbd == NULL)
359		return (ENXIO);
360
361	if (uio->uio_resid <= 0)
362		return (EINVAL);
363
364	if (kbd->kb_data == NULL || kbd->kb_data != dev->si_drv1)
365		panic("%s: kbd->kb_data != dev->si_drv1\n", __func__);
366
367	state = (vkbd_state_t *) kbd->kb_data;
368
369	VKBD_LOCK(state);
370
371	if (state->ks_flags & WRITE) {
372		VKBD_UNLOCK(state);
373		return (EALREADY);
374	}
375
376	state->ks_flags |= WRITE;
377	error = 0;
378	q = &state->ks_inq;
379
380	while (uio->uio_resid >= sizeof(q->q[0])) {
381		if (q->head == q->tail) {
382			if (q->cc == 0)
383				avail = sizeof(q->q)/sizeof(q->q[0]) - q->head;
384			else
385				avail = 0; /* queue must be full */
386		} else if (q->head < q->tail)
387			avail = sizeof(q->q)/sizeof(q->q[0]) - q->tail;
388		else
389			avail = q->head - q->tail;
390
391		if (avail == 0) {
392			if (flag & O_NONBLOCK) {
393				error = EWOULDBLOCK;
394				break;
395			}
396
397			error = VKBD_SLEEP(state, ks_inq, "vkbdw", 0);
398			if (error != 0)
399				break;
400		} else {
401			bytes = avail * sizeof(q->q[0]);
402			if (bytes > uio->uio_resid) {
403				avail = uio->uio_resid / sizeof(q->q[0]);
404				bytes = avail * sizeof(q->q[0]);
405			}
406
407			error = uiomove((void *) &q->q[q->tail], bytes, uio);
408			if (error != 0)
409				break;
410
411			q->cc += avail;
412			q->tail += avail;
413			if (q->tail == sizeof(q->q)/sizeof(q->q[0]))
414				q->tail = 0;
415
416			/* queue interrupt task if needed */
417			if (!(state->ks_flags & TASK) &&
418			    taskqueue_enqueue(taskqueue_swi_giant, &state->ks_task) == 0)
419				state->ks_flags |= TASK;
420		}
421	}
422
423	state->ks_flags &= ~WRITE;
424
425	VKBD_UNLOCK(state);
426
427	return (error);
428}
429
430/* Process ioctl */
431static int
432vkbd_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
433{
434	keyboard_t	*kbd = VKBD_KEYBOARD(dev);
435
436	return ((kbd == NULL)? ENXIO : kbdd_ioctl(kbd, cmd, data));
437}
438
439/* Poll device */
440static int
441vkbd_dev_poll(struct cdev *dev, int events, struct thread *td)
442{
443	vkbd_state_t	*state = (vkbd_state_t *) dev->si_drv1;
444	vkbd_queue_t	*q = NULL;
445	int		 revents = 0;
446
447	if (state == NULL)
448		return (ENXIO);
449
450	VKBD_LOCK(state);
451
452	q = &state->ks_inq;
453
454	if (events & (POLLIN | POLLRDNORM)) {
455		if (state->ks_flags & STATUS)
456			revents |= events & (POLLIN | POLLRDNORM);
457		else
458			selrecord(td, &state->ks_rsel);
459	}
460
461	if (events & (POLLOUT | POLLWRNORM)) {
462		if (q->cc < sizeof(q->q)/sizeof(q->q[0]))
463			revents |= events & (POLLOUT | POLLWRNORM);
464		else
465			selrecord(td, &state->ks_wsel);
466	}
467
468	VKBD_UNLOCK(state);
469
470	return (revents);
471}
472
473/* Interrupt handler */
474void
475vkbd_dev_intr(void *xkbd, int pending)
476{
477	keyboard_t	*kbd = (keyboard_t *) xkbd;
478	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
479
480	kbdd_intr(kbd, NULL);
481
482	VKBD_LOCK(state);
483
484	state->ks_flags &= ~TASK;
485	wakeup(&state->ks_task);
486
487	VKBD_UNLOCK(state);
488}
489
490/* Set status change flags */
491static void
492vkbd_status_changed(vkbd_state_t *state)
493{
494	VKBD_LOCK_ASSERT(state, MA_OWNED);
495
496	if (!(state->ks_flags & STATUS)) {
497		state->ks_flags |= STATUS;
498		selwakeuppri(&state->ks_rsel, PZERO + 1);
499		wakeup(&state->ks_flags);
500	}
501}
502
503/* Check if we have data in the input queue */
504static int
505vkbd_data_ready(vkbd_state_t *state)
506{
507	VKBD_LOCK_ASSERT(state, MA_OWNED);
508
509	return (state->ks_inq.cc > 0);
510}
511
512/* Read one code from the input queue */
513static int
514vkbd_data_read(vkbd_state_t *state, int wait)
515{
516	vkbd_queue_t	*q = &state->ks_inq;
517	int		 c;
518
519	VKBD_LOCK_ASSERT(state, MA_OWNED);
520
521	if (q->cc == 0)
522		return (-1);
523
524	/* get first code from the queue */
525	q->cc --;
526	c = q->q[q->head ++];
527	if (q->head == sizeof(q->q)/sizeof(q->q[0]))
528		q->head = 0;
529
530	/* wakeup ks_inq writers/poll()ers */
531	selwakeuppri(&state->ks_wsel, PZERO + 1);
532	wakeup(q);
533
534	return (c);
535}
536
537/****************************************************************************
538 ****************************************************************************
539 **                              Keyboard driver
540 ****************************************************************************
541 ****************************************************************************/
542
543static int		vkbd_configure(int flags);
544static kbd_probe_t	vkbd_probe;
545static kbd_init_t	vkbd_init;
546static kbd_term_t	vkbd_term;
547static kbd_intr_t	vkbd_intr;
548static kbd_test_if_t	vkbd_test_if;
549static kbd_enable_t	vkbd_enable;
550static kbd_disable_t	vkbd_disable;
551static kbd_read_t	vkbd_read;
552static kbd_check_t	vkbd_check;
553static kbd_read_char_t	vkbd_read_char;
554static kbd_check_char_t	vkbd_check_char;
555static kbd_ioctl_t	vkbd_ioctl;
556static kbd_lock_t	vkbd_lock;
557static void		vkbd_clear_state_locked(vkbd_state_t *state);
558static kbd_clear_state_t vkbd_clear_state;
559static kbd_get_state_t	vkbd_get_state;
560static kbd_set_state_t	vkbd_set_state;
561static kbd_poll_mode_t	vkbd_poll;
562
563static keyboard_switch_t vkbdsw = {
564	.probe =	vkbd_probe,
565	.init =		vkbd_init,
566	.term =		vkbd_term,
567	.intr =		vkbd_intr,
568	.test_if =	vkbd_test_if,
569	.enable =	vkbd_enable,
570	.disable =	vkbd_disable,
571	.read =		vkbd_read,
572	.check =	vkbd_check,
573	.read_char =	vkbd_read_char,
574	.check_char =	vkbd_check_char,
575	.ioctl =	vkbd_ioctl,
576	.lock =		vkbd_lock,
577	.clear_state =	vkbd_clear_state,
578	.get_state =	vkbd_get_state,
579	.set_state =	vkbd_set_state,
580	.get_fkeystr =	genkbd_get_fkeystr,
581	.poll =		vkbd_poll,
582	.diag =		genkbd_diag,
583};
584
585static int	typematic(int delay, int rate);
586static int	typematic_delay(int delay);
587static int	typematic_rate(int rate);
588
589/* Return the number of found keyboards */
590static int
591vkbd_configure(int flags)
592{
593	return (1);
594}
595
596/* Detect a keyboard */
597static int
598vkbd_probe(int unit, void *arg, int flags)
599{
600	return (0);
601}
602
603/* Reset and initialize the keyboard (stolen from atkbd.c) */
604static int
605vkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
606{
607	keyboard_t	*kbd = NULL;
608	vkbd_state_t	*state = NULL;
609	keymap_t	*keymap = NULL;
610	accentmap_t	*accmap = NULL;
611	fkeytab_t	*fkeymap = NULL;
612	int		 fkeymap_size, delay[2];
613	int		 error, needfree;
614
615	if (*kbdp == NULL) {
616		*kbdp = kbd = malloc(sizeof(*kbd), M_VKBD, M_NOWAIT | M_ZERO);
617		state = malloc(sizeof(*state), M_VKBD, M_NOWAIT | M_ZERO);
618		keymap = malloc(sizeof(key_map), M_VKBD, M_NOWAIT);
619		accmap = malloc(sizeof(accent_map), M_VKBD, M_NOWAIT);
620		fkeymap = malloc(sizeof(fkey_tab), M_VKBD, M_NOWAIT);
621		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
622		needfree = 1;
623		if ((kbd == NULL) || (state == NULL) || (keymap == NULL) ||
624		    (accmap == NULL) || (fkeymap == NULL)) {
625			error = ENOMEM;
626			goto bad;
627		}
628
629		VKBD_LOCK_INIT(state);
630		state->ks_inq.head = state->ks_inq.tail = state->ks_inq.cc = 0;
631		TASK_INIT(&state->ks_task, 0, vkbd_dev_intr, (void *) kbd);
632	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
633		return (0);
634	} else {
635		kbd = *kbdp;
636		state = (vkbd_state_t *) kbd->kb_data;
637		keymap = kbd->kb_keymap;
638		accmap = kbd->kb_accentmap;
639		fkeymap = kbd->kb_fkeytab;
640		fkeymap_size = kbd->kb_fkeytab_size;
641		needfree = 0;
642	}
643
644	if (!KBD_IS_PROBED(kbd)) {
645		kbd_init_struct(kbd, KEYBOARD_NAME, KB_OTHER, unit, flags, 0, 0);
646		bcopy(&key_map, keymap, sizeof(key_map));
647		bcopy(&accent_map, accmap, sizeof(accent_map));
648		bcopy(fkey_tab, fkeymap,
649			imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
650		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
651		kbd->kb_data = (void *)state;
652
653		KBD_FOUND_DEVICE(kbd);
654		KBD_PROBE_DONE(kbd);
655
656		VKBD_LOCK(state);
657		vkbd_clear_state_locked(state);
658		state->ks_mode = K_XLATE;
659		/* FIXME: set the initial value for lock keys in ks_state */
660		VKBD_UNLOCK(state);
661	}
662	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
663		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
664
665		vkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
666		delay[0] = kbd->kb_delay1;
667		delay[1] = kbd->kb_delay2;
668		vkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
669
670		KBD_INIT_DONE(kbd);
671	}
672	if (!KBD_IS_CONFIGURED(kbd)) {
673		if (kbd_register(kbd) < 0) {
674			error = ENXIO;
675			goto bad;
676		}
677		KBD_CONFIG_DONE(kbd);
678	}
679
680	return (0);
681bad:
682	if (needfree) {
683		if (state != NULL)
684			free(state, M_VKBD);
685		if (keymap != NULL)
686			free(keymap, M_VKBD);
687		if (accmap != NULL)
688			free(accmap, M_VKBD);
689		if (fkeymap != NULL)
690			free(fkeymap, M_VKBD);
691		if (kbd != NULL) {
692			free(kbd, M_VKBD);
693			*kbdp = NULL;	/* insure ref doesn't leak to caller */
694		}
695	}
696	return (error);
697}
698
699/* Finish using this keyboard */
700static int
701vkbd_term(keyboard_t *kbd)
702{
703	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
704
705	kbd_unregister(kbd);
706
707	VKBD_LOCK_DESTROY(state);
708	bzero(state, sizeof(*state));
709	free(state, M_VKBD);
710
711	free(kbd->kb_keymap, M_VKBD);
712	free(kbd->kb_accentmap, M_VKBD);
713	free(kbd->kb_fkeytab, M_VKBD);
714	free(kbd, M_VKBD);
715
716	return (0);
717}
718
719/* Keyboard interrupt routine */
720static int
721vkbd_intr(keyboard_t *kbd, void *arg)
722{
723	int	c;
724
725	if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
726		/* let the callback function to process the input */
727		(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
728					    kbd->kb_callback.kc_arg);
729	} else {
730		/* read and discard the input; no one is waiting for input */
731		do {
732			c = vkbd_read_char(kbd, FALSE);
733		} while (c != NOKEY);
734	}
735
736	return (0);
737}
738
739/* Test the interface to the device */
740static int
741vkbd_test_if(keyboard_t *kbd)
742{
743	return (0);
744}
745
746/*
747 * Enable the access to the device; until this function is called,
748 * the client cannot read from the keyboard.
749 */
750
751static int
752vkbd_enable(keyboard_t *kbd)
753{
754	KBD_ACTIVATE(kbd);
755	return (0);
756}
757
758/* Disallow the access to the device */
759static int
760vkbd_disable(keyboard_t *kbd)
761{
762	KBD_DEACTIVATE(kbd);
763	return (0);
764}
765
766/* Read one byte from the keyboard if it's allowed */
767static int
768vkbd_read(keyboard_t *kbd, int wait)
769{
770	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
771	int		 c;
772
773	VKBD_LOCK(state);
774	c = vkbd_data_read(state, wait);
775	VKBD_UNLOCK(state);
776
777	if (c != -1)
778		kbd->kb_count ++;
779
780	return (KBD_IS_ACTIVE(kbd)? c : -1);
781}
782
783/* Check if data is waiting */
784static int
785vkbd_check(keyboard_t *kbd)
786{
787	vkbd_state_t	*state = NULL;
788	int		 ready;
789
790	if (!KBD_IS_ACTIVE(kbd))
791		return (FALSE);
792
793	state = (vkbd_state_t *) kbd->kb_data;
794
795	VKBD_LOCK(state);
796	ready = vkbd_data_ready(state);
797	VKBD_UNLOCK(state);
798
799	return (ready);
800}
801
802/* Read char from the keyboard (stolen from atkbd.c) */
803static u_int
804vkbd_read_char(keyboard_t *kbd, int wait)
805{
806	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
807	u_int		 action;
808	int		 scancode, keycode;
809
810	VKBD_LOCK(state);
811
812next_code:
813
814	/* do we have a composed char to return? */
815	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
816		action = state->ks_composed_char;
817		state->ks_composed_char = 0;
818		if (action > UCHAR_MAX) {
819			VKBD_UNLOCK(state);
820			return (ERRKEY);
821		}
822
823		VKBD_UNLOCK(state);
824		return (action);
825	}
826
827	/* see if there is something in the keyboard port */
828	scancode = vkbd_data_read(state, wait);
829	if (scancode == -1) {
830		VKBD_UNLOCK(state);
831		return (NOKEY);
832	}
833	/* XXX FIXME: check for -1 if wait == 1! */
834
835	kbd->kb_count ++;
836
837	/* return the byte as is for the K_RAW mode */
838	if (state->ks_mode == K_RAW) {
839		VKBD_UNLOCK(state);
840		return (scancode);
841	}
842
843	/* translate the scan code into a keycode */
844	keycode = scancode & 0x7F;
845	switch (state->ks_prefix) {
846	case 0x00:	/* normal scancode */
847		switch(scancode) {
848		case 0xB8:	/* left alt (compose key) released */
849			if (state->ks_flags & COMPOSE) {
850				state->ks_flags &= ~COMPOSE;
851				if (state->ks_composed_char > UCHAR_MAX)
852					state->ks_composed_char = 0;
853			}
854			break;
855		case 0x38:	/* left alt (compose key) pressed */
856			if (!(state->ks_flags & COMPOSE)) {
857				state->ks_flags |= COMPOSE;
858				state->ks_composed_char = 0;
859			}
860			break;
861		case 0xE0:
862		case 0xE1:
863			state->ks_prefix = scancode;
864			goto next_code;
865		}
866		break;
867	case 0xE0:      /* 0xE0 prefix */
868		state->ks_prefix = 0;
869		switch (keycode) {
870		case 0x1C:	/* right enter key */
871			keycode = 0x59;
872			break;
873		case 0x1D:	/* right ctrl key */
874			keycode = 0x5A;
875			break;
876		case 0x35:	/* keypad divide key */
877			keycode = 0x5B;
878			break;
879		case 0x37:	/* print scrn key */
880			keycode = 0x5C;
881			break;
882		case 0x38:	/* right alt key (alt gr) */
883			keycode = 0x5D;
884			break;
885		case 0x46:	/* ctrl-pause/break on AT 101 (see below) */
886			keycode = 0x68;
887			break;
888		case 0x47:	/* grey home key */
889			keycode = 0x5E;
890			break;
891		case 0x48:	/* grey up arrow key */
892			keycode = 0x5F;
893			break;
894		case 0x49:	/* grey page up key */
895			keycode = 0x60;
896			break;
897		case 0x4B:	/* grey left arrow key */
898			keycode = 0x61;
899			break;
900		case 0x4D:	/* grey right arrow key */
901			keycode = 0x62;
902			break;
903		case 0x4F:	/* grey end key */
904			keycode = 0x63;
905			break;
906		case 0x50:	/* grey down arrow key */
907			keycode = 0x64;
908			break;
909		case 0x51:	/* grey page down key */
910			keycode = 0x65;
911			break;
912		case 0x52:	/* grey insert key */
913			keycode = 0x66;
914			break;
915		case 0x53:	/* grey delete key */
916			keycode = 0x67;
917			break;
918		/* the following 3 are only used on the MS "Natural" keyboard */
919		case 0x5b:	/* left Window key */
920			keycode = 0x69;
921			break;
922		case 0x5c:	/* right Window key */
923			keycode = 0x6a;
924			break;
925		case 0x5d:	/* menu key */
926			keycode = 0x6b;
927			break;
928		case 0x5e:	/* power key */
929			keycode = 0x6d;
930			break;
931		case 0x5f:	/* sleep key */
932			keycode = 0x6e;
933			break;
934		case 0x63:	/* wake key */
935			keycode = 0x6f;
936			break;
937		default:	/* ignore everything else */
938			goto next_code;
939		}
940		break;
941	case 0xE1:	/* 0xE1 prefix */
942		/*
943		 * The pause/break key on the 101 keyboard produces:
944		 * E1-1D-45 E1-9D-C5
945		 * Ctrl-pause/break produces:
946		 * E0-46 E0-C6 (See above.)
947		 */
948		state->ks_prefix = 0;
949		if (keycode == 0x1D)
950			state->ks_prefix = 0x1D;
951		goto next_code;
952		/* NOT REACHED */
953	case 0x1D:	/* pause / break */
954		state->ks_prefix = 0;
955		if (keycode != 0x45)
956			goto next_code;
957		keycode = 0x68;
958		break;
959	}
960
961	if (kbd->kb_type == KB_84) {
962		switch (keycode) {
963		case 0x37:	/* *(numpad)/print screen */
964			if (state->ks_flags & SHIFTS)
965				keycode = 0x5c;	/* print screen */
966			break;
967		case 0x45:	/* num lock/pause */
968			if (state->ks_flags & CTLS)
969				keycode = 0x68;	/* pause */
970			break;
971		case 0x46:	/* scroll lock/break */
972			if (state->ks_flags & CTLS)
973				keycode = 0x6c;	/* break */
974			break;
975		}
976	} else if (kbd->kb_type == KB_101) {
977		switch (keycode) {
978		case 0x5c:	/* print screen */
979			if (state->ks_flags & ALTS)
980				keycode = 0x54;	/* sysrq */
981			break;
982		case 0x68:	/* pause/break */
983			if (state->ks_flags & CTLS)
984				keycode = 0x6c;	/* break */
985			break;
986		}
987	}
988
989	/* return the key code in the K_CODE mode */
990	if (state->ks_mode == K_CODE) {
991		VKBD_UNLOCK(state);
992		return (keycode | (scancode & 0x80));
993	}
994
995	/* compose a character code */
996	if (state->ks_flags & COMPOSE) {
997		switch (keycode | (scancode & 0x80)) {
998		/* key pressed, process it */
999		case 0x47: case 0x48: case 0x49:	/* keypad 7,8,9 */
1000			state->ks_composed_char *= 10;
1001			state->ks_composed_char += keycode - 0x40;
1002			if (state->ks_composed_char > UCHAR_MAX) {
1003				VKBD_UNLOCK(state);
1004				return (ERRKEY);
1005			}
1006			goto next_code;
1007		case 0x4B: case 0x4C: case 0x4D:	/* keypad 4,5,6 */
1008			state->ks_composed_char *= 10;
1009			state->ks_composed_char += keycode - 0x47;
1010			if (state->ks_composed_char > UCHAR_MAX) {
1011				VKBD_UNLOCK(state);
1012				return (ERRKEY);
1013			}
1014			goto next_code;
1015		case 0x4F: case 0x50: case 0x51:	/* keypad 1,2,3 */
1016			state->ks_composed_char *= 10;
1017			state->ks_composed_char += keycode - 0x4E;
1018			if (state->ks_composed_char > UCHAR_MAX) {
1019				VKBD_UNLOCK(state);
1020				return (ERRKEY);
1021			}
1022			goto next_code;
1023		case 0x52:	/* keypad 0 */
1024			state->ks_composed_char *= 10;
1025			if (state->ks_composed_char > UCHAR_MAX) {
1026				VKBD_UNLOCK(state);
1027				return (ERRKEY);
1028			}
1029			goto next_code;
1030
1031		/* key released, no interest here */
1032		case 0xC7: case 0xC8: case 0xC9:	/* keypad 7,8,9 */
1033		case 0xCB: case 0xCC: case 0xCD:	/* keypad 4,5,6 */
1034		case 0xCF: case 0xD0: case 0xD1:	/* keypad 1,2,3 */
1035		case 0xD2:				/* keypad 0 */
1036			goto next_code;
1037
1038		case 0x38:				/* left alt key */
1039			break;
1040
1041		default:
1042			if (state->ks_composed_char > 0) {
1043				state->ks_flags &= ~COMPOSE;
1044				state->ks_composed_char = 0;
1045				VKBD_UNLOCK(state);
1046				return (ERRKEY);
1047			}
1048			break;
1049		}
1050	}
1051
1052	/* keycode to key action */
1053	action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
1054			&state->ks_state, &state->ks_accents);
1055	if (action == NOKEY)
1056		goto next_code;
1057
1058	VKBD_UNLOCK(state);
1059
1060	return (action);
1061}
1062
1063/* Check if char is waiting */
1064static int
1065vkbd_check_char(keyboard_t *kbd)
1066{
1067	vkbd_state_t	*state = NULL;
1068	int		 ready;
1069
1070	if (!KBD_IS_ACTIVE(kbd))
1071		return (FALSE);
1072
1073	state = (vkbd_state_t *) kbd->kb_data;
1074
1075	VKBD_LOCK(state);
1076	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
1077		ready = TRUE;
1078	else
1079		ready = vkbd_data_ready(state);
1080	VKBD_UNLOCK(state);
1081
1082	return (ready);
1083}
1084
1085/* Some useful control functions (stolen from atkbd.c) */
1086static int
1087vkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
1088{
1089	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
1090	int		 i;
1091#ifdef COMPAT_FREEBSD6
1092	int		 ival;
1093#endif
1094
1095	VKBD_LOCK(state);
1096
1097	switch (cmd) {
1098	case KDGKBMODE:		/* get keyboard mode */
1099		*(int *)arg = state->ks_mode;
1100		break;
1101
1102#ifdef COMPAT_FREEBSD6
1103	case _IO('K', 7):
1104		ival = IOCPARM_IVAL(arg);
1105		arg = (caddr_t)&ival;
1106		/* FALLTHROUGH */
1107#endif
1108	case KDSKBMODE:		/* set keyboard mode */
1109		switch (*(int *)arg) {
1110		case K_XLATE:
1111			if (state->ks_mode != K_XLATE) {
1112				/* make lock key state and LED state match */
1113				state->ks_state &= ~LOCK_MASK;
1114				state->ks_state |= KBD_LED_VAL(kbd);
1115				vkbd_status_changed(state);
1116			}
1117			/* FALLTHROUGH */
1118
1119		case K_RAW:
1120		case K_CODE:
1121			if (state->ks_mode != *(int *)arg) {
1122				vkbd_clear_state_locked(state);
1123				state->ks_mode = *(int *)arg;
1124				vkbd_status_changed(state);
1125			}
1126			break;
1127
1128		default:
1129			VKBD_UNLOCK(state);
1130			return (EINVAL);
1131		}
1132		break;
1133
1134	case KDGETLED:		/* get keyboard LED */
1135		*(int *)arg = KBD_LED_VAL(kbd);
1136		break;
1137
1138#ifdef COMPAT_FREEBSD6
1139	case _IO('K', 66):
1140		ival = IOCPARM_IVAL(arg);
1141		arg = (caddr_t)&ival;
1142		/* FALLTHROUGH */
1143#endif
1144	case KDSETLED:		/* set keyboard LED */
1145		/* NOTE: lock key state in ks_state won't be changed */
1146		if (*(int *)arg & ~LOCK_MASK) {
1147			VKBD_UNLOCK(state);
1148			return (EINVAL);
1149		}
1150
1151		i = *(int *)arg;
1152		/* replace CAPS LED with ALTGR LED for ALTGR keyboards */
1153		if (state->ks_mode == K_XLATE &&
1154		    kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
1155			if (i & ALKED)
1156				i |= CLKED;
1157			else
1158				i &= ~CLKED;
1159		}
1160
1161		KBD_LED_VAL(kbd) = *(int *)arg;
1162		vkbd_status_changed(state);
1163		break;
1164
1165	case KDGKBSTATE:	/* get lock key state */
1166		*(int *)arg = state->ks_state & LOCK_MASK;
1167		break;
1168
1169#ifdef COMPAT_FREEBSD6
1170	case _IO('K', 20):
1171		ival = IOCPARM_IVAL(arg);
1172		arg = (caddr_t)&ival;
1173		/* FALLTHROUGH */
1174#endif
1175	case KDSKBSTATE:	/* set lock key state */
1176		if (*(int *)arg & ~LOCK_MASK) {
1177			VKBD_UNLOCK(state);
1178			return (EINVAL);
1179		}
1180		state->ks_state &= ~LOCK_MASK;
1181		state->ks_state |= *(int *)arg;
1182		vkbd_status_changed(state);
1183		VKBD_UNLOCK(state);
1184		/* set LEDs and quit */
1185		return (vkbd_ioctl(kbd, KDSETLED, arg));
1186
1187	case KDSETREPEAT:	/* set keyboard repeat rate (new interface) */
1188		i = typematic(((int *)arg)[0], ((int *)arg)[1]);
1189		kbd->kb_delay1 = typematic_delay(i);
1190		kbd->kb_delay2 = typematic_rate(i);
1191		vkbd_status_changed(state);
1192		break;
1193
1194#ifdef COMPAT_FREEBSD6
1195	case _IO('K', 67):
1196		ival = IOCPARM_IVAL(arg);
1197		arg = (caddr_t)&ival;
1198		/* FALLTHROUGH */
1199#endif
1200	case KDSETRAD:		/* set keyboard repeat rate (old interface) */
1201		kbd->kb_delay1 = typematic_delay(*(int *)arg);
1202		kbd->kb_delay2 = typematic_rate(*(int *)arg);
1203		vkbd_status_changed(state);
1204		break;
1205
1206	case PIO_KEYMAP:	/* set keyboard translation table */
1207	case OPIO_KEYMAP:	/* set keyboard translation table (compat) */
1208	case PIO_KEYMAPENT:	/* set keyboard translation table entry */
1209	case PIO_DEADKEYMAP:	/* set accent key translation table */
1210		state->ks_accents = 0;
1211		/* FALLTHROUGH */
1212
1213	default:
1214		VKBD_UNLOCK(state);
1215		return (genkbd_commonioctl(kbd, cmd, arg));
1216	}
1217
1218	VKBD_UNLOCK(state);
1219
1220	return (0);
1221}
1222
1223/* Lock the access to the keyboard */
1224static int
1225vkbd_lock(keyboard_t *kbd, int lock)
1226{
1227	return (1); /* XXX */
1228}
1229
1230/* Clear the internal state of the keyboard */
1231static void
1232vkbd_clear_state_locked(vkbd_state_t *state)
1233{
1234	VKBD_LOCK_ASSERT(state, MA_OWNED);
1235
1236	state->ks_flags &= ~COMPOSE;
1237	state->ks_polling = 0;
1238	state->ks_state &= LOCK_MASK;	/* preserve locking key state */
1239	state->ks_accents = 0;
1240	state->ks_composed_char = 0;
1241/*	state->ks_prefix = 0;		XXX */
1242
1243	/* flush ks_inq and wakeup writers/poll()ers */
1244	state->ks_inq.head = state->ks_inq.tail = state->ks_inq.cc = 0;
1245	selwakeuppri(&state->ks_wsel, PZERO + 1);
1246	wakeup(&state->ks_inq);
1247}
1248
1249static void
1250vkbd_clear_state(keyboard_t *kbd)
1251{
1252	vkbd_state_t	*state = (vkbd_state_t *) kbd->kb_data;
1253
1254	VKBD_LOCK(state);
1255	vkbd_clear_state_locked(state);
1256	VKBD_UNLOCK(state);
1257}
1258
1259/* Save the internal state */
1260static int
1261vkbd_get_state(keyboard_t *kbd, void *buf, size_t len)
1262{
1263	if (len == 0)
1264		return (sizeof(vkbd_state_t));
1265	if (len < sizeof(vkbd_state_t))
1266		return (-1);
1267	bcopy(kbd->kb_data, buf, sizeof(vkbd_state_t)); /* XXX locking? */
1268	return (0);
1269}
1270
1271/* Set the internal state */
1272static int
1273vkbd_set_state(keyboard_t *kbd, void *buf, size_t len)
1274{
1275	if (len < sizeof(vkbd_state_t))
1276		return (ENOMEM);
1277	bcopy(buf, kbd->kb_data, sizeof(vkbd_state_t)); /* XXX locking? */
1278	return (0);
1279}
1280
1281/* Set polling */
1282static int
1283vkbd_poll(keyboard_t *kbd, int on)
1284{
1285	vkbd_state_t	*state = NULL;
1286
1287	state = (vkbd_state_t *) kbd->kb_data;
1288
1289	VKBD_LOCK(state);
1290
1291	if (on)
1292		state->ks_polling ++;
1293	else
1294		state->ks_polling --;
1295
1296	VKBD_UNLOCK(state);
1297
1298	return (0);
1299}
1300
1301/*
1302 * Local functions
1303 */
1304
1305static int delays[] = { 250, 500, 750, 1000 };
1306static int rates[] = {	34,  38,  42,  46,  50,  55,  59,  63,
1307			68,  76,  84,  92, 100, 110, 118, 126,
1308			136, 152, 168, 184, 200, 220, 236, 252,
1309			272, 304, 336, 368, 400, 440, 472, 504 };
1310
1311static int
1312typematic_delay(int i)
1313{
1314	return (delays[(i >> 5) & 3]);
1315}
1316
1317static int
1318typematic_rate(int i)
1319{
1320	return (rates[i & 0x1f]);
1321}
1322
1323static int
1324typematic(int delay, int rate)
1325{
1326	int value;
1327	int i;
1328
1329	for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; i --) {
1330		if (delay >= delays[i])
1331			break;
1332	}
1333	value = i << 5;
1334	for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; i --) {
1335		if (rate >= rates[i])
1336			break;
1337	}
1338	value |= i;
1339	return (value);
1340}
1341
1342/*****************************************************************************
1343 *****************************************************************************
1344 **                                    Module
1345 *****************************************************************************
1346 *****************************************************************************/
1347
1348KEYBOARD_DRIVER(vkbd, vkbdsw, vkbd_configure);
1349
1350static int
1351vkbd_modevent(module_t mod, int type, void *data)
1352{
1353	static eventhandler_tag	tag;
1354
1355	switch (type) {
1356	case MOD_LOAD:
1357		clone_setup(&vkbd_dev_clones);
1358		tag = EVENTHANDLER_REGISTER(dev_clone, vkbd_dev_clone, 0, 1000);
1359		if (tag == NULL) {
1360			clone_cleanup(&vkbd_dev_clones);
1361			return (ENOMEM);
1362		}
1363		kbd_add_driver(&vkbd_kbd_driver);
1364		break;
1365
1366	case MOD_UNLOAD:
1367		kbd_delete_driver(&vkbd_kbd_driver);
1368		EVENTHANDLER_DEREGISTER(dev_clone, tag);
1369		clone_cleanup(&vkbd_dev_clones);
1370		break;
1371
1372	default:
1373		return (EOPNOTSUPP);
1374	}
1375
1376	return (0);
1377}
1378
1379DEV_MODULE(vkbd, vkbd_modevent, NULL);
1380
1381