Unexpected USB bus resets on steering wheel while streaming

I am a very happy user of VirtualHere. My setup is as follows:

  • VirtualHere server: Raspberry Pi 4B 8GB RAM, running vhusbdarm (generic build) release 4.7.3 on a 32-bit Raspbian GNU/Linux 11 (bullseye), with 64-bit enabled kernel (boot parameter arm_64bit=1)
  • Network: Gigabit Ethernet copper network (with a switch in between)
  • VirtualHere client: Intel Core i7 6700 32GB RAM with an Nvidia GeForce RTX3060, running vhui64 release 5.8.2 on a Windows 10 64-bit with the latest updates applied

Unfortunately, in the following condition I am experiencing random yet frequent (once every minute or so) resets of the USB bus:

  • the following devices physically attached to the VH server:
    • a PXN V9 steering wheel (with pedals and gear shift), which is used by the VirtualHere client
    • a wireless Logitech K400 Plus keyboard+touchpad, acting as a local input device only (i.e., no relationships with VirtualHere)
  • streaming from the Windows host to the Raspberry using Sunshine and Moonlight, at a preset bitrate of 40Mbps and a resolution of 2560x1440, 60 FPS (the Sunshine server has the same resolution 2560x1440@60, whereas the HDMI output of the Moonlight client is set at 3840x2160@60)
  • playing Euro Truck Simulator 2

In short:
╔══════════════╗                            ╔══════════════╗
║  Moonlight   ║         streaming          ║   Sunshine   ║
║   client   ←─╫────────────────────────────╫─── server    ║
║              ║                            ║              ║
║   RASPBERRY  ║                            ║   WINDOWS    ║
║              ║                            ║              ║
║  VirtualHere ║        USB over IP         ║  VirtualHere ║
║  server   ┌──╫────────────────────────────╫→ client      ║
╚═══╤═══════╪══╝                            ╚══════════════╝
    │       │                                               
 K800      PXN                                              
keyboard    V9                                              
          wheel                                             


What I see is:

  • the wheel becomes unresponsive for a short while (usually 1-2 seconds) then resurrects, causing unwelcome sudden turns in the game
  • the wheel status LED blinks shortly, indicating a hardware reset happening
  • the Raspberry kernel (VirtualHere server) logs messages similar to the following:
    usb 1-1.2.2: reset full-speed USB device number 28 using xhci_hcd
  • every other devices keep being responsive

(Mostly) ruled out issues:

  • power: the steering wheel is attached to a USB hub with an external power supply; the hub itself never seems to reset
  • single-TT vs. multi-TT USB hubs, as extensively discussed here and here: the wheel is the sole and only USB device connected to the USB hub, which I assume to be enough to avoid protocol underruns caused by the TT bottleneck. For the sake of completeness, the wireless keyboard is directly connected to the Raspberry instead: I assume this also triggers a Transaction Translator, but this time is the Raspberry's internal one and, once again, for a single device only (the keyboard itself). To further complement the picture, a USB 3.0 flash drive is also connected directly to the Raspberry; it does not perform any (intentional) transfers during the session and I guess it does not involve any TTs
  • CPU contention: CPU usage never exceeds 35% on the Raspberry (VirtualHere client) in the aforementioned scenario; usage is of course higher on the Windows machine (VirtualHere server), but never saturates. Setting the nice priority of vhusbdarm on the Raspberry to an exceptionally high value (-20), as well as setting the priority of vhui64 on the Windows machine to an equally high value (Very High) does not help; similar arguments have been described in this topic
  • USB resets caused by events that are local to the Raspberry: configuring the onReset event handler on the VirtualHere server (Raspberry) to ignore reset events received from the VirtualHere client changes the logged kernel events to:
    Executed "" for onReset
    In this condition the steering wheel never resets (i.e., its LED never blinks), thus confirming that resets are not originated by the Raspberry, but still it loses its function for the mentioned time window (1-2 seconds).

Additional context information:

  • as many other similar devices, the wheel presents itself as a full-speed 12Mbps device
    • it exposes 3 interfaces on a single USB port: a joystick, a keyboard and a mouse; I am not really sure about the impact in terms of consumed resources (bandwidth), but I suspect that it just accounts for a single 12Mbps device
  • audio/video streaming (Sunshine/Moonlight) never glitches
  • auto-find is disabled client-side: the server's (Raspberry) IP address is statically configured instead
  • the latency recorded by the VirtualHere client is steadily below 2ms; however, interestingly, it occasionally spikes close to 10ms while in-game (a similar phenomenon has been described in this topic)

