Enabling both USB 3 and USB 2 ports for the ‘Gigabyte’ GA-970A-DS3P motherboard
The short version: With default BIOS settings (which enable USB 3 ports) for the Gigabyte GA-970A-DS3P motherboard, the USB 2 ports do not work (at least in Linux), only the two external USB 3 ports. In Linux, the GRUB configuration parameter “GRUB_CMDLINE_LINUX” must contain “iommu=soft” to get the USB 2 ports and USB 3 ports to work at the same time.
This blog post is essentially the seminal 2013 forum post “GA-970A-DS3P revision 1 no USB 3.0“, but this provides one data point that the solution with “iommu=soft” actually works (and is required) for a particular BIOS version and works (and is required) for a particular version of a particular Linux distribution of vintage 2020. For instance, later versions of a Linux distribution, say Ubuntu (or later updates to a particular version), may break the solution. And hopefully this blog post has clearer instructions with some additional checks to be confident in the solution.
It also shows that even in 2022, with the mainstream Ubuntu 22.04, the Linux community has still not solved the problem. This is ridiculous.
(Note: The motherboard is not to be confused with GA-970A-D3P (without “S”) which, for instance, has screen display output connectors (for HDMI, etc.), but fewer USB ports)
Introduction
With default settings in the BIOS and in Linux, the USB 2 ports on the GA-970A-DS3P motherboard do not work out of the box. With a USB hub on one of the USB 3 ports, the system nominally works fine, but there are six direct USB ports that can not be used (e.g., for keyboards and mice). For instance, this prevents using the workaround of using a USB 2 port instead of a USB 3 port for making macro keys on a QMK keyboard function properly.
It has nothing to do with the BIOS version
The motherboard used to test this on already had the latest version (FD, released 2016-05-02).
It has nothing to do with hardware
E.g., broken hardware. Some Internet searches will return such suggestions. Changing the BIOS setting “IOMMU” in menu “Peripherals” to “Enabled” will enable the USB 2 ports, and they work just fine (but the USB 3 ports will not work then). Thus this problem has nothing to do with broken hardware.
Internet searches
It is not easy to come up with search terms that will not result in near 100% false positives, even using the very specific name of the motherboard (GA-970A-D3P). However, these search terms in combination turned out to be very effective:
IOMMU enable USB 2 ports
Linux version
Both distribution and kernel version.
Identifying the kernel version
In a terminal, on a Ubuntu/Debian derived system:
cat /proc/version_signature
Alternatively, this may be more widely applicable, not just for Ubuntu:
hostnamectl
It also outputs the name of Linux distribution and its version.
Identifying the distribution, incl. version
In a terminal, on a Ubuntu/Debian derived system:
lsb_release -a
On Fedora:
cat /etc/fedora-release
Results
These systems were found to exhibit the problem and the fix described here worked:
- Ubuntu MATE 20.04 (Focal Fossa). Kernel version: 5.4.0-121.137-generic. Underlying distribution and version: Ubuntu 20.04.4 LTS. Released May 2020.
- Ubuntu 22.04 (Jammy Jellyfish). Kernel version: 5.15.0-41-generic. Underlying distribution and version: Ubuntu 20.04.4 LTS. Released 2022-04-21.
These systems were found to work without needing the fix described here. In other words, the USB 2 ports worked out of the box (and thus in effect in Linux):
- Fedora 36 KDE Plasma. Released 2022-05-02. It is not known if it is due to it being newer or quite different from Ubuntu or Debian. Kernel version: 6.2.15 (originally 6.1.13)
- Fedora 41 Cinnamon “spin”. Released 2024-11-29. Kernel version 6.12.11-200.fc41.x86_64 (originally 6.11.4-301.fc41.x86_64). Cinnamon version: 6.2.9
The fix
This is essentially the mentioned forum post, but here are more direct instructions, e.g., to be confident that GRUB is actually used on a particular system.
The fix is to add “iommu=soft”, though an explanation for why and how is lacking. The closest I have found is this 2016 bug report that has some internal details: Enabling AMD IOMMU blocks function of Via VL805 USB 3.0 chipset
However, GRUB is sort of hidden in contemporary Linux distributions. Often, nothing is shown during startup. The screen is simply blank until the Linux GUI environment comes up.
Updating the GRUB configuration
Use this procedure to change any of the GRUB configuration settings mentioned below. In a terminal, do:
ls -ls /etc/default/grub sudo vi /etc/default/grub sudo update-grub
The second line assumes proficiency in using vi or Vim (including quitting it…). If not, use some other editor, like Geany. But it must be run with administrator privileges (in order to make changes to file /etc/default/grub), and this may change an application’s normal behaviour… (Because it is run as another user.)
On Fedora, use this instead of “sudo update-grub”:
sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
Or in later versions (e.g., in Fedora 34 (released 2021-04-27) and later):
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
The first line is testing the existence of the GRUB configuration file. It should return something like:
4 -rw-r--r-- 1 root root 1228 Jul 13 18:51 /etc/default/grub
If not, the result is:
ls: cannot access '/etc/default/grub': No such file or directory
The last step (third line) is crucial; otherwise the GRUB behaviour does not change at all…
Prerequisites for the fix
Optional: Change the BIOS configuration to show a full splash screen (this will display more keyboard shortcuts). Press ‘Del’ about once per second after the beep (it will not react until a few seconds after the beep and ‘Del’ should not be pressed too late). In menu “BIOS Features”, change “Full Screen LOGO Show” to “Enabled”. In menu “Save & Exit” (right-most menu), choose “Save & Exit Setup” and “Yes” (the default).
The first question is if GRUB used or not on a particular system. Using the procedure from the previous section (including “sudo update-grub”!), uncomment (by removing the leading “#”) the line with “GRUB_INIT_TUNE”, so that the line reads:
GRUB_INIT_TUNE="480 440 1"
Or a Pac-Man theme (credit. Test it online. Some more to choose from. And even more.):
GRUB_INIT_TUNE="2000 494 3 0 2 988 3 740 3 0 2 588 3 988 3 740 3 0 2 588 3 0 2 123 3 523 3 0 2 1047 3 784 3 0 2 659 3 1047 3 784 3 0 2 659 3 0 2 131 3 494 3 0 2 988 3 740 3 0 2 588 3 988 3 740 3 0 2 588 3 0 2 123 2 588 2 659 2 698 2 698 2 740 2 784 2 784 2 831 2 880 2 988 2"
Restart the computer. There should be two beeps: One is when the BIOS is ready shortly after power on. I observed it 8-9 seconds after power on. The second beep came about 7 seconds after the first beep (indicating entering the GRUB part of the startup process).
Note: Even if the hardware is capable of making the beep (and it works perfectly fine in LMDE and Ubuntu), it may not work for Fedora GRUB (on the exact same hardware). It isn’t clear what the reason is (for instance, it could be something decided at compile time for GRUB, or it could be the configuration, e.g., some GRUB modules that aren’t included (by default), like ‘play.mod’).
Optional: Enable the GRUB startup menu. This is to be more confident that GRUB is actually used (allegedly, as an alternative, the Shift key can be held down while booting to make the menu show). Comment out (add a leading “#”) to the line with “GRUB_TIMEOUT_STYLE” in file “/etc/default/grub”, so the line reads:
#GRUB_TIMEOUT_STYLE=hidden
Note: In later versions of GRUB, or at least in the default configuration file, this is not available.
Optional: Shorten the time the GRUB startup menu is shown (it is usually set to 10 seconds). This can be done by commenting (add a leading “#”) the line with “GRUB_TIMEOUT” in file “/etc/default/grub” (this will use the default of 5 seconds) or change the “10” to a lower value. For the former, the line should read:
#GRUB_TIMEOUT=10
Optional: Change the GRUB menu entry that is chosen if the timeout period is reached. It is normally 0 for a simple setup, but for multi-boot systems it can be important (so the desired default operating system is started if nothing is chosen (times out)). Sample changing it to the third GRUB menu item:
GRUB_DEFAULT=2
To use a sub menu, double quotes must be included (second menu, fifth sub menu item in this example):
GRUB_DEFAULT="1>4"
The actual fix
To the string for “GRUB_CMDLINE_LINUX_DEFAULT” in file “/etc/default/grub”, add “iommu=soft”. The line should read something like:
GRUB_CMDLINE_LINUX_DEFAULT="splash iommu=soft"
Check
Before a restart
Check the output of sudo update-grub (Ubuntu and Debian-derived). For instance, in a terminal:
less /boot/grub/grub.cfg
On some systems, ‘sudo’ is required:
sudo less /boot/grub/grub.cfg
Look near “menuentry ‘Ubuntu’” (without the outer double quotes, but including the single quotes (note: as rendered on this page, it will not work if copy-pasted, due to the smart quotes; type it as the ASCII single quotes). Not indented).
After a restart
/proc/cmdline should now contain iommu=soft. For example, in a terminal,
cat /proc/cmdline
outputs something like (here, scroll right to see iommu=soft):
BOOT_IMAGE=/boot/vmlinuz-5.19.0-35-generic root=UUID=f43558c5-501a-4483-a223-a56b222f8004 ro splash iommu=soft vt.handoff=7
If not, one reason is if booting this Linux instance from another Linux instance’s GRUB menu. This Linux instance should be started directly from the BIOS. If it isn’t the default in the BIOS, then break into the BIOS (F2 a few seconds after the first beep) and select this Linux instance to start.
Blues
Was it broken in later versions of Ubuntu 22.04?
A later system update of Ubuntu 22.04, to approximately Linux kernel version 5.19.0-32 (or later) seems to have broken the fix described here. One mitigation is to force Ubuntu 22.04 to stay on the LTS kernel (Linux version 5.15 series, for example, 5.15.0-67.74):
sudo apt install --install-recommends linux-generic
And change the default menu item setup in file “/etc/default/grub” (GRUB will always select the kernel with the highest version number, not the one we are booted up as). For example, if the second menu, fifth sub menu item, happens to correspond to the 5.15 version, make it the default menu item by (the double quotes are crucial):
GRUB_DEFAULT="1>4"
This is the official way of doing it, but it is not very natural to have a (default) selection down in a sub menu that the user can’t see unless the user opens the sub menu (and the user only has 5 seconds to stop the GRUB countdown timer during boot).
A more natural way would be to rename “/etc/grub.d/40_custom” to “/etc/grub.d/00_custom” (so it will contribute to the very first menu item by being first in the alphabetic order of the files) and copy the sub menu item into that file. But this then requires manual maintenance when the kernel is updated. Or perhaps this part could be automated with a script (updating file “/etc/grub.d/40_custom”).
Some Linux variants may ignore the content of /etc/default/grub
For instance, extra steps may be necessary for /etc/default/grub and grub2-mkconfig to work. See for example this blog post. For example:
“… /etc/default/grub changes no longer being included when issuing grub2-mkconfig -o /boot/grub2/grub.cfg. It seems that at least some options set there are now silently ignored. … The grub2-editenv utility is actually the recommended path to alter these variables.”
BIOS setting for enabling USB 2 ports
It is possible to enable the USB 2 ports by a BIOS setting alone, but then the USB 3 ports don’t work (in Linux)…
Enabling the setting “IOMMU” in menu “Peripherals” will enable them (though it is probably due to an incidental effect).
But changing BIOS settings is not necessary if the above changes to GRUB have been made.
Conclusion
Even though this problem was identified in 2013 with a fairly mainstream and popular motherboard (presumably a particular popular chipset), nine years later in 2022 the Linux community still has not fixed the problem, so that Linux would work out of the box without the requirement for the fix described here.
This is very, very disappointing. They ought to make things work, instead of the minutia of how some window manager works slightly different than some other window manager.
Appendix A
Related to the GRUB configuration changes: Identify if a system is BIOS or UEFI (from GRUB 2 “discover what firmware your machine uses”):
[ -d /sys/firmware/efi ] && echo UEFI || echo BIOS
Note: Despite the confusing naming, this setting is dependent on content of the disks, not the actual BIOS. A system can have one disk using UEFI and another using BIOS.
Thank you for this, I have a Gigabyte 970a-D3P and only the front and 2 back USB’s were working. Now with this, really easy to follow explanation, they all work!!! Much appriciated. I did not change my Grub beep on boot, I just modified the grub with the “=soft” and wala!