#define DEBUGGING_LEVEL 0 // 1 = low; 2 = high; 3 = extreme
#define DEBUGLOG kprintf
#include <IOKit/assert.h>
#include <IOKit/IOMessage.h>
#include <IOKit/firewire/IOFireWireNub.h>
#include <IOKit/firewire/IOFireWireController.h>
#include <IOKit/firewire/IOConfigDirectory.h>
#include <IOKit/firewire/IOFireWireUserClient.h>
OSDefineMetaClass( IOFireWireNub, IOService )
OSDefineAbstractStructors(IOFireWireNub, IOService)
OSMetaClassDefineReservedUnused(IOFireWireNub, 0);
OSMetaClassDefineReservedUnused(IOFireWireNub, 1);
OSMetaClassDefineReservedUnused(IOFireWireNub, 2);
OSMetaClassDefineReservedUnused(IOFireWireNub, 3);
bool IOFireWireNub::init(OSDictionary * propTable)
{
OSNumber *offset;
if( !IOService::init(propTable))
return (false);
offset = OSDynamicCast(OSNumber, propTable->getObject("GUID"));
if(offset)
fUniqueID = offset->unsigned64BitValue();
return true;
}
void IOFireWireNub::free()
{
if(fDirectory)
fDirectory->release();
IOService::free();
}
IOFWSpeed IOFireWireNub::FWSpeed() const
{
return fControl->FWSpeed(fNodeID);
}
IOFWSpeed IOFireWireNub::FWSpeed(const IOFireWireNub *dst) const
{
return fControl->FWSpeed(fNodeID, dst->fNodeID);
}
int IOFireWireNub::maxPackLog(bool forSend) const
{
int log = fControl->maxPackLog(forSend, fNodeID);
return log;
}
int IOFireWireNub::maxPackLog(bool forSend, FWAddress address) const
{
int log = fControl->maxPackLog(forSend, fNodeID);
if(forSend) {
if(log > fMaxWritePackLog)
log = fMaxWritePackLog;
}
else if(address.addressHi == kCSRRegisterSpaceBaseAddressHi &&
address.addressLo > kConfigROMBaseAddress &&
address.addressLo < kConfigROMBaseAddress + 1024) {
if(log > fMaxReadROMPackLog)
log = fMaxReadROMPackLog;
}
else if(log > fMaxReadPackLog)
log = fMaxReadPackLog;
return log;
}
int IOFireWireNub::maxPackLog(bool forSend, const IOFireWireNub *dst) const
{
int log;
if(forSend) {
log = fControl->maxPackLog(fNodeID, dst->fNodeID);
}
else {
log = fControl->maxPackLog(dst->fNodeID, fNodeID);
}
return log;
}
void IOFireWireNub::setMaxPackLog(bool forSend, bool forROM, int maxPackLog)
{
if(forSend)
fMaxWritePackLog = maxPackLog;
else if(forROM)
fMaxReadROMPackLog = maxPackLog;
else
fMaxReadPackLog = maxPackLog;
}
IOFWReadCommand *IOFireWireNub::createReadCommand(FWAddress devAddress, IOMemoryDescriptor *hostMem,
FWDeviceCallback completion, void *refcon,
bool failOnReset)
{
IOFWReadCommand * cmd;
cmd = new IOFWReadCommand;
if(cmd) {
if(!cmd->initAll(this, devAddress,
hostMem, completion, refcon, failOnReset)) {
cmd->release();
cmd = NULL;
}
}
return cmd;
}
IOFWReadQuadCommand *IOFireWireNub::createReadQuadCommand(FWAddress devAddress, UInt32 *quads, int numQuads,
FWDeviceCallback completion, void *refcon,
bool failOnReset)
{
IOFWReadQuadCommand * cmd;
cmd = new IOFWReadQuadCommand;
if(cmd) {
if(!cmd->initAll(this, devAddress, quads, numQuads,
completion, refcon, failOnReset)) {
cmd->release();
cmd = NULL;
}
}
return cmd;
}
IOFWWriteCommand *IOFireWireNub::createWriteCommand(FWAddress devAddress, IOMemoryDescriptor *hostMem,
FWDeviceCallback completion, void *refcon,
bool failOnReset)
{
IOFWWriteCommand * cmd;
cmd = new IOFWWriteCommand;
if(cmd) {
if(!cmd->initAll(this, devAddress, hostMem,
completion, refcon, failOnReset)) {
cmd->release();
cmd = NULL;
}
}
return cmd;
}
IOFWWriteQuadCommand *IOFireWireNub::createWriteQuadCommand(FWAddress devAddress,
UInt32 *quads, int numQuads,
FWDeviceCallback completion, void *refcon,
bool failOnReset)
{
IOFWWriteQuadCommand * cmd;
cmd = new IOFWWriteQuadCommand;
if(cmd) {
if(!cmd->initAll(this, devAddress, quads, numQuads,
completion, refcon, failOnReset)) {
cmd->release();
cmd = NULL;
}
}
return cmd;
}
IOFWCompareAndSwapCommand *
IOFireWireNub::createCompareAndSwapCommand(FWAddress devAddress, const UInt32 *cmpVal, const UInt32 *newVal,
int size, FWDeviceCallback completion, void *refcon, bool failOnReset)
{
IOFWCompareAndSwapCommand * cmd;
cmd = new IOFWCompareAndSwapCommand;
if(cmd) {
if(!cmd->initAll(this, devAddress, cmpVal, newVal, size, completion, refcon, failOnReset)) {
cmd->release();
cmd = NULL;
}
}
return cmd;
}
IOFWPhysicalAddressSpace *IOFireWireNub::createPhysicalAddressSpace(IOMemoryDescriptor *mem)
{
return fControl->createPhysicalAddressSpace(mem);
}
IOFWPseudoAddressSpace *IOFireWireNub::createPseudoAddressSpace(FWAddress *addr, UInt32 len,
FWReadCallback reader, FWWriteCallback writer, void *refcon)
{
return fControl->createPseudoAddressSpace(addr, len, reader, writer, refcon);
}
IOReturn IOFireWireNub::getConfigDirectory(IOConfigDirectory *&dir)
{
dir = fDirectory;
return (kIOReturnSuccess);
}
IOReturn IOFireWireNub::newUserClient(task_t owningTask,
void * ,
UInt32 type,
IOUserClient ** handler )
{
IOReturn err = kIOReturnSuccess;
IOFireWireUserClient * client;
if( type != 11)
return( kIOReturnBadArgument);
client = IOFireWireUserClient::withTask(owningTask);
if( !client || (false == client->attach( this )) ||
(false == client->start( this )) ) {
if(client) {
client->detach( this );
client->release();
}
err = kIOReturnNoMemory;
}
*handler = client;
return( err );
}