IOFWReadQuadCommand.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/IOSyncer.h>
#include <IOKit/IOWorkLoop.h>
#include <IOKit/IOCommand.h>
OSDefineMetaClassAndStructors(IOFWReadQuadCommand, IOFWAsyncCommand)
OSMetaClassDefineReservedUnused(IOFWReadQuadCommand, 0);
OSMetaClassDefineReservedUnused(IOFWReadQuadCommand, 1);
#pragma mark -
void IOFWReadQuadCommand::gotPacket(int rcode, const void* data, int size)
{
setResponseCode( rcode );
if(rcode != kFWResponseComplete) {
if( (rcode == kFWResponseTypeError || rcode == kFWResponseAddressError) && fMaxPack > 4) {
fMaxPack = 4;
size = 0;
}
else {
complete(kIOFireWireResponseBase+rcode);
return;
}
}
else {
int i;
UInt32 *src = (UInt32 *)data;
for(i=0; i<size/4; i++)
*fQuads++ = *src++;
fSize -= size;
fBytesTransferred += size ;
}
if(fSize > 0) {
fAddressLo += size;
updateTimer();
fCurRetries = fMaxRetries;
fControl->freeTrans(fTrans);
execute();
}
else {
complete(kIOReturnSuccess);
}
}
bool IOFWReadQuadCommand::initAll(IOFireWireNub *device, FWAddress devAddress,
UInt32 *quads, int numQuads, FWDeviceCallback completion,
void *refcon, bool failOnReset)
{
if(!IOFWAsyncCommand::initAll(device, devAddress,
NULL, completion, refcon, failOnReset))
return false;
fSize = 4*numQuads;
fQuads = quads;
return true;
}
bool IOFWReadQuadCommand::initAll(IOFireWireController *control,
UInt32 generation, FWAddress devAddress,
UInt32 *quads, int numQuads, FWDeviceCallback completion,
void *refcon)
{
if(!IOFWAsyncCommand::initAll(control, generation, devAddress,
NULL, completion, refcon))
return false;
fSize = 4*numQuads;
fQuads = quads;
return true;
}
IOReturn IOFWReadQuadCommand::reinit(FWAddress devAddress,
UInt32 *quads, int numQuads, FWDeviceCallback completion,
void *refcon, bool failOnReset)
{
IOReturn res;
res = IOFWAsyncCommand::reinit(devAddress,
NULL, completion, refcon, failOnReset);
if(res != kIOReturnSuccess)
return res;
fSize = 4*numQuads;
fQuads = quads;
return res;
}
IOReturn IOFWReadQuadCommand::reinit(UInt32 generation, FWAddress devAddress,
UInt32 *quads, int numQuads, FWDeviceCallback completion, void *refcon)
{
IOReturn res;
res = IOFWAsyncCommand::reinit(generation, devAddress,
NULL, completion, refcon);
if(res != kIOReturnSuccess)
return res;
fSize = 4*numQuads;
fQuads = quads;
return res;
}
IOReturn IOFWReadQuadCommand::execute()
{
IOReturn result;
int transfer;
fStatus = kIOReturnBusy;
if(!fFailOnReset) {
fDevice->getNodeIDGeneration(fGeneration, fNodeID);
fSpeed = fControl->FWSpeed( fNodeID );
if( fMembers->fMaxSpeed < fSpeed )
{
fSpeed = fMembers->fMaxSpeed;
}
}
transfer = fSize;
if(transfer > fMaxPack)
{
transfer = fMaxPack;
}
int maxPack = (1 << fControl->maxPackLog(fWrite, fNodeID));
if( maxPack < transfer )
{
transfer = maxPack;
}
fTrans = fControl->allocTrans(this);
if(fTrans) {
result = fControl->asyncRead(fGeneration, fNodeID, fAddressHi,
fAddressLo, fSpeed, fTrans->fTCode, transfer, this);
}
else {
result = kIOFireWireOutOfTLabels;
}
IOReturn status = fStatus;
if(result != kIOReturnSuccess)
{
retain();
complete(result);
status = fStatus;
release();
}
return status;
}