Contribute
Register

USB-C Hotplug not working

Status
Not open for further replies.
Joined
Dec 3, 2011
Messages
437
Motherboard
HP Elite X2
CPU
i5-7600U
Graphics
HD 620 2736 x 1834
Mac
  1. MacBook Pro
  2. Mac Pro
Classic Mac
  1. 128K
  2. 512K
Mobile Phone
  1. iOS
Small discrepancy I came across when looking at a MacBookPro14,1.

The USB-C part of the Thunderbolt connector has a device-id of 8086:15b6, my Dell XPS 9360 has 8086:15b5.
Both are the DSL6340 USB 3.1 Controller [Alpine Ridge] controller.

However due to the device-id mis-match on the XPS, macOS is loading AppleUSBXHCI as a driver, whereas on the MacBookPro14,1 it loads AppleUSBXHCIAR.

Modifying the device-id in the DSDT promptly causes only 2 USB ports to show up, one USB 3 (SSP1) and USB 3.1 (SSP2) which matches the physical device layout.

DSDT with the required layout and properties for XPS 9630:

Code:
Device (XHC2)
{
    Name (_ADR, Zero)  // _ADR: Address

    Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
    {
        \RMDT.PUSH("_SB.PCI0.RP01.PXSX.DSB2.XHC2: Entering _DSM")

        If (Arg2 == Zero) { Return (Buffer() { 0x03 } ) }

        Return (Package()
        {
            "USBBusNumber", Zero,
            "AAPL,xhci-clock-id", One,
            "UsbCompanionControllerPresent", One,
            "device-id", Buffer() { 0xb6, 0x15, 0x00, 0x00 },
        })
    }

    Device (RHUB)
    {
        Name (_ADR, Zero)  // _ADR: Address
        Method (GPLD, 2, Serialized)
        {
            Name (PCKG, Package (0x01)
            {
                Buffer (0x10) {}
            })
            CreateField (DerefOf (PCKG [Zero]), Zero, 0x07, REV)
            REV = One
            CreateField (DerefOf (PCKG [Zero]), 0x40, One, VISI)
            VISI = Arg0
            CreateField (DerefOf (PCKG [Zero]), 0x57, 0x08, GPOS)
            GPOS = Arg1
            Return (PCKG)
        }

        Method (GUPC, 1, Serialized)
        {
            Name (PCKG, Package (0x04)
            {
                Zero,
                0xFF,
                Zero,
                Zero
            })
            PCKG [Zero] = Arg0
            Return (PCKG)
        }

        Method (TPLD, 2, Serialized)
        {
            Name (PCKG, Package (0x01)
            {
                Buffer (0x10) {}
            })
            CreateField (DerefOf (PCKG [Zero]), Zero, 0x07, REV)
            REV = One
            CreateField (DerefOf (PCKG [Zero]), 0x40, One, VISI)
            VISI = Arg0
            CreateField (DerefOf (PCKG [Zero]), 0x57, 0x08, GPOS)
            GPOS = Arg1
            CreateField (DerefOf (PCKG [Zero]), 0x4A, 0x04, SHAP)
            SHAP = One
            CreateField (DerefOf (PCKG [Zero]), 0x20, 0x10, WID)
            WID = 0x08
            CreateField (DerefOf (PCKG [Zero]), 0x30, 0x10, HGT)
            HGT = 0x03
            Return (PCKG)
        }

        Method (TUPC, 1, Serialized)
        {
            Name (PCKG, Package (0x04)
            {
                One,
                Zero,
                Zero,
                Zero
            })
            PCKG [One] = Arg0
            Return (PCKG)
        }

        Device (SSP1)
        {
            Name (_ADR, One)  // _ADR: Address
            Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
            {
                Return (TUPC (0x09))
            }

            Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
            {
                Return (TPLD (One, One))
            }

            Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
            {
                \RMDT.PUSH("_SB.PCI0.RP01.PXSX.DSB2.XHC2.SSP1: Entering _DSM")

                If (Arg2 == Zero) { Return (Buffer() { 0x03 } ) }

                Return (Package()
                {
                    "UsbCPortNumber", 0x02,
                    "UsbCompanionPortPresent", One
                })
            }
        }

        Device (SSP2)
        {
            Name (_ADR, 0x03)  // _ADR: Address
            Method (_UPC, 0, NotSerialized)  // _UPC: USB Port Capabilities
            {
                Return (TUPC (0x09))
            }

            Method (_PLD, 0, NotSerialized)  // _PLD: Physical Location of Device
            {
                Return (TPLD (One, One))
            }

            Method (_DSM, 4, NotSerialized)  // _DSM: Device-Specific Method
            {
                \RMDT.PUSH("_SB.PCI0.RP01.PXSX.DSB2.XHC2.SSP2: Entering _DSM")

                If (Arg2 == Zero) { Return (Buffer() { 0x03 } ) }

                Return (Package()
                {
                    "UsbCPortNumber", One,
                    "UsbCompanionPortPresent", One
                })
            }
        }
    }
}

