FreeBSD/sys/dev/vkbd/vkbd.c
/* Reset and initialize the keyboard (stolen from atkbd.c) */
Reset and initialize the keyboard (stolen from atkbd.c)
Reset and initialize the keyboard ( stolen from atkbd . c )
static int
vkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t	*kbd = NULL;
	vkbd_state_t	*state = NULL;
	keymap_t	*keymap = NULL;
	accentmap_t	*accmap = NULL;
	fkeytab_t	*fkeymap = NULL;
	int		 fkeymap_size, delay[2];
	int		 error, needfree;
	if (*kbdp == NULL) {
		*kbdp = kbd = malloc(sizeof(*kbd), M_VKBD, M_NOWAIT | M_ZERO);
		state = malloc(sizeof(*state), M_VKBD, M_NOWAIT | M_ZERO);
		keymap = malloc(sizeof(key_map), M_VKBD, M_NOWAIT);
		accmap = malloc(sizeof(accent_map), M_VKBD, M_NOWAIT);
		fkeymap = malloc(sizeof(fkey_tab), M_VKBD, M_NOWAIT);
		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
		needfree = 1;
		if ((kbd == NULL) || (state == NULL) || (keymap == NULL) ||
		    (accmap == NULL) || (fkeymap == NULL)) {
			error = ENOMEM;
			goto bad;
		}
		VKBD_LOCK_INIT(state);
		state->ks_inq.head = state->ks_inq.tail = state->ks_inq.cc = 0;
		TASK_INIT(&state->ks_task, 0, vkbd_dev_intr, (void *) kbd);
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return (0);
	} else {
		kbd = *kbdp;
		state = (vkbd_state_t *) kbd->kb_data;
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
		needfree = 0;
	}
	if (!KBD_IS_PROBED(kbd)) {
		kbd_init_struct(kbd, KEYBOARD_NAME, KB_OTHER, unit, flags, 0, 0);
		bcopy(&key_map, keymap, sizeof(key_map));
		bcopy(&accent_map, accmap, sizeof(accent_map));
		bcopy(fkey_tab, fkeymap,
			imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
		kbd->kb_data = (void *)state;
		KBD_FOUND_DEVICE(kbd);
		KBD_PROBE_DONE(kbd);
		VKBD_LOCK(state);
		vkbd_clear_state_locked(state);
		state->ks_mode = K_XLATE;
		VKBD_UNLOCK(state);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
		vkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
		delay[0] = kbd->kb_delay1;
		delay[1] = kbd->kb_delay2;
		vkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0) {
			error = ENXIO;
			goto bad;
		}
		KBD_CONFIG_DONE(kbd);
	}
	return (0);
bad:
	if (needfree) {
		if (state != NULL)
			free(state, M_VKBD);
		if (keymap != NULL)
			free(keymap, M_VKBD);
		if (accmap != NULL)
			free(accmap, M_VKBD);
		if (fkeymap != NULL)
			free(fkeymap, M_VKBD);
		if (kbd != NULL) {
			free(kbd, M_VKBD);
			*kbdp = NULL;	
		}
	}
	return (error);
}
static int vkbd_init ( int unit , keyboard_t * * kbdp , void * arg , int flags ) { keyboard_t * kbd = NULL ; vkbd_state_t * state = NULL ; keymap_t * keymap = NULL ; accentmap_t * accmap = NULL ; fkeytab_t * fkeymap = NULL ; int fkeymap_size , delay [ 2 ] ; int error , needfree ; if ( * kbdp == NULL ) { * kbdp = kbd = malloc ( sizeof ( * kbd ) , M_VKBD , M_NOWAIT | M_ZERO ) ; state = malloc ( sizeof ( * state ) , M_VKBD , M_NOWAIT | M_ZERO ) ; keymap = malloc ( sizeof ( key_map ) , M_VKBD , M_NOWAIT ) ; accmap = malloc ( sizeof ( accent_map ) , M_VKBD , M_NOWAIT ) ; fkeymap = malloc ( sizeof ( fkey_tab ) , M_VKBD , M_NOWAIT ) ; fkeymap_size = sizeof ( fkey_tab ) / sizeof ( fkey_tab [ 0 ] ) ; needfree = 1 ; if ( ( kbd == NULL ) || ( state == NULL ) || ( keymap == NULL ) || ( accmap == NULL ) || ( fkeymap == NULL ) ) { error = ENOMEM ; goto bad ; } VKBD_LOCK_INIT ( state ) ; state -> ks_inq . head = state -> ks_inq . tail = state -> ks_inq . cc = 0 ; TASK_INIT ( & state -> ks_task , 0 , vkbd_dev_intr , ( void * ) kbd ) ; } else if ( KBD_IS_INITIALIZED ( * kbdp ) && KBD_IS_CONFIGURED ( * kbdp ) ) { return ( 0 ) ; } else { kbd = * kbdp ; state = ( vkbd_state_t * ) kbd -> kb_data ; keymap = kbd -> kb_keymap ; accmap = kbd -> kb_accentmap ; fkeymap = kbd -> kb_fkeytab ; fkeymap_size = kbd -> kb_fkeytab_size ; needfree = 0 ; } if ( ! KBD_IS_PROBED ( kbd ) ) { kbd_init_struct ( kbd , KEYBOARD_NAME , KB_OTHER , unit , flags , 0 , 0 ) ; bcopy ( & key_map , keymap , sizeof ( key_map ) ) ; bcopy ( & accent_map , accmap , sizeof ( accent_map ) ) ; bcopy ( fkey_tab , fkeymap , imin ( fkeymap_size * sizeof ( fkeymap [ 0 ] ) , sizeof ( fkey_tab ) ) ) ; kbd_set_maps ( kbd , keymap , accmap , fkeymap , fkeymap_size ) ; kbd -> kb_data = ( void * ) state ; KBD_FOUND_DEVICE ( kbd ) ; KBD_PROBE_DONE ( kbd ) ; VKBD_LOCK ( state ) ; vkbd_clear_state_locked ( state ) ; state -> ks_mode = K_XLATE ; VKBD_UNLOCK ( state ) ; } if ( ! KBD_IS_INITIALIZED ( kbd ) && ! ( flags & KB_CONF_PROBE_ONLY ) ) { kbd -> kb_config = flags & ~ KB_CONF_PROBE_ONLY ; vkbd_ioctl ( kbd , KDSETLED , ( caddr_t ) & state -> ks_state ) ; delay [ 0 ] = kbd -> kb_delay1 ; delay [ 1 ] = kbd -> kb_delay2 ; vkbd_ioctl ( kbd , KDSETREPEAT , ( caddr_t ) delay ) ; KBD_INIT_DONE ( kbd ) ; } if ( ! KBD_IS_CONFIGURED ( kbd ) ) { if ( kbd_register ( kbd ) < 0 ) { error = ENXIO ; goto bad ; } KBD_CONFIG_DONE ( kbd ) ; } return ( 0 ) ; bad : if ( needfree ) { if ( state != NULL ) free ( state , M_VKBD ) ; if ( keymap != NULL ) free ( keymap , M_VKBD ) ; if ( accmap != NULL ) free ( accmap , M_VKBD ) ; if ( fkeymap != NULL ) free ( fkeymap , M_VKBD ) ; if ( kbd != NULL ) { free ( kbd , M_VKBD ) ; * kbdp = NULL ; } } return ( error ) ; }
Reset and initialize the keyboard (stolen from atkbd.c)
Reset and initialize the keyboard ( stolen from atkbd . c )
/* FIXME: set the initial value for lock keys in ks_state */ /* insure ref doesn't leak to caller */