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

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)

DriverBus / transportCoversIn NextBSD?Verdict
hmshidbus (USB via usbhid, I2C via iichid)relative mice, wheel, AC-Pan h-scroll, ≤16 buttons, absolute VM tabletsno — add itthe right mouse driver
umsuhub (USB only)relative mice + sysmouse + HUG_TWHEEL tiltnolegacy; can’t do absolute VM mice
utouch (port)uhub (USB only)absolute USB HID mice only (VBox/bhyve)port onlydeprecated → use hms
hmthidbusmultitouch touchpads and touchscreens (16 contacts)no — add for touchneeded for trackpad/touchscreen
hpenhidbuspens/stylus + single-touch digitizersno — add for penneeded for pen
iichid + ig4iicbus (I2C-HID)I2C precision touchpads/touchscreens transportno — add for I2Cneeded for laptop touchpads
ietphidbusElan I2C touchpads (some come up here not hmt)noadd for broad Elan coverage
hconfhidbusdigitizer config (Precision-Touchpad mode switch)nohmt hard-depends on it
SAM / IPTS / ITHCSurface-specificMicrosoft Surface kbd/touch/penabsentwon’t work in base (Linux-only)
virtio-input guestvirtioQEMU/KVM virtio pointers/keyboardsno driver existsuse 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

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:

Crucially: utouch never drove any Surface touchscreen either, so picking hms changes nothing here.

Lenovo ThinkPad

QEMU/KVM, VirtualBox, bhyve

How we got here (timeline)

WhenWhatRef
pre-2021wulf7 maintains iichid + utouch as out-of-tree ports; people use them (and webcamd) because base had no evdev HID stackgithub.com/wulf7
2021-01-08HID stack imported into base: hidbus, usbhid, iichid, and hidmap+drivers (hms/hmt/hpen)commits 2b4464b0b114, 01f2e864f795, b1f1b07f6d41, afd590d9e566; D27777
Apr 2021First shipped in FreeBSD 13.0 — but new USB stack OFF by default (hw.usb.usbhid.enable=0) to avoid fighting ums/ukbdD28124, commit b62f6dfaed3d
2024-07usbhid+hidbus added to GENERIC (still off by default)commit 13d00a43cba4, D45658
2025-07-30FreeBSD 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.