It seems that 8086:15bd may be valid as well, though my DSDT also appears to be fairly complete when it comes to USB C so that may have something to do with it as well. For myself, setting RMV to one is all it takes for reliable USB-C hotplug (video output and storage devices tested). I don't have any thunderbolt devices to test with so I don't know what happens when those are plugged in but the bridges appear when a USB C device is attached. USB-C1.pngUSB-C.png
 
Joined
Jul 3, 2014
Messages
934
Motherboard
Dell XPS 9360 (KabyLake R)
CPU
Intel i7 8550U
Graphics
Intel UHD 620
Mac
  1. MacBook
  2. MacBook Pro
Mobile Phone
  1. Android
I don't have any thunderbolt devices to test with so I don't know what happens when those are plugged in but the bridges appear when a USB C device is attached.

True USB works without the change, but shows 4 ports for me in the IORegistry.

USB-C hotplug also works if you did not boot initially with an USB device inserted?

Note that your screenshot already shows AppleUSBXHCIAR loaded. I'll do some more digging to see what the differences / benefits of AppleUSBXHCIAR over AppleUSBXHCI are.
 
Last edited:
Joined
Dec 3, 2011
Messages
437
Motherboard
HP Elite X2
CPU
i5-7600U
Graphics
HD 620 2736 x 1834
Mac
  1. MacBook Pro
  2. Mac Pro
Classic Mac
  1. 128K
  2. 512K
Mobile Phone
  1. iOS
USB-C hotplug also works if you did not boot initially with an USB device inserted?

That's correct, it does. Here's the portion of my DSDT that pertains to USB-C (already hot patched for RMV)

Code:
        Scope (_SB.PCI0.RP01.PXSX)
        {
            Method (_RMV, 0, NotSerialized)  // _RMV: Removal Status
            {
                Return (One)
            }

            Device (EP02)
            {
                Name (_ADR, 0x00020000)  // _ADR: Address
                Device (TXHC)
                {
                    Name (_ADR, Zero)  // _ADR: Address
                    Method (_PRW, 0, NotSerialized)  // _PRW: Power Resources for Wake
                    {
                        Store (Package (0x02)
                            {
                                Zero,
                                Zero
                            }, Local0)
                        Store (0x6D, Index (Local0, Zero))
                        If (LEqual (USWE, One))
                        {
                            Store (0x03, Index (Local0, One))
                        }

                        Return (Local0)
                    }

                    Device (RHUB)
                    {
                        Name (_ADR, Zero)  // _ADR: Address
                        Device (HS01)
                        {
                            Name (_ADR, One)  // _ADR: Address
                            Method (_UPC, 0, Serialized)  // _UPC: USB Port Capabilities
                            {
                                Return (GUPC (0xFF, 0x09))
                            }

                            Method (_PLD, 0, Serialized)  // _PLD: Physical Location of Device
                            {
                                Return (TPLD (One, 0x14))
                            }
                        }

                        Device (HS02)
                        {
                            Name (_ADR, 0x02)  // _ADR: Address
                            Method (_UPC, 0, Serialized)  // _UPC: USB Port Capabilities
                            {
                                Return (GUPC (Zero, 0xFF))
                            }

                            Method (_PLD, 0, Serialized)  // _PLD: Physical Location of Device
                            {
                                Return (TPLD (Zero, 0x15))
                            }
                        }

                        Device (SS01)
                        {
                            Name (_ADR, 0x03)  // _ADR: Address
                            Method (_UPC, 0, Serialized)  // _UPC: USB Port Capabilities
                            {
                                Return (GUPC (0xFF, 0x09))
                            }

                            Method (_PLD, 0, Serialized)  // _PLD: Physical Location of Device
                            {
                                Return (TPLD (One, 0x14))
                            }
                        }

                        Device (SS02)
                        {
                            Name (_ADR, 0x04)  // _ADR: Address
                            Method (_UPC, 0, Serialized)  // _UPC: USB Port Capabilities
                            {
                                Return (GUPC (Zero, 0xFF))
                            }

                            Method (_PLD, 0, Serialized)  // _PLD: Physical Location of Device
                            {
                                Return (TPLD (Zero, 0x15))
                            }
                        }
                    }
                }
            }

            Method (_PS0, 0, Serialized)  // _PS0: Power State 0
            {
            }

            Method (_PS3, 0, Serialized)  // _PS3: Power State 3
            {
                Store (" Host router Upstream port _PS3", Debug)
                Acquire (OSUM, 0xFFFF)
                Store (MMTB (), Local0)
                \_GPE.SXST (Local0)
                Release (OSUM)
            }
        }
 
