Ejemplo n.º 1
0
Archivo: atkbd.c Proyecto: MarginC/kame
/* keyboard interrupt routine */
static int
atkbd_intr(keyboard_t *kbd, void *arg)
{
	atkbd_state_t *state;
	int delay[2];
	int c;

	if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
		/* let the callback function to process the input */
		(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
					    kbd->kb_callback.kc_arg);
	} else {
		/* read and discard the input; no one is waiting for input */
		do {
			c = atkbd_read_char(kbd, FALSE);
		} while (c != NOKEY);

		if (!KBD_HAS_DEVICE(kbd)) {
			/*
			 * The keyboard was not detected before;
			 * it must have been reconnected!
			 */
			state = (atkbd_state_t *)kbd->kb_data;
			init_keyboard(state->kbdc, &kbd->kb_type,
				      kbd->kb_config);
			atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
			get_typematic(kbd);
			delay[0] = kbd->kb_delay1;
			delay[1] = kbd->kb_delay2;
			atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
			KBD_FOUND_DEVICE(kbd);
		}
	}
	return 0;
}
Ejemplo n.º 2
0
/* reset and initialize the device */
static int
atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
    keyboard_t *kbd;
    atkbd_state_t *state;
    keymap_t *keymap;
    accentmap_t *accmap;
    fkeytab_t *fkeymap;
    int fkeymap_size;
    int delay[2];
    int *data = (int *)arg;	/* data[0]: controller, data[1]: irq */
    int error, needfree;

    /* XXX */
    if (unit == ATKBD_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]);
        needfree = 0;
    } else if (*kbdp == NULL) {
        *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT | M_ZERO);
        state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT | M_ZERO);
        /* NB: these will always be initialized 'cuz !KBD_IS_PROBED */
        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]);
        needfree = 1;
        if ((kbd == NULL) || (state == NULL) || (keymap == NULL)
                || (accmap == NULL) || (fkeymap == NULL)) {
            error = ENOMEM;
            goto bad;
        }
    } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
        return 0;
    } else {
        kbd = *kbdp;
        state = (atkbd_state_t *)kbd->kb_data;
        bzero(state, sizeof(*state));
        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)) {
        state->kbdc = atkbdc_open(data[0]);
        if (state->kbdc == NULL) {
            error = ENXIO;
            goto bad;
        }
        kbd_init_struct(kbd, ATKBD_DRIVER_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;

        if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
            if (flags & KB_CONF_FAIL_IF_NO_KBD) {
                error = ENXIO;
                goto bad;
            }
        } else {
            KBD_FOUND_DEVICE(kbd);
        }
        atkbd_clear_state(kbd);
        state->ks_mode = K_XLATE;
        /*
         * 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)) {
        kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
        if (KBD_HAS_DEVICE(kbd)
                && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
                && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) {
            kbd_unregister(kbd);
            error = ENXIO;
            goto bad;
        }
        atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
        get_typematic(kbd);
        delay[0] = kbd->kb_delay1;
        delay[1] = kbd->kb_delay2;
        atkbd_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_DEVBUF);
        if (keymap != NULL)
            free(keymap, M_DEVBUF);
        if (accmap != NULL)
            free(accmap, M_DEVBUF);
        if (fkeymap != NULL)
            free(fkeymap, M_DEVBUF);
        if (kbd != NULL) {
            free(kbd, M_DEVBUF);
            *kbdp = NULL;	/* insure ref doesn't leak to caller */
        }
    }
    return error;
}
Ejemplo n.º 3
0
/* reset and initialize the device */
static int
atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
{
	keyboard_t *kbd;
	atkbd_state_t *state;
	keymap_t *keymap;
	accentmap_t *accmap;
	fkeytab_t *fkeymap;
	int fkeymap_size;
	int delay[2];
	int *data = (int *)arg;	/* data[0]: controller, data[1]: irq */

	/* XXX */
	if (unit == ATKBD_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_WAITOK|M_ZERO);
		state = kmalloc(sizeof(*state), M_DEVBUF, M_WAITOK|M_ZERO);
		keymap = kmalloc(sizeof(key_map), M_DEVBUF, M_WAITOK);
		accmap = kmalloc(sizeof(accent_map), M_DEVBUF, M_WAITOK);
		fkeymap = kmalloc(sizeof(fkey_tab), M_DEVBUF, M_WAITOK);
		fkeymap_size = NELEM(fkey_tab);
	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
		return 0;
	} else {
		kbd = *kbdp;
		state = (atkbd_state_t *)kbd->kb_data;
		bzero(state, sizeof(*state));
		keymap = kbd->kb_keymap;
		accmap = kbd->kb_accentmap;
		fkeymap = kbd->kb_fkeytab;
		fkeymap_size = kbd->kb_fkeytab_size;
	}

	if (!KBD_IS_PROBED(kbd)) {
		state->kbdc = atkbdc_open(data[0]);
		if (state->kbdc == NULL) {
			return ENXIO;
		}
		kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
				KB_PRI_ATKBD, 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;
	
		if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
			if (flags & KB_CONF_FAIL_IF_NO_KBD) {
				return ENXIO;
			}
		} else {
			KBD_FOUND_DEVICE(kbd);
		}
		atkbd_clear_state(kbd);
		state->ks_mode = K_XLATE;
		/* 
		 * 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)) {
		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
		if (!KBD_HAS_DEVICE(kbd)
		    && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
		    && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) {
			return ENXIO;
		}
		atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
		get_typematic(kbd);
		delay[0] = kbd->kb_delay1;
		delay[1] = kbd->kb_delay2;
		atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
		KBD_FOUND_DEVICE(kbd);
		KBD_INIT_DONE(kbd);
	}
	if (!KBD_IS_CONFIGURED(kbd)) {
		if (kbd_register(kbd) < 0) {
			return ENXIO;
		}
		KBD_CONFIG_DONE(kbd);
	}

	return 0;
}