Contribute
Register

ASUS 100 Series and Later Custom SSDT for XHCI USB Port Control

MacMan

Administrator
Staff member
Joined
Feb 2, 2010
Messages
8,180
Motherboard
ASUS TUF Z390-PRO GAMING - 2606 - UEFI
CPU
i9-9900K
Graphics
Vega 64
Mac
  1. MacBook Pro
  2. Mac Pro
Classic Mac
  1. Power Mac
  2. PowerBook
Mobile Phone
  1. iOS
As part of building my newest systems, I wanted to create a method to disable chipset XHCI ports without using a kext. I found that by creating a custom SSDT for the XHCI ports I could easily disable unused motherboard USB ports or hide unsupported devices that use these USB ports. This allowed me to support all the chipset XHCI ports implemented on my CustoMac motherboards.

The following guide was specifically written for ASUS 100 / 200 / 300 Series CustoMac motherboards running High Sierra 10.13.4 or greater. This SSDT method only deals with the XHCI based USB ports implemented in the motherboard chipset. USB 3.1 Gen 2 ports are implemented outside of the main chipset and are supported in macOS High Sierra.

What makes this method possible is that the default SSDT for XHCI ports has every possible XHCI port defined. It contains entries for HS01 thru HS14, SS01 thru SS10 and USR1 and USR2. When we look at the ports implemented on a specific motherboards later on, we will see that they typically have less then the maximum defined. Additionally, I have yet to find a motherboard that has implemented USR1 or USR2.

The following method has been implemented and verified working on the following ASUS desktop motherboards running High Sierra:

ASUS Z170-DELUXE
ASUS ROG STRIX Z270-I GAMING
ASUS ROG STRIX Z370-E GAMING

In the case of the ASUS ROG STRIX Z370-E GAMING, I was also able to hide the unsupported Bluetooth controller and the AURA Led Controller from showing up in System Information and IORegistryExplorer.

The steps required to create the modified SSDT is as follows:
  1. Document number of USB ports implemented on your motherboard
  2. Map USB port locations (Optional)
  3. Extract DSDT/SSDT using Clover
  4. Modify the SSDT
  5. Verify Clover ACPI AutoMerge Setting
  6. Install the modified SSDT
  7. Verify port operation

1. Documenting USB ports

As good starting point is to refer to the manual that come with your motherboard or the manufacturers website. The only USB ports we are interested in are the ports implemented in the chipset as these are the XHCI ports. Here is what is implemented on the boards I've tested with.

ASUS Z170-DELUXE
5 x USB 3.1 Gen 1 port(s) (1 at back panel, 4 at mid-board)
5 x USB 2.0 port(s) (1 at back panel, 4 at mid-board)
Total XHCI Ports: 15 (10 High Speed and 5 Super Speed)
ASUS ROG STRIX Z270-I GAMING
6 x USB 3.1 Gen 1 port(s) (4 at back panel, 2 at mid-board)
4 x USB 2.0 port(s) (4 at back panel)
Total XHCI Ports: 16 (10 High Speed and 6 Super Speed)​

ASUS ROG STRIX Z370-E GAMING
6 x USB 3.0 port(s) (2 at back panel, 4 at mid-board)
6 x USB 2.0 port(s) (2 at back panel, 4 at mid-board)
Total XHCI Ports: 18 (12 High Speed and 6 Super Speed)​

2. Mapping USB ports

It is a good exercise to understand what ports are where in your system. Before you start, disable Legacy USB and EHCI support in the UEFI if those options are available.

Since these boards have all the ports defined in the SSDT you don't need to have RehabMan's USBInjectAll.kext installed, but having it installed won't hurt. You will need the Remove XHCI USB Port Limit patch in Clover to get access to all the ports. In MultiBeast 10.3+ you can find this patch under Drivers -> USB -> Remove XHCI USB Port Limit.

To do the actual mapping you need to plug an USB2 and USB3 device into each port and check the device information in IORegistryExplorer. When you are done you will have map just like this one I did for the ASUS ROG STRIX Z270-I GAMING:

ASUS Z270I-Gaming.jpeg


Make note if you find that you have ports that have no external connections or for unused/unsupported devices like a Bluetooth controller, WiFi adapter, AURA Led Controller, etc. You'll want to disable them during step 4.

