IOUSBControllerUserClient.cpp [plain text]
#include <libkern/OSByteOrder.h>
#include <IOKit/assert.h>
#include <IOKit/IOLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOKitKeys.h>
#include <IOKit/usb/IOUSBController.h>
#include <IOKit/usb/IOUSBControllerV2.h>
#include <IOKit/usb/IOUSBLog.h>
#include "IOUSBControllerUserClient.h"
#define super IOUserClient
#ifndef kIOUserClientCrossEndianKey
#define kIOUserClientCrossEndianKey "IOUserClientCrossEndian"
#endif
#ifndef kIOUserClientCrossEndianCompatibleKey
#define kIOUserClientCrossEndianCompatibleKey "IOUserClientCrossEndianCompatible"
#endif
OSDefineMetaClassAndStructors(IOUSBControllerUserClient, IOUserClient)
enum {
kMethodObjectThis = 0,
kMethodObjectOwner
};
const IOExternalMethod
IOUSBControllerUserClient::sMethods[kNumUSBControllerMethods] =
{
{ (IOService*)kMethodObjectThis, ( IOMethod ) &IOUSBControllerUserClient::open, kIOUCScalarIScalarO, 1, 0 },
{ (IOService*)kMethodObjectThis, ( IOMethod ) &IOUSBControllerUserClient::close, kIOUCScalarIScalarO, 0, 0 },
{ (IOService*)kMethodObjectThis, ( IOMethod ) &IOUSBControllerUserClient::EnableKernelLogger, kIOUCScalarIScalarO, 1, 0 },
{ (IOService*)kMethodObjectThis, ( IOMethod ) &IOUSBControllerUserClient::SetDebuggingLevel, kIOUCScalarIScalarO, 1, 0 },
{ (IOService*)kMethodObjectThis, ( IOMethod ) &IOUSBControllerUserClient::SetDebuggingType, kIOUCScalarIScalarO, 1, 0 },
{ (IOService*)kMethodObjectThis, ( IOMethod ) &IOUSBControllerUserClient::GetDebuggingLevel, kIOUCScalarIScalarO, 0, 1 },
{ (IOService*)kMethodObjectThis, ( IOMethod ) &IOUSBControllerUserClient::GetDebuggingType, kIOUCScalarIScalarO, 0, 1 },
{ (IOService*)kMethodObjectThis, ( IOMethod )&IOUSBControllerUserClient::SetTestMode, kIOUCScalarIScalarO, 2, 0 }
,
{ (IOService*)kMethodObjectThis, ( IOMethod )&IOUSBControllerUserClient::ReadRegister, kIOUCScalarIScalarO, 2, 1 }
,
{ (IOService*)kMethodObjectThis, ( IOMethod )&IOUSBControllerUserClient::WriteRegister, kIOUCScalarIScalarO, 3, 0 }
};
const IOItemCount
IOUSBControllerUserClient::sMethodCount = sizeof( IOUSBControllerUserClient::sMethods ) /
sizeof( IOUSBControllerUserClient::sMethods[ 0 ] );
void
IOUSBControllerUserClient::SetExternalMethodVectors()
{
fMethods = sMethods;
fNumMethods = kNumUSBControllerMethods;
}
IOExternalMethod *
IOUSBControllerUserClient::getTargetAndMethodForIndex(IOService **target, UInt32 index)
{
if (index < (UInt32)fNumMethods)
{
if ((IOService*)kMethodObjectThis == fMethods[index].object)
*target = this;
else if ((IOService*)kMethodObjectOwner == fMethods[index].object)
*target = fOwner;
else
return NULL;
return (IOExternalMethod *) &fMethods[index];
}
else
return NULL;
}
bool
IOUSBControllerUserClient::initWithTask(task_t owningTask, void *security_id, UInt32 type, OSDictionary * properties)
{
if ( properties != NULL )
{
properties->setObject( kIOUserClientCrossEndianCompatibleKey, kOSBooleanTrue);
}
if (!owningTask)
return false;
fTask = owningTask;
fOwner = NULL;
fGate = NULL;
fDead = false;
SetExternalMethodVectors();
return (super::initWithTask(owningTask, security_id , type, properties));
}
bool
IOUSBControllerUserClient::start( IOService * provider )
{
fOwner = OSDynamicCast(IOUSBController, provider);
if (!fOwner)
return false;
if(!super::start(provider))
return false;
fMemMap = fOwner->getProvider()->mapDeviceMemoryWithIndex(0);
if (!fMemMap)
{
USBLog(1, "IOUSBControllerUserClient::start - unable to get a memory map");
return kIOReturnNoResources;
}
return true;
}
IOReturn
IOUSBControllerUserClient::open(bool seize)
{
IOOptionBits options = seize ? (IOOptionBits) kIOServiceSeize : 0;
USBLog(1, "+IOUSBControllerUserClient::open");
if (!fOwner)
return kIOReturnNotAttached;
if (!fOwner->open(this, options))
return kIOReturnExclusiveAccess;
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::close()
{
if (!fOwner)
return kIOReturnNotAttached;
if (fOwner && (fOwner->isOpen(this)))
fOwner->close(this);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::EnableKernelLogger(bool enable)
{
if (!fOwner)
return kIOReturnNotAttached;
KernelDebugEnable(enable);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::SetDebuggingLevel(KernelDebugLevel inLevel)
{
if (!fOwner)
return kIOReturnNotAttached;
KernelDebugSetLevel(inLevel);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::SetDebuggingType(KernelDebuggingOutputType inType)
{
if (!fOwner)
return kIOReturnNotAttached;
KernelDebugSetOutputType(inType);
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::GetDebuggingLevel(KernelDebugLevel * inLevel)
{
if (!fOwner)
return kIOReturnNotAttached;
*inLevel = KernelDebugGetLevel();
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::GetDebuggingType(KernelDebuggingOutputType * inType)
{
if (!fOwner)
return kIOReturnNotAttached;
*inType = KernelDebugGetOutputType();
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::SetTestMode(UInt32 mode, UInt32 port)
{
IOUSBControllerV2 *v2 = OSDynamicCast(IOUSBControllerV2, fOwner);
if (!v2)
return kIOReturnNotAttached;
return v2->SetTestMode(mode, port);
}
IOReturn
IOUSBControllerUserClient::ReadRegister(UInt32 offset, UInt32 size, void *value)
{
UInt8 bVal;
UInt16 wVal;
UInt32 lVal;
USBLog(1, "+IOUSBControllerUserClient::ReadRegister Offset(0x%x), Size (%d)", (int)offset, (int)size);
if (!fOwner)
return kIOReturnNotAttached;
if (!fMemMap)
return kIOReturnNoResources;
switch (size)
{
case 8:
bVal = *((UInt8 *)fMemMap->getVirtualAddress() + offset);
*(UInt8*)value = bVal;
USBLog(1, "IOUSBControllerUserClient::ReadRegister - got byte value 0x%x", bVal);
break;
case 16:
wVal = OSReadLittleInt16((void*)(fMemMap->getVirtualAddress()), offset);
*(UInt16*)value = wVal;
USBLog(1, "IOUSBControllerUserClient::ReadRegister - got word value 0x%x", wVal);
break;
case 32:
lVal = OSReadLittleInt32((void*)(fMemMap->getVirtualAddress()), offset);
*(UInt32*)value = lVal;
USBLog(1, "IOUSBControllerUserClient::ReadRegister - got long value 0x%lx", lVal);
break;
default:
USBLog(1, "IOUSBControllerUserClient::ReadRegister - invalid size");
return kIOReturnBadArgument;
}
return kIOReturnSuccess;
}
IOReturn
IOUSBControllerUserClient::WriteRegister(UInt32 offset, UInt32 size, UInt32 value)
{
USBLog(1, "+IOUSBControllerUserClient::WriteRegister Offset(0x%x), Size (%d) Value (0x%x)", (int)offset, (int)size, (int)value);
if (!fOwner)
return kIOReturnNotAttached;
return kIOReturnSuccess;
}
void
IOUSBControllerUserClient::stop( IOService * provider )
{
super::stop( provider );
if (fMemMap)
{
fMemMap->release();
fMemMap = NULL;
}
}
IOReturn
IOUSBControllerUserClient::clientClose( void )
{
if( !isInactive())
terminate();
return( kIOReturnSuccess );
}