Skip to content
FreeBSDDeep Dive Published Updated 9 min readViews unavailable

FreeBSD USB Host Diagnostics: Enumeration, Drivers, and Device Recovery

Trace FreeBSD USB devices from controller enumeration through interface drivers, inspect descriptors safely, and verify storage or peripheral recovery.

FreeBSD USB troubleshooting is a chain-of-ownership problem. The host controller must enumerate a device, the USB stack must select a configuration, a driver must attach to each interface, and the subsystem driver must expose an operating-system object such as a disk, serial port, input device, or generic ugen node. A device can appear in usbconfig while failing later in the chain; “USB detected” is not the same as “the application can use it.”

This guide covers host-side diagnostics, not USB device-mode configuration for boards that present themselves as a peripheral. It also distinguishes bus enumeration from storage/CAM behavior: a thumb drive can enumerate successfully but fail during SCSI commands, partition discovery, or mounting. Record the FreeBSD release and hardware topology so that an intermittent result can be compared after a port, hub, cable, firmware, or driver change.

Capture the topology and baseline first

Before unplugging devices or resetting a bus, record the current USB list, kernel messages, interface drivers, and any dependent devices. A device address such as ugen1.2 is assigned during enumeration and can change after disconnect, reset, or reboot; do not treat it as a permanent hardware identity. The descriptors contain vendor/product identifiers and configuration/interface details that help identify the actual device model and its requested power/bandwidth.

freebsd-version -kru
usbconfig list
usbconfig show_ifdrv
dmesg | tail -n 100
devinfo -rv

usbconfig lists USB devices and attached interface drivers. dmesg shows recent kernel messages but may wrap or omit older boot evidence; save the relevant lines before they scroll away. devinfo -rv shows the device tree and attachment relationships. Compare the expected controller, bus, hub, device, and attached driver rather than searching only for the product’s marketing name.

Confirm the cable, physical port, and hub path. A bus-powered hub can expose a power-budget failure that resembles a missing driver, and a marginal cable may allow enumeration but fail under transfer load. If the device is behind a docking station, test the direct host port only during a controlled window and record which topology change altered the result.

Inspect descriptors and interface attachment

Use usbconfig to inspect a specific currently enumerated device. Replace ugen1.2 with the address printed by the current usbconfig list output:

usbconfig -d ugen1.2 dump_device_desc
usbconfig -d ugen1.2 dump_all_desc
usbconfig -d ugen1.2 show_ifdrv

The device descriptor identifies fields such as vendor/product IDs and device class. Configuration descriptors describe power requirements, interface count, alternate settings, and endpoints. A composite device can expose separate interfaces for audio, HID controls, storage, or serial functions; one interface attaching does not prove all interfaces have the right driver. Compare the selected configuration and attached driver names with the device’s intended function and the corresponding FreeBSD manual page.

The generic USB device node and subsystem object are different layers. For mass storage, the umass(4) driver connects USB mass-storage protocol to the SCSI/CAM stack; the disk may appear as daN, with a corresponding passN device. For other device classes, look for the expected ttyU*, uhid*, ums*, uaudio*, or vendor-specific nodes where supported. Do not assume every USB device should have a da disk or a generic ugen interface available to user software.

Follow the device through the intended subsystem

For a USB storage device, inspect kernel logs and camcontrol devlist after enumeration. The expected progression includes a USB Mass Storage attachment, CAM bus path, and a direct-access device. If the device appears in usbconfig but not in CAM, investigate the mass-storage interface and driver attachment. If CAM sees it but no partition or filesystem is visible, continue with the normal disk, gpart, and mount workflow; do not reset the USB bus as a substitute for understanding the reported storage error.

camcontrol devlist
camcontrol inquiry da0
geom disk list da0
gpart show -p da0

The device node da0 is an example, not a stable identity. Verify model/serial and bus path before issuing any write, partition, or filesystem command. Do not run gpart create, newfs, or a destructive test just because a USB disk is missing from the desktop; identify the provider and existing data first. A removable drive can be valid but unmounted, encrypted, formatted with an unsupported filesystem, or held by another consumer.

For an input, serial, audio, or scanner device, validate the relevant character-device node and service/package integration rather than relying on the bus listing. Some peripherals require firmware or userland drivers outside the base system. Consult the device-class manual, the relevant port’s documentation, and devd(8) rules only after confirming the interface is actually attached. A devd rule cannot compensate for an absent USB driver or unsupported descriptor.

Use reset and power controls with care

