Contribute
Register

[Guide] Creating a Custom SSDT for USBInjectAll.kext

No, it's 2 usb ports and 1 usb C. In total is 3 ports.

I never use the hackintool for do this work... sound good. I use hackintool for generate the ssdt to compile?
 
Hi all. I just installed Catalina on a z490/10900k system via OpenCore. I have a native BCM94360CS2 pcie card that allowed sleep on a Skylake/Nvidia/High Sierra build just fine. However, by unplugging my internal usb connectors, I've realized that the card is causing an instant wake issue. All other internals (AIO/HUB/RGB) don't cause any issues (sleep works). Can anyone shed any insights?

Edit: Forgot to mention. I did my USB mapping and have a USBmap.kext. Nothing in ACPI. Should I remove the kext and do a .AML instead? Would it work better? I mapped it out correctly to 255 should I change it to 0 or 3 for external?
 
Hi all. I just installed Catalina on a z490/10900k system via OpenCore. I have a native BCM94360CS2 pcie card that allowed sleep on a Skylake/Nvidia/High Sierra build just fine. However, by unplugging my internal usb connectors, I've realized that the card is causing an instant wake issue. All other internals (AIO/HUB/RGB) don't cause any issues (sleep works). Can anyone shed any insights?

Edit: Forgot to mention. I did my USB mapping and have a USBmap.kext. Nothing in ACPI. Should I remove the kext and do a .AML instead? Would it work better? I mapped it out correctly to 255 should I change it to 0 or 3 for external?

I think (but I not sure) the USBPorts.kext is the best solution also for opencore, that mapping your usb in a kext. I do the same, but also for me not working good
 
Something wrong with your code. If there are 3 usb 3 ports and one usb C in your system then you should have 3 pairs of HS/SS PORTS for usb 3 and one for single sided usb C (not sure about usb c port, you can verify) you have
HS01/SS01
SS02
HS04/SS04
HS05
HS07
HS08
Use Hackintool for port mapping and auto generating files

I try to use hackintool like you suggest:

1) Open Hackintool , USB , clean all , refresh
2) Plug all the USB Port (USB2 / USB3 / USB-C)
3) Clean the other port without green color
4) Generate the file (amd and USBPorts.kext)

I try to use the USBPorts.kext , and after the reboot on the hakintools I see only the ports I have selected when I plug the usb (I think it's correct).

But when I plug the iphone the system tell me the device use too much energy and disable all the usb port.

Where is my error?

Also attach the log file
 

Attachments

  • debug_3693.zip
    12.9 MB · Views: 120
I try to use hackintool like you suggest:

1) Open Hackintool , USB , clean all , refresh
2) Plug all the USB Port (USB2 / USB3 / USB-C)
3) Clean the other port without green color
4) Generate the file (amd and USBPorts.kext)

I try to use the USBPorts.kext , and after the reboot on the hakintools I see only the ports I have selected when I plug the usb (I think it's correct).

But when I plug the iphone the system tell me the device use too much energy and disable all the usb port.

Where is my error?

Also attach the log file
Follow instructions here
 
I think (but I not sure) the USBPorts.kext is the best solution also for opencore, that mapping your usb in a kext. I do the same, but also for me not working good

I'm not sure we have the same issue. I've mapped my USBs to a kext, and it's all working well. The problem I'm having is that my BCM94360CS2 card is causing instant wakes after sleep. If I unplug it, I get sleep to work natively. Pretty stumped as to what to do. I bought a native card to avoid these issues :)

EDIT: Whoops, now I've realized I've posted in the wrong thread. My bad!
 
I try to use hackintool like you suggest:

1) Open Hackintool , USB , clean all , refresh
2) Plug all the USB Port (USB2 / USB3 / USB-C)
3) Clean the other port without green color
4) Generate the file (amd and USBPorts.kext)