Joined
Dec 3, 2011
Messages
437
Motherboard
HP Elite X2
CPU
i5-7600U
Graphics
HD 620 2736 x 1834
Mac
  1. MacBook Pro
  2. Mac Pro
Classic Mac
  1. 128K
  2. 512K
Mobile Phone
  1. iOS
Can you post _GPE.SXST? I'm interested to see more of that function.

Sure -

Code:
        Method (SXST, 1, Serialized)
        {
            Add (Arg0, 0x0548, Local0)
            OperationRegion (PXVD, SystemMemory, Local0, 0x08)
            Field (PXVD, DWordAcc, NoLock, Preserve)
            {
                TB2P,   32,
                P2TB,   32
            }

            Store (0x64, Local1)
            Store (TB2P, Local2)
            Store ("SXST 0x1D cmd", Debug)
            Store (0x3B, P2TB)
            While (LGreater (Local1, Zero))
            {
                Store (Subtract (Local1, One), Local1)
                Store (TB2P, Local2)
                If (LEqual (Local2, 0xFFFFFFFF))
                {
                    Store ("Dev gone", Debug)
                    Return (0x02)
                }

                If (And (Local2, One))
                {
                    Store ("Cmd acknowledged", Debug)
                    Break
                }

                Sleep (0x32)
            }

            Store (Zero, P2TB)
            Sleep (0x32)
            Store ("End-of-SXST", Debug)
            Return (One)
        }
 
Joined
Mar 23, 2017
Messages
39
Motherboard
Razer Blade 15
CPU
i7-8750H
Graphics
HD 630, GTX 1070
of cause you can have it, but currently it is configured for my personal setup. I have connected a CalDigit Thunderbolt3 Station to one of my internal TB3 ports. So the TBT3 SSDT is configured to use the Ethernet-, USB3.1- and eSATA-Ports of that TB3-Station,
and this will be the result in IORegExplorer:
Bildschirmfoto2017-11-13um21.17.58.png

All connected Thunderbolt devices will be correctly detected - but none of them shows up in SystemProfiler under "Thunderbolt" tab. Each device gets listed under their corresponding Device-TAB: Ethernet, SATA and USB. And also listed under the PCI-Devices tab:
Bildschirmfoto2017-11-13um21.24.50.png

Btw: can't set corresponding "Thunderbolt"-names for USB0 and XHC1, cause i don't know how to set:
Name (_ADR, Zero) // _ADR: Address
for "XHC1@01000000" or "USB0@00000000". If anyone is able to help, don't hesitate to post solution here.

So use it at your own risk...

SSDT-7-eGpu.aml is my configuration to get an AkitioNode eGPU connected to onbard Thunderbolt3 port.
DSDT.aml is unmodified, original DSDT from my ASRock Z270 SuperCarrier Motherboard with latest BIOS 2.20

I am wondering how you mapped your devices to the specific addresses. Do your TB3 devices show up when you have it connected? In my case, the devices do not load and are not recognised by macOS (but the kexts do load, but do not initialise).
 
Joined
Jun 12, 2012
Messages
350
Another question though: Has anyone managed to power up their USB-C or Thunderbolt without having a device plugged at boot?

Goodwin_C was able to in that other thread. You may want to contact him since it looks like you're re-discovering things we already found (he was able to get USB-C 100% working, and got stuck on establishing a Thunderbolt handshake IIRC).

EDIT:
Also
15b5 DSL6340 USB 3.1 Controller [Alpine Ridge]
15b6 DSL6540 USB 3.1 Controller [Alpine Ridge]
From https://pci-ids.ucw.cz/read/PC/8086

