Contribute
Register

[HOW TO] USB ports map for macOS with USBToolBox

So, a couple of things.
I'll start with a bit of background. The entire reason that mapping is needed is because macOS USB kexts have a limitation of 15 so called Personalities per controller. I will use personality to describe either the 2.0 or 3.0 part of a physical USB port, as these are separate.

macOS checks three sources in the below order to create these personalities:
1. IOKit Matching of USB maps. Within /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHostPlatformProperties.kext/Contents/Info.plist (whew), there is a list of USB maps that match against a) SMBIOS/Model and b) the controller name in IOService (XHC1, EHC1, etc). Because these maps use IOKit matching, matching can be done by IONameMatch, IOPCIMatch, IOPropertyMatch, etc. Any sort of IOKit matching works here. The name of each personality will be the label given by the map. As long as one of these types of matching is being done, it doesn't matter if there are 6 or 8 or whatever number of properties. The USB maps that CorpNewt's USBMap utility and USBToolBox make in "native" mode use this mechanism as well. The below image comes from AppleUSBHotPlatformProperties.kext (Note that it only uses IONameMatch).

1675887195073.png

2. ACPI probing. ACPI can contain devices which represent USB personalities, which are nested underneath the USB controller. The USB kexts will check the _UPC method for USB type, placement, etc. The name of each personality will be the ACPI device name representing that personality.

3. Probe hardware. This one I know less about. SSDT-RHUB from the Dortania guide forces the USB kexts to fall back to hardware detection. It does this by disabling the ACPI USB hub device that contains all of the USB ports. You can tell if this is happening based on the personality names. The personality name will match a class name such as AppleUSB30XHCIPort.

This leads to some corrections that I would like to make regarding the comments above:
1) The name of each USB personality does not matter. The kexts will use the "port" property to figure out where the personality maps to in hardware. So while it may look weird if USBToolBox starts at HS04 or whatever, it is fine to leave the name as it is.

2) All USB Controllers should be mapped, including thunderbolt controllers which may only have 2-4 ports. This can help with sleep, spurious wake ups, etc.

3) Port count should be the highest "port" value that any USB personality has within that controller.

4) If using USBToolBox.kext and map (including the default map), you should not need any ACPI renames to avoid USB maps that come with macOS. You should also be able to avoid renames if you set a probe score above 0 in any "native" usb map. USBToolBox with a map will override any USB map that comes with macOS, and will attempt to force every port to work when using the default map that comes in the USBToolBox/kext release zip. This can be used during installation to have basic USB functionality. In addition, USBToolBox will disable ACPI probing, which is especially useful on problematic hardware (some Ryzen boards and 400 series Intel boards).
 
Last edited:
Thank You 1Revenger1!!, I knew I would get a coder or close with a better explanation Than what I provided.
2) All USB Controllers should be mapped, including thunderbolt controllers which may only have 2-4 ports. This can help with sleep, spurious wake ups, etc.
This then shows the limitation of Hackintool. Most of the additional faster controllers (such as Asmedia) do not show up in the tools USB section even when using the inject command so mapping with these controllers is not possible with this tool alone. However, CorpNewt, (in the MacOS only), and the USBToolbox will always show all of the controllers, and in Windows, HWinfo64 can be used to confirm all controllers that drivers have been installed for, including Thunderbolt, through the use of this application, it will show all ports from the motherboard and or PCIe slot(s).
BTW I never use sleep in any OS.
 
@dasboot5
Thanks, this is the (excellent) guide by ChrisWayg, available also on another forum, I have read it, I mean somewhere in the forum, here in tonymacx86.
 
Showing ports of third-party controllers is a good benefit with this method, and I managed to add four ports of the ASMedia controller on my motherboard. I would recommend starting from ports of third-party controllers, internal ports (including front ones), and then rear ports, as well as from USB 3.2 Gen 2 ports, USB 3.2 Gen 1 ports, and then USB 2.0 ports. When a series is finished on ‘D. Discover Ports’, go to mark them on ‘S. Select Ports and Build Kext’, and go back for the other series. This procedure could reduce confusion efficiently.
 
1) The name of each USB personality does not matter. The kexts will use the "port" property to figure out where the personality maps to in hardware. So while it may look weird if USBToolBox starts at HS04 or whatever, it is fine to leave the name as it is.