I try to use the USBPorts.kext , and after the reboot on the hakintools I see only the ports I have selected when I plug the usb (I think it's correct).

But when I plug the iphone the system tell me the device use too much energy and disable all the usb port.

Where is my error?

Also attach the log file
can u post a Hackintool screenshot after using usbinjectall and port limit patch and connecting usb devices individually in each usb 3 port and usb c as your usbport.kext s not proper.
use this guide
 
Overview

One of the serious issues most users will face with 10.11.x (and later, including 10.12.x) is the new USB stack in OS X/macOS. It has a much heavier reliance on ACPI, and as a result is much more likely to expose bugs in your ACPI implementation of _PLD, and _UPC.

It is covered in detail in my guide: https://www.tonymacx86.com/threads/guide-10-11-usb-changes-and-solutions.173616/

You should be familiar with the write-up above before attempting a custom SSDT.

Many tend to over-simplify the problem, and, for example, believe they can simply apply the port-limit patch and install USBInjectAll.kext and be done with it. In fact, the port limit patch is known to cause problems (it causes access outside a fixed array bounds). Somewhat alarming is the fact that Multibeast includes the port limit patch without mention of its problems. Also, for each update, a new port limit patch may need to be created (as I write this, no working patch exists for 10.14.1, for example).

The fact: Using the port limit patch is not good solution for anything. For reliable USB (assuming your ACPI implementation of _PLD and _UPC is broken... and you don't want to fix it), you must implement a custom SSDT for USBInjectAll.kext that configures your ports on XHC such that the port limit patch is not needed, and each UsbConnnector value is correct for each port.

Note: It is also possible to build a port injector codeless kext. That method is not covered in this guide.

This guide is written such that there is no dependency on any port limit patch.

Not only does a custom SSDT allow you to avoid the port limit patch, but disabling USB ports that are not used can have some power saving properties, and can avoid bugs with sleep, restart, or shutdown.

This guide will show how this is done.

The process consists of the following steps:
- preparation for port discovery
- port discovery
- creating custom SSDT for USBInjectAll.kext
- testing/verification

The MaciASL used by this guide is available here: https://bitbucket.org/RehabMan/os-x-maciasl-patchmatic/downloads/
Make sure you have ACPI 6.2a selected in MaciASL->Preferences->iASL.


Preparation for port discovery

In order to create a custom SSDT that contains the correct data for a given computer's USB arrangement, we must first discover all the ports that need to be enabled. Once we know which ports are used, we can eliminate the unused ports.

In order to discover the ports, we need to at some point inject all possible ports, then test them. Due to the 15 port limit injection of the ports and testing may have to be done in groups (of 15 or less).

Requirements:
- EHC1->EH01 and EHC2->EH02 rename (in config.plist), if applicable (your chipset may not have EHCI, or it may be disabled)
- XHCI controller must be named XHC or XHCI (for most PCs it is default XHC)
- install USBInjectAll.kext (install to the system volume)
- if you plan to use it, install FakePCIID.kext + FakePCIID_XHCIMux.kext. FakePCIID_XHCIMux only applicable if you have enabled EHCI controller(s).
- if you have an existing SSDT for USBInjectAll, use -uia_ignore_rmcf
- XHCI injector kext, if required (XHCI-unsupported.kext)

The EHCx renames and port limit patches are available in config_patches.plist (https://github.com/RehabMan/OS-X-USB-Inject-All/raw/master/config_patches.plist) in the USBInjectAll.kext repository. Use copy/paste from a plist editor to get them into your own config.plist.

The EHCx renames look like this in Xcode:
View attachment 228080

The -uia_ignore_rmcf is added to config.plist/Boot/Arguments:
View attachment 228083

After preparing for port discovery, you should check in ioreg that all expected (depending on exclusions) ports are injected for your chipset on both EHCI and XHCI controllers.

For the NUC7i7KYK, we cannot inject all the ports at one time, so we inject at first only the HSxx ports, then next the SSxx and USRx ports. This partial injection is covered in detail in the following section.

Injection of just HSxx:
View attachment 361994

Injection of just HS03,SSxx,USRx:
View attachment 361995

This is what full looks like on my Lenovo u430 using FakePCIID_XHCIMux.kext. Full injection is possible with the u430 as its xHCI controller has less than 15 ports possible.

Note they are the same as the ports provided by USBInjectAll.kext.

XHC:
View attachment 228103

EH01:
View attachment 228104

Once you have all ports being injected, you can proceed to the next step where you will determine which ports are actually needed.


Port discovery

In order to discover which ports need to be in the SSDT, we will use IORegistryExplorer:

- run IORegistryExplorer
- test each port with both USB2 and USB3 devices

Since IORegistryExplorer tracks changes to IOKit objects (existing objects black, new objects in green, disconnected objects in red), we can use the data to determine which ports are actually used.

IORegistryExplorer.app can be downloaded from the attachment at this thread: http://www.tonymacx86.com/audio/58368-guide-how-make-copy-ioreg.html

After you download and extract IORegistryExplorer.app, run it. And keep it running throughout the test.

Note: All data needed by this guide is in the IOService registry plane. DO NOT CHANGE the registry plane from IOService.

Test each port by inserting a both a USB2 device and a USB3 device (obviously, independently). If you look carefully while you insert and remove the devices you can see which ports are assigned to which physical port (you will see the changes in ioreg).

Note: If you have a USB3 hub it can make it easier to test each port. Since a USB3 hub connects to both the USB3 pins and the USB2 pins of a USB3 port (and can be used in a USB2-only port), and it requires no action to eject properly, you will find it much quicker to use a USB3 hub instead of a set of USB2/USB3 memory sticks. In the examples that follow, I'm using a USB3 hub to test ports.

DO NOT USE the 'Search' box in IORegistryExplorer.app! Just look at the correct section of the ioreg tree on the left pane (scroll as necessary to find the EH01/EH02/XHC as applicable to your hardware).

Note that to test each port properly, you may need to move any USB keyboard or mouse device to different ports so that you can test each port with both USB2 and USB3 (or USB3 hub).

For the NUC6i7KYK, testing must be done in groups as it is not possible to enable all ports at once. For this reason, we first test with just the HSxx ports enabled, then follow up testing of the SSxx and USRx ports.

On my NUC6i7KYK, we boot with kernel flag -uia_exclude_ss uia_exclude=USR1,USR2 to test only the HSxx ports.
This is what it looks like before testing any of the ports:
View attachment 361975

You can see that only the HS03 port is being used. The HS03 port happens to be where my Dell U3011 USB hub is plugged in, which also happens to have my USB keyboard/mouse dongle. The HS09 is the internal bluetooth controller. Making a note of the ports needed for operable keyboard and mouse is important when you go to test the SSxx ports, since you will need to use uia_include to include the HSxx port that your keyboard and mouse are attached to.

After testing all ports:
View attachment 361979

I usually monitor ioreg as I plug and unplug devices so I know where the ports are located physically.
As you can see, the following ports are used:
HS01: USB3 front left
HS02: USB3 front right
HS03: USB3 rear bottom
HS04: USB3 rear top
HS09: bluetooth

Next, we boot with -uia_exclude_hs uia_include=HS03 to test SSxx and USRx ports. Before testing, it looks like this:
View attachment 361980

After testing all ports with a USB3 device:
View attachment 361981

Results:
SS01: USB3 front left
SS02: USB3 front right
SS03: USB3 rear bottom
SS04: USB3 rear top

Note that the SSxx ports will have a corresponding HSxx port. The SSxx port (or SSPx) is used when you plug in a USB3 device. The HSxx port is used when you plug in a USB2 device. USB2 only ports will use only HSxx.

Composite results:
HS01/SS01: USB3 front left
HS02/SS02: USB3 front right
HS03/SS03: USB3 rear bottom
HS04/SS04: USB3 rear top
HS09: bluetooth

So, although the controller used on this Skylake computer has the potential for 26 ports (HS01-HS14, SS01-SS10, USR1, USR2), only 9 ports are connected. We can eliminate HS05-HS08, HS10-HS14, SS05-SS10, USR1, and USR2.

Let's take a look at the test results for my Lenovo u430 (using FakePCIID_XHCIMux.kext).

Before testing:
View attachment 228112

View attachment 228111

After testing all ports:
View attachment 228113

View attachment 228114

Ports used (EH01/HUB1/XHC):
PR11: internal hub
HP11: touchscreen
HP12/SSP1: USB3 left
HP14: USB2 far right
HP15: USB2 near right
HP15: camera
HP16: bluetooth

Or, if we remove FakePCIID_XHCIMux.kext:

Before testing:
View attachment 228116

View attachment 228117

After testing:
View attachment 228122

View attachment 228123

Ports used (only on XHC):
HS01: touchscreen
HS02/SSP1: USB3 left
HS02: USB2 far right
HS03: USB2 near right
HS05: camera
HS06: bluetooth

As you can see, FakePCIID_XHCIMux.kext has the effect of moving all HSxx ports to EHCI (to the internal hub on EH01.PR11).

After you have collected the data in IORegistryExplorer, and you are certain that is accurate, you are now prepared to create a custom SSDT based on the data you have obtained in ioreg.


Creating custom SSDT for USBInjectAll.kext

USBInjectAll.kext is coded in a data driven way. Nothing is hard-coded in the kext code itself. All data is contained in the Info.plist. When USBInjectAll.kext starts, matching on EH01/EH02/XHC, or the internal hubs connected to EH01/EH02 port 1, it consults the configuration data in Info.plist as related to the device it has attached to and injects the data it finds there. But an SSDT can be used to override the data in the Info.plist.

A template is provided in the USBInjectAll.kext github repo, SSDT-UIAC-ALL.dsl, which has overrides for all the data already in the USBInjectAll.kext Info.plist. You could compile SSDT-UIAC-ALL.dsl to SSDT-UIAC-ALL.aml (File Save As, format: ACPI Machine Language Binary in MaciASL) and place it in ACPI/patched, and although all the data in the Info.plist will be overridden by the SSDT, no net change would be observed, as the data in SSDT-UIAC-ALL.dsl is the same as the data already in the USBInjectAll.kext Info.plist.

In order to effect our changes, we must modify the SSDT-UIAC-ALL.dsl so it contains only the ports we need.

The steps are as follows:
- use SSDT-UIAC-ALL.dsl as a template (https://github.com/RehabMan/OS-X-USB-Inject-All/raw/master/SSDT-UIAC-ALL.dsl)
- remove configuration sections that don't apply to the target hardware
- remove ports from the various sections that are not needed
- change UsbConnector values to match physical hardware/ports

The first step is to eliminate configuration data from SSDT-UIAC-ALL.dsl that don't apply to the target hardware and USB configuration.

For example, if no ports are active on EH01/EH02 or the related USB hubs (on PR11/PR21), you can eliminate the configuration data for EH01/EH02/HUB1/HUB2. In the case of Skylake, it has no EHCI controllers, so EH01/EH02/HUB1/HUB2 configuration can be removed without much consideration. Same would be true if you're disabling EHCI either via BIOS or ACPI (covered later). And you can eliminate any XHC configuration that does not match your XHC device-id. Look in ioreg to find your XHC device-id.

For example, you can see that the NUC6i7KYK uses 0xa12f:
View attachment 228093

So, for the NUC's XHC, it will match against the data for "8086_a12f" in the SSDT-UIAC-ALL.dsl. We can eliminate all other XHC configuration data.

For the NUC6i7KYK, we end up with this starter template:
Code:
// Initial trimmed SSDT-UIAC.dsl for NUC6i7KYK
DefinitionBlock ("", "SSDT", 2, "hack", "UIAC", 0)
{
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            "8086_a12f", Package()
            {
                "port-count", Buffer() { 26, 0, 0, 0 },
                "ports", Package()
                {
                    "HS01", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "HS02", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "HS03", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "HS04", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "HS05", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 5, 0, 0, 0 },
                    },
                    "HS06", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 6, 0, 0, 0 },
                    },
                    "HS07", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 7, 0, 0, 0 },
                    },
                    "HS08", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 8, 0, 0, 0 },
                    },
                    "HS09", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 9, 0, 0, 0 },
                    },
                    "HS10", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 10, 0, 0, 0 },
                    },
                    "HS11", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 11, 0, 0, 0 },
                    },
                    "HS12", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 12, 0, 0, 0 },
                    },
                    "HS13", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 13, 0, 0, 0 },
                    },
                    "HS14", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 14, 0, 0, 0 },
                    },
                    "SS01", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 17, 0, 0, 0 },
                    },
                    "SS02", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 18, 0, 0, 0 },
                    },
                    "SS03", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 19, 0, 0, 0 },
                    },
                    "SS04", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 20, 0, 0, 0 },
                    },
                    "SS05", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 21, 0, 0, 0 },
                    },
                    "SS06", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 22, 0, 0, 0 },
                    },
                    "SS07", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 23, 0, 0, 0 },
                    },
                    "SS08", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 24, 0, 0, 0 },
                    },
                    "SS09", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 25, 0, 0, 0 },
                    },
                    "SS10", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 26, 0, 0, 0 },
                    },
                    "USR1", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 15, 0, 0, 0 },
                    },
                    "USR2", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 16, 0, 0, 0 },
                    },
                },
            },
        })
    }
}
//EOF