On the ASUS ROG STRIX Z370-E GAMING USB3 ports 3 and 4 and USB2 ports 11 and 12 are on internal headers that I'm not using. So I've disabled them in the SSDT on my build. If I didn't disable USB3 3 and 4 and USB2 3, 4, 11 and 12 in the SSDT, I would get phantom USB ports in IORegistryExplorer. This is because macOS sees the ports via the SSDT and adds entries for them.

3. Extracting SSDT

Before Clover, extracting the DSDT and SSDT could be painful. But thanks to the Clover developers it is now easy and is done when Clover is booted and at the main menu by pressing the F4 key. This will place the extracted DSDT and SSDT on the boot EFI volume under /EFI/EFI/CLOVER/ACPI/origin/. I would suggest copying this folder and it's contents to your macOS volume to make it easier to work with without having to keep the EFI volume mounted. After you copy this folder you can delete it's contents on the EFI volume as it's not used by Clover.

4. Modifying the SSDT

After you boot into macOS you will need to mount the EFI volume and copy /Volumes/EFI/EFI/CLOVER/ACPI/origin/ to your macOS volume. In the folder you copied, the SSDT file names are comprised of the SSDT number and SSDT table name. So look for a file that starts with SSDT and contains xh_rvp. In the case of the ASUS ROG STRIX Z270-I GAMING it was named SSDT-4-xh_rvp08.aml. Now open the SSDT using MaciASL.

The first thing to do is review the DefinitionBlock. Here is what it looks like for the ASUS ROG STRIX Z270-I GAMING SSDT-4-xh_rvp08.aml:

DefinitionBlock ("", "SSDT", 2, "INTEL", "xh_rvp08", 0x00000000)

The first step is to rename the first field to the SSDT file name we will be using in Clover:

DefinitionBlock ("SSDT-4", "SSDT", 2, "INTEL", "xh_rvp08", 0x00000000)

You can see that the table name is fifth field of the DefinitionBlock.

Additionally you will see in the DefinitionBlock that every possible XHCI device is listed, HS01 thru HS14, SS01 thru SS10 and USR1 and USR2. But as we know from step 1 and 2 we don't have all of them implemented.

ASUS has done us a huge favor in their SSDT by documenting what ports are actually implemented. Here is what was in the ASUS ROG STRIX Z270-I GAMING SSDT:

Code:
    Name (USSD, Package (0x10)
    {
        One,
        One,
        One,
        One,
        One,
        One,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero
    })
    Name (UHSD, Package (0x10)
    {
        One,
        One,
        One,
        One,
        One,
        One,
        One,
        One,
        One,
        One,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero,
        Zero
    })

