IOFireWireAVCUserClient.cpp [plain text]
#include "IOFireWireAVCUserClient.h"
#include <IOKit/IOLib.h>
#include <IOKit/firewire/IOFireWireUnit.h>
#include <IOKit/firewire/IOFireWireController.h>
#define FWKLOG
OSDefineMetaClassAndStructors(IOFireWireAVCUserClient, IOUserClient)
IOExternalMethod IOFireWireAVCUserClient::sMethods[kIOFWAVCUserClientNumCommands] =
{
{ 0,
(IOMethod) &IOFireWireAVCUserClient::open,
kIOUCScalarIScalarO,
0,
0
},
{ 0,
(IOMethod) &IOFireWireAVCUserClient::close,
kIOUCScalarIScalarO,
0,
0
},
{ 0,
(IOMethod) &IOFireWireAVCUserClient::openWithSessionRef,
kIOUCScalarIScalarO,
1,
0
},
{ 0,
(IOMethod) &IOFireWireAVCUserClient::getSessionRef,
kIOUCScalarIScalarO,
0,
1
},
{ 0,
(IOMethod) &IOFireWireAVCUserClient::AVCCommand,
kIOUCStructIStructO,
0xffffffff,
0xffffffff
},
{ 0,
(IOMethod) &IOFireWireAVCUserClient::AVCCommandInGen,
kIOUCStructIStructO,
0xffffffff,
0xffffffff
},
{ 0,
(IOMethod) &IOFireWireAVCUserClient::updateAVCCommandTimeout,
kIOUCScalarIScalarO,
0,
0
}
};
IOFireWireAVCUserClient *IOFireWireAVCUserClient::withTask(task_t owningTask)
{
IOFireWireAVCUserClient* me = new IOFireWireAVCUserClient;
if( me )
{
if( !me->init() )
{
me->release();
return NULL;
}
me->fTask = owningTask;
}
return me;
}
bool IOFireWireAVCUserClient::init( OSDictionary * dictionary )
{
bool res = IOService::init( dictionary );
fOpened = false;
fStarted = false;
return res;
}
bool IOFireWireAVCUserClient::start( IOService * provider )
{
FWKLOG(( "IOFireWireAVCUserClient : starting\n" ));
if( fStarted )
return false;
fUnit = OSDynamicCast(IOFireWireAVCNub, provider);
if (fUnit == NULL)
return false;
if( !IOUserClient::start(provider) )
return false;
fStarted = true;
do {
IOService *fwim = fUnit->getDevice()->getBus()->getProvider();
OSNumber *num;
UInt32 device;
UInt32 generation;
UInt16 nodeID;
num = OSDynamicCast(OSNumber, fwim->getProperty("PHY Vendor_ID"));
if(!num)
break;
if(num->unsigned32BitValue() != 0x601d)
break;
num = OSDynamicCast(OSNumber, fwim->getProperty("PHY Device_ID"));
if(!num)
break;
device = num->unsigned32BitValue();
if(device != 0x81400 && device != 0x81401)
break;
IOFireWireController *control = fUnit->getDevice()->getController();
control->getIRMNodeID(generation, nodeID);
if(nodeID == control->getLocalNodeID()) {
FWKLOG(("Setting AVC device to root\n"));
fUnit->getDevice()->getNodeIDGeneration(generation, nodeID);
control->makeRoot(generation, nodeID);
IOSleep(1000); }
} while (false);
return true;
}
IOExternalMethod* IOFireWireAVCUserClient::getTargetAndMethodForIndex(IOService **target, UInt32 index)
{
if( index >= kIOFWAVCUserClientNumCommands )
return NULL;
else
{
*target = this;
return &sMethods[index];
}
}
IOExternalAsyncMethod* IOFireWireAVCUserClient::getAsyncTargetAndMethodForIndex(IOService **target, UInt32 index)
{
#if 0
if( index >= kIOFWAVCUserClientNumAsyncCommands )
return NULL;
else
{
*target = this;
return &sAsyncMethods[index];
}
#else
return NULL;
#endif
}
IOReturn IOFireWireAVCUserClient::clientClose( void )
{
FWKLOG(( "IOFireWireAVCUserClient : clientClose\n" ));
if( fOpened )
{
fOpened = false;
}
fStarted = false;
terminate( kIOServiceRequired );
return kIOReturnSuccess;
}
IOReturn IOFireWireAVCUserClient::clientDied( void )
{
FWKLOG(( "IOFireWireAVCUserClient : clientDied\n" ));
return clientClose();
}
IOReturn IOFireWireAVCUserClient::open
( void *, void *, void *, void *, void *, void * )
{
IOReturn status = kIOReturnSuccess;
FWKLOG(( "IOFireWireAVCUserClient : open\n" ));
if( fOpened )
status = kIOReturnError;
if( status == kIOReturnSuccess )
{
if( fUnit->open(this) )
{
fOpened = true;
}
else
status = kIOReturnExclusiveAccess;
}
return status;
}
IOReturn IOFireWireAVCUserClient::openWithSessionRef( IOFireWireSessionRef sessionRef, void *, void *, void *, void *, void * )
{
IOReturn status = kIOReturnSuccess;
IOService * service;
FWKLOG(( "IOFireWireAVCUserClient : openWithSessionRef\n" ));
if( fOpened || !fUnit->isOpen() )
status = kIOReturnError;
if( status == kIOReturnSuccess )
{
service = OSDynamicCast( IOService, (OSObject*)sessionRef );
if( service == NULL )
status = kIOReturnBadArgument;
}
if( status == kIOReturnSuccess )
{
while( fUnit != service && service != NULL )
service = service->getProvider();
if( service == NULL )
status = kIOReturnBadArgument;
}
return status;
}
IOReturn IOFireWireAVCUserClient::getSessionRef( IOFireWireSessionRef * sessionRef, void *, void *, void *, void *, void * )
{
IOReturn status = kIOReturnSuccess;
FWKLOG(( "IOFireWireAVCUserClient : getSessionRef\n" ));
if( !fOpened )
status = kIOReturnError;
if( status == kIOReturnSuccess )
{
*sessionRef = (IOFireWireSessionRef)this;
}
return status;
}
IOReturn IOFireWireAVCUserClient::close
( void *, void *, void *, void *, void *, void * )
{
FWKLOG(( "IOFireWireAVCUserClient : close\n" ));
if( fOpened )
{
fUnit->close(this);
fOpened = false;
}
return kIOReturnSuccess;
}
IOReturn IOFireWireAVCUserClient::AVCCommand(UInt8 * cmd, UInt8 * response,
UInt32 len, UInt32 *size)
{
IOReturn res;
res = fUnit->AVCCommand(cmd,len,response,size);
IOSleep(8); return res;
}
IOReturn IOFireWireAVCUserClient::AVCCommandInGen(UInt8 * cmd, UInt8 * response,
UInt32 len, UInt32 *size)
{
IOReturn res;
UInt32 generation;
generation = *(UInt32 *)cmd;
cmd += sizeof(UInt32);
len -= sizeof(UInt32);
res = fUnit->AVCCommandInGeneration(generation,cmd,len,response,size);
IOSleep(8); return res;
}
IOReturn IOFireWireAVCUserClient::updateAVCCommandTimeout
( void *, void *, void *, void *, void *, void * )
{
fUnit->updateAVCCommandTimeout();
return kIOReturnSuccess;
}