In the case of the NUC6i7KYK, it matches against a section in SSDT-UIAC-ALL.dsl that matches specifically against "8086_a12f". Some XHC devices will match against only part of the device-id. For example, the u430 device-id is 0x9c31. As there is no specific configuration for "8086_9c31", it will match against "8086_9xxx". Always use the template data that has the most specific match for your device-id. For example, if your device-id is 0x9cb1, you should use the template data for "8086_9cb1", not "8086_9xxx". Similarly, if your device id 0x9ded, use the template data 8086_9dxx, not 8086_9xxx.

After you trim the template down to include only the configuration sections you need, now it is time to further trim the data to eliminate unused ports. As you recall, the NUC6i7KYK uses only HS01-HS04, HS09, and SS01-SS04.

The resulting SSDT-UIAC.dsl for NUC6i7KYK with only the ports we need:
Code:
// Port trimmed SSDT-UIAC.dsl for NUC6i7KYK
DefinitionBlock ("", "SSDT", 2, "hack", "UIAC", 0)
{
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            "8086_a12f", Package()
            {
                "port-count", Buffer() { 26, 0, 0, 0 },
                "ports", Package()
                {
                    "HS01", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "HS02", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "HS03", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "HS04", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "HS09", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 9, 0, 0, 0 },
                    },
                    "SS01", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 17, 0, 0, 0 },
                    },
                    "SS02", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 18, 0, 0, 0 },
                    },
                    "SS03", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 19, 0, 0, 0 },
                    },
                },
            },
        })
    }
}
//EOF

