Turning on PUNKTFUNK_DUALSENSE_USBIP=1 made the DualSense vanish from the host entirely - unusable in game and absent from Steam's controller list. The usbip path replaces uhid, so there is no fallback.
Enumeration was never the problem: the kernel bound both drivers to the virtual pad ('playstation ... hidraw6: USB HID v1.11 Gamepad [Sony Interactive Entertainment DualSense Wireless Controller]' and snd-usb-audio processing the mixer). ~56 ms later, as soon as snd-usb-audio submitted the first isochronous OUT URB, the link tore down:
usb 11-1: recv xbuf, 0
vhci_hcd: sendmsg failed!, ret=-32 for 48
vhci_hcd vhci_hcd.0: stop threads / release socket / disconnect device
usbip_ret_submit_iso filled each packet descriptor's actual_length correctly (the bytes accepted, = the requested length on OUT) but set the URB-level actual_length from transfer_buffer.len(), and the transfer buffer is only populated INBOUND. So an OUT reply stated per-packet actuals summing to N x 392 against a total of 0.
The kernel's usbip_recv_iso() sums the packet table and compares it to the URB's actual_length; on a mismatch it raises ERROR_TCP and returns -EPIPE, which drops the connection rather than the URB - hence the pad disappearing outright and the attach loop retrying forever. The function's own doc comment already stated the required semantics; only the aggregate missed them.
actual_length is now the running total of the per-packet actuals, which is unchanged for IN (where it equals the buffer) and correct for OUT. to_bytes()'s debug_assert encoded the same wrong rule for ISO and now checks the kernel's invariant directly, against the descriptor table.
The OUT unit test asserted actual_length == 0 - it had locked in the bug, conflating 'sends no payload back' with 'consumed nothing'. It now pins the real invariant, sum(table actual_length) == actual_length.
Not yet re-tested on hardware.