I recently purchased the dead cheap Sabrent USB 3 Hub for 11.99€ not expecting much. I was really just after a replacement for my DIY usb interruptor (that still does the job) and I was already laughing at the claimed USB 3 support when I bagged this. I do have some USB 2 HID devices that I only need for gaming and do not want powered up (and wasting plugs) on my computer all the time. This is the sole use case for the purchase and it did claim to have Linux support – which usually means that the xhci_hcd kernel driver recognizes the device as something usable.

tl;dr: Do not use for disks or power hungry devices to prevent data loss.

So I really wasn’t expecting much when I pried the device open. There are not even screws (but it’s not glued, too – bonus?).

Opened Sabrent USB 3.0 Hub

So the first things I noticed is an unused power connector (marked with 6.1V?) and an attached usb cable that looks like it was melted on the pin connector. Yuk. There is no stress relaxation for the cable. It just looks like there is one but the plastic piece in question can freely slide around the cable. Better don’t pull that.

I’m not sure why there is a power connector by the way. This is a completely passive hub and I didn’t feel lucky to try this without further examinations on the circuit.

Backside of the hub

The backside is more tidy but I can spot at least two soldering points for a button that may be cold already. Too be fair it’s the backside so this may not be an issue and only affect stability of the button.

The reason I pried this open is basically that I didn’t expect this to really have USB 3 capabilities at all so I wanted to check that they didn’t just use “blue” ports. I’ve been burnt by this before. Everything looks to be in order though and the datasheet for the built in VL815-Q7 by VIA Labs, Inc. (VLI) does indeed list the chip to be capable of USB 3. VLI describes it as a “USB 3.1 Gen 1 4-Port Hub Controller” and it is known to work “under Windows, Mac OS X, and various Linux kernels without additional drivers” . So let’s plug it in:

[ 1707.347836] usb 2-5: new SuperSpeed Gen 1 USB device number 8 using xhci_hcd
[ 1707.387594] usb 2-5: New USB device found, idVendor=2109, idProduct=0815, bcdDevice= 7.04
[ 1707.387599] usb 2-5: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 1707.387601] usb 2-5: Product: USB3.0 Hub             
[ 1707.387602] usb 2-5: Manufacturer: VIA Labs, Inc. 

Shiny. That was easy. Let’s ask lsusb -t

/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/10p, 5000M
    |__ Port 5: Dev 8, If 0, Class=Hub, Driver=hub/4p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M
    |__ Port 5: Dev 12, If 0, Class=Hub, Driver=hub/4p, 480M

And sure enough it claims to be up for the task of both, USB2 and USB3 indicated by the 480M and 5000M. So let’s plug an USB3 mass storage device and check some readouts (no write tests made because I had no empty usb3 stick around). I used the good old dd command for all: dd if=/dev/sde2 of=/dev/null bs=4k

Connected to the hub:

3727616+0 records in
3727616+0 records out
15268315136 bytes (15 GB, 14 GiB) copied, 190.052 s, 80.3 MB/s

Connected to the motherboard directly:

3727616+0 records in
3727616+0 records out
15268315136 bytes (15 GB, 14 GiB) copied, 188.997 s, 80.8 MB/s

Connected to the computer case ports on the front:

3727616+0 records in
3727616+0 records out
15268315136 bytes (15 GB, 14 GiB) copied, 188.327 s, 81.1 MB/s

So while this is not stellar it definitely is not just USB 2 speeds and probably limited by the USB stick itself, since I get similar readings on all ports. Speed wise it’s at least not in the way or limiting the device and my use case are joysticks, gamepads and maybe a gaming keyboard. Nothing that would require such speed anyway.

But.

During my first tests I played around with the power button for an empty outlet and I really didn’t expect this to affect other outlets but it does. It looks like the power breaks down shortly and the error log is filled with I/O errors for the mass storage device.

[ 1706.292620] usb 2-5.4: Failed to set U1 timeout to 0x0,error code -19
[ 1706.296089] usb 2-5.4: Set SEL for device-initiated U1 failed.
[ 1706.299672] usb 2-5.4: Set SEL for device-initiated U2 failed.
[ 1706.299680] usb 2-5.4: usb_reset_and_verify_device Failed to disable LPM
[ 1706.339639] blk_update_request: I/O error, dev sde, sector 2468080 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
[ 1706.339641] Buffer I/O error on dev sde2, logical block 247326, async page read
[ 1706.395683] sde: detected capacity change from 30310400 to 0

This will result in data loss during write operations. While this is not a problem for HID devices, I mean who cares if a click doesn’t make it, one should definitely not use this for disks or at least not touch it while it’s writing until it’s indeed “save to unplug the device now”.

Also it must be kept in mind that this is a passive hub. USB 3.0 is specified with 5V and 900mAh. This does not magically multiply for this model – it’s 900mAh _total_ for all 4 plugs and to be fair that is clearly stated in it’s description.

It does suck that it may be fine speed wise but does exactly the one thing I bought it for poorly: Disable one and only one plug at will. Keeping this in mind it does (surprisingly) work as advertised.

Oh yeah, and don’t watch out for a CE sign on that one xD

I love gaming over multiple monitors. It’s my current choice for work and games – especially simulations. Having several monitors attached to one computer (or graphic card) is not a big deal in 2021 any more. The framebuffer in recent graphic cards is insanely huge compared to some years ago, when one really had to think twice about the possible resolution when e.g. connecting a beamer to a laptop (good old SiS 630 anyone?).

xfce4-display-settings for my refurbished “new” set of displays

This couldn’t be easier nowadays. Even mixing the integrated graphic card of a recent Intel CPU with an NVIDIA or AMD dedicated graphic card does usually “just work”. Some driver specific mode may have to be set but that’s it. The workspace easily expands over multiple displays and windows can be moved around freely.