We can comment each port based on notes we took about each:
Code:
// Port trimmed with port comments SSDT-UIAC.dsl for NUC6i7KYK
DefinitionBlock ("", "SSDT", 2, "hack", "UIAC", 0)
{
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            "8086_a12f", Package()
            {
                "port-count", Buffer() { 26, 0, 0, 0 },
                "ports", Package()
                {
                    "HS01", Package() // HS USB3 front left
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "HS02", Package() // HS USB3 front right
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "HS03", Package() // HS USB3 rear bottom
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "HS04", Package() // HS USB3 rear top
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "HS09", Package() // bluetooth
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 9, 0, 0, 0 },
                    },
                    "SS01", Package() // SS USB3 front left
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 17, 0, 0, 0 },
                    },
                    "SS02", Package() // SS USB3 front right
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 18, 0, 0, 0 },
                    },
                    "SS03", Package() // SS USB3 rear bottom
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 19, 0, 0, 0 },
                    },
                    "SS04", Package() // SS USB3 rear top
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 20, 0, 0, 0 },
                    },
                },
            },
        })
    }
}
//EOF

And we should change the UsbConnector values to match the type of port. The defaults are not always correct (USBInjectAll has no way to know what the correct value is).

Note: DO NOT CHANGE the port address assignments. All of the port addresses in SSDT-UIAC-ALL.dsl are correct. Changing them can only break things.