usbconfig reset forces the USB stack to re-enumerate the selected device. It can clear transient state, but it also disrupts active I/O and changes bus addresses. Before using it, stop the owning application, unmount filesystems cleanly, flush any expected writes, and confirm that no VM, jail, or service is using the device. A reset of a hub or controller can affect multiple downstream devices even when the intended target is one peripheral.

# Inspect first; reset only the selected device in a maintenance window.
usbconfig -d ugen1.2 dump_all_desc
usbconfig -d ugen1.2 reset
usbconfig list
dmesg | tail -n 100

After reset, re-discover the device address instead of reusing the old ugen value. Compare the new descriptor and driver attachment with the baseline. Do not script repeated resets as a health strategy; repeated re-enumeration can hide a power, cable, firmware, or device failure and may interrupt writes. power_off, suspend, and driver-detach operations are also state-changing actions. Use the usbconfig(8) documentation to understand their impact and test on noncritical hardware before automation.

For a storage device, orderly removal begins at the filesystem and GEOM/CAM layers: stop applications, unmount all mounted filesystems, verify no swap or pool use, and only then disconnect. usbconfig controls the USB subsystem, not data durability. A successful reset or disconnect does not prove pending filesystem writes were committed.

Diagnose frequent USB signatures

No device appears in usbconfig list. Check power, cable, hub, physical port, host-controller driver, and boot/kernel messages. If several devices on one hub vanish together, focus on the hub or upstream controller rather than changing each peripheral’s userland configuration. Compare direct-host and hub paths one variable at a time.

Descriptors appear but no class driver attaches. Inspect every interface and class/subclass/protocol value, then verify support in the relevant driver manual and the running kernel. A composite device may require a driver on one interface while leaving another intentionally unclaimed. Check whether the driver is built in or loaded; an absent kldstat entry alone does not prove a driver is unavailable.

A device repeatedly disconnects under load. Correlate dmesg timestamps with transfer workload, hub power, cable movement, port choice, and controller errors. A device can enumerate at low speed and fail when sustained throughput or higher power is demanded. Test with a known-good cable and powered hub only when the device specifications permit it; do not infer that a powered hub is always safer.

USB storage enumerates but file operations fail. Follow the CAM path, inspect device inquiry and kernel errors, check media health and filesystem status, and compare the exact device provider. Avoid repeated bus resets during writes. If the device is failing, prioritize an image or recovery plan appropriate to the data instead of writing a new partition table.

Behavior changes after reboot or port move. Device addresses and unit numbers are enumeration-dependent. Match vendor/product ID, serial, physical port path, and CAM inquiry data. Update devd or application matching only after deciding which identity is stable for the deployment; do not hard-code ugen1.2 as a durable device identifier.

Build a bounded evidence capture

For an intermittent problem, collect a narrow before/during/after record. Use usbconfig -v to capture list detail, dmesg to preserve attach/detach events, and camcontrol devlist for storage. Capture one hotplug event and one controlled workload, not hours of unrelated output. Include FreeBSD release, architecture, controller, hub topology, vendor/product ID, device serial if appropriate, selected configuration, driver names, and exact port.

Keep the evidence local and redact serial numbers or identifiers before sharing externally. USB descriptors can include device strings and topology details that are operationally sensitive. Do not issue arbitrary vendor control requests through usbconfig do_request; that interface can send synchronous control requests, and incorrect requests may change device state or expose unsupported behavior. Use it only when the device or driver documentation specifies exact values and the test is authorized.

If a port or kernel module change is being considered, first determine whether the feature is built into the current kernel, a loadable module, or a userland package. Review the driver manual and boot messages, keep a known-good boot environment where appropriate, and make one change at a time. Rebooting and changing cable, port, module, and package simultaneously may restore service but destroys the evidence needed to prevent recurrence.

Validate the complete device contract

Define success at the function layer: storage can perform the required read/write test, a serial device exposes the expected port and can exchange a known frame, an input device produces the expected event, or a scanner/audio device works in its intended application. Validate both after initial attach and after the lifecycle event that matters (reboot, suspend/resume, hub reset, or service restart). A successful descriptor dump is only one stage of the test.

For storage, use a disposable filesystem or a read-only observation where possible and verify clean unmount before unplugging. For a non-storage peripheral, use its documented test utility and confirm the application opens the selected device node. Check the relevant service logs and repeat under representative load long enough to expose disconnects. Record the expected device path or stable identifier and ensure monitoring notices missing attachment rather than assuming that a one-time setup persists.

Treat the USB host stack as a dependency chain: controller, bus, descriptor/configuration, interface driver, subsystem node, and application. Each layer has its own evidence and failure modes. Once the exact failing boundary is known, a small reversible test is safer and more informative than repeated resets or broad driver changes.

Related:

Sources:

Comments