示例#1
0
void
wskbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct wskbd_softc *sc = (struct wskbd_softc *)self;
	struct wskbddev_attach_args *ap = aux;
	kbd_t layout;
#if NWSMUX > 0
	struct wsmux_softc *wsmux_sc;
	int mux, error;
#endif

	sc->sc_isconsole = ap->console;

#if NWSMUX > 0 || NWSDISPLAY > 0
	sc->sc_base.me_ops = &wskbd_srcops;
#endif
#if NWSMUX > 0
	mux = sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux;
	if (ap->console) {
		/* Ignore mux for console; it always goes to the console mux. */
		/* printf(" (mux %d ignored for console)", mux); */
		mux = -1;
	}
	if (mux >= 0) {
		printf(" mux %d", mux);
		wsmux_sc = wsmux_getmux(mux);
	} else
		wsmux_sc = NULL;
#else
#if 0	/* not worth keeping, especially since the default value is not -1... */
	if (sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux >= 0)
		printf(" (mux ignored)");
#endif
#endif	/* NWSMUX > 0 */

	if (ap->console) {
		sc->id = &wskbd_console_data;
	} else {
		sc->id = malloc(sizeof(struct wskbd_internal),
		    M_DEVBUF, M_WAITOK | M_ZERO);
		bcopy(ap->keymap, &sc->id->t_keymap, sizeof(sc->id->t_keymap));
	}

#if NWSDISPLAY > 0
	timeout_set(&sc->sc_repeat_ch, wskbd_repeat, sc);
#endif

	sc->id->t_sc = sc;

	sc->sc_accessops = ap->accessops;
	sc->sc_accesscookie = ap->accesscookie;
	sc->sc_repeating = 0;
	sc->sc_translating = 1;
	sc->sc_ledstate = -1; /* force update */

	/*
	 * If this layout is the default choice of the driver (i.e. the
	 * driver doesn't know better), pick the existing layout of the
	 * current mux, if any.
	 */
	layout = sc->id->t_keymap.layout;
#if NWSMUX > 0
	if (layout & KB_DEFAULT) {
		if (wsmux_sc != NULL && wsmux_get_layout(wsmux_sc) != KB_NONE)
			layout = wsmux_get_layout(wsmux_sc);
	}
#endif
	for (;;) {
		if (wskbd_load_keymap(&sc->id->t_keymap, layout, &sc->sc_map,
		    &sc->sc_maplen) == 0)
			break;
#if NWSMUX > 0
		if (layout == sc->id->t_keymap.layout)
			panic("cannot load keymap");
		if (wsmux_sc != NULL && wsmux_get_layout(wsmux_sc) != KB_NONE) {
			printf("\n%s: cannot load keymap, "
			    "falling back to default\n%s",
			    sc->sc_base.me_dv.dv_xname,
			    sc->sc_base.me_dv.dv_xname);
			layout = wsmux_get_layout(wsmux_sc);
		} else
#endif
			panic("cannot load keymap");
	}
	wskbd_update_layout(sc->id, layout);

	/* set default bell and key repeat data */
	sc->sc_bell_data = wskbd_default_bell_data;
	sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;

	if (ap->console) {
		KASSERT(wskbd_console_initted); 
		KASSERT(wskbd_console_device == NULL);

		wskbd_console_device = sc;

		printf(": console keyboard");

#if NWSDISPLAY > 0
		wsdisplay_set_console_kbd(&sc->sc_base); /* sets sc_displaydv */
		if (sc->sc_displaydv != NULL)
			printf(", using %s", sc->sc_displaydv->dv_xname);
#endif
	}
	printf("\n");

#if NWSMUX > 0
	if (wsmux_sc != NULL) {
		error = wsmux_attach_sc(wsmux_sc, &sc->sc_base);
		if (error)
			printf("%s: attach error=%d\n",
			    sc->sc_base.me_dv.dv_xname, error);

		/*
		 * Try and set this encoding as the mux default if it
		 * hasn't any yet, and if this is not a driver default
		 * layout (i.e. parent driver pretends to know better).
		 * Note that wsmux_set_layout() rejects layouts with
		 * KB_DEFAULT set.
		 */
		if (wsmux_get_layout(wsmux_sc) == KB_NONE)
			wsmux_set_layout(wsmux_sc, layout);
	}