When you look at Name (USSD, Package (0x10) you will see 16 entries where each entry is a port. So the first 6 entries have a One which means SS01 thru SS06 are enabled and the next 10 have a Zero which means SS07 thru SS16 are disabled. Likewise in Name (UHSD, Package (0x10) you see 16 entries of which the first 10 have a One which means HS01 thru HS10 are active and the next 6 have a Zero which means HS11 thru HS16 are disabled. You may find on some boards that the number of entries may be different and/or the enabled ports may not be contiguous. Just count down the entries to get the port number that is enabled and/or disabled.

To actually disable a port we need to change the return value for _UPC. Here is what HS11 looks like for the ASUS ROG STRIX Z270-I GAMING as extracted:

Code:
        Scope (\_SB.PCI0.XHC.RHUB.HS11)
        {
            Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
            {
                Return (GUPC (One))
            }

            Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
            {
                Return (GPLD (DerefOf (Index (UHSD, 0x0A)), 0x0B))
            }
        }

Here is what the disabled code looks like:

Code:
        Scope (\_SB.PCI0.XHC.RHUB.HS11)
        {
            Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
            {
                Return (GUPC (Zero))
            }

            Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
            {
                Return (GPLD (DerefOf (Index (UHSD, 0x0A)), 0x0B))
            }
        }

We changed Return (GUPC (One)) to Return (GUPC (Zero)). This effectively disables the port. So do this for every HSxx and SSxx port you want to disable.

When you are done, compile the SSDT and save the compiled code using the name you used in the DefinitionBlock. For the ASUS ROG STRIX Z270-I GAMING the compiled SSDT was saved as SSDT-4.aml.

5. Verify Clover ACPI AutoMerge Setting

Before we install our new SSDT we need to ensure that Clover is configured to auto merge our new SSDT into the existing SSDT tables. MultiBeast 10.3+ and the standalone tonymacx86 Clover installers starting with v2.4k r4428 have AutoMerge set correctly. The config.plist provided in MultiBeast 10.2 or earlier looks like this at the beginning of the ACPI section:

Code:
<dict>
    <key>ACPI</key>
    <dict>
        <key>DSDT</key>
        <dict>
...

So we need to add AutoMerge=True so that our SSDT replaces the existing SSDT without reordering the SSDT tables.

Here is what it looks like after adding AutoMerge :
Code:
<dict>
    <key>ACPI</key>
    <dict>
        <key>AutoMerge</key>
        <true/>
        <key>DSDT</key>
        <dict>
...

6. Installing the SSDT

Next we need to copy the modified SSDT to the EFI volume and remove USBInjectAll.kext if it wasn't already removed. You copy the SSDT, in the case of the example SSDT-4.aml to /Volumes/EFI/EFI/CLOVER/ACPI/patched/ and reboot your system.

7. Verifying port operation

The final step is to test every port and ensure that it is working and the USB3 ports are running at 5 Gbps.

I've attached the original SSDT for the ASUS ROG STRIX Z270-I GAMING along with the modified version.
 

Attachments

  • SSDT-4-xh_rvp08.dsl
    14.4 KB · Views: 467
  • SSDT-4.dsl
    14.5 KB · Views: 607
Unless I am missing something here, RehabMan has provided an alternative method of creating an SSDT for selecting only specific USB ports to be active. The learning curve for that process seemed easier, at least for me whose knowledge of "computerese" is very limited. Documenting and mapping the USB ports is identical to the above, but once past that, using RehabMan's "SSDT-UIAC-ALL.dsl" document as a source is relatively simple, as long as the device ID of the motherboard is known. Instructions for that alternative method can be found in this forum: https://www.tonymacx86.com/threads/guide-creating-a-custom-ssdt-for-usbinjectall-kext.211311/ The only problem I had (and have) with that process is clearing my inevitable syntax errors after compiling. But eventually all works out. (If I can do it, anyone can.)

The zipped source document, and the app that opens and runs it, are attached below.
 

Attachments

  • SSDT-UIAC-ALL.dsl.zip
    2.4 KB · Views: 294
  • MaciASL RM 1.31.app.zip
    3.5 MB · Views: 265
Last edited:
Thanks @MacMan, Have this working perfectly on my Z370 Strix E

However I just wanted to ask, I have the USBX SSDT to provide 2.1A charging for all the ports however now since using this method I only get the standard 500mA on all ports defined in this method of yours, and only 2.1A fast charging port working is the seperate USB 3.1 G2 port.

Any idea why this could be the case? With a customised SSDT-UIAC and the USBinjectAll I have 2.1A charging on all ports

Also with the SSDT-UIAC I can define ports as internal / external etc, however when using this method all ports appear as 'Built-In'. On a real Mac all internal USB connections appear as "Built-In" and external ones not built in, and I have noticed too that in IOReg under "XHC" the USB ports are defined under "Ports".
 
Adding that information wasn't a priority as I was most interested in having a kext free method to enable all USB ports. It would be possible to add it to the SSDT. If I get some time I will look into it but I would be open to anyone to run with it and add the info here.
 
No need to worry about updating 3rd party, kexts clashing or if Apple blacklists them. That is why it's always better to minimize the number of add-on kexts you install.
 
MacMan - Thanks very much for your great tutorial.

Asus Z170 Hero VIII
I had a problem editing DefinitionBlock with MaciASL. When I saved SSDT-4.aml, the modified DefinitionBlock had not been saved.
It was still DefinitionBlock ("", "SSDT", 2, "INTEL", "xh_rvp08", 0x00000000)
However, the Return (GUPC (One)) to Return (GUPC (Zero)) changes were saved.

After a lot of searching, I couldn't find an answer so I put SSDT-4.aml in /Volumes/EFI/EFI/CLOVER/ACPI/patched/ with the original DefinitionBlock.
It seems to work. IORegistryExplorer shows only the enabled USB ports and my front panel USB3 ports work at full speed.

Thanks for your help.
 
Hello @MacMan! I built a new system with an Asus Z370-E, and I was wondering if you could also upload its file, since it seems you only uploaded the -I version and you mention you got it working in that motherboard too.

I'm pretty bad at these stuff, and to be honest I go a little crazy just by reading your original post. I guess though that with your Z370-E file I'd just to put it in and be done with it... right?

Thank you very much!
 
Back
Top