Common port connector types are USB2 = 0, USB3 = 3, internal = 255.

USB type C ports can be either 9 or 10, which depends on how the hardware deals with the two possible orientations of a USB type C device/cable.
If a USB-C uses the same SSxx in both orientations, then it has an internal switch (UsbConnector=9).
If a USB-C uses a different SSxx in each orientation, then it has no switch (UsbConnector=10).

HSxx ports that are connected to a USB3 port should be marked UsbConnector=3, not UsbConnector=0.

Note: Read the ACPI spec for more valid values (_UPC).

In the case of the NUC6i7KYK, only HS09 needs adjusting. Since the bluetooth controller is internal, it should be 255.

The final SSDT-UIAC.dsl is:
Code:
// Port trimmed with port comments and correct UsbConnector SSDT-UIAC.dsl for NUC6i7KYK
DefinitionBlock ("", "SSDT", 2, "hack", "UIAC", 0)
{
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            "8086_a12f", Package()
            {
                "port-count", Buffer() { 26, 0, 0, 0 },
                "ports", Package()
                {
                    "HS01", Package() // HS USB3 front left
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "HS02", Package() // HS USB3 front right
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "HS03", Package() // HS USB3 rear bottom
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "HS04", Package() // HS USB3 rear top
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "HS09", Package() // bluetooth
                    {
                        "UsbConnector", 255,
                        "port", Buffer() { 9, 0, 0, 0 },
                    },
                    "SS01", Package() // SS USB3 front left
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 17, 0, 0, 0 },
                    },
                    "SS02", Package() // SS USB3 front right
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 18, 0, 0, 0 },
                    },
                    "SS03", Package() // SS USB3 rear bottom
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 19, 0, 0, 0 },
                    },
                    "SS04", Package() // SS USB3 rear top
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 20, 0, 0, 0 },
                    },
                },
            },
        })
    }
}
//EOF

Now we are ready to compile this file and place it in EFI/Clover/ACPI/patched. In MaciASL, you can compile as AML by using File -> Save As, format: ACPI Machine Language Binary. Save it to a location you know how to navigate to (desktop). Then mount your EFI partition and copy it to EFI/Clover/ACPI/patched. I suggest using SSDT-UIAC.aml for the name.

Note: If you're using config.plist/ACPI/SortedOrder, you must insure that the new SSDT is listed in SortedOrder. If SortedOrder is specified, Clover will load only those SSDTs listed in SortedOrder.