Interestingly, the issue does not occur if I quit the driving session and return to the main in-game menu, which still has a complex 3D model continuously rendered in the background: the streamed scene keeps changing (so there is quite a lot of data flowing) but, if I keep the game in the background (with the 3D model still moving and consuming CPU, GPU) and I open the Game Controllers panel of Windows, the wheel does not miss a beat; VirtualHere does not record any latency spikes either, despite the scenario being substantially similar to the driving session.

So far, I am inclined to think that the steering wheel driver is very sensitive to latency fluctuations, but:

  • it is unclear why these fluctuations occur in the first place, especially given that they never happen while the main in-game menu 3D animation is rolling, despite it being equally resource (CPU, GPU, network) demanding as regular driving
  • the wheel itself does not require any specific drivers (it uses those supplied with Windows): it is its vibration function that does

Besides reducing the set of potentially latency-sensitive functions, for example by disabling the wheel vibration (which I will soon consider testing), I am not really sure how to work around this issue.
Thank you very much for reading so far.
 

#3

Thank you very much for your swift feedback.

I will consider your suggestions in the future (unfortunately, none of them is handy for me at present).

Although of limited use, I am sharing some additional findings:

  • Obviously the steering wheel works flawlessly when directly connected to the Windows PC where Euro Truck Simulator 2 is executed.
  • In an attempt to consistently replicate the issue, I have put a close to in-game resource demand on the Windows host by using MSI Kombustor, a well-known GPU stress test tool which has a CPU burn-in test built-in. Being one of the main suspects, I have then monitored network latency. Results:
    • I have broken down end-to-end latency between the Raspberry Pi and the Windows host by sending ICMP requests from a third host in between the two (the switch between the two machines, which has an IP address and several diagnosis utilities): latency was mostly ascribed to the Windows host.
    • Latency was totally unaffected by GPU usage, whereas of course it was heavily impacted by CPU usage. For this reason, the GPU stress test has always been kept running during all the tests.
    • The latency recorded by VirtualHere was steadily around 1ms without CPU load (but with both the GPU benchmark as well as the Sunshine+Moonlight streaming running).
    • The latency recorded by VirtualHere under CPU load (all its cores involved) heavily fluctuated in the range 6-15ms. Sunshine+Moonlight seemed totally unaffected.
    • Increasing the priority of the vhui64 client process on the Windows host, even to an insane value (Real Time), did not improve latency at all. As a side note, after a short while this priority often appeared to self-reset to a lower value: I was unable to motivate this.
    • I have connected both the steering wheel and the wireless keyboard in the usual way (one to the hub, the other one directly to the Raspberry), which is also suggested in the official Raspberry Pi documentation:

[...] spread full- and low-speed devices out between the Raspberry Pi’s own USB port and the single TT hub.


                         ╔═════════════════════╗             
           ┌─────────┐   ║ Raspberry Pi        ║             
 PXN V9    │ USB 2.0 │   ║                     ║             
 wheel  ───┤ single  ├───╫──(built-in USB 2.0  ║      K800   
           │ TT hub  │   ║    single TT hub)───╫─── wireless 
           └─────────┘   ║                     ║    keyboard 
                         ╚═════════════════════╝             

  •  
    • USB bus resets never happened even under CPU load and fluctuating latency: the wheel was always responsive, including vibration, as confirmed by the absence of any log messages on the Raspberry Pi (VirtualHere server) and by its responsiveness in the USB game controller settings tool.
    • In some rare cases, the Raspberry logged messages similar to the following:
      xhci_hcd 0000:01:00.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 1
      xhci_hcd 0000:01:00.0: Looking for event-dma 000000044004f000 trb-start 000000044004f500 trb-end 000000044004f500 seg-start 000000044004f000 seg-end 000000044004fff0

For a while I have been a bit confident that latency was to be blamed, but these tests seem to dispute this theory, leaving the following potential causes open:

  • subtleties in the wheel USB driver
  • the potential bug in the XHCI controller of the Pi 4B which you mentioned here and here

In order to consider the latter, I have verified the firmware currently in use:

$ sudo rpi-eeprom-update 
*** UPDATE AVAILABLE ***
BOOTLOADER: update available
   CURRENT: gio 3 set 2020, 12:11:43, UTC (1599135103)
    LATEST: mer 11 gen 2023, 17:40:52, UTC (1673458852)
   RELEASE: default (/lib/firmware/raspberrypi/bootloader/default)
            Use raspi-config to change the release.

  VL805_FW: Using bootloader EEPROM
     VL805: up to date
   CURRENT: 000138a1
    LATEST: 000138a1

Although the VL805 chipset firmware is declared to be at the latest release, I have tried to use raspi-config as suggested to switch to the latest bootloader.

This is the point I have reached so far.

#4

If you see "ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 1" that is definitely a kernel bug unfortunately. 

First update to 6.6 kernel (bookworm) when you can.

 I don't think updating the pi bootloader will fix it because as i understand, that is mostly related to the other processor (videocore) in the pi and not the actual arm64 processor or peripherals (i.e usb host controller)
 

#5

Thank you very much again Michael. Indeed my kernel is 6.1.21-v8+.

First, a quick of complement to the stress test report I have posted above setting priority of network traffic for client process vhui64.exe to Highest using the ASUS GameFirst utility did not improve latency at all: it kept being affected by CPU load alone.

Next, I have completed the EEPROM upgrade step. Since bootloader upgrades are automatically fetched, it was enough to reboot the Raspberry:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓         ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ $ sudo rpi-eeprom-update                                           ┃         ┃ $ sudo rpi-eeprom-update                                         ┃
┃ *** UPDATE AVAILABLE ***                                           ┃         ┃ BOOTLOADER: up to date                                           ┃
┃ BOOTLOADER: update available                                       ┃         ┃    CURRENT: gio 11 mag 2023, 06:26:03, UTC (1683786363)          ┃
┃    CURRENT: gio 3 set 2020, 12:11:43, UTC (1599135103)             ┣━▶︎  R  ━▶︎┫     LATEST: gio 11 mag 2023, 06:26:03, UTC (1683786363)          ┃
┃     LATEST: mer 11 gen 2023, 17:40:52, UTC (1673458852)            ┃    E    ┃    RELEASE: latest (/lib/firmware/raspberrypi/bootloader/latest) ┃
┃    RELEASE: default (/lib/firmware/raspberrypi/bootloader/default) ┣━▶︎  B  ━▶︎┫             Use raspi-config to change the release.              ┃
┃             Use raspi-config to change the release.                ┃    O    ┃   VL805_FW: Using bootloader EEPROM                              ┃
┃                                                                    ┣━▶︎  O  ━▶︎┫      VL805: up to date                                           ┃
┃   VL805_FW: Using bootloader EEPROM                                ┃    T    ┃    CURRENT: 000138c0                                             ┃
┃      VL805: up to date                                             ┃         ┃     LATEST: 000138c0                                             ┃
┃    CURRENT: 000138a1                                               ┃         ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
┃     LATEST: 000138a1                                               ┃                                                                             
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛                                                                             
 