Games do not see one huge desktop but individual displays

There is however a catch. Games tend to read the primary display only and the maximum resolution offered usually comes with the readout of this very first display – or worse – the first display connected. This sucks especially when the monitors have different resolutions, as it was the case for me for several years now, because I didn’t just purchase a set but collected discarded monitors over the time. This can often be omitted by temporary disabling the “false” ones or by force window mode.

This results in hacky scripts involving xrandr, wmctrl and xdotool. This is for example how I hammered X4: Foundations into shape _after_ it started, because it would allow me to select a single display only. Set to window mode it can be freely scaled but that comes with a disturbing window decorations so with this the X4 window gets positioned to 0x0, expanded to 5770×1210 and the window decorations purged:

xdotool search --class "X4" windowmove --sync %@ 0 0 windowsize %@ 5770 1210 set_window --overrideredirect 1 %@
X4: Foundations on Extreme Multihead

That’s a pain to find out and the fun really stops when it comes to Proton or some games that would not allow resizing over their maximum detected resolution – like for example Everspace.

How about a virtual monitor?

So the idea was to introduce a completely virtual monitor to the systems with the resolution of choice. VNC servers do that all the time so it must be possible. The usual approach won’t work in this case though: When loading the dummy driver the real displays can usually no longer be used and the drivers for AMD and NVIDIA do not really offer such a feature at all.

It is perfectly possible to define virtual monitors with a recent xrand but they have to be mapped on an existing output (a real port). One can use an unused port (as in: no monitor connected) for this, add a Modeline and even force it as “online” like so: echo on > /sys/kernel/debug/dri/0/HDMI-A-1/force

I was delighted to see the display showing up briefly but the AMD driver made short work of my soaring hopes by forcing it off again in an instant. So close and yet so far. This would require some hardware hacking by creating a dummy plug for the port. That’s basically some resistors in the right place making the computer think a display is connected. I hear they can also be purchased and this may be a way for others.

Others seem to have had success by compiling the experimental DisplayLink driver that seems to offer (virtual) monitors but I really didn’t feel like fiddling with something even more alien that will probably break on the next kernel update again.

Intel to my aid!

The success for me was in the end to use of the Intel driver and it’s VirtualHeads feature. The caveat is that one probably needs an Intel CPU for this to work and has to create a X11 config file. If this is done without adding the usual driver people will experience black screens on reboot only. This may be a show stopper for inexperienced Linux users who don’t know how to recover from a broken X11 config (yet :D). For me this is an amdgpu so my file /etc/X11/xorg.conf.d/20-intel-virtual-and-amd.conf has to look like this:

Section "Device"
       Identifier "amdgpu0"
       Driver "amdgpu"
Endsection

Section "Device"
       Identifier "IntelVirtual0"
       Driver     "intel"
       Option     "VirtualHeads" "1" 
EndSection

Triple check that your driver is used in there instead or you will end up with a broken config without the possibility to log in to a graphical window manager. When in doubt start e.g. a new session to your liking on the next display server where you can switch back with the key combination ctrl+alt+F[1-0]: startx /usr/bin/startxfce4 :2

Once started a new provider shows up and the new output “VIRTUAL1” is available: xrandr --listproviders

Providers: number : 2
Provider 0: id: 0x59 cap: 0xf, Source Output, Sink Output, Source Offload, Sink Offload crtcs: 6 outputs: 4 associated providers: 1 name:AMD Radeon RX 5600 XT @ pci:0000:03:00.0
Provider 1: id: 0x9e cap: 0xb, Source Output, Sink Output, Sink Offload crtcs: 5 outputs: 4 associated providers: 1 name:Intel

Configuring the virtual monitor with xrandr

Now that we have a virtual monitor we need a Modeline for it. This is usually the current screen (of the framebuffer) and can be calculated (e.g. sum of all monitors x height and Hz of one monitor) or by asking the system: xrandr | grep Screen

gtf (or cvt) helps obtaining the Modeline: gtf 5760 1200 60

  # 5760x1200 @ 60.00 Hz (GTF) hsync: 74.52 kHz; pclk: 579.47 MHz
  Modeline "5760x1200_60.00"  579.47  5760 6144 6768 7776  1200 1201 1204 1242  -HSync +Vsync

Now all information needed to finally set up the virtual display is there. I’m creating the virtual display on top of the three real displays because I also want to see what’s drawn on it. That’s not strictly required though and in fact most graphical tools to configure the monitor location will even refuse this – because this use case is simply not considered or supported. Gnome for example really didn’t like this. XFCE4 didn’t care. Ymmv:

xrandr --newmode "5760x1200_60.00"  579.47  5760 6144 6768 7776  1200 1201 1204 1242  -HSync +Vsync
xrandr --addmode VIRTUAL1 "5760x1200_60.00"
xrandr --setmonitor Virtual 5760/1554x1200/324+0+0 VIRTUAL1 
xrandr --output VIRTUAL1 --mode "5760x1200_60.00" --pos 0x0 --primary

It’s done.

The virtual monitor becomes visible in display settings (xfce4-display-settings here)

And it works!

After a lot of research and fiddling (and breaking my X config several times) I finally found a working solution. Games let me select the virtual monitor or see at least my primary with my “maximum” resolution. Sometimes this still requires window mode but I could care less – the decorations are optional. And it works like a charm! Here is a small selection of the games I play most at the moment:

This is how my set-up looks:

Now I’ve another problem. With this my usual 1080p gaming resolution is no longer and my graphic card is simply not up for the job any more 🤣

At least gaming itself is easy as pie on Linux in 2021. Complex display set-ups? Not so much.