After you have copied the SSDT to ACPI/patched, you are ready to test. If it does not work (ports missing, port discovery done incorrectly, wrong template used, etc), you can always use -uia_ignore_rmcf to disable the override code in SSDT, and then check your work.

As you can see from the image below from the NUCi7KYK, we now have just the ports that we need injected and are well under the 15-port limit:
View attachment 228145

Lenovo u430 example with EH01 and HUB1

Since Skylake doesn't have an EHCI controller, we only needed to customize for XHC. The Lenovo u430 uses an 8-series chipset, therefore it has an EHCI controller. Although it can be disabled (which I actually do for my u430 in real use), this walk through will keep it enabled as a way of demonstrating EHCI and the related hub configuration.

Just as we did with the Skylake NUC6, we start by removing all configuration sections not needed from SSDT-UIAC-ALL for the Lenovo u430 based on the data we collected with FakePCIID_XHCIMux.kext. The XHC controller is 0x9c31, so we need only "8086_9xxx" for the XHC configuration, and we need EH01 and HUB1 for the ports on the EHCI controller and related hub.

The resulting trimmed SSDT is:
Code:
// Initial trim SSDT-UIAC.dsl for u430
DefinitionBlock ("", "SSDT", 2, "hack", "UIAC", 0)
{
    Device(UIAC)
    {
        Name(_HID, "UIA00000")

        Name(RMCF, Package()
        {
            "HUB1", Package()
            {
                "port-count", Buffer() { 8, 0, 0, 0 },
                "ports", Package()
                {
                    "HP11", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "HP12", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "HP13", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "HP14", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "HP15", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 5, 0, 0, 0 },
                    },
                    "HP16", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 6, 0, 0, 0 },
                    },
                    "HP17", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 7, 0, 0, 0 },
                    },
                    "HP18", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 8, 0, 0, 0 },
                    },
                },
            },
            "EH01", Package()
            {
                "port-count", Buffer() { 8, 0, 0, 0 },
                "ports", Package()
                {
                    "PR11", Package()
                    {
                        "UsbConnector", 255,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "PR12", Package()
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "PR13", Package()
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "PR14", Package()
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "PR15", Package()
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 5, 0, 0, 0 },
                    },
                    "PR16", Package()
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 6, 0, 0, 0 },
                    },
                    "PR17", Package()
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 7, 0, 0, 0 },
                    },
                    "PR18", Package()
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 8, 0, 0, 0 },
                    },
                },
            },
            "8086_9xxx", Package()
            {
                "port-count", Buffer() { 13, 0, 0, 0 },
                "ports", Package()
                {
                    "HS01", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "HS02", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "HS03", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "HS04", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "HS05", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 5, 0, 0, 0 },
                    },
                    "HS06", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 6, 0, 0, 0 },
                    },
                    "HS07", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 7, 0, 0, 0 },
                    },
                    "HS08", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 8, 0, 0, 0 },
                    },
                    "HS09", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 9, 0, 0, 0 },
                    },
                    "SSP1", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 10, 0, 0, 0 },
                    },
                    "SSP2", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 11, 0, 0, 0 },
                    },
                    "SSP3", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 12, 0, 0, 0 },
                    },
                    "SSP4", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 13, 0, 0, 0 },
                    },
                },
            },
        })
    }
}
//EOF

If we installed that SSDT unmodified at this point, because all possible ports are included, we would have same result as without it.

Also note it is good practice for the XHC configuration to change to the actual device id, in this case "8086_9c31". In this case, either will work "8086_9xxx" or "8086_9c31", but using a specific configuration identifier helps identify the specific XHC device this SSDT was made for.

Note: You can also use "XHC".

So, after removing ports that are not used, and changing the XHC configuration identifier to "8086_9c31":
Code:
// Port trimmed SSDT-UIAC.dsl for u430
DefinitionBlock ("", "SSDT", 2, "hack", "UIAC", 0)
{
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            "HUB1", Package()
            {
                "port-count", Buffer() { 8, 0, 0, 0 },
                "ports", Package()
                {
                    "HP11", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                    "HP12", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 2, 0, 0, 0 },
                    },
                    "HP13", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 3, 0, 0, 0 },
                    },
                    "HP14", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 4, 0, 0, 0 },
                    },
                    "HP15", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 5, 0, 0, 0 },
                    },
                    "HP16", Package()
                    {
                        //"UsbConnector", 0,
                        "portType", 0,
                        "port", Buffer() { 6, 0, 0, 0 },
                    },
                },
            },
            "EH01", Package()
            {
                "port-count", Buffer() { 8, 0, 0, 0 },
                "ports", Package()
                {
                    "PR11", Package()
                    {
                        "UsbConnector", 255,
                        "port", Buffer() { 1, 0, 0, 0 },
                    },
                },
            },
            "8086_9c31", Package()
            {
                "port-count", Buffer() { 13, 0, 0, 0 },
                "ports", Package()
                {
                    "SSP1", Package()
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 10, 0, 0, 0 },
                    },
                },
            },
        })
    }
}
//EOF

