Contribute
Register

USB-C Hotplug not working

Status
Not open for further replies.
I don't think I understand how to use your kext, btw. I tried it and it didn't work. What's the correct usage scenario?

It should attach to WTBT in IOService plane. The following will show in the log:

Code:
IOElectrify: IOElectrify::init() <ptr>
IOElectrify: Version 1.0.0 starting on OS X Darwin 17.2.
IOElectrify: IOElectrify::attach() WTBT
IOElectrify: IOElectrify::detach() <ptr>
IOElectrify: IOElectrify::attach() WTBT
IOElectrify: IOElectrify::start() WTBT
IOElectrify: found method TF with guid 86ccfd48-205e-4a77-9c48-2021cbede341
IOElectrify: setPowerState 2
IOElectrify: --> awake(2)
IOElectrify: found method TF with guid 86ccfd48-205e-4a77-9c48-2021cbede341
IOElectrify: Calling method WMTF
IOElectrify: Thunderbolt force-power: ON.

Note that both the <name> and <_UID> properties of WTBT need to match your configuration in Info.plist.

Another question though: Has anyone managed to power up their USB-C or Thunderbolt without having a device plugged at boot?
 
Last edited:
Hi, I use your ssdt, but the slot it shows as "airport" not the "thunderbolt"

do I missing something?
To get detailed help, i need an IORegistryExplorer Output of your Thunderbolt Implementation, so i can guess whats going wrong for you. Please be so kind and attach one here, so i can take a look into it.
 
To get detailed help, i need an IORegistryExplorer Output of your Thunderbolt Implementation, so i can guess whats going wrong for you. Please be so kind and attach one here, so i can take a look into it.
Here you are

Thank you
 

Attachments

  • DSDT&EFI&IOReg.zip
    5.9 MB · Views: 156
As we all know there are 3 Thunderbolt drivers in the AppleThunderboltNHI package:

  • AppleThunderboltNHI
  • AppleThunderboltNHIType2
  • AppleThunderboltNHIType3
The only one we are interested in is AppleThunderboltNHIType3, the USB-C Thunderbolt 3 driver.
All 3 drivers interact with ACPI methods to a certain extent. This might have to do with the Thunderbolt driver not showing expected results.

Going over the AppleThunderboltNHIType3 driver, the following ACPI interactions can be located:

Code:
// int64 AppleThunderboltNHIType3::setupPowerSavings(AppleThunderboltNHIType3 *this)
// int64 AppleThunderboltNHIType3::enablePower(bool)
Method (RTPC, 1, Serialized)
{
    \RMDT.P2("RP01.PXSX.DSB0.NHI0.RTPC(): ", Arg0)
}

// int64 AppleThunderboltNHIType3::setUSBMode(bool)
// int64 AppleThunderboltNHIType3::setupPowerSavings(AppleThunderboltNHIType3 *this)
Method (MUST, 1, Serialized)
{
    \RMDT.P2("RP01.PXSX.DSB0.NHI0.MUST(): ", Arg0)
}

// int64 AppleThunderboltNHIType3::setupPowerSavings(AppleThunderboltNHIType3 *this)
// int64 AppleThunderboltNHIType3::platformReset(int)
Method (XRST, 1, Serialized)
{
    \RMDT.P2("RP01.PXSX.DSB0.NHI0.XRST(): ", Arg0)
}

// int64 AppleThunderboltNHIType3::prePCIWake()
Method (TRPE, 2, Serialized)
{
    \RMDT.P3("RP01.PXSX.DSB0.NHI0.TRPE(): ", Arg0, Arg1)
}

// int64 AppleThunderboltNHIType3::lateSleep()
Method (SXFP, 1, Serialized)
{
    \RMDT.P2("RP01.PXSX.DSB0.NHI0.SXFP(): ", Arg0)
}

// int64 AppleThunderboltNHIType3::setupJTAG()
// Missing in MacBook14,1 -- No parameters
Method (JCNT, 0, Serialized)
{
    \RMDT.PUSH("RP01.PXSX.DSB0.NHI0.JCNT()")
}

// int64 AppleThunderboltNHIType3::setTMS(unsigned __int8, bool)
// Missing in MacBook14,1 -- 2 parameters (int bool)
Method (JTMS, 2, Serialized)
{
    \RMDT.P3("RP01.PXSX.DSB0.NHI0.JTMS(): ", Arg0, Arg1)
}

// int64 AppleThunderboltNHIType3::setTCK(bool)
// Missing in MacBook14,1 -- 1 parameters (bool)
Method (JTCK, 1, Serialized)
{
    \RMDT.P2("RP01.PXSX.DSB0.NHI0.JTCK(): ", Arg0)
}

// int64 AppleThunderboltNHIType3::setTDI(bool)
// Missing in MacBook14,1 -- 1 parameters (bool)
Method (JTDI, 1, Serialized)
{
    \RMDT.P2("RP01.PXSX.DSB0.NHI0.JTDI(): ", Arg0)
}

// int64 AppleThunderboltNHIType3::getTDO(bool *)
// Missing in MacBook14,1 -- 1 parameters (bool)
Method (JTDO, 0, Serialized)
{
    \RMDT.PUSH("RP01.PXSX.DSB0.NHI0.JTDO()")
}

The minimal set to be possibly implemented (match between AppleThunderboltNHIType3 and MacBookPro14,1 DSDT) would be:
  • RTPC
  • MUST
  • XRST
  • TPRE
  • SXFP
I'll continue seeing how this interaction affects the AppleIntelThunderboltNHI driver.
 
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
                })
            }
        }
    }
}
 
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:
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)
            }
        }
 
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)
        }
 
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:
Status
Not open for further replies.
Back
Top