IOFWAsyncPHYCommand.cpp [plain text]
#include <IOKit/firewire/IOFWCommand.h>
#include <IOKit/firewire/IOFireWireController.h>
#include <IOKit/firewire/IOFireWireNub.h>
#include <IOKit/firewire/IOLocalConfigDirectory.h>
#include <IOKit/assert.h>
#include <IOKit/IOWorkLoop.h>
#include <IOKit/IOCommand.h>
#pragma mark -
OSDefineMetaClassAndStructors( IOFWAsyncPHYCommand, IOFWCommand )
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 0 );
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 1 );
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 2 );
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 3 );
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 4 );
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 5 );
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 6 );
OSMetaClassDefineReservedUnused( IOFWAsyncPHYCommand, 7 );
#pragma mark -
bool IOFWAsyncPHYCommand::initAll(
IOFireWireController * control,
UInt32 generation,
UInt32 data1,
UInt32 data2,
FWAsyncPHYCallback completion,
void * refcon,
bool failOnReset )
{
bool success = true;
success = IOFWCommand::initWithController( control );
if( success )
{
fMaxRetries = kFWCmdDefaultRetries;
fCurRetries = fMaxRetries;
fTrans = NULL;
fData1 = data1;
fData2 = data2;
fComplete = completion;
fSync = (completion == NULL);
fRefCon = refcon;
fTimeout = 1000*125;
fGeneration = generation;
fFailOnReset = failOnReset;
if( !fFailOnReset )
{
fGeneration = fControl->getGeneration();
}
}
return success;
}
void IOFWAsyncPHYCommand::free()
{
IOFWCommand::free();
}
IOReturn IOFWAsyncPHYCommand::reinit(
UInt32 generation,
UInt32 data1,
UInt32 data2,
FWAsyncPHYCallback completion,
void * refcon,
bool failOnReset )
{
if( fStatus == kIOReturnBusy || fStatus == kIOFireWirePending )
return fStatus;
fComplete = completion;
fRefCon = refcon;
fSync = (completion == NULL);
fCurRetries = fMaxRetries;
fTrans = NULL;
fData1 = data1;
fData2 = data2;
fGeneration = generation;
fFailOnReset = failOnReset;
if( !fFailOnReset )
{
fGeneration = fControl->getGeneration();
}
return (fStatus = kIOReturnSuccess);
}
IOReturn IOFWAsyncPHYCommand::complete(IOReturn status)
{
IOFWCommand::fMembers->fCompletionStatus = status;
if( fStatus == kIOFireWireCompleting )
{
return kIOReturnSuccess;
}
fStatus = kIOFireWireCompleting;
fControl->handleAsyncCompletion( this, status );
IOReturn completion_status = IOFWCommand::fMembers->fCompletionStatus;
removeFromQ(); if(fTrans)
{
fControl->freeTrans( fTrans );
fTrans = NULL;
}
if( (completion_status == kIOFireWireBusReset) && !fFailOnReset)
{
if( fControl->scanningBus() )
{
setHead( fControl->getAfterResetHandledQ() );
return fStatus = kIOFireWirePending; }
}
fStatus = completion_status;
if( fSync )
{
fSyncWakeup->signal( completion_status );
}
else if( fComplete )
{
(*fComplete)( fRefCon, completion_status, fControl, this );
}
return completion_status;
}
void IOFWAsyncPHYCommand::setRetries( int retries )
{
fMaxRetries = retries;
fCurRetries = fMaxRetries;
};
void IOFWAsyncPHYCommand::setAckCode( int ack )
{
fAckCode = ack;
}
int IOFWAsyncPHYCommand::getAckCode( void )
{
return fAckCode;
}
void IOFWAsyncPHYCommand::setResponseCode( UInt32 rcode )
{
fResponseCode = rcode;
}
UInt32 IOFWAsyncPHYCommand::getResponseCode( void ) const
{
return fResponseCode;
}
void IOFWAsyncPHYCommand::gotAck( int ackCode )
{
setAckCode( ackCode );
if( ackCode == kFWAckComplete )
{
complete( kIOReturnSuccess );
}
else
{
complete( kIOReturnTimeout );
}
}
void IOFWAsyncPHYCommand::gotPacket( int rcode )
{
setResponseCode( rcode );
if( rcode != kFWResponseComplete )
{
complete( kIOFireWireResponseBase+rcode );
}
else
{
complete( kIOReturnSuccess );
}
}
IOReturn IOFWAsyncPHYCommand::execute()
{
IOReturn result;
fStatus = kIOReturnBusy;
fTrans = fControl->allocTrans( NULL, this );
if( fTrans )
{
result = fControl->asyncPHYPacket( fGeneration, fData1, fData2, this);
}
else
{
result = kIOFireWireOutOfTLabels;
}
IOReturn status = fStatus;
if( result != kIOReturnSuccess )
{
retain();
complete( result );
status = fStatus;
release();
}
return status;
}