In this case, there is no need to modify any of the UsbConnector values, since they are already set correctly. The USB Hub driver in macOS/OS X does not use UsbConnector and we don't really understand the purpose of portType. You can experiment with different values if you need to. Refer to the hub driver Info.plist in IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBHub.kext/Contents/Info.plist for ideas.

Note: If anyone has a Sierra or El Capitan ioreg from a MacPro6,1, MacBookPro8,1, MacBookPro6,1, iMac13,x, or MacBookPro8,3 along with information about the physical hub ports where portType=2 or portType=0 is used, please share.

After we install this SSDT, remove -uia_ignore_rmcf, we can verify in ioreg and test that all ports work.

Here we have images of the ports injected on EH01, HUB1, and XHC:
View attachment 228099

View attachment 228100

Note that for my Lenovo u430, I decided to disable the EHCI controller and have everything on XHC. FakePCIID_XHCIMux.kext is not installed.

The resulting SSDT is as follows (in this SSDT, I used "XHC" instead of "8086_9xxx" or "8086_9c31" just to show it is possible):
Code:
// With EHCI disabled, SSDT-UIAC.dsl for u430
DefinitionBlock ("", "SSDT", 2, "hack", "UIAC", 0)
{
    Device(UIAC)
    {
        Name(_HID, "UIA00000")
        Name(RMCF, Package()
        {
            "XHC", Package()
            {
                //"port-count", Buffer() { 0x0d, 0, 0, 0},
                "ports", Package()
                {
                    "HS01", Package() // touchscreen
                    {
                        "UsbConnector", 255,
                        "port", Buffer() { 0x01, 0, 0, 0 },
                    },
                    "HS02", Package() // HS USB3 left
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 0x02, 0, 0, 0 },
                    },
                    "HS03", Package() // USB2 far right
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 0x03, 0, 0, 0 },
                    },
                    "HS04", Package() // USB2 near right
                    {
                        "UsbConnector", 0,
                        "port", Buffer() { 0x04, 0, 0, 0 },
                    },
                    "HS05", Package() // camera
                    {
                        "UsbConnector", 255,
                        "port", Buffer() { 0x05, 0, 0, 0 },
                    },
                    "HS06", Package() // bluetooth
                    {
                        "UsbConnector", 255,
                        "port", Buffer() { 0x06, 0, 0, 0 },
                    },
                    "SSP1", Package() // SS USB3 left
                    {
                        "UsbConnector", 3,
                        "port", Buffer() { 0x0a, 0, 0, 0 },
                    },
                },
            },
        })
    }

//
// Disabling EHCI #1
//
    External(_SB.PCI0, DeviceObj)
    External(_SB.PCI0.LPCB, DeviceObj)
    External(_SB.PCI0.EH01, DeviceObj)
    Scope(_SB.PCI0)
    {
        // registers needed for disabling EHC#1
        Scope(EH01)
        {
            OperationRegion(PSTS, PCI_Config, 0x54, 2)
            Field(PSTS, WordAcc, NoLock, Preserve)
            {
                PSTE, 2  // bits 2:0 are power state
            }
        }
        Scope(LPCB)
        {
            OperationRegion(RMLP, PCI_Config, 0xF0, 4)
            Field(RMLP, DWordAcc, NoLock, Preserve)
            {
                RCB1, 32, // Root Complex Base Address
            }
            // address is in bits 31:14
            OperationRegion(FDM1, SystemMemory, Add(And(RCB1,Not(Subtract(ShiftLeft(1,14),1))),0x3418), 4)
            Field(FDM1, DWordAcc, NoLock, Preserve)
            {
                ,15,    // skip first 15 bits
                FDE1,1, // should be bit 15 (0-based) (FD EHCI#1)
            }
        }
        Device(RMD1)
        {
            //Name(_ADR, 0)
            Name(_HID, "RMD10000")
            Method(_INI)
            {
                // disable EHCI#1
                // put EHCI#1 in D3hot (sleep mode)
                Store(3, ^^EH01.PSTE)
                // disable EHCI#1 PCI space
                Store(1, ^^LPCB.FDE1)
            }
        }
    }
}
//EOF

