Re: request for comments: kbdmux(4) (long)

From: Maksim Yevmenkin <maksim.yevmenkin_at_savvis.net>
Date: Thu, 30 Jun 2005 15:17:28 -0700
Dear Hackers,

first, thanks to everyone, who have replied to this thread. i appreciate 
feedback and will try to improve kbdmux(4) in the near future.

second, i have attached proposed patch that should simplify use of 
kbdmux(4). the idea is that new keyboard will be attached to the kbdmux 
(if present). also syscons(4) would first look for kbdmux keyboard and 
then (if kbdmux keyboard was not found) for any keyboard. if syscons(4) 
finds kbdmux keyboard it will automatically attach all non-busy 
keyboards to the kbdmux.

as always, i would like hear from folks.

thanks,
max

Maksim Yevmenkin wrote:
> Dear Hackers,
> 
> the next version of experimental keyboard multiplexer (kbdmux(4)) is 
> available at http://www.geocities.com/m_evmenkin/kbdmux-3.tar.gz.
> 
> at this point i'm almost happy with the code. i have tested it with real 
> usb keyboard and a couple of ps2 keyboards connected to the ps2 to usb 
> adapter.
> 
> Jun 22 17:59:38 beetle kernel: ukbd1: CHESEN PS2 to USB Converter, rev 
> 1.10/0.10, addr 2, iclass 3/1
> Jun 22 17:59:38 beetle kernel: kbd2 at ukbd1
> 
> console works, X works. i even dropped into the debugger with 
> ctrl+alt+esc and all keyboards were still working.
> 
> the remaining issues are
> 
> - kbdmux model: kbdmux(4) is "super-keyboard" driver that consumes input 
> (raw scancodes) from slave keyboards. the side effect is that _all_ 
> keyboards attached to the kbdmux share the _same_ state. basically user 
> can press ctrl on one keyboard and "C" on another keyboard and it still 
> will work. is that good enough?
> 
> - locking: right now the code relies on Giant mutex (just like the rest 
> keyboard drivers do);
> 
> - code duplication: there are a pieces of code that were stolen from 
> atkbd.c. very similar pieces of code exist in ukbd.c, vkbd.c and now in 
> kbdmux.c. imo that is three times too many. perhaps these pieces could 
> be moved into some common shared place?
> 
> - need comments/input from "non-intel" folks;
> 
> so, providing the code is good, what is the best why to connect 
> kbdmux(4) to the rest of the system?
> 
> - should kbdmux(4) be merged with kbd/syscons and used by default?
> 
> - kbdmux(4) switches all keyboards into K_RAW mode, so if kbdmux(4) is 
> the default keyboard then perhaps all keyboard drivers could be 
> simplified and just return K_RAW scancodes?
> 
> - if kbdmux(4) is not default keyboard then what syscons(4) should do? 
> look for "kbdmux" keyboard first and the look for any ("*") keyboard?
> 
> - what kbdcontrol(8) behavior should be? should it be smart enough to 
> recognize if current keyboard is kbdmux and behave differently?
> 
> - should kbdmux(4) go into 6.x?
> 
> thanks,
> max
> _______________________________________________
> freebsd-current_at_freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe_at_freebsd.org"


--- /sys/sys/kbio.h.orig	Sun Mar 11 14:47:04 2001
+++ /sys/sys/kbio.h	Wed Jun 29 14:10:55 2005
_at__at_ -60,6 +60,10 _at__at_
 /* set keyboard repeat rate (obsolete, use KDSETREPEAT below) */
 #define KDSETRAD	_IO('K', 67 /*, int */)
 
+/* add/remove keyboard to/from mux */
+#define KBADDKBD	_IO('K', 68 /*, int */)	/* add keyboard */
+#define KBRELKBD	_IO('K', 69 /*, int */)	/* release keyboard */
+
 /* see console.h for the definition of the following ioctl */
 #if notdef
 #define KDRASTER	_IOW('K', 100, scr_size_t)
--- /sys/dev/kbd/kbd.c.orig	Thu Jun  2 12:57:55 2005
+++ /sys/dev/kbd/kbd.c	Wed Jun 29 14:34:56 2005
_at__at_ -185,8 +185,11 _at__at_
 {
 	const keyboard_driver_t **list;
 	const keyboard_driver_t *p;
+	keyboard_t *mux;
 	int index;
 
+	mux = kbd_get_keyboard(kbd_find_keyboard("kbdmux", 0));
+
 	for (index = 0; index < keyboards; ++index) {
 		if (keyboard[index] == NULL)
 			break;
_at__at_ -208,6 +211,11 _at__at_
 		if (strcmp(p->name, kbd->kb_name) == 0) {
 			keyboard[index] = kbd;
 			kbdsw[index] = p->kbdsw;
+
+			if (mux != NULL)
+				(*kbdsw[mux->kb_index]->ioctl)
+					(mux, KBADDKBD, (caddr_t) &index);
+
 			return (index);
 		}
 	}
_at__at_ -216,6 +224,11 _at__at_
 		if (strcmp(p->name, kbd->kb_name) == 0) {
 			keyboard[index] = kbd;
 			kbdsw[index] = p->kbdsw;
+
+			if (mux != NULL)
+				(*kbdsw[mux->kb_index]->ioctl)
+					(mux, KBADDKBD, (caddr_t) &index);
+
 			return (index);
 		}
 	}
