Repository navigation
Conversation
USB 3.2 Gen 2 (10 Gbps) devices were reported by libusb at a speed the usb-redir protocol cannot express, so QEMU attached them at full speed while forwarding their SuperSpeed descriptors. Guests rejected them with "Invalid ep0 maxpacket: 9" and "unable to enumerate USB device". - present LIBUSB_SPEED_SUPER_PLUS as SuperSpeed to the guest - apply QEMU's bMaxPacketSize0 fix-up whenever the device is presented at a non-SuperSpeed link - unmount the host volumes of a mass storage device before redirecting it - reconnect a saved device when it appears while the virtual machine runs Resolves utmapp#7530 Assisted-by: OpenCode:deepseek-v4.1-flash
|
If you don't have the entitlement you can still test with sudo (QEMU command line only) or with SIP off (get entitlement without needing a profile). Either way we do not accept untested PR as per CONTRIBUTING.md. |
Once a USB 3.2 Gen 2 device enumerates at SuperSpeed, the guest drives it as
a UAS (USB Attached SCSI) device, where the command tag is the USB 3 bulk
stream id, so usbredirhost cancels bulk stream transfers constantly.
libusb's Darwin backend did not handle LIBUSB_TRANSFER_TYPE_BULK_STREAM in
darwin_cancel_transfer(), so every cancel returned
LIBUSB_ERROR_INVALID_PARAM ("unknown endpoint type 4"). The cancelled
transfers stayed in flight on the host controller: the first UAS commands
timed out (30 second SCSI timeout, uas_eh_abort_handler, repeated device
resets), and the device was left captured by macOS after the virtual machine
stopped, until it was physically replugged.
darwin_abort_transfers() already aborts a single bulk stream with
AbortStreamsPipe(); route BULK_STREAM to it. The same omission is still
present in upstream libusb master.
Resolves utmapp#7530
Assisted-by: OpenCode:deepseek-v4.1-flash
|
As requested, I ran the tests physically with the hardware from the report. Setup: MacBook Air M4, macOS 27.0.1, the ASM2362 USB 3.2 Gen 2 enclosure (
Both attaching and detaching were confirmed on the physical device. The detach behaviour depends on the libusb fix ( |
Summary
QEMU USB passthrough fails for USB 3.2 Gen 2 (10 Gbps) devices — the external SSDs and NVMe enclosures that most users hit in #7530 — with the guest rejecting the device as
Invalid ep0 maxpacket: 9. This change fixes the speed negotiation that causes it, unmounts the host volumes of a mass storage device before it is redirected so macOS never loses a mounted disk, and reconnects a saved device automatically when it appears again (for example after a firmware update restarts it).Resolves #7530, #2728, #3975, #3995, #5154, #6291, #6721 and #6764.
Root cause
UTM's QEMU passthrough does not hand the device to QEMU directly: it uses SPICE usb-redir with libusb running in the app process (CocoaSpice/usbredirhost). The entitlements are already in place (
com.apple.security.device.usb,com.apple.vm.device-access), so macOS can release the device from its kernel drivers; the failure is in the speed negotiation:LIBUSB_SPEED_SUPER_PLUS(kUSBDeviceSpeedSuperPlus).usbredirhost_send_device_connect(), so it sendsusb_redir_speed_unknown.hw/usb/redirect.c) while still forwarding the device's SuperSpeed descriptor, whosebMaxPacketSize0is 9 (the SuperSpeed encoding, 512 bytes).Invalid ep0 maxpacket: 9, thenunable to enumerate USB device.This matches the reports: USB 2.0 and USB 3.0 (5 Gbps) devices keep working, 10 Gbps SSDs and NVMe enclosures fail, and a USB 2.0 hub "fixes" it by forcing the host device to enumerate at high speed. The usb-redir protocol has no speed above SuperSpeed, so these devices are presented at 5 Gbps instead of 10 Gbps.
Changes
patches/usbredir-0.14.0.patch(new): presentLIBUSB_SPEED_SUPER_PLUSdevices as SuperSpeed, so the guest gets a link and descriptors that match.patches/qemu-10.0.12-utm.patch: the existingbMaxPacketSize0fix-up only ran when QEMU had marked the device as SuperSpeed. Run it whenever the device is presented at a non-SuperSpeed link, which also covers speeds libusb cannot report (for example 20 GbpskUSBDeviceSpeedSuperPlusBy2devices are reported as unknown speed).Services/UTMUSBDeviceUnmount.swift(new, macOS): before redirecting a device, unmount its mounted volumes with DiskArbitration so the capture does not tear the storage driver away from macOS with volumes still in use. If a volume is busy the connection is refused with a clear message instead of risking data loss. The helper also maps the "device still in use" errors from libusb to a message that tells the user what to do.VMDisplayQemuDisplayController): a device in the saved auto-connect list is connected again without prompting when it is attached while the virtual machine is running. This covers devices that reset themselves, for example during a firmware update, and come back a few seconds later.Related issues
These issues are less specific or describe a different problem and are only possibly related: #3322, #3375, #4167, #5664, #7288.
Testing
I confirmed the report with a synthetic test: without access to the
com.apple.vm.device-accessentitlement a local build cannot capture the physical device (on macOS 27 the device is markedNeedsDeviceAccessEntitlement = Yes, so even root cannot), which makes a hardware test impossible. The tests were run on macOS 27.0, MacBook Air M4 (Apple Silicon).The reporter's ASM2362 enclosure (
174c:2362) was used to confirm the reported values:speed=5 (LIBUSB_SPEED_SUPER_PLUS),bcdUSB=0x0320,bMaxPacketSize0=9USBSpeed=5,UsbLinkSpeed=10000000000SUPER_PLUSfalls through to "unknown"); the patched one handles speeds below 6 and mapsSUPER_PLUStosuper.End-to-end in QEMU, with a synthetic usb-redir device that mirrors the SSD descriptors (
bcdUSB 0x0320,bMaxPacketSize0 = 9, mass storage interface) and an Alpine Linux guest on the serial console:unknownspeed)new high-speed USB device,Invalid ep0 maxpacket: 9,unable to enumerate USB devicesuperspeed)new SuperSpeed USB device number 2,New USB device found, idVendor=174c, idProduct=2362unknownspeed)new high-speed USB device, descriptor accepted (the fix-up rewritesbMaxPacketSize0to 64)The physical device itself could not be captured on this machine (see above), and the automatic reconnection path also needs a device that resets while a virtual machine is running, which was not exercised here.
Testing: Tested by the author on macOS 27.0, MacBook Air M4 (Apple Silicon), assisted by the AI agent (DeepSeek V4.1 Flash via OpenCode) which set up and ran the diagnostics and the QEMU tests under the author's supervision. The author acknowledges that this change has been tested and/or reviewed by a human in accordance with UTM's AI contribution guidelines.