Looks like Apple played a game of "mix n match" if it combined 6340 TB with 6540 USB IDs.
I could've sworn that there's a Mac with a 6340, though; guess I was wrong. Does a simple hex edit in USBXHCIAR fix the mismatch?
 
Last edited:
Joined
Jul 3, 2014
Messages
934
Motherboard
Dell XPS 9360 (KabyLake R)
CPU
Intel i7 8550U
Graphics
Intel UHD 620
Mac
  1. MacBook
  2. MacBook Pro
Mobile Phone
  1. Android
Goodwin_C was able to in that other thread.
.....
Does a simple hex edit in USBXHCIAR fix the mismatch?

I haven't seen any activity from goodwin_c as of late. Lets see if he's still around.

Putting device-id in DSM is enough to make AppleUSBXHCIAR load instead of AppleUSBXHCI.

I might write a USCI USB driver for MacOS, this would allow us to be notified in a cross system compatible way of any cable plugs/unplugs. That would be a good leverage point to potentially undertake activities with regards to PCI rescanning on those events.
 
Joined
Oct 20, 2011
Messages
41
Motherboard
DELL XPS 9550
CPU
i7-6700HQ
Graphics
HD 530 / GTX960M
Mobile Phone
  1. Android
I haven't seen any activity from goodwin_c as of late. Lets see if he's still around.

Putting device-id in DSM is enough to make AppleUSBXHCIAR load instead of AppleUSBXHCI.

I might write a USCI USB driver for MacOS, this would allow us to be notified in a cross system compatible way of any cable plugs/unplugs. That would be a good leverage point to potentially undertake activities with regards to PCI rescanning on those events.

As topic for my lovely 9550 was banned on Tony - i have stopped most of my activity here, except of some read-only :) I'm trying to write here as less as possible. Viva la other forums.

As of powering on TBT on boot - best place ever, IMHO, is - _OSI method (or, as most are using - XOSI). Just add call to TBFP on the beginning of custom XOSI - and you are done with enabled TB on early stages (as fast as ACPI platform will get initialized by darwin core)
Regarding fully functional TBT... Guys, you are trying to invent workarounds. Sure, great if you can. But it's not really what we need.
Main problem is that TB controller (i'm talking about ICM - connection manager of TB) - is not working at all in Hackintosh. TB is complex system, with internal firmware, with ability to configure input-output lines, with full duplex messaging system between controller and OS. Just open IORegExplorer and check LocalNode and ThunderboltPort - they are not Matched. Also - open ThunderboltHAL and check Statistics - you will see that TB driver is not getting any "proper" responses from TB ICM.
I have some suggestions that needs deep digging, analysing and reverse engineering. First of all - good source for understanding TB internals is here - https://github.com/torvalds/linux/tree/master/drivers/thunderbolt
Also, it's still not clear why there are communication problems as communication layer looks clean, it has no cryptography and on TB3 it is common for all hardware (doesn't matter is it mac or not). Maybe, something with ACPI. Maybe, hardware is not getting initialized in time. Or even maybe TB controller is not booted in correct mode and needs reset (still can't find enough time to investigate all this PCI-X config memory features to find out how to properly reset TB - it needs special sequence by writing command into ICM memory and later sending reset command to PCI device, you can see this in Linux driver)
Also, looks like TB driver has problems with internal TB enumeration - it should read DROM from controller and using this info - populate all Ports in IOreg. On early stages - Mac efi driver is writing device properthy with shorted version of DROM - it is easy to generate this part (done on my machine). But, i suggest that later driver reads real DROM from controller. And there is tricky thing - there is machine type and vendor in that string, and maybe (just maybe, i'm not sure) - driver doesn't like our "Dell" and "XPS" from there :) Again, needs time, knowledge and digging
 
Joined
Oct 20, 2011
Messages
41
Motherboard
DELL XPS 9550
CPU
i7-6700HQ
Graphics
HD 530 / GTX960M
Mobile Phone
  1. Android
By the way - as i understand things - notification layer in TB3 is not on ACPI level. Thunderbolt 3 is MMIO based device - and there is memory-region for communication mailbox. And separate IRQ. So it is supposed that any changes in TB configuration should go through ICM interface (and NHI device is where it is located)
 
Status
Not open for further replies.
Top