_at__at_ -282,13 +295,19 _at__at_
  * exclusive use.
  */
 
-/* find the keyboard specified by a driver name and a unit number */
+/*
+ * find the keyboard specified by a driver name and a unit number
+ * starting at given index
+ */
 int
-kbd_find_keyboard(char *driver, int unit)
+kbd_find_keyboard2(char *driver, int unit, int index)
 {
 	int i;
 
-	for (i = 0; i < keyboards; ++i) {
+	if ((index < 0) || (index >= keyboards))
+		return (-1);
+
+	for (i = index; i < keyboards; ++i) {
 		if (keyboard[i] == NULL)
 			continue;
 		if (!KBD_IS_VALID(keyboard[i]))
_at__at_ -299,7 +318,15 _at__at_
 			continue;
 		return (i);
 	}
+
 	return (-1);
+}
+
+/* find the keyboard specified by a driver name and a unit number */
+int
+kbd_find_keyboard(char *driver, int unit)
+{
+	return (kbd_find_keyboard2(driver, unit, 0));
 }
 
 /* allocate a keyboard */
--- /sys/dev/kbd/kbdreg.h.orig	Wed Jun 16 02:46:48 2004
+++ /sys/dev/kbd/kbdreg.h	Tue Jun 28 13:32:23 2005
_at__at_ -196,6 +196,7 _at__at_
 int			kbd_change_callback(keyboard_t *kbd, void *id,
 				     kbd_callback_func_t *func, void *arg);
 int			kbd_find_keyboard(char *driver, int unit);
+int			kbd_find_keyboard2(char *driver, int unit, int index);
 keyboard_t 		*kbd_get_keyboard(int index);
 
 /* a back door for the console driver to tickle the keyboard driver XXX */
--- /sys/dev/syscons/syscons.c.orig	Sun May 29 01:43:43 2005
+++ /sys/dev/syscons/syscons.c	Thu Jun 30 14:44:15 2005
_at__at_ -148,6 +148,7 _at__at_
 static	int		debugger;
 
 /* prototypes */
+static int sc_allocate_keyboard(sc_softc_t *sc, int unit);
 static struct tty *sc_alloc_tty(struct cdev *dev);
 static int scvidprobe(int unit, int flags, int cons);
 static int sckbdprobe(int unit, int flags, int cons);
_at__at_ -1164,6 +1165,14 _at__at_
 	*(int *)data = scp->status & LED_MASK;
 	return 0;
 
+    case KBADDKBD:		/* add/remove keyboard to/from mux */
+    case KBRELKBD:
+	error = kbd_ioctl(sc->kbd, cmd, data);
+	if (error == ENOIOCTL)
+	    error = ENODEV;
+	return error;
+	break;
+
     case CONS_SETKBD: 		/* set the new keyboard */
 	{
 	    keyboard_t *newkbd;
_at__at_ -1652,8 +1661,7 _at__at_
     if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) {
 	/* try to allocate a keyboard automatically */
 	if (++kbd_interval >= 25) {
-	    sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard,
-					sckbdevent, sc);
+	    sc->keyboard = sc_allocate_keyboard(sc, -1);
 	    if (sc->keyboard >= 0) {
 		sc->kbd = kbd_get_keyboard(sc->keyboard);
 		kbd_ioctl(sc->kbd, KDSKBMODE,
_at__at_ -2639,9 +2647,10 _at__at_
     sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter);
     sc->adp = vid_get_adapter(sc->adapter);
     /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */
-    sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard,
-				sckbdevent, sc);
+
+    sc->keyboard = sc_allocate_keyboard(sc, unit);
     DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard));
+
     sc->kbd = kbd_get_keyboard(sc->keyboard);
     if (sc->kbd != NULL) {
 	DPRINTF(1, ("sc%d: kbd index:%d, unit:%d, flags:0x%x\n",
_at__at_ -3579,4 +3588,31 _at__at_
 	if (devptr == NULL)
 		return (&main_console);
 	return (SC_STAT(devptr));
+}
+
+
+
+static int
+sc_allocate_keyboard(sc_softc_t *sc, int unit)
+{
+	int		 idx0, idx;
+	keyboard_t	*k0;
+
+	idx0 = kbd_allocate("kbdmux", unit, (void *)&sc->keyboard, sckbdevent, sc);
+	if (idx0 != -1) {
+		k0 = kbd_get_keyboard(idx0);
+
+		for (idx = kbd_find_keyboard2("*", -1, 0);
+		     idx != -1;
+		     idx = kbd_find_keyboard2("*", -1, idx + 1)) {
+			if (idx == idx0 || 
+			    KBD_IS_BUSY(kbd_get_keyboard(idx)))
+				continue;
+
+			kbd_ioctl(k0, KBADDKBD, (caddr_t) &idx);
+		}
+	} else
+		idx0 = kbd_allocate("*", unit, (void *)&sc->keyboard, sckbdevent, sc);
+
+	return (idx0);
 }
Received on Thu Jun 30 2005 - 20:17:36 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:37 UTC