Interestingly, the VIA VL805 USB host controller firmware has been updated as well. In fact, recent revisions of the Raspberry Pi 4B miss a dedicated EEPROM for the VL805, thus its firmware is directly embedded in the bootloader (see this link  and this link). I happen to own a Rev 1.4 board by the way:
$ cat /proc/cpuinfo | grep -wi rev
Model        : Raspberry Pi 4 Model B Rev 1.4
The EEPROM release notes for BCM2711, which is found on the Raspberry Pi 4, suggest that 000138c0 is the latest available VL805 firmware at the time of writing. Changes introduced by this release are discussed here. Although they are not necessarily relevant for the issue under consideration, they looked promising, so additional tests followed.

  • Several test rounds confirmed that ERROR Transfer event TRB DMA messages only occurred at the time of starting/stopping streaming using the Moonlight client on the Raspberry: they never occurred during or outside the streaming session and they were never correlated with USB bus resets. In other words, such messages were never followed by USB resets and never followed resets either. There are reports around concerning this kind of error, like this one and this one, but I couldn't find any specifically addressing the Raspberry Pi and/or the VL805 chipset.
  • Thinking of a potential conflict (i.e., USB bus contention) between VirtualHere and remote controller functions implemented in Moonlight, I have tried to set option ClaimPorts=1 on the VirtualHere server. No changes: USB resets continued to happen.
  • Since USB resets often occurred in-game when steering along curves (therefore with a stronger vibration feedback), I have tried to disable any force feedbacks in Euro Truck Simulator 2, but this did not help either: USB resets continued to happen as usual.
    Let me remind that the steering wheel power budget has never been an issue: all reset events have always been explicitly logged by VirtualHere when the onReset= trigger was set, so they have never been originated by the Raspberry Pi hardware.
  • Finally, some observations on the reset pattern:
    • Although I could not easily reproduce it, the first USB reset usually never occurred before a few minutes since starting the Moonlight+Sunshine streaming, and corresponding gaming session. The cause for this (apparent) delay has never been thermal throttling, as the Raspberry never exceeded 60° even during the streaming session.
    • USB resets occurred mostly in bursts: usually in pairs, but sometimes 4 in a row. As an example:
             feb 02 18:53:00 hostname vhusbdarm[14138]: Executed "" for onReset
             feb 02 18:53:00 hostname vhusbdarm[14138]: Executed "" for onReset
             feb 02 18:53:00 hostname vhusbdarm[14138]: Executed "" for onReset
             feb 02 18:53:01 hostname vhusbdarm[14138]: Executed "" for onReset
      Although the steering wheel indeed exposes multiple "devices", I could not find a reasonable way to match their count (3: a gamepad, a joystick and a keyboard) with the even number of resets (2 or 4) in each burst. Kernel messages were not helpful either to figure out which device(s) incurred the reset (I know: I could have removed the onReset handler altogether to get notified about the low level bus resets, but I didn't during this test session).
    • Very interestingly, most of the times when a reset occurred, input from the wheel was frozen for a while, and input from the wireless keyboard was totally impaired as well. It was hard to detect whether this happened for each and every reset, but the impression was that the whole USB HID input subsystem temporarily failed, even if the wireless keyboard has never been adopted by VirtualHere and has always been connected to a different physical USB port on the Raspberry (without any hubs in between).

Since a USB controller firmware bug is still a possibility, I have searched a few references:

In case it is useful, here is a detailed view of the device tree during all the described tests:
   $ lsusb -tv
   /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
       ID 1d6b:0003 Linux Foundation 3.0 root hub
       |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
           ID 0781:5583 SanDisk Corp. Ultra Fit
       |__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/4p, 5000M
           ID 05e3:0626 Genesys Logic, Inc. 
   /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
       ID 1d6b:0002 Linux Foundation 2.0 root hub
       |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
           ID 2109:3431 VIA Labs, Inc. Hub
           |__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/4p, 480M
               ID 05e3:0610 Genesys Logic, Inc. Hub
               |__ Port 2: Dev 17, If 1, Class=Human Interface Device, Driver=usbhid, 12M
                   ID 2f24:0125  
               |__ Port 2: Dev 17, If 2, Class=Human Interface Device, Driver=usbhid, 12M
                   ID 2f24:0125  
               |__ Port 2: Dev 17, If 0, Class=Human Interface Device, Driver=usbhid, 12M
                   ID 2f24:0125  
           |__ Port 4: Dev 18, If 0, Class=Human Interface Device, Driver=usbhid, 12M
               ID 046d:c52b Logitech, Inc. Unifying Receiver
           |__ Port 4: Dev 18, If 1, Class=Human Interface Device, Driver=usbhid, 12M
               ID 046d:c52b Logitech, Inc. Unifying Receiver
           |__ Port 4: Dev 18, If 2, Class=Human Interface Device, Driver=usbhid, 12M
               ID 046d:c52b Logitech, Inc. Unifying Receiver

Looks as if there are very few steps left that I can make before undertaking the major upgrades you have suggested (software or hardware).
 

#6

I think it is worth getting the Pi5 if you can because Pi got rid of the entire VL805 mess and made their own RP1 chip which handles everything now and its much faster and more reliable, for example every port is seperate now and doesnt share any bandwidth with the others. E.g https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf  Chapter 5. USB

#7

Not surprisingly, you were right: the issue apparently lied in the Raspberry USB controller hardware.

However, instead of taking a big leap forward by upgrading either the OS (software) or the Raspberry (hardware), I have worked it around by using the Raspberry Pi's USB-C port: besides being the official source of power, this port has USB 2.0 functions (see also the schematics) and, most importantly, its data lines are connected to a previous generation of USB controller. There are 2 main caveats for being able to use it:

  1. The USB-C port has limited capabilities:
    • Power - It does not implement the PD (Power Delivery) specification, so it is only able to accept a 5V power input; moreover, revisions of the Raspberry Pi 4 earlier than 1.2 (excluded) have been known for compatibility issues with certain cables (see this article and this article), causing power not to be properly delivered. Although these issues have been addressed by now, and the absence of any negotiation should never induce any power supplies to deliver more than 5V, care must be taken in using a power supply that delivers the expected voltage and current (see again the specifications), not more (and not less either, to prevent underpowering): ideally, the official Raspberry Pi power supply
    • Data - The Raspberry Pi 4's USB-C port is indeed connected to the USB controller used on previous models. However:
  2. When the USB-C port is taken to be used as a data port, the Raspberry needs to be powered in some other ways. Viable alternatives are:
    1. supplying power through GPIO pins: not always doable since the GPIO header may already be in use by some HATs (but a shim could in principle still be used); moreover, providing power by this method requires care because there seems to be no protection against voltage spikes (in fact, usage of a suitable power HAT is advised)
    2. supplying power via PoE, which requires a proper HAT
    3. using a USB-C splitter cable, to convey data and power from two separate lines; consider that:
      • the cable should be designed in such a way that on the split end one of the sockets is marked to accept power, whereas the other one to accept data (preferably USB 2.0-only): there are some cables around where at least one of the sockets violates this condition (e.g., they are both marked for data or one of them is meant to support an audio device)
      • multi-functional USB-C hubs are generally not usable; for example, this one is able to power the Raspberry but is not detected at all as a USB device, possibly because it uses a data interface different from USB 2.0
      • an adapter like this one may be fine, but it requires an additional USB-C to USB A cable

Finally, this is what I did:

  • obtain a USB-C splitter cable with the aforementioned properties (I have used this one)
  • connect the cable as follows:

                        Raspberry   
                         power      
                         supply     
                 ┌───┐     ⬇︎       
          Data   │   │    ┌─┐       
        (USB 2.0 │   │    │ │ Power 
         type A) └─╥─┘    └╥┘(USB-C)
                   ║       ║        
                   ║       ║Splitter
                   ╚═══╦═══╝cable   
                       ║            
                      ┌╨┐USB-C      
   ┌──────────────────┼─┼──┐        
┌──┴─┐                └─┘  │        
│ETH │ Raspberry           │        
└──┬─┘                     │        
┌──┴─┐                     │        
│USB3│                     │        
└──┬─┘                     │        
┌──┴─┐                     │        
│USB2│                     │        
└──┬─┘                     │        
   └───────────────────────┘        

  • set the Raspberry to enable the USB-C port to operate in USB host mode; this can be accomplished in two ways:
    1. by using the old dwc2 overlay: this requires appending the following line to file /boot/config.txt:
      dtoverlay=dwc2,dr_mode=host
      In principle, it should also be possible to dynamically load the dwc2 overlay using the shell command sudo dtoverlay dwc2 dr_mode=host, for immediate testing
    2. alternatively, by instructing the more recent XHCI framework to enable OTG mode: this can be achieved by appending the following line to /boot/config.txt:
      otg_mode=1

That's it. The steering wheel has never been affected by a single reset since switching to this setup, regardless of the picked driver (dwc2 or xhci) . Not even with a powered USB hub connected to the splitter.
No Rasperry powering issues either. As a side note, the splitter cable that I have used supplies power also on the USB type A socket: I suppose some care should be taken in avoiding connecting a USB hub affected by backpowering to this port: this might damage the hub and/or the Raspberry power supply (I doubt it can damage the Raspberry board itself since its USB C port should have some sort of power control circuitry).

So, here is an overview of the tested scenarios:

=== SCENARIO 1 - Failing ===

                                                   Raspberry                                                
                                                    power                                                   
                                                    supply                                                  
                                                      ⬇︎                                                    
                                                     ┌─┐                                                    
                                                     │ │ Power                                              
                                                     └╥┘(USB-C)                                             
                                                      ║                                                     
                                                      ║                                                     
                                                      ║                                                     
                Hub                                  ┌╨┐USB-C                                               
               power              ┌──────────────────┼─┼──┐                                 ┌──────────────┐
               supply          ┌──┴─┐                └─┘  │                                 │              │
                 ⬇︎            │ETH │ Raspberry           │                                 │              │
              ┌───────┐        └──┬─┘                     │                                 │  Windows 10  │
Steering ═════╡ USB 3 │   ┌───┐┌──┴─┐                     │          Network                │              │
wheel         │  hub  ╞═══╡   ││USB3├┈┈┐                  │╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍/   /╍╍╍╍╍╍╍╍╍╍╍╍│              │
              │       │   └───┘└──┬─┘ ┌┴────┐             │                                 │              │
              └───────┘   ┌───┐┌──┴─┐ │ VIA │             │                                 │              │
Wireless ═════════════════╡   ││USB2├┈┤VL805├─xhci        │                                 │              │
keyboard                  └───┘└──┬─┘ └─────┘             │                                 │              │
                                  └───────────────────────┘                                 │              │
                                              VirtualHere                                   └──────────────┘
                                                server                                        VirtualHere   
                                                                                                client      
                                               Moonlight                                                    
                                                client                                         Sunshine     
                                                                                                server      


=== SCENARIO 2 - Working ===

                                              ┌───────┐                                                     
Steering ═════════════════════════════════════╡ USB 3 │                                                     
wheel                                         │  hub  │⬅︎ Hub power supply                                  
                                              └───╥───┘                                                     
                                                  ║                                                         
                                                  ║                                                         
                                                ┌─╨─┐                                                       
                                                │   │  Raspberry                                            
                                                │   │   power                                               
                                                └───┘   supply                                              
                                                ┌───┐     ⬇︎                                                
                                         Data   │   │    ┌─┐                                                
                                       (USB 2.0 │   │    │ │ Power                                          
                                        type A) └─╥─┘    └╥┘(USB-C)                                         
                                                  ║       ║                                                 
                                                  ║       ║Splitter                                         
                                                  ╚═══╦═══╝cable                                            
                                                      ║                                                     
                                                     ┌╨┐USB-C                                               
                                  ┌──────────────────┼─┼──┐                                 ┌──────────────┐
                               ┌──┴─┐                └┬┘  │                                 │              │
                               │ETH │ Raspberry       ┊   │                                 │              │
                               └──┬─┘              ┌──┴──┐│                                 │  Windows 10  │
                          ┌───┐┌──┴─┐              │ BCM ││          Network                │              │
Wireless ═════════════════╡   ││USB3├┈┈┐           │ SoC ││╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍/   /╍╍╍╍╍╍╍╍╍╍╍╍│              │
keyboard                  └───┘└──┬─┘ ┌┴────┐      └─┬───┘│                                 │              │
                               ┌──┴─┐ │ VIA │       dwc2  │                                 │              │
                               │USB2├┈┤VL805├─xhci  driver│                                 │              │
                               └──┬─┘ └─────┘ driver      │                                 │              │
                                  └───────────────────────┘                                 │              │
                                              VirtualHere                                   └──────────────┘
                                                server                                        VirtualHere   
                                                                                                client      
                                               Moonlight                                                    
                                                client                                         Sunshine     
                                                                                                server      

Resulting USB devices layout (the root_hub on Bus 03 corresponds to the USB-C port):

/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M                   
    ID 1d6b:0002 Linux Foundation 2.0 root hub                                   
    |__ Port 1: Dev 5, If 0, Class=Hub, Driver=hub/4p, 480M                      
        ID 05e3:0610 Genesys Logic, Inc. Hub                                     
        |__ Port 1: Dev 9, If 0, Class=Human Interface Device, Driver=usbhid, 12M
            ID 2f24:0125                                                         
        |__ Port 1: Dev 9, If 1, Class=Human Interface Device, Driver=usbhid, 12M
            ID 2f24:0125                                                         
        |__ Port 1: Dev 9, If 2, Class=Human Interface Device, Driver=usbhid, 12M
            ID 2f24:0125                                                         
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M              
    ID 1d6b:0003 Linux Foundation 3.0 root hub                                   
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M       
        ID 0781:5583 SanDisk Corp. Ultra Fit                                     
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M               
    ID 1d6b:0002 Linux Foundation 2.0 root hub                                   
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M                      
        ID 2109:3431 VIA Labs, Inc. Hub                                          
        |__ Port 2: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
            ID 046d:c52b Logitech, Inc. Unifying Receiver                        
        |__ Port 2: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 12M
            ID 046d:c52b Logitech, Inc. Unifying Receiver                        
        |__ Port 2: Dev 3, If 2, Class=Human Interface Device, Driver=usbhid, 12M
            ID 046d:c52b Logitech, Inc. Unifying Receiver                        

 

=== SCENARIO 3 - Working === (only the USB-C port driver differs)

                                              ┌───────┐                                                     
Steering ═════════════════════════════════════╡ USB 3 │                                                     
wheel                                         │  hub  │⬅︎ Hub power supply                                  
                                              └───╥───┘                                                     
                                                  ║                                                         
                                                  ║                                                         
                                                ┌─╨─┐                                                       
                                                │   │  Raspberry                                            
                                                │   │   power                                               
                                                └───┘   supply                                              
                                                ┌───┐     ⬇︎                                                
                                         Data   │   │    ┌─┐                                                
                                       (USB 2.0 │   │    │ │ Power                                          
                                        type A) └─╥─┘    └╥┘(USB-C)                                         
                                                  ║       ║                                                 
                                                  ║       ║Splitter                                         
                                                  ╚═══╦═══╝cable                                            
                                                      ║                                                     
                                                     ┌╨┐USB-C                                               
                                  ┌──────────────────┼─┼──┐                                 ┌──────────────┐
                               ┌──┴─┐                └┬┘  │                                 │              │
                               │ETH │ Raspberry       ┊   │                                 │              │
                               └──┬─┘              ┌──┴──┐│                                 │  Windows 10  │
                          ┌───┐┌──┴─┐              │ BCM ││          Network                │              │
Wireless ═════════════════╡   ││USB3├┈┈┐           │ SoC ││╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍/   /╍╍╍╍╍╍╍╍╍╍╍╍│              │
keyboard                  └───┘└──┬─┘ ┌┴────┐      └─┬───┘│                                 │              │
                               ┌──┴─┐ │ VIA │        │    │                                 │              │
                               │USB2├┈┤VL805├───xhci─┘    │                                 │              │
                               └──┬─┘ └─────┘  driver     │                                 │              │
                                  └───────────────────────┘                                 │              │
                                              VirtualHere                                   └──────────────┘
                                                server                                        VirtualHere   
                                                                                                client      
                                               Moonlight                                                    
                                                client                                         Sunshine     
                                                                                                server      

Resulting USB devices layout (the root_hub on Bus 03 again corresponds to the USB-C port; I am not sure why the steering wheel driver has changed from usbhid to usbfs: I would have expected the HID layer to be visible from this output anyway):

/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 480M               
    ID 1d6b:0002 Linux Foundation 2.0 root hub                                   
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M                      
        ID 05e3:0610 Genesys Logic, Inc. Hub                                     
        |__ Port 1: Dev 5, If 0, Class=Human Interface Device, Driver=usbfs, 12M 
            ID 2f24:0125                                                         
        |__ Port 1: Dev 5, If 1, Class=Human Interface Device, Driver=usbfs, 12M 
            ID 2f24:0125                                                         
        |__ Port 1: Dev 5, If 2, Class=Human Interface Device, Driver=usbfs, 12M 
            ID 2f24:0125                                                         
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M              
    ID 1d6b:0003 Linux Foundation 3.0 root hub                                   
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M       
        ID 0781:5583 SanDisk Corp. Ultra Fit                                     
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M               
    ID 1d6b:0002 Linux Foundation 2.0 root hub                                   
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M                      
        ID 2109:3431 VIA Labs, Inc. Hub                                          
        |__ Port 2: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
            ID 046d:c52b Logitech, Inc. Unifying Receiver                        
        |__ Port 2: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 12M
            ID 046d:c52b Logitech, Inc. Unifying Receiver                        
        |__ Port 2: Dev 3, If 2, Class=Human Interface Device, Driver=usbhid, 12M
            ID 046d:c52b Logitech, Inc. Unifying Receiver                        

With this little trick your software works flawlessly even on the Raspberry Pi 4!

Thank you very much again!

#8

Thanks for the great explanation! I knew the USB-C port was connected to the usb host controller in the BCM CPU but i didnt know you could switch it to host if you wanted. Thats really good to know as well as not having to buy another pi :)