IOUSBRootHubDevice.cpp [plain text]
#include <libkern/OSByteOrder.h>
#include <IOKit/usb/IOUSBLog.h>
#include <IOKit/usb/IOUSBRootHubDevice.h>
#include <IOKit/usb/IOUSBHubPolicyMaker.h>
#include <IOKit/usb/IOUSBControllerV3.h>
#define super IOUSBHubDevice
#define self this
#ifndef IOUSBROOTHUBDEVICE_USE_KPRINTF
#define IOUSBROOTHUBDEVICE_USE_KPRINTF 0
#endif
#if IOUSBROOTHUBDEVICE_USE_KPRINTF
#undef USBLog
#undef USBError
void kprintf(const char *format, ...)
__attribute__((format(printf, 1, 2)));
#define USBLog( LEVEL, FORMAT, ARGS... ) if ((LEVEL) <= IOUSBROOTHUBDEVICE_USE_KPRINTF) { kprintf( FORMAT "\n", ## ARGS ) ; }
#define USBError( LEVEL, FORMAT, ARGS... ) { kprintf( FORMAT "\n", ## ARGS ) ; }
#endif
#define SAFE_RELEASE_NULL(object) do { \
if (object) object->release(); \
(object) = NULL; \
} while (0)
#define _IORESOURCESENTRY _expansionData->_IOResourcesEntry
OSDefineMetaClassAndStructors( IOUSBRootHubDevice, IOUSBHubDevice )
IOUSBRootHubDevice*
IOUSBRootHubDevice::NewRootHubDevice()
{
IOUSBRootHubDevice *me = new IOUSBRootHubDevice;
if (!me)
return NULL;
if (!me->init())
{
me->release();
me = NULL;
}
return me;
}
bool
IOUSBRootHubDevice::init()
{
if (!super::init())
return false;
if (!_expansionData)
{
_expansionData = (ExpansionData *)IOMalloc(sizeof(ExpansionData));
if (!_expansionData)
return false;
bzero(_expansionData, sizeof(ExpansionData));
}
return true;
}
bool
IOUSBRootHubDevice::InitializeCharacteristics()
{
UInt32 characteristics = kIOUSBHubDeviceIsRootHub;
USBLog(5, "%s[%p]::InitializeCharacteristics", getName(), this);
if (GetSpeed() == kUSBDeviceSpeedHigh)
characteristics |= kIOUSBHubDeviceIsOnHighSpeedBus;
SetHubCharacteristics(characteristics);
return true;
}
bool
IOUSBRootHubDevice::start(IOService *provider)
{
mach_timespec_t timeSpec;
bool returnValue = false;
USBLog(5, "%s[%p]::start", getName(), this);
timeSpec.tv_sec = 5;
timeSpec.tv_nsec = 0;
_IORESOURCESENTRY = waitForService(serviceMatching("IOResources"), &timeSpec);
returnValue = super::start(provider);
if ( !returnValue)
{
USBLog(5, "IOUSBRootHubDevice[%p]::start - super returned false", this);
return false;
}
_commandGate = IOUSBDevice::_expansionData->_commandGate;
_commandGate->retain();
USBLog(5, "%s[%p]::start (_commandGate %p)", getName(), this, IOUSBDevice::_expansionData->_commandGate);
return returnValue;
}
void
IOUSBRootHubDevice::stop( IOService *provider )
{
if ( _commandGate )
{
_commandGate->release();
_commandGate = NULL;
}
super::stop(provider);
}
void
IOUSBRootHubDevice::free()
{
if (_expansionData)
{
IOFree(_expansionData, sizeof(ExpansionData));
_expansionData = NULL;
}
super::free();
}
IOReturn
IOUSBRootHubDevice::GatedDeviceRequest (OSObject *owner, void *arg0, void *arg1, void *arg2, void *arg3 )
{
IOUSBRootHubDevice *me = (IOUSBRootHubDevice*)owner;
if (!me)
return kIOReturnNotResponding;
return me->DeviceRequestWorker((IOUSBDevRequest*)arg0, (uintptr_t)arg1, (uintptr_t)arg2, (IOUSBCompletion*)arg3);
}
IOReturn
IOUSBRootHubDevice::DeviceRequest(IOUSBDevRequest *request, IOUSBCompletion *completion)
{
return DeviceRequest(request, 0, 0, completion);
}
IOReturn
IOUSBRootHubDevice::DeviceRequest(IOUSBDevRequest *request, UInt32 noDataTimeout, UInt32 completionTimeout, IOUSBCompletion *completion)
{
if (!IOUSBDevice::_expansionData->_commandGate)
{
USBLog(5, "IOUSBRootHubDevice[%p]::DeviceRequest - but no IOUSBDevice::_expansionData->_commandGate", this);
return kIOReturnNotResponding;
}
if (_myPolicyMaker && (_myPolicyMaker->getPowerState() == kIOUSBHubPowerStateLowPower))
{
USBLog(5, "IOUSBRootHubDevice[%p]::DeviceRequest - doing a device request while in low power mode - should be OK", this);
}
return (IOUSBDevice::_expansionData->_commandGate)->runAction(GatedDeviceRequest, request, (void*)noDataTimeout, (void*)completionTimeout, completion);
}
IOReturn
IOUSBRootHubDevice::DeviceRequestWorker(IOUSBDevRequest *request, UInt32 noDataTimeout, UInt32 completionTimeout, IOUSBCompletion *completion)
{
#pragma unused (noDataTimeout, completionTimeout, completion)
IOReturn err = 0;
UInt16 theRequest;
UInt8 dType, dIndex;
if (!request)
return(kIOReturnBadArgument);
theRequest = (request->bRequest << 8) | request->bmRequestType;
switch (theRequest)
{
case kClearDeviceFeature:
if (request->wIndex == 0)
err = _controller->ClearRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kGetDescriptor:
dType = request->wValue >> 8;
dIndex = request->wValue & 0x00FF;
switch (dType) {
case kUSBDeviceDesc:
err = _controller->GetRootHubDeviceDescriptor((IOUSBDeviceDescriptor*)request->pData);
request->wLenDone = sizeof(IOUSBDeviceDescriptor);
break;
case kUSBConfDesc:
{
OSData *fullDesc = OSData::withCapacity(1024); UInt16 newLength;
err = _controller->GetRootHubConfDescriptor(fullDesc);
newLength = fullDesc->getLength();
if (newLength < request->wLength)
request->wLength = newLength;
bcopy(fullDesc->getBytesNoCopy(), (char *)request->pData, request->wLength);
request->wLenDone = request->wLength;
fullDesc->free();
break;
}
case kUSBStringDesc:
{
OSData *fullDesc = OSData::withCapacity(1024); UInt16 newLength;
err = _controller->GetRootHubStringDescriptor((request->wValue & 0x00ff), fullDesc);
newLength = fullDesc->getLength();
if (newLength < request->wLength)
request->wLength = newLength;
bcopy(fullDesc->getBytesNoCopy(), (char *)request->pData, request->wLength);
request->wLenDone = request->wLength;
fullDesc->free();
break;
}
default:
err = kIOReturnBadArgument;
}
break;
case kGetDeviceStatus:
if ((request->wValue == 0) && (request->wIndex == 0) && (request->pData != 0))
{
*(UInt16*)(request->pData) = HostToUSBWord(1); request->wLenDone = 2;
}
else
err = kIOReturnBadArgument;
break;
case kSetAddress:
if (request->wIndex == 0)
err = _controller->SetHubAddress(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kSetConfiguration:
if (request->wIndex == 0)
configuration = request->wValue;
else
err = kIOReturnBadArgument;
break;
case kSetDeviceFeature:
if (request->wIndex == 0)
err = _controller->SetRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kGetConfiguration:
if ((request->wIndex == 0) && (request->pData != 0))
{
*(UInt8*)(request->pData) = configuration;
request->wLenDone = 1;
}
else
err = kIOReturnBadArgument;
break;
case kClearInterfaceFeature:
case kClearEndpointFeature:
case kGetInterface:
case kGetInterfaceStatus:
case kGetEndpointStatus:
case kSetInterfaceFeature:
case kSetEndpointFeature:
case kSetDescriptor:
case kSetInterface:
case kSyncFrame:
err = kIOReturnUnsupported;
break;
case kClearHubFeature:
if (request->wIndex == 0)
err = _controller->ClearRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kClearPortFeature:
err = _controller->ClearRootHubPortFeature(request->wValue, request->wIndex);
break;
case kGetPortState:
if ((request->wValue == 0) && (request->pData != 0))
err = _controller->GetRootHubPortState((UInt8 *)request->pData, request->wIndex);
else
err = kIOReturnBadArgument;
break;
case kGetHubDescriptor:
if ((request->wValue == ((kUSBHubDescriptorType << 8) + 0)) && (request->pData != 0))
{
err = _controller->GetRootHubDescriptor((IOUSBHubDescriptor *)request->pData);
request->wLenDone = sizeof(IOUSBHubDescriptor);
}
else
err = kIOReturnBadArgument;
break;
case kGetHubStatus:
if ((request->wValue == 0) && (request->wIndex == 0) && (request->pData != 0))
{
err = _controller->GetRootHubStatus((IOUSBHubStatus *)request->pData);
request->wLenDone = sizeof(IOUSBHubStatus);
}
else
err = kIOReturnBadArgument;
break;
case kGetPortStatus:
if ((request->wValue == 0) && (request->pData != 0))
{
err = _controller->GetRootHubPortStatus((IOUSBHubPortStatus *)request->pData, request->wIndex);
request->wLenDone = sizeof(IOUSBHubPortStatus);
}
else
err = kIOReturnBadArgument;
break;
case kSetHubDescriptor:
if (request->pData != 0)
err = _controller->SetRootHubDescriptor((OSData *)request->pData);
else
err = kIOReturnBadArgument;
break;
case kSetHubFeature:
if (request->wIndex == 0)
err = _controller->SetRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kSetPortFeature:
err = _controller->SetRootHubPortFeature(request->wValue, request->wIndex);
break;
default:
err = kIOReturnBadArgument;
}
return(err);
}
bool
IOUSBRootHubDevice::IsRootHub(void)
{
return true;
}
UInt32
IOUSBRootHubDevice::RequestExtraPower(UInt32 requestedPower)
{
OSNumber * numberObject = NULL;
UInt32 totalExtraCurrent = 0;
UInt32 maxPowerPerPort = 0;
UInt32 extraAllocated = 0;
OSObject * propertyObject = NULL;
if ( (_expansionData == NULL) || ( _IORESOURCESENTRY == NULL ))
{
USBLog(5, "%s[%p]::RequestExtraPower - _expansionData or _IORESOURCESENTRY is NULL", getName(), this);
return 0;
}
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentExtra);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
totalExtraCurrent = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::RequestExtraPower - we have a kAppleCurrentExtra with %d", getName(), this, (uint32_t) totalExtraCurrent);
}
SAFE_RELEASE_NULL(propertyObject);
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentAvailable);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
maxPowerPerPort = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::RequestExtraPower - we have a kAppleCurrentAvailable with %d", getName(), this, (uint32_t) maxPowerPerPort);
}
SAFE_RELEASE_NULL(propertyObject);
USBLog(5, "%s[%p]::RequestExtraPower - requestedPower = %d, available: %d", getName(), this, (uint32_t)requestedPower, (uint32_t) totalExtraCurrent);
if (requestedPower > (maxPowerPerPort-500)) {
USBLog(5, "%s[%p]::RequestExtraPower - requestedPower = %d was grater than the maximum per port of %d. Using that value instead", getName(), this, (uint32_t)requestedPower, (uint32_t) (maxPowerPerPort-500));
requestedPower = maxPowerPerPort-500;
}
if (requestedPower <= totalExtraCurrent)
{
extraAllocated = requestedPower;
totalExtraCurrent -= extraAllocated;
USBLog(5, "%s[%p]::RequestExtraPower - setting kAppleCurrentExtra to %d", getName(), this, (uint32_t) totalExtraCurrent);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentExtra, totalExtraCurrent, 32);
}
USBLog(5, "%s[%p]::RequestExtraPower - extraAllocated = %d", getName(), this, (uint32_t)extraAllocated);
return extraAllocated;
}
void
IOUSBRootHubDevice::ReturnExtraPower(UInt32 returnedPower)
{
OSNumber * numberObject = NULL;
OSObject * propertyObject = NULL;
UInt32 powerAvailable = 0;
USBLog(5, "%s[%p]::ReturnExtraPower - returning = %d", getName(), this, (uint32_t)returnedPower);
if ( (_expansionData == NULL) || ( _IORESOURCESENTRY == NULL ))
{
USBLog(5, "%s[%p]::ReturnExtraPower - _expansionData or _IORESOURCESENTRY is NULL", getName(), this);
return;
}
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentExtra);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
powerAvailable = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::ReturnExtraPower - we have a kAppleCurrentExtra with %d", getName(), this, (uint32_t) powerAvailable);
}
SAFE_RELEASE_NULL(propertyObject);
if (returnedPower > 0)
{
powerAvailable += returnedPower;
USBLog(5, "%s[%p]::ReturnExtraPower - setting kAppleCurrentExtra to %d", getName(), this, (uint32_t) powerAvailable);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentExtra, powerAvailable, 32);
}
return;
}
void
IOUSBRootHubDevice::InitializeExtraPower(UInt32 maxPortCurrent, UInt32 totalExtraCurrent)
{
OSNumber * numberObject = NULL;
OSObject * propertyObject = NULL;
UInt32 propertyValue = 0;
USBLog(5, "%s[%p]::InitializeExtraPower - maxPortCurrent = %d, totalExtraCurrent: %d", getName(), this, (uint32_t)maxPortCurrent, (uint32_t) totalExtraCurrent);
if ( _expansionData == NULL )
{
USBLog(5, "%s[%p]::InitializeExtraPower - _expansionData is NULL", getName(), this);
return;
}
if ( _IORESOURCESENTRY == NULL)
{
USBLog(5, "%s[%p]::InitializeExtraPower - no _IORESOURCESENTRY available", getName(), this);
}
else
{
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentExtra);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
propertyValue = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::InitializeExtraPower - we have a kAppleCurrentExtra with %d", getName(), this, (uint32_t) propertyValue);
if ( propertyValue < totalExtraCurrent)
{
USBLog(5, "%s[%p]::InitializeExtraPower - kAppleCurrentExtra, setting it to %d", getName(), this, (uint32_t) totalExtraCurrent);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentExtra, totalExtraCurrent, 32);
}
}
else
{
USBLog(5, "%s[%p]::InitializeExtraPower - we did NOT have a kAppleCurrentExtra, setting it to %d", getName(), this, (uint32_t) totalExtraCurrent);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentExtra, totalExtraCurrent, 32);
}
SAFE_RELEASE_NULL(propertyObject);
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentAvailable);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
propertyValue = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::InitializeExtraPower - we have a kAppleCurrentAvailable with %d", getName(), this, (uint32_t) propertyValue);
if (propertyValue < maxPortCurrent )
{
USBLog(1, "%s[%p]::InitializeExtraPower - we have a kAppleCurrentAvailable with %d, but maxPortCurrent is %d, setting it to that", getName(), this, (uint32_t) propertyValue, (uint32_t) maxPortCurrent);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentAvailable, maxPortCurrent, 32);
}
}
else
{
USBLog(5, "%s[%p]::InitializeExtraPower - we did NOT have a kAppleCurrentAvailable in IOResources, setting it to %d", getName(), this, (uint32_t) maxPortCurrent);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentAvailable, maxPortCurrent, 32);
}
SAFE_RELEASE_NULL(propertyObject);
}
super::InitializeExtraPower(maxPortCurrent, totalExtraCurrent);
}
void
IOUSBRootHubDevice::SetSleepCurrent(UInt32 sleepCurrent)
{
OSNumber * numberObject = NULL;
OSObject * propertyObject = NULL;
UInt32 propertyValue = 0;
USBLog(5, "%s[%p]::SetSleepCurrent - %d", getName(), this, (uint32_t)sleepCurrent);
if ( (_expansionData == NULL) || ( _IORESOURCESENTRY == NULL ))
{
USBLog(5, "%s[%p]::SetSleepCurrent - _expansionData or _IORESOURCESENTRY is NULL", getName(), this);
return;
}
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentInSleep);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
propertyValue = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::SetSleepCurrent - we have a kAppleCurrentInSleep with %d", getName(), this, (uint32_t) propertyValue);
}
SAFE_RELEASE_NULL(propertyObject);
if ( propertyValue < sleepCurrent )
{
USBLog(5, "%s[%p]::SetSleepCurrent - setting kAppleCurrentInSleep to %d", getName(), this, (uint32_t) sleepCurrent);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentInSleep, sleepCurrent, 32);
}
}
UInt32
IOUSBRootHubDevice::GetSleepCurrent()
{
OSNumber * numberObject = NULL;
OSObject * propertyObject = NULL;
UInt32 propertyValue = 0;
if ( (_expansionData == NULL) || ( _IORESOURCESENTRY == NULL ))
{
USBLog(5, "%s[%p]::GetSleepCurrent - _expansionData or _IORESOURCESENTRY is NULL", getName(), this);
return 0;
}
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentInSleep);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
propertyValue = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::SetSleepCurrent - we have a kAppleCurrentInSleep with %d", getName(), this, (uint32_t) propertyValue);
}
SAFE_RELEASE_NULL(propertyObject);
USBLog(5, "%s[%p]::GetSleepCurrent - returning %d", getName(), this, (uint32_t)propertyValue);
return propertyValue;
}
UInt32
IOUSBRootHubDevice::RequestSleepPower(UInt32 requestedPower)
{
OSNumber * numberObject = NULL;
OSObject * propertyObject = NULL;
UInt32 totaSleepCurrent = 0;
UInt32 maxPowerPerPort = 0;
UInt32 extraAllocated = 0;
if ( (_expansionData == NULL) || ( _IORESOURCESENTRY == NULL ))
{
USBLog(5, "%s[%p]::RequestSleepPower - _expansionData or _IORESOURCESENTRY is NULL", getName(), this);
return 0;
}
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentInSleep);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
totaSleepCurrent = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::RequestSleepPower - we have a kAppleCurrentInSleep with %d", getName(), this, (uint32_t) totaSleepCurrent);
}
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentAvailable);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
maxPowerPerPort = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::RequestSleepPower - we have a kAppleCurrentAvailable with %d", getName(), this, (uint32_t) maxPowerPerPort);
}
SAFE_RELEASE_NULL(propertyObject);
USBLog(5, "%s[%p]::RequestSleepPower - requestedPower = %d, available: %d", getName(), this, (uint32_t)requestedPower, (uint32_t) totaSleepCurrent);
if (requestedPower > maxPowerPerPort) {
USBLog(5, "%s[%p]::RequestSleepPower - requestedPower = %d was more than the maximum per port of: %d, limiting request to %d", getName(), this, (uint32_t)requestedPower, (uint32_t) maxPowerPerPort, (uint32_t) maxPowerPerPort);
requestedPower = maxPowerPerPort;
}
if (requestedPower <= totaSleepCurrent)
{
extraAllocated = requestedPower;
totaSleepCurrent -= extraAllocated;
USBLog(5, "%s[%p]::RequestSleepPower - setting kAppleCurrentInSleep to %d", getName(), this, (uint32_t) totaSleepCurrent);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentInSleep, totaSleepCurrent, 32);
}
USBLog(5, "%s[%p]::RequestSleepPower - extraAllocated = %d", getName(), this, (uint32_t)extraAllocated);
return extraAllocated;
}
void
IOUSBRootHubDevice::ReturnSleepPower(UInt32 returnedPower)
{
OSNumber * numberObject = NULL;
OSObject * propertyObject = NULL;
UInt32 powerAvailable = 0;
USBLog(5, "%s[%p]::ReturnSleepPower - returning = %d", getName(), this, (uint32_t)returnedPower);
propertyObject = (_IORESOURCESENTRY)->copyProperty(kAppleCurrentInSleep);
numberObject = OSDynamicCast(OSNumber, propertyObject);
if (numberObject)
{
powerAvailable = numberObject->unsigned32BitValue();
USBLog(5, "%s[%p]::ReturnSleepPower - we have a kAppleCurrentInSleep with %d", getName(), this, (uint32_t) powerAvailable);
}
SAFE_RELEASE_NULL(propertyObject);
if (returnedPower > 0)
{
powerAvailable += returnedPower;
USBLog(5, "%s[%p]::ReturnSleepPower - setting kAppleCurrentInSleep to %d", getName(), this, (uint32_t) powerAvailable);
(_IORESOURCESENTRY)->setProperty(kAppleCurrentInSleep, powerAvailable, 32);
}
return;
}
IOReturn
IOUSBRootHubDevice::GetDeviceInformation(UInt32 *info)
{
OSObject * propertyObject = NULL;
OSString * theString = NULL;
bool isBuiltIn = false;
*info = 0;
*info =(( 1 << kUSBInformationDeviceIsCaptiveBit ) |
( 1 << kUSBInformationDeviceIsInternalBit ) |
( 1 << kUSBInformationDeviceIsConnectedBit ) |
( 1 << kUSBInformationDeviceIsEnabledBit ) |
( 1 << kUSBInformationDeviceIsRootHub )
);
propertyObject = _controller->copyProperty("Card Type");
theString = OSDynamicCast(OSString, propertyObject);
if ( theString)
isBuiltIn = theString->isEqualTo("Built-in");
SAFE_RELEASE_NULL(propertyObject);
if (isBuiltIn)
*info |= (1 << kUSBInformationRootHubisBuiltIn);
USBLog(2, "IOUSBRootHubDevice[%p]::GetDeviceInformation returning 0x%x", this, (uint32_t)*info);
return kIOReturnSuccess;
}
OSMetaClassDefineReservedUsed(IOUSBRootHubDevice, 0);
OSMetaClassDefineReservedUsed(IOUSBRootHubDevice, 1);
OSMetaClassDefineReservedUsed(IOUSBRootHubDevice, 2);
OSMetaClassDefineReservedUsed(IOUSBRootHubDevice, 3);
OSMetaClassDefineReservedUnused(IOUSBRootHubDevice, 4);