Don't expect to understand the code under "Disabling EHCI #1" unless you have had a good read of the ACPI specification and the Intel 8-series chipset datasheet.

Here is the result with everything on XHC (no EH01 to be found in ioreg):
View attachment 228125


Problem Reporting

If you have a problem, please describe the problem clearly, make sure your profile accurately describes your hardware and provide all the data as requested in the FAQ.

Read FAQ, "Problem Reporting". Attach all requested files/output.
https://www.tonymacx86.com/threads/faq-read-first-laptop-frequent-questions.164990/
Use the gen_debug.sh tool mentioned in the FAQ, that way it is less likely you'll omit something.

Compress all files as ZIP. Do not use external links. Attach all files using site attachments only.
Hi Guys,

I'm hoping someone in the forum can help.


I want to disable a specific port on the Root Hub.

My computer shows HS13 as USB 2.0 Hub.

I want to disable the H80i V2@ 14940000 (Port 4). This device is preventing sleep.
Sleeps works when:
1. I removed the CPU USB header from the motherboard
2. OR if I removed HS13 completely in SSDT-UIAC.aml

What is the best and most elegant way to achieve this without affecting the other 3 devices that also sits on HS13 Hub ?


USB Hub Ports.png
 
Thank you RehabMan again, for providing us this amazing guide.

If someone is interested, here is the SSDT for Gigabyte Z390 Aorus Ultra mobo.
It has only a XHCI controller, with the following ports:

(USB2 / USB3)
HS03 / SS03 : USB3.1 Gen2 [red], next to the Ethernet port
HS04 / SS04 : USB3.1 Gen2 [red], next to the Ethernet port
HS05 / SS05 : USB3.1 Gen1 [yellow], next to the Type-C port
HS06 / SS06 : USB3.1 Type-C back
HS07 / SS07 : USB3.1 Gen1 [yellow], next to the HDMI port
HS08 / SS08 : USB3.1 Gen1 [yellow], next to the HDMI port

(USB2)
HS11 : 4 USB2 back ports (hub)
HS12 : USB2 internal ITE, ignored to stay at 15 port limit
HS13 : 2 USB2 front ports (hub), assuming you're using the mobo USB_1 internal header
HS14 : USB2 internal bluetooth
Thanks for posting your SSDT. I have the same mobo, but on Catalina. I tried your SSDT, but I always get the same result: I end up with HS01-14 + SS01, like the SSDT isn't working. What USB-EC patch are you using? This mobo is H_EC, which seems to be a bit of an outsider from what I can tell.
 
Last edited:
Thanks for posting your SSDT. I have the same mobo, but on Catalina. I tried your SSDT, but I always get the same result: I end up with HS01-14 + SS01, like the SSDT isn't working. What USB-EC patch are you using? This mobo is H_EC, which seems to be a bit of an outsider from what I can tell.
Hey @cramletram,

I've been using Opencore with Catalina and Big Sur and made some modifications on my initial USB config.
Attached the Opencore 0.67 EFI folder, without both SMBIOS (Generic item info) and Resources folders.

In this setup, I use USBMap.kext to config my USB ports, but you can use a SSDT with same results. The important part is understand which ports to enable/disable.

If you open the USBMap.kext/Contents/Info.plist/IOKitPersonalities/iMac19,1-XHC/IOProviderMergeProperties/Ports you should notice all the ports that are enabled on my setup, as well their types.

For keeping inside the 15 port limit, I disabled port HS06 (USB 2.0 port on the USB Type-C back connector) and enabled port HS13 (USB 2.0 port on the internal USB 3.0 header), due to a Wifi Card 94360 USB sleep issue, but if you don't use that card you can disable HS13 and enable HS06. Choose the best setup, you only need to edit the USBMap.kext (No USBInjectAll.kext dependency).

Notes:
- Using Z390 Aorus Ultra BIOS version 10h.
- My graphics card is Radeon RX 5600 XT, so you should config your Vega 64 on the config.plist, specially "boot-args".
- Pay attention to the rest of Opencore files, you should be good with that EFI folder if your MOBO is the same of mine.
- If you plan to use a SSDT, use the excellent USBMap-master tool to build yours. More information on the Dortania's Opencore Post-Install Guide.
 

Attachments

  • OC 0.67 EFI Z390 Ultra [BIOS 10h].zip
    2.4 MB · Views: 109
Last edited:
Back
Top