-
Notifications
You must be signed in to change notification settings - Fork 39
SuperHID
In its current state (proof-of-concept), SuperHID extends the Linux HID gadget with multitouch stuff.
Using the gadget subsystem, originally designed for real hardware, implies having to simulate and drive a ton of hardware:
- A USB host controller (HCD)
- A USB device controller (UCD), along with its endpoints and the glue to the HCD
- A USB device that links to a UCD
The resulting fake device is then passed to a guest using the PV USB backend/frontend.
In the proof-of-concept, the dummy_hcd kernel module is used as an HCD+UCD, with the critical limitation that it supports only 1 USB device, with no easy way to extend to multiple devices.
In general, the gadget subsystem is not meant to be used like that. Gadgets are for "slave" USB devices, not hosts...
In the current scheme, we spend a lot of effort and resource to simulate a "real" device, when in the end it gets "virtualized"...
The main idea for making it simpler would be to stop using the gadget subsystem, and just plug SuperHID somewhere in the PV USB mechanism. The frontends just bring up "fake" devices anyway!
I see two ways of doing this:
- usbback could be modified to be able to use a special kernel module in place of real USB devices. That way, the frontend would need no modification, but that implies understanding and modifying the huge mess that is usbback...
- A separate USB backend could be written, using some of the guts of usbback as a starting point. That new backend would talk to SuperHID instead of real devices. That means not having to mess with usbback, but the frontends may have to be modified to be able to deal with multiple PV USB backends...
The second approach seems to make the most sense to me, so that's what I'm looking at.
Some HID background could be useful to understand the core of SuperHID.
When using SuperHID, the input follows that path:
Device (HID)
v
Linux (HID->Event)
v
input_server (Event)
v
SuperHID plugin (Event->HID)
v
SuperHID driver (HID)
v
SuperHID fake device (HID->USB)
Then, passing the superhid fake device through to any guest gives it all the input we want.
- No code needed in the guest VM
- Multi-touch works in Microsoft Windows 8, and any other pv-usb-enabled guest
- All the input still goes through input_server, which gives total control over what event goes to which VM
- The input events follow a long path, as illustrated above
- Implement the plugin directly in input_server, to reduce the packets journey.
- Implement a way to skip the relative-to-absolute translation that happens in input_server, to make input faster and more reliable (but potentially breaking other input features).
- Enhance the superhid gadget driver (and/or the virtual USB controller) to be able to create multiple devices (right now we get only one).
- Get the toolstack and the USB subsystem to automatically pass the right SuperHID fake input device to the right guest.
The superhid proof-of-concept is now functionnal, and the superhid device itself can be used as-is.
However, the USB controller needs a lot of work. Right now, we use dummy_hcd, which simulates a real life controller, with power, latency and ports limitations. This module has been created only for development purposes, to simulate devices before actually getting access to the real hardware. The problem of that module is that is requires the clock to be set to 1000HZ, and it probably uses too much resources.
What SuperHID needs is something that would be more of a "fake USB controller", that would be dummy-er than dummy_hcd. Like just enough code to create a fake controller and pipe the packets to the fake devices (gadgets).
-
Make sure the dom0 Linux kernel has been (re)compiled with an HZ value of 1000 and gadget support.
-
In OE: ./bb xenclient-superhid
-
Send and install the resulting module to the (OpenXT) test machine (superhid.ko)
-
In input.git/superhid (with a 32 bits compiler): gcc -o shp -lpthread -levent superhidplugin.c
-
Send shp to the test machine
-
On the test machine:
# cat > /etc/modprobe.d/superhid.conf <<EOF options superhid idVendor=0x03eb idProduct=0x211c bcdDevice=0x0001 iManufacturer=jed iProduct=superhid EOF # modprobe dummy_hcd # modprobe superhid # ./shp <domid>
Note: idVendor and idProduct are set to an existing input device to make some guests recognise it. Ideally, those values could be anything, as the device is just a standard HID device.
- Pass the superhid device to the (Windows/Linux) guest
At that point, the guest should see a new multitouch HID device and should be able to use it.