Simple Skylake USB Fix (no kexts required)

Back in December 2015 I blogged about My Initial ElCapitan USB workaround and yeah the nullifying of Device (XHC) was nothing more than a hack. I also forgot to share what it is that I use these days. Well. Let me start with a screenshot:
Skylake_UMAP_Patch
This shows you that all my USB 2.0 and USB 3.0 ports are enabled. I did that with this tiny SSDT:

DefinitionBlock ("ssdt_usb.aml", "SSDT", 2, "APPLE ", "Xhci", 0x00001000)
{
    External (\UMAP, IntObj)

    Scope (\_SB)
    {
        Method (_INI, 0, NotSerialized)  // _INI: Initialize
        {
            Store ("Method \\_SB._INI Called", Debug)
            Store (0xf2ff, \UMAP)
        }
    }

Now you say; “Ok. So you store a value of 0xf2ff into UMAP, but what is that?

Good question. Let’s first have a look at how UMAP is defined in the Skylake DSDT:

    Name (UMAP, 0xFFFF)

This value can, in theory, enable up to 32 USB ports since the bits are linked to physical ports (USB 2.0 and USB 3.0 on the same port share one and the same bit).

My GA-B150M-D3H (DDR4) motherboard has ten USB 2.0 (HSnn) ports and six USB 3.0 (SSnn) ports. Giving me a total of sixteen ports. We also know that there is a limit of fifteen ports, so I had one too many, but I don’t use one of the headers on the motherboard and thus I have fifteen active ports. In short. I don’t need a port limit patch.

Let’s continue with some essential code which I found in one of the SSDT’s (xh_rvp10):

    Scope (\_SB.PCI0.XHC.RHUB.HS01)
    {
        Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
        {
            If (LEqual (And (UMAP, One), One))
            {
                If (LEqual (And (HUBC, One), One))
                {
                    Return (GUPC (Zero))
                }
                Else
                {
                    Return (GUPC (One))
                }
            }
            Else
            {
                Return (GUPC (Zero))
            }
        }

        Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
        {
            If (LEqual (And (UMAP, One), One))
            {
                If (LEqual (And (HUBC, One), One))
                {
                    Return (GPLD (Zero, Zero))
                }
                Else
                {
                    Return (GPLD (One, One))
                }
            }
            Else
            {
                Return (GPLD (Zero, Zero))
            }
        }
    }

What this does is that it checks bit-0 of UMAP and when that is set/high (read: has a value of one) then the port is enabled. The same kind of code snippet is also used for port SS01 (USB 3.0):

    Scope (\_SB.PCI0.XHC.RHUB.SS01)
    {
        Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
        {
            If (LEqual (And (UMAP, One), One))
            {
                If (LEqual (And (HUBC, One), One))
                {
                    Return (GUPC (Zero))
                }
                Else
                {
                    Return (GUPC (One))
                }
            }
            Else
            {
                Return (GUPC (Zero))
            }
        }

        Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
        {
            If (LEqual (And (UMAP, One), One))
            {
                If (LEqual (And (HUBC, One), One))
                {
                    Return (GPLD (Zero, Zero))
                }
                Else
                {
                    Return (GPLD (One, One))
                }
            }
            Else
            {
                Return (GPLD (Zero, Zero))
            }
        }
    }

In fact. This kind of code snippets is used for all USB ports. The mask value is different for each port. The two sub-routines (GUPC and GPLD) are used to prevent code duplication.

We also need to know the value of HUBC and that is defined in the DSDT as:

    Name (HUBC, Zero)

Now we know the value of HUBC and thus we can strip the routine a little. No. We are not going to do that in the ACPI tables. This is only meant to help you understand what is does, and here is an example:

    Scope (\_SB.PCI0.XHC.RHUB.XXNN)
    {
        Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
        {
            If (LEqual (And (UMAP, One), One))
            {
                Return (GUPC (One))
            }
            Else
            {
                Return (GUPC (Zero))
            }
        }

        Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
        {
            If (LEqual (And (UMAP, One), One))
            {
                Return (GPLD (One, One))
            }
            Else
            {
                Return (GPLD (Zero, Zero))
            }
        }
    }

In short. Method _UPS returns Return (GUPC (One)) for active/enabled ports and Return (GUPC (Zero)) for inactive/disabled ports.

Edit: I no longer use a tiny SSDT but let RevoBoot handle it for me, but I don’t know if Clover can do this. In yes, then you want
08 55 4D 41 50 0B FF FF
in your DSDT.aml to be replaced with the value that you need for your hardware. On the other hand. You may already use a SSDT where you can add Method (_INI) {...}
or use a one liner to set the value. To me the most simple solution there is.

Long story short. If you want a real vanilla solution, then use this instead of (unsigned) third party kexts 😉

Have fun!

96 thoughts on “Simple Skylake USB Fix (no kexts required)

  1. Thanks for this!

    Can you explain how you derived 0xf2ff as the appropriate value? I can now see HS01-HS14 and SS01-SS10 with your suggestion above, but not USR1 and USR2.

    • Sure.

      1.) Open Calculator
      2.) Select View -> Programmer
      3.) Click on the button with the text: “16”
      4.) Enter value of 0xffff
      5.) Toggle the bits (31…15..0) by clicking on them

      The readout is from right to left. My first USB 2.0 port (HS00) is bit-0 and my last USB 3.0 port (SS06) is bit 15.

  2. Hi Pike,

    I looked at my dsdt, i have a slightly different code compared to yours.

    Scope (\)
                    {
                        Name (UPC0, Package (0x04)
                        {
                            0xFF, 
                            Zero, 
                            Zero, 
                            Zero
                        })
                        Name (PLD0, Buffer (0x10)
                        {
                            /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0008 */  0x91, 0x12, 0x80, 0x00, 0x03, 0x00, 0x00, 0x00 
                        })
                        Name (UPC1, Package (0x04)
                        {
                            Zero, 
                            0xFF, 
                            Zero, 
                            Zero
                        })
                        Name (PLD1, Buffer (0x10)
                        {
                            /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0008 */  0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
                        })
                        Name (UPC2, Package (0x04)
                        {
                            0xFF, 
                            Zero, 
                            Zero, 
                            Zero
                        })
                        Name (PLD2, Buffer (0x10)
                        {
                            /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0008 */  0x99, 0x10, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00 
                        })
                        Name (UPC3, Package (0x04)
                        {
                            0xFF, 
                            Zero, 
                            Zero, 
                            Zero
                        })
                        Name (PLD3, Buffer (0x10)
                        {
                            /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0008 */  0x99, 0x10, 0x80, 0x01, 0x03, 0x00, 0x00, 0x00 
                        })
                        Name (UPC4, Package (0x04)
                        {
                            0xFF, 
                            Zero, 
                            Zero, 
                            Zero
                        })
                        Name (PLD4, Buffer (0x10)
                        {
                            /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0008 */  0x93, 0x11, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00 
                        })
                        Name (UPCI, Package (0x04)
                        {
                            Zero, 
                            0xFF, 
                            Zero, 
                            Zero
                        })
                        Name (PLDI, Buffer (0x10)
                        {
                            /* 0000 */  0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0008 */  0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
                        })
                        Name (PLDC, Buffer (0x14)
                        {
                            /* 0000 */  0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0008 */  0x24, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                            /* 0010 */  0xDD, 0x00, 0x95, 0x00                         
                        })
                    }
    
    
    Scope (URTH.HSP0)
                    {
                        Method (_UPC, 0, Serialized)  // _UPC: USB Port Capabilities
                        {
                            Name (UPCP, Package (0x04)
                            {
                                Zero, 
                                Zero, 
                                Zero, 
                                Zero
                            })
                            CopyObject (UPC0, UPCP)
                            Return (UPCP)
                        }
    
                        Method (_PLD, 0, Serialized)  // _PLD: Physical Location of Device
                        {
                            Name (PLDP, Buffer (0x10) {})
                            Store (PLD0, PLDP)
                            Return (PLDP)
                        }
                    }
    

    If i understand correctly, I’m supposed to change the variables UPCX?
    but the UPCX have different values.

    • No. That won’t work. Method (_UPC, …) returns UDCP with the value of UPC0 in the first spot – your code snippet is not dynamically generated. It’s static.

      What motherboard is this? Which BIOS brand?

      • Hi, pike
        thanks for reply!
        yea,i’m kind of understand what you mean. the value of UDCP will return a set of static values based on which port is used, but i’m not sure what should i do next 😳
        i’m also not sure about the exactly model that is used for my laptop(thinkpad x1 yoga) because lenovo tends to ‘serialized’ the motherboard, bios info to a unique string (it uses a part number as the model of the motherboard) …
        here is my original dsdt/ssdt folder(https://www.dropbox.com/sh/82j7zgzoi4vl2y6/AACZeq9sg2J-GabmHQf9spyza?dl=0)
        maybe this can help to identify the brand and info?

        for the brand of bios i guess it should be American Megatrends Inc

      • cpu model is intel i7 6600u

        Store (“ssdtPRGen version….: 18.9 / Mac OS X 10.11.5 (15F34)”, Debug)
        Store (“custom mode……….: 0”, Debug)
        Store (“host processor…….: Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz”, Debug)
        Store (“target processor…..: i7-6600U”, Debug)
        Store (“number of processors.: 1”, Debug)
        Store (“baseFrequency……..: 500”, Debug)
        Store (“frequency…………: 2600”, Debug)
        Store (“busFrequency………: 100”, Debug)
        Store (“logicalCPUs……….: 4”, Debug)
        Store (“maximum TDP……….: 15”, Debug)
        Store (“packageLength……..: 28”, Debug)
        Store (“turboStates……….: 6”, Debug)
        Store (“maxTurboFrequency….: 3200”, Debug)
        Store (“machdep.xcpm.mode….: 1”, Debug)

  3. would this maybe be a solution for my asrock x99m extreme4? the typical x99 injection does not work (or i’m to low level for it)? would you like to help me if i give you my dsdt code?

    greetings

  4. Hi

    I just tried to do this using an SSDT, but I cannot seem to get it working.

    I want to disable HS01, HS02, HS07, HS08, HS10.

    My board have 6 ports which are USB 2.0 only: HS07, HS08, HS11, HS12, HS13, HS14

    This is the SSDT I’m injecting:

    DefinitionBlock ("ssdt_usb.aml", "SSDT", 2, "APPLE ", "Xhci", 0x00001000)
    {
        External (\UMAP, IntObj)
     
        Scope (\_SB)
        {
            Method (_INI, 0, NotSerialized)  // _INI: Initialize
            {
                Store ("Method \\_SB._INI Called", Debug)
                Store (0x3D3C, \UMAP)
            }
        }
    }
    

    But Iojones shows ports HS01-HS14 + SS03 enabled.

    • A few tips:

      1.) The boot loader that you are using (Clover?) may not load ssdt_usb.aml (use ssdt-n.aml instead).
      2.) There may only be one SSDT with “Xhci” in the ACPI namespace.
      3.) Make sure that \_SB._INI doesn’t already exist in any other ACPI table.
      4.) You need to have Name (\UMAP, 0XFFFF) in your DSDT (or some other value than 0xFFFF).
      5.) This only works for Skylake configurations, and even then not all of them.

      • 1) The SSDT shows up in Maciasl and Clover bootlog shows it being loaded.

        2) Just to be sure, if none shows up in Maciasl before loading the above and when loading it in Maciasl the file contains the same as the .asl file, there should be no conflict?

        3) Have to check up on that tomorrow.

        4) If not in DSDT, any way to add it other than a fully patched DSDT? (Haven’t checked yet).

        5) xh_rvp10 SSDT looks very close to what you have posted in the examples above.

        I’m on a GA-Z170X-UD3.

        Thanks for answering my questions 🙂

      • Sorry. I had a typo in my reply. Please check if you have Name (UMAP) in your DSDT (not UNAME or anything else).

        Eh. And you aren’t using/loading any kexts that inject the devices?

      • I don’t have any kexts loaded while testing this I normally use USBInjectAll by letting Clover inject it on boot.

        I’m pretty sure that I don’t have any other \_SB._INI in other ACPI tables.

        I could not find the UNAM entry anywhere in my DSDT.

        I’m not really sure about this, but it seems like something weird is going on in my xh_rvp10:

            If (LEqual (PCHV, SPTH))
            {
                Scope (\_SB.PCI0.XHC.RHUB.HS11)
        .
        .
        .
        

        I put the whole file (xh_rvp10) on pastebin here: http://pastebin.com/jLp0xya1
        The above can be found on line 436 and 819.

        EDIT: I do have a Name (UMAP, 0xFFFF), but no Name (UNAM, 0xFFFF) (or any other value).

      • Correct. The name is UMAP and not UNAM. The latter name was only used during some test runs and I got confused about the name in the comments.

        What is the value of HUBC in the DSDT?

      • EDIT2: These are the ports that I have been able to map out on my board:

        As you can see from those: I have no idea about what ports HS10 and SS07, SS08, SS10 are.

      • Name (HUBC, Zero)

        Hmm just for fun I tried this:

        Store (Zero, \UMAP)

        Now It shows HS01-HS14 in IOJones but no SSxx (SS01-SS10).

        While:

        Store (0x3D3C, \UMAP)

        Shows HS01-HS14 + SS03

      • Only the SSxx ports check UMAP. The HS01-HS14 ports don’t check UMAP but HUBC and you would need to set bits instead of clearing them.

        Edit: Your ACPI tables may include ports that are not there. I have the same problem with my boards. You can safely ignore them, remove them from the SSDT or set/clear bits for them.

      • Aha that did the trick! Thanks!

        Store (0xC2C3, \HUBC)
        Store (0x013C, \UMAP)

        I needed to disable some of the HS ports as I have 14 of those and would only be able to enable a single SS port if not disabling any HS ports.

        I didn’t notice the reversed check on HUBC, thanks for pointing me in the right direction.

        EDIT: This line threw me off a bit:
        “This value can, in theory, enable up to 32 USB ports since the bits are linked to physical ports (USB 2.0 and USB 3.0 on the same port share one and the same bit).”

        To me it sounded like enabling bit 0 of UMAP would enable HS01 and SS01.

      • While I’m at it, is there any way to define the UsbConnector type?

        I’m guessing I would have to implement something to rewrite the Index 1 of this?:

                Method (GUPC, 1, Serialized)
                {
                    Name (PCKG, Package (0x04)
                    {
                        Zero, 
                        0xFF, 
                        Zero, 
                        Zero
                    })
                    Store (Arg0, Index (PCKG, Zero))
                    Return (PCKG)
                }
        

        Could probably be as simple as:

        Store (Arg1, Index (PCKG, One))
        

        And then something like:

        Return (GUPC (One, 0x00))
        

        For a Type A port?

      • Yep that worked out 🙂

        Another question:

        Do you know what the DPxx part of these are:

        Scope (\_SB.PCI0.XHC.RHUB.HS01.DP01)

        All ports (HS01-HS14 and SS01-SS10) have DP01-DP04.

        I’m sorry for all of these questions, I’m trying to learn at least a small bit about the ACPI tables and it’s quite hard to find any good sources of information about it.

      • Yes I did. Name (HUBC, [value]) is also used to manage controllers routed through a high-speed (HSnn) or super-speed (SSnn) port. I have one sitting under SSP4 (Asmedia 107x controller) and the DPnn bits represent the (4) ports of it. Your hardware may not include one, but the ACPI tables are usually pretty common for a wide range of motherboards.

        On a side note; macOS Sierra now also recognises the USB 3.1 bus.

      • Where is the USB 3.1 bus defined? Is it the USR1 and USR2?

        As both USR1 and USR2 are disabled in my SSDT, but still show up (see below).

            Scope (\_SB.PCI0.XHC.RHUB.USR1)
            {
                Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
                {
                    Return (GUPC (Zero))
                }
        
                Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
                {
                    Return (GPLD (Zero, Zero))
                }
            }
        

        The Alpine Ridge controller shows up in System Information as a second USB 3.0 Bus in 10.11.6 on my machine.

        I’m unable to find the controller in IOJones, but I’m able to attach /some/ devices to it (iPhone, mice, and keyboard but not USB storage devices).

      • That depends in the setup of the hardware, but your USB 3.0 Bus – the one in that picture – will show up as “USB 3.1 Bus” in macOS Sierra (since DP3).

  5. Hi Piker,

    I’ve been using RehabMan’s USBInjectAll.kext till know, excluding the ports I don’t use (uia_exclude=HS07;HS08;HS12;HS13;HS14) to get to a total of 15 ports.
    but this method is indeed much more vanilla, so I tried to get it to work but with no succes, jet.

    my Asus Z170-PG acpi contains an SSDT called xh_rvp08, more or less simular to your xh_rvp10m, as it seems to me… (a part of it is shown below)

    Since I have more than 16 ports, there are 2 16 bit variables to switch ports on/off.
    USSD and UHSD, defined in the SSDT itself instead of in DSDT.

    I’ve tried to drop the xh_rvp08 ssdt with clover config, and load an edited version.(this part works, I can see the SSDT is loaded in maciASL). USSD and UHSD are edited so the ports mentioned above should be disabled.

    But it doesn’t seem to have any effect. IORegExplorer keeps showing HS01 – HS 10, and no SS01 – SS06.
    (the Rehabman USBInjectAll.kext and SSDT-usbfix, are disabled.)

    Could this work?
    What am I missing here?

    DefinitionBlock ("SSDT-5.aml", "SSDT", 2, "INTEL", "xh_rvp08", 0x00000000)
    {
    
        External (_SB_.PCI0.XHC_.RHUB, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS01, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS02, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS03, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS04, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS05, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS06, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS07, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS08, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS09, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS10, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS11, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS12, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS13, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.HS14, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS01, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS02, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS03, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS04, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS05, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS06, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS07, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS08, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS09, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.SS10, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.USR1, DeviceObj)
        External (_SB_.PCI0.XHC_.RHUB.USR2, DeviceObj)
    
        Scope (\_SB.PCI0.XHC.RHUB)
        {
            Method (GPLD, 2, Serialized)
            {
                Name (PCKG, Package (0x01)
                {
                    Buffer (0x10) {}
                })
                CreateField (DerefOf (Index (PCKG, Zero)), Zero, 0x07, REV)
                Store (One, REV) /* \_SB_.PCI0.XHC_.RHUB.GPLD.REV_ */
                CreateField (DerefOf (Index (PCKG, Zero)), 0x40, One, VISI)
                Store (Arg0, VISI) /* \_SB_.PCI0.XHC_.RHUB.GPLD.VISI */
                CreateField (DerefOf (Index (PCKG, Zero)), 0x57, 0x08, GPOS)
                Store (Arg1, GPOS) /* \_SB_.PCI0.XHC_.RHUB.GPLD.GPOS */
                Return (PCKG) /* \_SB_.PCI0.XHC_.RHUB.GPLD.PCKG */
            }
    
            Method (GUPC, 1, Serialized)
            {
                Name (PCKG, Package (0x04)
                {
                    Zero, 
                    0xFF, 
                    Zero, 
                    Zero
                })
                Store (Arg0, Index (PCKG, Zero))
                Return (PCKG) /* \_SB_.PCI0.XHC_.RHUB.GUPC.PCKG */
            }
        }
    
        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, 
            One, 
            One, 
            One, 
            One, 
            Zero, 
            Zero
        })
        Scope (\_SB.PCI0.XHC.RHUB.HS01)
        {
            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, Zero)), One))
            }
        }
    
        Scope (\_SB.PCI0.XHC.RHUB.HS02)
        {
            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, One)), 0x02))
            }
        }
    
    etcetera...
    
    
  6. ok, I thought this line was sort of a bitmask check:

    would return the zero or one set in de array UHSD at the index 0x01 (one), but that was hopeful guessing…. what does it do exactly?
    (the Ones and Zero’s do match with my usb2 an 3 ports)

    my bios is the latest: Asus Pro Gaming Z170 1901

    does xh_rvp08 or xh_rvp10 say anything abouts its content or version?

    I’ll see if I can make a modified version work, that is more like your xh_rvp10.
    Would it be ok to put the bitmask’s in that SSDT?

  7. Hey Piker! I would really love to use this method, instead of USBInjectAll.kext Unfortunately I am having trouble following your method (Editing my SSDT) and applying it with Clover. Is it possible if I send you a dumped DSDT/SSDT and you to apply this fix for in exchange for a small donation for your time? I am using the Gigabyte H170N-Wifi that has 4usb ports + 1 USBtype C w/ USB3 support.

  8. Hi Mr. Pike!
    Thanks a lot for all your work. The unsupported processor patchs are working wonderfully in my X99 with 5960X. Incredible! No Fake CPU ID, NO VoodooTSC Sync kext, No nullCPUpowermanagement kext!

    I was checking this USB fix in my Asus X99 deluxe, and incredible! It seems to work too, no USB kext at all. I am in 10.11.6. By error I delete the SSDT that joalmojuj sent me compiled. And the USB ports are working. It seem I don´t need anything (no kext, no SSDT fixes) in 10.11.6! and the OS is seeing all the USB ports… Is that possible? Thanks a lot in advance.

  9. Hi Pike,

    Like cnrd, I patch SSDT with UMAP and HUBC and the good ports are recognize on my GA-Z170MX-Gaming 5 in IORegistryExplorer without kext and “15 ports patch”. Thanks.

    DefinitionBlock ("ssdt-5.aml", "SSDT", 2, "APPLE ", "Xhci", 0x00001000)
    {
        External (\UMAP, IntObj)
        External (\HUBC, IntObj)
    
        Scope (\_SB)
        {
            Method (_INI, 0, NotSerialized)  // _INI: Initialize
            {
                Store ("Method \\_SB._INI Called", Debug)
                Store (0xCF04, \HUBC)
                Store (0x003B, \UMAP)
            }
        }
    }
    

    result : HS01, HS02, HS04, HS05, HS06, HS07, HS08, HS13, HS14, SS01, SS02, SS04, SS05, SS06 recognize.

    But when I plug a USB3 device (USB key, external hard drive…), it is recognize as USB2.
    Do you have a idea ? Thank you.

  10. Hi guys, I have a Gigabyte Z170-UD5-TH board with 6700k and wondering if anyone has attempted this board yet as i’m stuck and can’t figure it out? :/ I’m running Sierra GM and my existing usb 3 SSDT no longer works

    Many thanks in advance,
    Rob

      • It also stopped working on my system for the Sierra Installer (put on a USB drive with createinstallmedia) (verbose complain about: “could not create all ports”), but it works fine after installing.

        Luckily I’m able to create all HSxx ports even if the injector doesn’t work.

        This is all on the developer GM.

        Unrelated, but Pike: Do you know what is going on with the nvidia drivers?

        They do not work with boot flags (only nvram).

        I can only boot with a single monitor or it will sleep both screens the same way as using iMac17,1 or MacPro6,1 did in the past. (System is still running as I can ssh into it).

      • Thankyou for your help, It was working fine with 10.11.6 however when I did a fresh install of 10.12 GM it no longer works, I havent tried any betas of Sierra.
        There is a interesting bit, I have a 4 port usb 3.0 hub to which my mouse and keyboard connect and when I plug a usb 3 flash drive it runs at 5Gbps, however when I plug that same flash disk into the front or rear panel usb 3 ports it isn’t recognised at all. The front and rear usb 2.0 ports work fine however
        Im sorry it took me soo long to reply but I wasn’t able to post for some reason here it wasn’t letting me

      • Ok so Apple changed something and gave us new homework. Great.

        Have you checked the USB ports in IORegistryExplorer, to see what is going on? Your USB hub obviously connects to a working port, so which port is that? Is that the first USB 3.0 port?

      • I have no problems with wake with the usb ssdt from 10.11.6, however I only have usb 3 from the 4 port hub that I have connected from boot which is rather odd

  11. I found out that with your ssdt I am able to view all my ports (only 15 of them), however usb 3 doesn’t seem to be working even on my hub, if I plug a usb 2.0 device into a usb 3 port that is in the 15 ports that are enabled then it works
    Any luck with your scenario Chris?

    Rob

    • #1 is that in sierra, the port limit patch isn’t applying. need to take a peek . pikes probably hit it on the nose.
      after that i was able to create a ssdt that just defines the HUBC and UMAP values. i haven’t figured out the masking yet though (as what ones actually turn on/off the port)

    • This is my issue ^^. Several people have reported it in the comments here all since Sept 2016. For me, I have a USB 3.0 HDD enclosure that does 70MB/Sec on Windows and Linux. But here (Sierra 10.12.3) and with all correct USBInjectAll port mappings, it appear on ‘SS’ port (meant for USB 3). Yet the transfer speed is only 14MB/Sec. Tried all my USB 3 ports and none do the faster speed… and yeah I followed all rehabman’s guide for setting the USB type to = 3 kept within 15 port limit, etc. etc.

      On the ‘SS’ port, the exact transfer speed is like very *slightly* faster then on the ‘HS’ ports. But only by a fraction of a second. Like around 10ms per second.

  12. I have done a little research and my usb ssdt from El Capitan seems to be alright, instead it is the usbinjectall that isn’t doing its job. I installed the latest one available and only have access to the one usb 3 port thats left as all 14 others are all usb 2, IOreg reports. I don’t know why its not allowing me to have no port restriction. any ideas?

      • I’m really not sure, I tried the USB-SSDT.command script for the Z170X-UD3 however it has a few ports that are different from my Z170-UD5-TH. When I use the generated SSDT from the USB-SSDT script then I am able to use a few USB ports however only when I’m within the 15 port limit

  13. I just noticed the same problem here. Port number 0d and 0e are my only working USB3 ports.
    These two ports (on the front) are the the only usb3 ports I’ve used till now.

    The lower port numbers that are not activated, still count, so SS03 – SS06 are not working here at the moment, because they exceed the port limit.

    …to be continued.

  14. The byte pattern is still there in AppleUSBXHCIPCI but the patch has no effect.

    83 BD 8C FE FF FF 10
    0000000000005f34 cmp dword [ss:rbp+var_174], 0x10

  15. I’ve discovered that something went wrong with the port enumeration, when I used the SSDT based on SSDT-5 of CNRD. SS01 an SS02 became SS05 an SS06, the other SS ports did not get assigned to a physical port I think. I will check out later what is going wrong, exactly.
    It’s probably a difference in the order of the ports of my ASUS versus the Gigabyte board of CNRD.

    Temporarily back to usbinjectall.kext. to be continued.
    (I’m still on 10.11.6)

  16. Hi All,

    I am have a GA-Z170-UD5 rev.01 with F20b BIOS. It’s has almost the same xh_rvp10, as Sander37, except for

    Name (USSD, Package (0x10)
    Name (UHSD, Package (0x10)

    It doesn’t have HUBC or UMAP
    Here is the whole thing: http://pastebin.com/ZZ33YEvR

    What will be the best way to handle it? Add

    DefinitionBlock ("ssdt-5.aml", "SSDT", 2, "APPLE ", "Xhci", 0x00001000)
    {
    External (\UMAP, IntObj)
    External (\HUBC, IntObj)

    Scope (\_SB)
    {
    Method (_INI, 0, NotSerialized) // _INI: Initialize
    {
    Store ("Method \\_SB._INI Called", Debug)
    Store (0xCF04, \HUBC)
    Store (0x003B, \UMAP)
    }
    }
    }

    to DSDT and use cnrd’s AML?
    Thank you.

      • that was my first thought – it’s hardcoded. Pardon my ignorance, but I don’t know what UMAP and HUBC do. I would assume it’s a map of physical to logical ports. So if I have all hardcoded “active”, what does it mean for the macOS?
        In my IOReg it show 14 HS and 1 SS. I assume, that is where port limit hits.
        What if I GUPC (Zero) ports, that are not present? Is it a viable option or it will count inactive ports toward a 15 port limit anyway?

        Thank you!
        I am really honored to receive an answer from you.

      • The UMAP and HUBC are simple bit masks that are checked to enable/disable USB ports, but this check is missing from your ACPI tables. In your case the BIOS enables all of them. Hence you running into the 15 port limitation. Even ports that may not be there, or you don’t want to use, are enabled.

        The first thing I would dp is to check for ports that you want to have enabled. The next thing is to copy your current xh_rvp10 table and disable the ports in it that you do not want. For those ports you change Return (GUPC (One)) into Return (GUPC (Zero)) Then you drop the factory table from your Clover config.plist (see Clover WiKi).

        Note: I changed the bit-masks and have 15 active ports, and thus I do not need to lift the port restriction with a patch.

        p.s. If this is too complicated, then I would suggest to use the kext from Rehabman.

  17. Hi Pike, I copied your SSDT ’cause my XHC@14 listed just like you on the first picture in this post also I don’t have any experience how to create SSDT. All USB works but my bluetooth doesn’t work. It says no bluetooth available. I also tried @cnrd script but that doesn’t work either. No any bluetooth available.(https://www.tonymacx86.com/threads/native-usb-2-0-usb-3-0-on-skylake.202787/).

    Motherboard ASUS Z170-A CPU 6700K
    This is my port map;

    HS01- USB 2.0 and USB 3.0 — Case Front
    HS02- USB 2.0 and USB 3.0 — Case Front
    HS05- USB 2.0 and USB 3.0 — Mother Board Back
    HS06- USB 2.0 and USB 3.0 — Mother Board Back
    HS09- USB 2.0 — Mother Board Back
    HS10- USB 2.0 — Mother Board Back
    HS12- Internal USB 2.0
    HS14- Internal USB 2.0 WIFI-Bluetooth

    SS01 – USB 3.0
    SS02 – USB 3.0
    SS05 – USB 3.0
    SS06 – USB 3.0

    @cnrd’s script second question is ‘are you using it as an internally connected port (For example WiFi/Bluetooth module)?’
    I said yes for HS14 but no bluetooth?

    This is the SSDT which I copied from yours. With this SSDT all USB ports are working but no bluetooth. (I also removed increase port limit just like you.)

    https://app.box.com/s/cpf970l49z3pcz0gt4m3wlav5kt5xjod

    This is my WIFI-Bluetooth Combo Card;
    https://www.aliexpress.com/item/Broadcom-BCM94360CD-Dual-band-2-4GHz-5GHz-a-b-g-n-Wireless-Card-with-BT4-0/2054147349.html?spm=2114.13010608.0.0.ZUmKEN

    Actually my all USB and Bluetooth working with @Rehabman USBInjectAll.kext and increase port limit method. My big problem is when I download anything Magic Mouse is start lagging. I am waiting to finish download which I use my Magic Mouse proper way.

    I thought maybe without kext and port limit I can fix that problem.

    How to activate the bluetooth in your method?

    Thank you.

    • I have the same card and when I received it the cable (black USB connector for the motherboard) was wired the wrong way (flipped). Sorry. I currently do not have the card nearby, but you should definitely check this with someone else, if your card is new and did not work before (assuming that the driver loads).

      • My English not very well probably I explained myself wrong. My card is working OOB. As you know Bluetooth connection on this card with USB 2 Cable. I am using for this with USBInjectAll.kext and increase port limit method. With this method only problem when I download something Magic Mouse lagging. When I finished download everything turn be normal.

        But when I removed USBInjectAll.kext and increase port limit and add you SSDT method, all USB + WIFI working but Bluetooth doesn’t. Why your method doesn’t activate the Bluetooth I don’t get it.

  18. Piker,

    I am also trying to get rid of USBInjectAll.kext with an AsRock Z170 itx board. With it, all my USB ports are working, and I managed to exclude the ones I don’t need so I am under the 15 port limit.

    However, without it, I only have HS01-HS10. My DSDT looks okay, with no bitmask and all ports properly configured (with perfect _UPC and _PLD methods). I can not find any difference between HS01-HS10 and all the rest.

    If I drop my xh_rvp08 SSDT, all USB ports are gone.

    What I don’t get is why only HS01-HS10. If I’d the first 15 port, that would make sense, and I could disable port with an SSDT.

    Any ideas? Also, there is no XHCI handoff option in my bios at all.

    Thanks in advance.

      • Hi,

        I see the SSn ports in the SSDT so that is fine, but why are the first two posts, usually the front panel ports, disabled?

        Scope (\_SB.PCI0.XHC.RHUB.SS01)
        {
        Method (_UPC, 0, NotSerialized)
        {
        Return (GUPC (Zero))
        }
        Method (_PLD, 0, NotSerialized)
        {
        Return (GPLD (Zero, 0x05))
        }
        }

        Scope (\_SB.PCI0.XHC.RHUB.SS02)
        {
        Method (_UPC, 0, NotSerialized)
        {
        Return (GUPC (Zero))
        }
        Method (_PLD, 0, NotSerialized)
        {
        Return (GPLD (Zero, 0x06))
        }
        }

        To enable the ports, you have to change the “Zero” into “One”. In case you do not want them, leave it as is, but change the port numbers to One (now 0x5) and 0x2 (now 0x6) and change all following ports the same way. Up one for each enabled port. That works for me.

      • Sadly, even with your suggested modifications, I only get the HS01-HS10 ports.

        In the DSDT, these ports are the only ports that have their _ADS as a simple Name(), all the other ports are either have an _ADR method (USR1-2, SS01-06) or are inside a logic check (If (LEqual (PCHV (), SPTH)), whatever this might mean). This is only difference between the working ports and the not working ports.

        Anyway, I was just hoping the solution would be obvious for you, since you know a lot more about these ACPI tables than I do. Thanks for everything, I will keep on tinkering.

  19. Thank you for sharing! I’m about to upgrade my rig with a new MB and Kaby Lake CPU. With this upgrade, I want to keep my installation as clean and vanilla as possible. I still need to do some research and reading on SSDT’s, but before I dive in: will this code also work with a Kaby Lake CPU? Thanks again.

  20. Any idea if this still works in High Sierra? USB issues are pretty common in HS (timeouts, assertions), and creating my own SSDT with port discovery and power injection didn’t make it any better. I just want to get rid of UsbInjectAll at this point, even though I’m now under the port limit, so longer need a patch for that.

  21. Hello pikeralpha, first congratulation for your incredible knowledge in this issue, I am loosing my mind lol I have been trying to fix this on my own since about 2 months, watching youtube videos from everyone, trying everything.kexts (lol) installing, formatting, reinstalling… I need help and I can’t find this by my own. I’m just a normal user with some informatic skills but this is going far over my knowledge 😛

    I have a Mac Pro 2,1, I succesfully installed El Capitan and I can’t figured out what is wrong with my Wifi (no hardware recognized) and 4 UHCx, 1 EHC1 and 4 inatek PCI card XHCx. XHC doesn’t even appear in system dsdt.

    About this mac/system report/USB
    Bus controller : AppleUSBXHCIFL1100
    PCI ID : 0x1100
    PCI revision ID : 0x0010
    PCI provider ID : 0x1b73

    System DSDT – (I tried UHC1 and UH01 – EHCI like EH01…)
    Device (UHC1)
    {Name (_ADR, 0x001D0000) // _ADR: Address
    Name (UPS1, Package (0x02)
    {0x03, 0x03})
    Method (_PRW, 0, NotSerialized) // _PRW: Power Resources for Wake
    {Return (UPS1)}

    OperationRegion (USBR, PCI_Config, 0xC4, One)
    Field (USBR, AnyAcc, NoLock, Preserve)
    {URES, 8}

    Method (_PSW, 1, NotSerialized) // _PSW: Power State Wake
    {If (LEqual (Arg0, Zero))
    {Store (Zero, URES)}

    If (LEqual (Arg0, One))
    {Store (0x03, URES)}}}

    IORedExp
    IOUSB:/
    Root / EHCI Root Hub Simulation@1D,7
    Root / UHCI Root Hub Simulation@1D
    Root / UHCI Root Hub Simulation@1D,1
    etc…
    (there is way too much stuff to paste it here, but I can send it if you want obviously)

    I went to IOUSBfamily.kext / AppleUSBEHCI.kext, UHCI.kext, XHCI.kext…. I don’t know what to do!! Should I change the name of the file? Change everywhere it states “UHCI” to “UC0x”?
    Sigh… I hope this post is not annoying but I am a little bit out of hope… Can you help me?

    Thank you!

Leave a comment