Beispiel #1
0
/* finish using this keyboard */
static int
ukbd_term(keyboard_t *kbd)
{
	ukbd_state_t *state;
	int error;
	int s;

	s = splusb();

	state = (ukbd_state_t *)kbd->kb_data;
	DPRINTF(("ukbd_term: ks_ifstate=0x%x\n", state->ks_ifstate));

	untimeout(ukbd_timeout, (void *)kbd, state->ks_timeout_handle);
	callout_handle_init(&state->ks_timeout_handle);

	if (state->ks_ifstate & INTRENABLED)
		ukbd_enable_intr(kbd, FALSE, NULL);
	if (state->ks_ifstate & INTRENABLED) {
		splx(s);
		DPRINTF(("ukbd_term: INTRENABLED!\n"));
		return ENXIO;
	}

	error = kbd_unregister(kbd);
	DPRINTF(("ukbd_term: kbd_unregister() %d\n", error));
	if (error == 0) {
		kbd->kb_flags = 0;
		if (kbd != &default_kbd) {
			free(kbd->kb_keymap, M_DEVBUF);
			free(kbd->kb_accentmap, M_DEVBUF);
			free(kbd->kb_fkeytab, M_DEVBUF);
			free(state, M_DEVBUF);
			free(kbd, M_DEVBUF);
		}
	}

	splx(s);
	return error;
}
Beispiel #2
0
/* finish using this keyboard */
static int
ukbd_term(keyboard_t *kbd)
{
	ukbd_state_t *state;
	int error;

	crit_enter();
	state = (ukbd_state_t *)kbd->kb_data;
	DPRINTF(("ukbd_term: ks_ifstate=0x%x\n", state->ks_ifstate));

	callout_stop(&state->ks_timeout);

	if (state->ks_ifstate & INTRENABLED)
		ukbd_enable_intr(kbd, FALSE, NULL);
	if (state->ks_ifstate & INTRENABLED) {
		crit_exit();
		DPRINTF(("ukbd_term: INTRENABLED!\n"));
		return ENXIO;
	}

	error = kbd_unregister(kbd);

	DPRINTF(("ukbd_term: kbd_unregister() %d\n", error));
	if (error == 0) {
		kbd->kb_flags = 0;
		if (kbd != &default_kbd) {
			kfree(kbd->kb_keymap, M_DEVBUF);
			kfree(kbd->kb_accentmap, M_DEVBUF);
			kfree(kbd->kb_fkeytab, M_DEVBUF);
			kfree(state, M_DEVBUF);
			kfree(kbd, M_DEVBUF);
		}
	}
	crit_exit();
	return error;
}
Beispiel #3
0
/*
 * Reset and initialize the device.  Note that unit 0 (UKBD_DEFAULT) is an
 * always-connected device once it has been initially detected.  We do not
 * deregister it if the usb keyboard is unplugged to avoid losing the 
 * connection to the console.  This feature also handles the USB bus reset
 * which detaches and reattaches USB devices during boot.
 */
static int
ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	ukbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	void **data = (void **)arg;
	struct usb_attach_arg *uaa = (struct usb_attach_arg *)data[0];

	if (unit == UKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd)) {
			return 0;
		}
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size = NELEM(default_fkeytab);
	} else if (*kbdp == NULL) {
		*kbdp = kbd = kmalloc(sizeof(*kbd), M_DEVBUF, M_INTWAIT | M_ZERO);
		state = kmalloc(sizeof(*state), M_DEVBUF, M_INTWAIT);
		keymap = kmalloc(sizeof(key_map), M_DEVBUF, M_INTWAIT);
		accmap = kmalloc(sizeof(accent_map), M_DEVBUF, M_INTWAIT);
		fkeymap = kmalloc(sizeof(fkey_tab), M_DEVBUF, M_INTWAIT);
		fkeymap_size = NELEM(fkey_tab);
		if ((state == NULL) || (keymap == NULL) || (accmap == NULL)
		     || (fkeymap == NULL)) {
			if (state != NULL)
				kfree(state, M_DEVBUF);
			if (keymap != NULL)
				kfree(keymap, M_DEVBUF);
			if (accmap != NULL)
				kfree(accmap, M_DEVBUF);
			if (fkeymap != NULL)
				kfree(fkeymap, M_DEVBUF);
			kfree(kbd, M_DEVBUF);
			return ENOMEM;
		}
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (ukbd_state_t *)kbd->kb_data;
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER,
				unit, flags, KB_PRI_USB,
				0, 0);
		bzero(state, sizeof(*state));
		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;

		if (probe_keyboard(uaa, flags)) {
			return ENXIO;
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		ukbd_clear_state(kbd);

		/*
		 * If reattatching to an already open keyboard (e.g. console),
		 * try to restore the translation mode.  Otherwise set the
		 * translation mode to, well, translation mode so we don't
		 * get garbage.
		 */
		state->ks_mode = K_XLATE;
		state->ks_iface = uaa->iface;
		state->ks_uaa = uaa;
		state->ks_ifstate = 0;
		callout_init_mp(&state->ks_timeout);
		/*
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		if (KBD_HAS_DEVICE(kbd)
		    && init_keyboard((ukbd_state_t *)kbd->kb_data,
				     &kbd->kb_type, kbd->kb_flags)) {
			return ENXIO;
		}
		ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state));
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0) {
			kbd->kb_flags = 0;
			/* XXX: Missing free()'s */
			return ENXIO;
		}
		if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0)
			ukbd_timeout((void *)kbd);
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}
Beispiel #4
0
/* reset and initialize the device */
static int
ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	ukbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	void **data = (void **)arg;
	struct usb_attach_arg *uaa = (struct usb_attach_arg *)data[0];

	/* XXX */
	if (unit == UKBD_DEFAULT) {
		*kbdp = kbd = &default_kbd;
		if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
			return 0;
		state = &default_kbd_state;
		keymap = &default_keymap;
		accmap = &default_accentmap;
		fkeymap = default_fkeytab;
		fkeymap_size =
			sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
	} else if (*kbdp == NULL) {
		*kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT);
		if (kbd == NULL)
			return ENOMEM;
		bzero(kbd, sizeof(*kbd));
		state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT);
		keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
		accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
		fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
		if ((state == NULL) || (keymap == NULL) || (accmap == NULL)
		     || (fkeymap == NULL)) {
			if (state != NULL)
				free(state, M_DEVBUF);
			if (keymap != NULL)
				free(keymap, M_DEVBUF);
			if (accmap != NULL)
				free(accmap, M_DEVBUF);
			if (fkeymap != NULL)
				free(fkeymap, M_DEVBUF);
			free(kbd, M_DEVBUF);
			return ENOMEM;
		}
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (ukbd_state_t *)kbd->kb_data;
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags, 0, 0);
		bzero(state, sizeof(*state));
		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;

		if (probe_keyboard(uaa, flags))
			return ENXIO;
		else
			KBD_FOUND_DEVICE(kbd);
		ukbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		state->ks_iface = uaa->iface;
		state->ks_uaa = uaa;
		state->ks_ifstate = 0;
		callout_handle_init(&state->ks_timeout_handle);
		/* 
		 * FIXME: set the initial value for lock keys in ks_state
		 * according to the BIOS data?
		 */
		KBD_PROBE_DONE(kbd);
	}
	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
		if (KBD_HAS_DEVICE(kbd)
		    && init_keyboard((ukbd_state_t *)kbd->kb_data,
				     &kbd->kb_type, kbd->kb_flags))
			return ENXIO;
		ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state));
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0)
			return ENXIO;
		if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0)
			ukbd_timeout((void *)kbd);
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}