USB Port Mapping For Full Speed USB 3.0
Recently I had to transfer some files between computers and I noticed that, although all of my USB 3.0 ports were functional, they all capped out at around 25-30MB/s. This was confirmed with a few different SanDisk EXtreme USB 3.0 external flash drives and an external Western Digital USB 3.0 SSD hard drive. The same external drives would consistently transfer upwards of 100MB/s on my Macbook Pro - so I knew there was something going on with the Hackintosh's USB 3.0 ports. It was because of this that I decided to start looking into the whole "Custom SSDT/USBMap.kext" thing.
After seeing many different forum posts and methods for generating a custom SSDT/USBMap.kext files, I realized why it seems so confusing - practically none of these threads were written clear enough to work for me. Before I go on, here's the most simple way I can explain what this whole SSDT/USBMap.kext thing is for (as far as I understand it LOL):
When building a current Hackintosh, part of the MacOS installation involves using the "USBInjectAll.kext" and a USB Port Limit Patch together to get the actual physical USB ports working. Apparently this is because since the last OSX (El Capitan 10.11.x), Apple implemented a 15 USB port limit in the operating system itself. The USBInjectAll.kext and Port Limit Patch allows MacOS to "see" every physical USB port in the hardware side, but on the software side (the actual OS) you're still limited to no more than 15 USB ports that will actually work.
"No problem - the z370N WiFi only has a total of 9 USB ports, so we're good!" ...but not really. Using my build as an example, I have 6 USB 3.0's in the rear I/O, 2 USB 3.0's on the front case plugged into the internal 3.0 internal header, 1 USB port plugged into the internal 2.0 header, and 1 USB-C port. That's a total of 10 physical USB ports... but MacOS "sees" many more. Each USB 3.0 physical port actually counts as TWO USB ports in MacOS (more on this later).
Why This Becomes A Long Term Problem
When you first boot up a new Hackintosh build, chances are at that time you'll only have a mouse, keyboard, and USB flash drive installer plugged into the system - so the USB's might seem all good to go, but in reality it's not. To see for yourself why this is an issue, try plugging in a different USB device into every physical USB port you have:
Issue 1: Some devices will work, some won't, some might work at first then stop working when you plug something else into a different USB port. Worse, if you restart your Hackintosh, the USB ports that worked before the restart might not work after the restart.
Issue 2: MacOS updates might/will eventually break the USB Port Limit Patch. As seen when going from Mojave 10.14.1 to 10.14.2, the USB Port Limit Patch had to be figured out and then subsequently changed/updated in order to get USB ports working again. 10.14.3 didn't need an update, but it might break again in a future update.
Issue 3: Some USB 3.0 physical ports might be operating at USB 3.0 speed or only at USB 2.0 speed. And after a restart that might change randomly (see Problem #1 above).
This is why although having USBInjectAll.kext and the USB Port Limit Patch during install helps get things rolling, but relying on them for long-term use and optimized functionality/speed is very inconsistent and not a real solution to the problem.
What's The Real Solution Then?
The actual solution is to specifically tell MacOS to only use specific USB ports of your choosing (within the 15 port limit) for reliable and consistent USB functionality along with the correct USB speeds based on the type of USB port. This is where having a custom SSDT file or a USBMap.kext file comes into the picture. As I understand it, both methods essentially do the same thing (tell MacOS what port to always use and at the correct speed) but via different means. At first I looked into creating a custom SSDT file, but to be honest I found it a little complicated. Later during research I came across
corpnewt's USBMap script which helps you create your own USBMap/kext file.
The Procedure
1. The first requirement was to have "USBInjectAll.kext" in the "EFI —> CLOVER —> kexts —> Other folder" - which I already had. Next, I needed to add some entries in my config.plist file:
Acpi —> Patches —> add
“change EHC1 to EH01”
Acpi —> Patches —> add
“change EHC2 to EH02”
Acpi —> Patches —> add
“change XHCI to XHC”
Acpi —> Patches —> add
“change XHC1 to XHC”
2. After a reboot, I ran the USBMap script using Terminal, and take a look at all of the ports it detected:
Pay attention to the "HS" and "SS" ports. The "HS" ports are USB 2.0, and the matching "SS" ports are USB 3.0. Remember how I said that E
ach USB 3.0 physical port actually counts as TWO USB ports in MacOS? this is where that becomes important - since a physical USB 3.0 port can accept both USB 2.0 and USB 3.0 devices, that single physical USB port counts as TWO USB ports in MacOS.
So back to the image above: if you count every "HS", "SS", and "USR" port shown, the total comes out to
TWENTY-FOUR! Way higher than the maximum 15 allowed in MacOS. No problem - realistically I only really need the USB-C port and a total of 5 physical USB Type-A ports to work:
1x Rear USB-C port for my External HDD
2x Rear USB 2.0 ports for my Webcam and DJ Controller
2x Front Case USB 2.0/3.0 ports for quick access
1x Internal USB 2.0 port for my Logitech keyboard/mouse receiver
3. Using the USBMap script, I configured every USB port detected, keeping the ports I needed and disabling the ports I don't use:
Note that there are a total of 9 ports enabled:
- The rear USB-C port is at USB 3.0 full speed already
- The rear center USB ports are limited to USB 2.0 (both devices being used are 2.0)
- The two front panel USB ports are both USB 2.0 and 3.0
- The internal USB 2.0 port is (obviously) only set to 2.0 speed
- I kept "HS10" enabled, but I suspect that I might not need it (?)
Aside from configuring each kept port to the right speed needed, I also disabled the bank of 4 USB ports on the rear I/O of the Z370n since I don't need them, and I have the two front case ports if I do need to plug some other device into the system.
4. With all of my USB ports configured, I then had USBMap generate my custom "USBMap.kext" file.
5. I moved my custom "USBMap.kext" file into my "EFI —> CLOVER —> kexts —> Other" folder; this is the new file that my system will use to only enable the USB ports I specified (and their speeds) and ignore all of the other USB ports that were previously detected in the USBMap script.
6. Finally, I deleted "USBInjectAll.kext" from the "Other" folder AND deleted the USB port Limit Patch from my config.plist file, which is found in the "Kernel and Kext Patches -> KextstoPatch" tab.
One more reboot to finalize everything and success!
Conclusion and Final Thoughts
So at the end of all this, I now have all USB 3.0 ports showing 60-100MB/s transfer rate (tested by using a few different USB 3.0 flash drives and external hard drives). I also noticed that my Logitech bluetooth mouse and keyboard seem to be "snappier", with no response lag or random hesitations - whether this is a result of the USBMap.kext is up to debate, but it's something I noticed anyways.
Considering I went with the .kext method, the build is still a "Vanilla" build. Before doing this I experimented with installing mexts into L/E/ but that wasn't fixing the USB 3.0 speed issue. However with the USBMap.kext residing in my EFI folder, MacOS itself is still untouched, and any future MacOS 10.14.x updates won't affect my USB port mapping. Also, since I have the USBMap.kext file I don't have to deal with future port limit patching. Whether this holds up when we eventually get to MacOS 10.15 is yet to be seen, but for now I'm covered, even if somehow I have to do a clean reinstall of MacOS.
Quick thanks to
@Edhawk for some advice/guidance when I first started looking into doing this.
Next up, I'm planning on dual-booting my Hackintosh with macOS and Windows 10.