IOFWReadCommand.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(IOFWReadCommand, IOFWAsyncCommand)
OSMetaClassDefineReservedUnused(IOFWReadCommand, 0);
OSMetaClassDefineReservedUnused(IOFWReadCommand, 1);
#pragma mark -
void IOFWReadCommand::gotPacket(int rcode, const void* data, int size)
{
setResponseCode( rcode );
if(rcode != kFWResponseComplete) {
if(rcode == kFWResponseTypeError && fMaxPack > 4) {
fMaxPack = 4;
size = 0;
}
else {
complete(kIOFireWireResponseBase+rcode);
return;
}
}
else {
fMemDesc->writeBytes(fBytesTransferred, data, size);
fSize -= size;
fBytesTransferred += size;
}
if(fSize > 0) {
fAddressLo += size;
fControl->freeTrans(fTrans); updateTimer();
fCurRetries = fMaxRetries;
execute();
}
else {
complete(kIOReturnSuccess);
}
}
bool IOFWReadCommand::initAll(IOFireWireNub *device, FWAddress devAddress,
IOMemoryDescriptor *hostMem, FWDeviceCallback completion,
void *refcon, bool failOnReset)
{
return IOFWAsyncCommand::initAll(device, devAddress,
hostMem, completion, refcon, failOnReset);
}
bool IOFWReadCommand::initAll(IOFireWireController *control,
UInt32 generation, FWAddress devAddress,
IOMemoryDescriptor *hostMem, FWDeviceCallback completion,
void *refcon)
{
return IOFWAsyncCommand::initAll(control, generation, devAddress,
hostMem, completion, refcon);
}
IOReturn IOFWReadCommand::reinit(FWAddress devAddress,
IOMemoryDescriptor *hostMem,
FWDeviceCallback completion, void *refcon, bool failOnReset)
{
return IOFWAsyncCommand::reinit(devAddress,
hostMem, completion, refcon, failOnReset);
}
IOReturn IOFWReadCommand::reinit(UInt32 generation, FWAddress devAddress,
IOMemoryDescriptor *hostMem,
FWDeviceCallback completion, void *refcon)
{
return IOFWAsyncCommand::reinit(generation, devAddress,
hostMem, completion, refcon);
}
IOReturn IOFWReadCommand::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;
}