NextBSD input & touch drivers: hms vs utouch
A code-review spike — USB mice, VM (QEMU/KVM/VirtualBox/bhyve) pointers, trackpads, touchscreens, and pens. Source read against freebsd-src and wulf7/utouch; version-gated facts confirmed on releng/15.0.
Contents
- Why this is a NextBSD problem at all
- The driver landscape (one table)
hmsvsums— mice & VM absolute pointers- What
utouchactually is - Touch, touchpad & pen —
hmt/hpen/iichid - Microsoft Surface (the bad news)
- Lenovo ThinkPad
- QEMU/KVM, VirtualBox, bhyve
- How we got here (timeline)
- Recommendation for the NextBSD kernel config
- Sources & caveats
Why this is a NextBSD problem at all
On stock FreeBSD a USB mouse and an I2C touchpad “just work” even though sys/amd64/conf/GENERIC does not list hms, ums, hmt, hpen, iichid, ig4, hidmap, or ietp as compiled-in device lines. GENERIC compiles in only the keyboard leaves (hkbd, ukbd) and the HID transports (hid, hidbus, usbhid) — the mouse and touch leaf drivers are shipped as loadable .ko modules that devd/devmatch auto-loads on demand when a device appears.
The fix is therefore not a kext and not a tunable — it is to bake the needed leaf drivers into config/NEXTBSD. This is the same reasoning already applied to graphics deps (iic, LINDEBUGFS) and the live-media filesystems in that config.
The driver landscape (one table)
| Driver | Bus / transport | Covers | In NextBSD? | Verdict |
|---|---|---|---|---|
hms | hidbus (USB via usbhid, I2C via iichid) | relative mice, wheel, AC-Pan h-scroll, ≤16 buttons, absolute VM tablets | no — add it | the right mouse driver |
ums | uhub (USB only) | relative mice + sysmouse + HUG_TWHEEL tilt | no | legacy; can’t do absolute VM mice |
utouch (port) | uhub (USB only) | absolute USB HID mice only (VBox/bhyve) | port only | deprecated → use hms |
hmt | hidbus | multitouch touchpads and touchscreens (16 contacts) | no — add for touch | needed for trackpad/touchscreen |
hpen | hidbus | pens/stylus + single-touch digitizers | no — add for pen | needed for pen |
iichid + ig4 | iicbus (I2C-HID) | I2C precision touchpads/touchscreens transport | no — add for I2C | needed for laptop touchpads |
ietp | hidbus | Elan I2C touchpads (some come up here not hmt) | no | add for broad Elan coverage |
hconf | hidbus | digitizer config (Precision-Touchpad mode switch) | no | hmt hard-depends on it |
| SAM / IPTS / ITHC | Surface-specific | Microsoft Surface kbd/touch/pen | absent | won’t work in base (Linux-only) |
virtio-input guest | virtio | QEMU/KVM virtio pointers/keyboards | no driver exists | use emulated USB tablet instead |
hms vs ums — mice & VM absolute pointers
hms (sys/dev/hid/hms.c) is the evdev-only HID mouse/pointer driver built on the generic hidmap usage→evdev mapper. Its static map is the decisive evidence:
[HMS_REL_X] = HMS_MAP_REL(HUG_X, REL_X), /* hms.c:86 relative mouse */ [HMS_REL_Y] = HMS_MAP_REL(HUG_Y, REL_Y), /* hms.c:87 */ [HMS_ABS_X] = HMS_MAP_ABS(HUG_X, ABS_X), /* hms.c:89 ABSOLUTE (VM tablet) */ [HMS_ABS_Y] = HMS_MAP_ABS(HUG_Y, ABS_Y), /* hms.c:90 */ [HMS_HWHEEL] = HMS_MAP_REL_CN(HUC_AC_PAN, REL_HWHEEL), /* hms.c:92 h-scroll */ [HMS_BTN] = HMS_MAP_BUT_RG(1, 16, BTN_MOUSE), /* hms.c:93 up to 16 buttons */
Relative-vs-absolute is chosen at parse time: can_map_variable() binds a HID item to the relative map slot or the absolute slot depending on whether the descriptor sets HIO_RELATIVE (hidmap.c:349-358). For an absolute device the logical min/max (e.g. a VM tablet’s 0–32767 range) is propagated into the evdev ABS_X/ABS_Y absinfo (hidmap.c:583-592), and the device is advertised INPUT_PROP_DIRECT vs INPUT_PROP_POINTER accordingly (hms.c:177-181).
So hms correctly drives VM “usb-tablet” absolute pointers — the exact capability ums lacks. ums (sys/dev/usb/input/ums.c) is structurally relative-only: every axis is gated on HIO_RELATIVE (ums.c:92-93, 470-507), there is no EV_ABS/ABS_X anywhere in the file, and it hardcodes INPUT_PROP_POINTER.
Honest gaps where ums still does something hms doesn’t
- No
/dev/sysmousefromhms.hmsis evdev-only;umsadditionally speaks the legacy sysmouse/MSC FIFO (ums.c:876-921, 1030-1146). For NextBSD’s evdev-first (libinput/Xorg-evdev) userland this is a non-issue; only legacymoused/console-mouse consumers that read/dev/sysmousedirectly would care. HUG_TWHEELtilt-wheel.umsmaps the old Intellimouse tilt usage (ums.c:515-522);hmsonly does horizontal scroll via Consumer-pageHUC_AC_PAN(hms.c:92). Modern mice use AC-Pan, so impact is small.INPUT_PROP_DIRECTon VM tablets. For an absolute VM mouse,hmstags it touchscreen-class (hms.c:179). Axis data is correct, but libinput/X may classify it as a touch device; worth a glance if VM-pointer behaviour looks off.
Attachment order: with hw.usb.usbhid.enable=1 (the FreeBSD 15.0 default), usbhid bids BUS_PROBE_DEFAULT + 1 (usbhid.c:813) and beats ums’s BUS_PROBE_DEFAULT, so a USB mouse attaches usbhid → hidbus → hms. Set it to 0 and ums takes over instead. Both can be compiled in simultaneously (the tunable is the documented switch).
What utouch actually is
Reading the source (utouch.c, 542 lines, plus README) settles it: utouch targets the absolute-coordinate USB HID mouse that hypervisors emulate — not a touchscreen. Its probe only descends a Generic-Desktop / HUG_MOUSE collection and accepts the device only when X/Y are absolute (utouch.c:383-402). It never looks at the Digitizer usage page, contact IDs, or tip-switch — there is no touchscreen/multitouch/pen code at all. Its device match is maximally generic (any HID-class non-boot interface, utouch.c:508-512) with no quirk table, so it supports no device hms lacks.
The README is explicit (README.md:24-30): “This driver is deprecated on FreeBSD 13+. Please use hms(4) bundled with base system.” It even gives the loader lines (hw.usb.usbhid.enable=1, usbhid_load="YES") — i.e. the historical workaround was about the new stack being off by default, not about hms lacking capability. utouch emits evdev only (no sysmouse) and last saw a functional commit in 2021; 2023 was a build fix.
Touch, touchpad & pen — hmt/hpen/iichid
hmt — multitouch
sys/dev/hid/hmt.c is the Windows-compatible HID multitouch driver and covers both Precision Touchpads and multitouch touchscreens, distinguished at probe by matching HUD_TOUCHSCREEN vs HUD_TOUCHPAD TLCs (hmt.c:245-248, 689-700). Up to 16 contacts (evdev.h:84), full evdev Type-B MT protocol (ABS_MT_SLOT, ABS_MT_POSITION_X/Y, TRACKING_ID, PRESSURE, TOUCH_MAJOR/MINOR, hmt.c:78-91). It hard-depends on hconf to switch a Precision Touchpad out of mouse mode (hmt.c:362-367, 911).
hpen — pen & single-touch digitizers
sys/dev/hid/hpen.c handles pens/stylus and single-touch digitizers: ABS_PRESSURE, ABS_TILT_X/Y, BTN_TOUCH, BTN_STYLUS/STYLUS2, eraser (BTN_TOOL_RUBBER), in-range hover (hpen.c:72-97, 131-146). It deliberately yields generic multitouch screens to hmt.
iichid + ig4 — the I2C-HID path
Laptop precision touchpads are almost always I2C-HID, attaching acpi → ig4 (I2C controller) → iicbus → iichid → hidbus → hmt/hms/hconf. iichid matches ACPI _HID PNP0C50/ACPI0C50/ELAN0000 (iichid.c:138-146).
Microsoft Surface (the bad news)
Surface touch/pen does not work in FreeBSD base, and not for lack of a HID leaf driver:
- Surface Pro 4 and everything newer route touch/pen through IPTS (Intel Precise Touch & Stylus) or ITHC (Intel Touch Host Controller) — these need Intel-specific drivers plus an
iptsduserspace daemon. None of that exists in FreeBSD base or ports (IPTS was never even mainlined in Linux). - Surface Laptop/Book keyboard+touchpad are gated behind the Surface Aggregator Module (SAM) — no SAM driver exists anywhere in FreeBSD
releng/15.0(verified by source search). It is a Linux-only capability today. - Only the Surface Pro 3 exposes touch+pen as plain N-Trig I2C-HID (
NTRG0001/PNP0C50), which is architecturally compatible withiichid+hmt/hpen— but treat as “should attach,” not field-proven on FreeBSD.
Crucially: utouch never drove any Surface touchscreen either, so picking hms changes nothing here.
Lenovo ThinkPad
- Touchpad: modern ThinkPads (X1 Carbon gen7+, T490/T14 onward) present the precision touchpad as I2C-HID →
ig4/iichid/hmt/hms/hconf(Elan models may land onietp). Older machines use a PS/2 Synaptics pad on the legacypsmdriver. - TrackPoint: commonly stays on PS/2 (
psm/atkbdc) even on I2C-HID machines — a single ThinkPad can present bothpsm0andiichid/hmt. (On the T460s in question, the trackpad/point is PS/2psm0and already works; only the external USB mouse needshms.) - Touchscreens (X1 Yoga / Carbon touch): USB-HID or I2C-HID →
hmt(+hpenfor the Wacom AES pen). - Caveat: the
IICHID_SAMPLING/GPIO-IRQ issue above is the dominant real-world ThinkPad problem — detection is reliable, smooth motion needs the sampling tunables.
QEMU/KVM, VirtualBox, bhyve
- Emulated USB tablet/mouse (QEMU
-device usb-tablet/usb-mouse, VirtualBox/VMware USB tablet): works viausbhid → hidbus → hms. The absolute tablet maps toABS_X/ABS_Ycorrectly — this is precisely theutouchuse case, now covered byhms. - Native
virtio-input: no in-kernel guest driver exists inreleng/15.0— only the bhyve emulator backend (usr.sbin/bhyve/pci_virtio_input.c) is present. A guest given a purevirtio-inputdevice gets no evdev node. Configure the VM to present a USB tablet instead.utouchdidn’t help here either.
How we got here (timeline)
| When | What | Ref |
|---|---|---|
| pre-2021 | wulf7 maintains iichid + utouch as out-of-tree ports; people use them (and webcamd) because base had no evdev HID stack | github.com/wulf7 |
| 2021-01-08 | HID stack imported into base: hidbus, usbhid, iichid, and hidmap+drivers (hms/hmt/hpen) | commits 2b4464b0b114, 01f2e864f795, b1f1b07f6d41, afd590d9e566; D27777 |
| Apr 2021 | First shipped in FreeBSD 13.0 — but new USB stack OFF by default (hw.usb.usbhid.enable=0) to avoid fighting ums/ukbd | D28124, commit b62f6dfaed3d |
| 2024-07 | usbhid+hidbus added to GENERIC (still off by default) | commit 13d00a43cba4, D45658 |
| 2025-07-30 | FreeBSD 15.0: usbhid enabled by default (usbhid_enable = 1) | commit 74072e9f16c1, D45659 |
The “base didn’t work” era is the 13.x–14.x window where the capable driver was present but disabled, so an absolute VM mouse or I2C touchpad needed manual enabling — or the utouch/webcamd ports. On releng/15.0 the stack is in GENERIC and on by default; the transition is over. (Note: webcamd’s genuinely unique coverage is non-HID — webcams, DVB tuners, USB radio — irrelevant to pointer/touch input.)
Recommendation for the NextBSD kernel config
Because there is no .ko tree, bake these into config/NEXTBSD (nextbsd-redux/nextbsd-kernel). Common prerequisites evdev/EVDEV_SUPPORT/hid/hidbus/usbhid are already present via GENERIC.
# mice (issue #335 / PR nextbsd-kernel#46) — the reported bug device hms # HID mouse: relative + absolute (VM tablet); peer of hkbd # touch / touchpad / pen — the follow-on this spike recommends device hidmap # 1:1 usage->evdev mapper hpen/hms build on device hmt # multitouch touchpads AND touchscreens device hpen # pens/stylus + single-touch digitizers device hconf # Precision-Touchpad mode switch (hmt hard-depends) # I2C-HID transport for laptop precision touchpads/touchscreens device iicbus device ig4 # Intel/AMD LPSS I2C controller device iichid # HID-over-I2C (PNP0C50/ACPI0C50/ELAN0000) device ietp # Elan I2C touchpads that bind here instead of hmt options IICHID_SAMPLING # MANDATORY on amd64 (no GPIO IRQ) — else I2C HID won't attach
Phasing suggestion: device hms alone closes the reported USB-mouse bug (#335) and is testable on the T460s now. The touch/I2C block is the “don’t make us reopen this per device class” addition — sound by code inspection and parity with GENERIC’s module set, but not functionally verifiable on the T460s (its trackpad is PS/2). Land it knowing touch validation happens later on real I2C-HID / touchscreen hardware.
Sources & caveats
Caveat on the source tree: the local freebsd-src checkout reviewed for code citations is on main (16-CURRENT, HEAD 70ef02b5d3fd, 2026-05-10), not releng/15.0. The HID stack is mature and stable across this window, so the file:line citations are expected to hold on 15.0; the version-gated facts (the usbhid_enable=1 default, GENERIC contents) were independently verified against releng/15.0. Re-confirm citations if the kernel patch-repo rebases onto a materially older 15.0 cut.
- Code:
sys/dev/hid/{hms,hmt,hpen,hconf,hidmap,hidbus,ietp}.c,sys/dev/usb/input/{ums,usbhid,uhid}.c,sys/dev/iicbus/iichid.c,sys/dev/ichiic/ig4_acpi.c,sys/amd64/conf/GENERIC. - github.com/wulf7/utouch (source + README) · FreshPorts misc/utouch-kmod · github.com/wulf7/iichid
- D27777 (base import) · D28124 (tunable) · D45658 (into GENERIC) · D45659 (enable by default, 15.0)
- hms(4), hmt(4), hpen(4), iichid(4), hidbus(4) man pages · HID Support in FreeBSD 13 (FreeBSD Foundation)
- Surface: kernel.org SAM overview · Phoronix: Surface SAM on Linux