#endif

#if NWSDISPLAY > 0 && NWSMUX == 0
	if (ap->console == 0) {
		/*
		 * In the non-wsmux world, always connect wskbd0 and wsdisplay0
		 * together.
		 */
		extern struct cfdriver wsdisplay_cd;

		if (wsdisplay_cd.cd_ndevs != 0 && self->dv_unit == 0) {
			if (wskbd_set_display(self,
			    wsdisplay_cd.cd_devs[0]) == 0)
				wsdisplay_set_kbd(wsdisplay_cd.cd_devs[0],
				    (struct wsevsrc *)sc);
		}
	}
#endif
}
示例#2
0
void
wskbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct wskbd_softc *sc = (struct wskbd_softc *)self;
	struct wskbddev_attach_args *ap = aux;
#if NWSMUX > 0
	int mux, error;
#endif

	sc->sc_isconsole = ap->console;

#if NWSMUX > 0 || NWSDISPLAY > 0
	sc->sc_base.me_ops = &wskbd_srcops;
#endif
#if NWSMUX > 0
	mux = sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux;
	if (ap->console) {
		/* Ignore mux for console; it always goes to the console mux. */
		/* printf(" (mux %d ignored for console)", mux); */
		mux = -1;
	}
	if (mux >= 0)
		printf(" mux %d", mux);
#else
#if 0	/* not worth keeping, especially since the default value is not -1... */
	if (sc->sc_base.me_dv.dv_cfdata->wskbddevcf_mux >= 0)
		printf(" (mux ignored)");
#endif
#endif	/* NWSMUX > 0 */

	if (ap->console) {
		sc->id = &wskbd_console_data;
	} else {
		sc->id = malloc(sizeof(struct wskbd_internal),
		    M_DEVBUF, M_WAITOK | M_ZERO);
		sc->id->t_keymap = ap->keymap;
		wskbd_update_layout(sc->id, ap->keymap->layout);
	}

#if NWSDISPLAY > 0
	timeout_set(&sc->sc_repeat_ch, wskbd_repeat, sc);
#endif

	sc->id->t_sc = sc;

	sc->sc_accessops = ap->accessops;
	sc->sc_accesscookie = ap->accesscookie;
	sc->sc_repeating = 0;
	sc->sc_translating = 1;
	sc->sc_ledstate = -1; /* force update */

	if (wskbd_load_keymap(sc->id->t_keymap,
	    &sc->sc_map, &sc->sc_maplen) != 0)
		panic("cannot load keymap");

	sc->sc_layout = sc->id->t_keymap->layout;

	/* set default bell and key repeat data */
	sc->sc_bell_data = wskbd_default_bell_data;
	sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;

	if (ap->console) {
		KASSERT(wskbd_console_initted); 
		KASSERT(wskbd_console_device == NULL);

		wskbd_console_device = sc;

		printf(": console keyboard");

#if NWSDISPLAY > 0
		wsdisplay_set_console_kbd(&sc->sc_base); /* sets sc_displaydv */
		if (sc->sc_displaydv != NULL)
			printf(", using %s", sc->sc_displaydv->dv_xname);
#endif
	}
	printf("\n");

#if NWSMUX > 0
	if (mux >= 0) {
		error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base);
		if (error)
			printf("%s: attach error=%d\n",
			    sc->sc_base.me_dv.dv_xname, error);
	}
#endif

#if WSDISPLAY > 0 && NWSMUX == 0
	if (ap->console == 0) {
		/*
		 * In the non-wsmux world, always connect wskbd0 and wsdisplay0
		 * together.
		 */
		extern struct cfdriver wsdisplay_cd;

		if (wsdisplay_cd.cd_ndevs != 0 && self->dv_unit == 0) {
			if (wskbd_set_display(self,
			    wsdisplay_cd.cd_devs[0]) == 0)
				wsdisplay_set_kbd(wsdisplay_cd.cd_devs[0],
				    (struct wsevsrc *)sc);
		}
	}
#endif

}