Montag, 20. Juli 2009

21.) USB "Device Removal" problem [Update]

The modified IOUSBFamily-343.4.4.kext from the InsanelyMac Forum did not work for me. It solved the "Device Removal" problem upon wakeup from sleep, but my USB-Soundsystem does not work with this patched IOUSBFamily and there are some other issues.

So I began to study the relevant code in detail. This is the function from IOUSBFamily.kext, which marks the EHCI controller as "external" aka "Card Type=PCI":
void
AppleUSBEHCI::CheckSleepCapability(void)
{
_controllerCanSleep = true;
_hasPCIPwrMgmt = false;
_onCardBus = (0 != _device->metaCast("IOCardBusDevice"));
if ( !_device->getProperty("AAPL,clock-id") &&
!((getPlatform()->getChipSetType() == kChipSetTypeGossamer) &&
getPlatform()->getMachineType() == kGossamerTypeYosemite) )
{
if (_device->getProperty("built-in")) {

if (_device->hasPCIPowerManagement(kPCIPMCPMESupportFromD3Cold)) {
_device->setProperty(kIOPCIPMEOptionsKey, kOSBooleanTrue);
if (_device->enablePCIPowerManagement(kPCIPMCSPowerStateD3) == kIOReturnSuccess) {
_hasPCIPwrMgmt = true;
setProperty("Card Type","Built-in");
}
}
} else {
if (_device->hasPCIPowerManagement()) {
_device->setProperty(kIOPCIPMEOptionsKey, kOSBooleanTrue);
if (_device->enablePCIPowerManagement() == kIOReturnSuccess) {
_hasPCIPwrMgmt = true;
setProperty("Card Type","Built-in");
}
}
}
if (!_hasPCIPwrMgmt) {
USBError(1, "AppleUSBOHCI[%p]::CheckSleepCapability - controller will be unloaded across sleep",this);
_controllerCanSleep = false;
setProperty("Card Type","PCI");
}

} else {
setProperty("Card Type","Built-in");
}
if ( _onCardBus ) {
setProperty("Card Type","CardBus");
USBLog(1, "AppleUSBEHCI[%p]::CheckSleepCapability - i CANNOT sleep(CardBus)", this);
_controllerCanSleep = false;
}
_ExpressCardPort = ExpressCardPort(_device);
_badExpressCardAttached = false;
}

IOPCIDevice::hasPCIPowerManagement() from IOPCIFamily.kext returns false and this is actually the problem. Why it does return false? It's a bug in IOPCIFamily.kext or it's the EHCI pci device itself? To figure that out I used lspci to dump the powermanagement capabilities of the EHCI controller in the ICH10 southbride. Here is the output of lspci for the two EHCI controller:
00:1d.7 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Controller #1
Subsystem: Giga-byte Technology GA-EP45-DS5 Motherboard
Region 0: Memory at e9304000 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=0 PME+

00:1a.7 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Controller #2
Subsystem: Giga-byte Technology GA-EP45-DS5 Motherboard
Region 0: Memory at e9305000 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-

The EHCI controllers of the Gigabyte GA-EP45-DS3 mainboard are not advertising any PM capabilities:
  1. PME: D0=off
  2. PME: D1=off
  3. PME: D2=off
  4. PME: D3cold=off
  5. PME: D3hot=off
Therefore the EHCI controller are seen as external. I still don't know whether this is a problem of all ICH10 southbridges or only a typical problem of some Gigabyte mainboards. This is to output of lspci from my MacBook Pro 13. As you can see, the MacBook does advertise all PM capabilities:
00:04.1 USB Controller: nVidia Corporation Unknown device 0aa6 (rev b1)
Subsystem: nVidia Corporation Unknown device cb79
Region 0: Memory at 93489200 (32-bit, non-prefetchable)
Capabilities: [80] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-
This is the lspci output from an ASUS mainboard I've found in the Internet. It has also an ICH10 southbrigde, but with advertised PM capabilities. So the problem of the missing PM capabilities is not related to the ICH10 southbrigde:
00:1a.7 USB Controller: Intel Corporation ICH10 USB2 EHCI Controller #2
Subsystem: ASUSTeK Computer Inc. Unknown device 82d4
Region 0: Memory at fe7ffc00 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 PME-Enable- DSel=0 DScale=0 PME-


Update: There is a solution for this annoying bug. You can fix it by patching the EHCI devices in the DSDT. Gigabyte uses the names USBE and USE2 for EHCI devices. Here is the patch. You must at the green part:
Device (USBE)
{
Name (_ADR, 0x001D0007)
Method (_S3D, 0, NotSerialized)
{
If (LEqual (OSFL, 0x02))
{
Return (0x02)
}
Return (0x03)
}

Name (_PRW, Package (0x02)
{
0x0D,
0x03
})

Method (_DSM, 4, NotSerialized)
{
Store (Package (0x04)
{
"AAPL,clock-id",
Buffer (One)
{
One
},
"device-type",
Buffer (0x05)
{
"EHCI"
}
}, Local0)
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
}

}

Kommentare:

  1. I would check out this post. It might solve your USB problems. You may also apply it EHCI as well.

    http://www.insanelymac.com/forum/index.php?showtopic=168014

    AntwortenLöschen
  2. Is there a way to fix the missing PwrManagement Info of the PCI Device by patching in the DSDT?

    AntwortenLöschen
  3. I don't know. I guess it's not possible, because this info will be read from the pci config space. What I don't understand is, why some mainboards with ICH10 have pm capabilities and others not (like Gigabyte).

    AntwortenLöschen
  4. Hi,
    I was able to come up with a work around... Adding a block to the DSDT table with a reference to AAPL,clock-id.
    This is the block I added to each of the EHCI controllers:
    Method (_DSM, 4, NotSerialized)
    {
    Store (Package (0x03)
    {
    "AAPL,clock-id",
    0x0001,
    Buffer (0x01)
    {
    0x00
    }
    }, Local0)
    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
    Return (Local0)
    }

    so my full device entry looks like:
    Device (USE2)
    {
    Name (_ADR, 0x001A0007)
    Method (_S3D, 0, NotSerialized)
    {
    If (LEqual (OSFL, 0x02))
    {
    Return (0x02)
    }

    Return (0x03)
    }

    Name (_PRW, Package (0x02)
    {
    0x0D,
    0x03
    })
    Method (_DSM, 4, NotSerialized)
    {
    Store (Package (0x03)
    {
    "AAPL,clock-id",
    0x0001,
    Buffer (0x01)
    {
    0x00
    }
    }, Local0)
    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
    Return (Local0)
    }
    }

    AntwortenLöschen
  5. It is possible :) I managed to make a DSDT Patch which solves this:

    http://www.insanelymac.com/forum/index.php?s=&showtopic=155345&view=findpost&p=1240686

    AntwortenLöschen