2) All USB Controllers should be mapped, including thunderbolt controllers which may only have 2-4 ports. This can help with sleep, spurious wake ups, etc.
So questions: If you have only two controller chips (one Intel for main USB 3.0,3.1 and 3.2 ports) and One with 4 ports for TB 4.0 which also is Intel. Should the Thunderbolt ports be noted as USB C rather than 3? Should USB 3.1 Gen 2 always be noted as 3 unless it in fact is being interfaced with a cable that is a C port at the IO? IE type E internal to C not type A assuming the Type E internal is in fact delivering a real Gen 2 signal and power delivery.
What are the limitations for naming a port or combo-port a 3 vs a 9 or a 10? (know about the flip switch, but there is no actual naming for Thunderbolt 4's speed which is higher than 3.1 gen 2 (Gen 2 is 10gb per sec) (3.2 gen 2x2 is 20gb per sec) TB 4.0 is 40gb per sec which is the same as USB 4.0. Is 3 as a port name as High as the speeds go for Macs and does using 3 for a port name limit the speed to a max of 10GB per sec and this would include TB 4.0 even when mapped????
 
Thunderbolt should be labeled as USB-C ports yes (you'll need to figure out if it has a switch or not when setting the type).
If it's 3.1 Gen 2 (ugh these names) but is USB-A, the type should the 3 for USB-A I think.

I don't really know what limitations there are for TB4, I've never messed with it.
 
Thank you @dasboot5 and @1Revenger1 for the insights on macOS handling of USB and the interplay of maps.

It looks like USBToolBox brings the USB mapping chore fully into the post-Catalina era and it should be the go-to for today's builders.

Re TB4, I like to think — but I do not know — that there's a HW/ACPI/OS driver distinction between the Thunderbolt controller and its USB & DP personalities.

How the port is multiplexed is according to the TB spec, but when connected to a USB device it's served by a USB controller, and in similar vein if it's being served as a DisplayPort controller. When connected to a TB device it is served as a TB controller and USB/DisplayPort/Ethernet etc are tunneled?

The reason I think this distinction is important is that when the port is working as thunderbolt, none of the historical macOS limits associated with mapping apply to the tunneled devices, just as they don't apply to hubs daisy-chained from a root hub.

This is how I think, but I don't know.

Can anyone speak to these details?
 
I'm mostly familiar with TB3, so I'll speak from my experience there. One thing to realize before starting is that TB3 and 4 controllers have a USB Controller built in to them. How the port works depends on what is on the other side of the cable.

Some docks/hubs expose themselves as a PCI switch with their own USB Controller built in. This is likely what you mean by a Thunderbolt device. Functionally, this means that the TB Device has it's own USB Controller which handles everything. This shouldn't need to be mapped. Thunderbolt 2 and 1 only have PCIe tunneling and DP Alt mode. Apple has a good diagram of this on their documentation:
Unfortunately this picture only shows older Thunderbolt controllers without USB, but it's good to see how the PCI side works.
Figure_1-5_resized_2x.png

Displayport is handled by a GPU. Which GPU depends on your device's wiring.

"Dumber" USB-C hubs will just appear connected to a USB Controller within the computer itself. A common configuration is for USB 3.0 to be handled in the TB controller while the 2.0 portion is attached to the XHCI controller in the PCH. This behaves the same as any other USB hubs you'd see in a computer. This also doesn't need to be mapped.

Oh, don't forget USB-PD support in TB3 and TB4 controllers too :)

TLDR; don't bother mapping anything connected to a thunderbolt or USB-C port. They either have their own USB Controller that connects over PCIe or are a USB hub that doesn't need to be mapped. It is still important to annotate USB Personalities for the Thunderbolt Port itself as USB-C though (either with or without a switch).
 
I noticed this when checking my Toolbox map in Hackintool. The resulting map had all ports commented for location and type by me but none of the comments were showing up. I went to the Map text, right-clicked to get show package contents, and then opened the Plist in Propertree. A # preceded the comments so I removed it. No change. I check a USB Map Kext from Hackintool and the C is capitalized in the Hackintool version. Even with the # removed it still would not display my comments in Hackintool, but changing the leading C's to Capital C's fixed it. Coding error.
 
Back
Top