# keyboard unresponsive when 2nd keyboard unplugged



## lclee (Feb 7, 2011)

I have previously requested help on this topic ( see http://forums.freebsd.org/showthread.php?t=21510 ). I believe that this is gdm issue and not a USB issue.

Briefly, when an additional USB keyboard is plugged in, it becomes part of the current graphical console and keyboard input can be entered on either keyboard.  When the secondary  keyboard is unplugged, the primary keybard is also disabled, until either the user logs out or another secondary keyboard is plugged back in.

Can anyone explain or point me at a document that explains how a USB keyboard attaches and detaches to the currently running gdm.  Even pointing  me towards the proper source code would be helpful.

Thanks
Larry


----------



## wblock@ (Feb 7, 2011)

There's kbdmux(4).  With GNOME, this probably also involves sysutils/hal and the X server's input device hotplugging code.


----------



## SirDice (Feb 11, 2011)

I've tried kbdmux once. Xorg doesn't like it. Replugging the first keyboard seems to work.

I've tried with HAL and I've tried to set the keyboard manually and using kbdmux. With kbdmux Xorg just refuses to start. With HAL you get the problem as described. Plugging in a second keyboard, both keyboards work. Unplug the second one and the first stops working.


----------



## lclee (Mar 9, 2011)

Here is a summary of what I have discovered.

Kernel Plumbing

  I'm new to FreeBSD and so I spent a bit of time figuring this out.  This may not be exactly 100% right or complete, but if I'm grotesquely wrong please let me know.

  Here is a simple ascii picture of how these drivers are plumbed.


```
|
    syscons ( /dev/vtty{0..8} )
      |
    kbd ( /dev/kbd{*} )
      |
    kbdmux ( /dev/kbdmux0  /dev/kbd1 )
      |
      +------|
      |      |
      |    ukbd ( /dev/ukbd{0..*} /dev/kbd{2..*} )
      |
    atkbd ( /dev/atkbd0 /dev/kbd0 )
```
 
  There is also a good deal of USB code beneath the ukbd driver, some of which interfaces with the hald/dbus user processes.

I noticed that when a USB keyboard is unplugged that an ioctl (KBSMODE, K_XLATE) is issued.  So I did a stack trace on the user process (Xorg) at the time the ioctl was issued and found.


```
#0  0x0000000802afa720 in KbdOff ()
  #1  0x0000000802af9e8b in KbdProc ()
  #2  0x0000000000431862 in DisableDevice ()
  #3  0x0000000000431b09 in RemoveDevice ()
  #4  0x0000000000480676 in DeleteInputDeviceRequest ()
  #5  0x000000000045ec60 in config_hal_fini ()
  #6  0x000000000045ecef in config_hal_fini ()
  #7  0x000000080101fc49 in filter_func ()
  #8  0x000000080114100f in dbus_connection_dispatch ()
  #9  0x000000080114135b in dbus_connection_borrow_message ()
  #10 0x000000000045e90f in config_dbus_core_fini ()
  #11 0x000000000043cabe in WakeupHandler ()
  #12 0x0000000000464f94 in WaitForSomething ()
  #13 0x00000000004371cf in Dispatch ()
  #14 0x000000000042d7ba in main ()
```
This is what I believe to be happening.

  The kernel drivers are performing correctly.  This is based on code inspection as well as printf in various places to verify their actions.

  Xorg is receiving a message via hald/dbus saying a keyboard has been unplugged. Xorg responds by shutting down it's keyboard device, not knowing that it has indirectly opened kbdmux which supports multiple keyboards.  

  I believe the correct action is for Xorg to ignore this particular message, but I don't know how to make this happen.   I have been unable to find the source code for libhal.so.1 and libdbus-1.so.3 and I frankly don't understand the code in x11-servers/xorg-server/*/dbus-core.c.


----------



## wblock@ (Mar 9, 2011)

The libraries for hal and dbus come from the ports: sysutils/hal and sysutils/dbus.

Seems like kbdmux shouldn't send a keyboard detached message unless it's the last keyboard.  AFAIK, that was the point of kbdmux, to make multiple keyboards act like one.


----------



## lclee (Mar 9, 2011)

Thank you  for the pointer to the libhald and libdbus.  I will look at them, but I suspect that the necessary changes will be in the area of x11-servers/xorg-server/*/dbus-core.c.  Either in the processing of a keyboard removed message or in registering which messages to receive.

The crux of my argument is that a keyboard detached message shouldn't be processed by Xorg because the default installation and configuration for gdm/Xorg programs uses ttyv8 which sits on top of  kbdmux0 .  I should probably run a test on kbdmux to verify it's operation when _all_ keyboards are removed, but I don't think that even this is an issue.

I do not believe that kbdmux originates, forwards or is even aware that  the keyboard removed message has been sent.  I think the same is true for ukbd, but I'm not positive.  I think the message originates from the USB code that is below ukbd.

FWIW, even when Xorg has disabled the the 'X' keyboard and is refusing to read any keyboard data. I can still do a CTL-ALT-F2 and switch to a serial console.  So everything in the driver stack is working up thru and including syscons.  This is part of why I believe that the problem is in Xorg and not in the kernel drivers.

Thanks
Larry


----------

