#import <IOKit/firewire/IOFireWireController.h>
#import <IOKit/firewire/IOFWWorkLoop.h>
#import <IOKit/firewire/IOFireWireLink.h>
#import "IOFWQEventSource.h"
#import <IOKit/IOTimerEventSource.h>
IOReturn IOFireWireController::createTimeoutQ( void )
{
fTimer = IOTimerEventSource::timerEventSource( this, clockTick );
if(!fTimer)
{
return false;
}
fTimeoutQ.fTimer = fTimer;
fWorkLoop->addEventSource( fTimer );
return kIOReturnSuccess;
}
void IOFireWireController::destroyTimeoutQ( void )
{
fWorkLoop->removeEventSource(fTimer);
fTimer->release();
}
void IOFireWireController::timeoutQ::headChanged(IOFWCommand *oldHead)
{
#if 0
{
IOFWCommand *t = fHead;
if(oldHead)
IOLog("IOFireWireController::timeoutQ::headChanged(%s:%p)\n",
oldHead->getMetaClass()->getClassName(), oldHead);
else
IOLog("IOFireWireController::timeoutQ::headChanged(0)\n");
while(t) {
AbsoluteTime d = t->getDeadline();
IOLog("%s:%p deadline %llx\n",
t->getMetaClass()->getClassName(), t, AbsoluteTime_to_scalar(&d));
t = t->getNext();
}
}
#endif
if(!fHead)
{
fTimer->cancelTimeout();
}
else
{
fTimer->wakeAtTime(fHead->getDeadline());
}
}
void IOFireWireController::timeoutQ::busReset()
{
#if 0
{
IOFWCommand *t = fHead;
if(oldHead)
IOLog("IOFireWireController::timeoutQ::headChanged(%s:%p)\n",
oldHead->getMetaClass()->getClassName(), oldHead);
else
IOLog("IOFireWireController::timeoutQ::headChanged(0)\n");
while(t) {
AbsoluteTime d = t->getDeadline();
IOLog("%s:%p deadline %lx:%lx\n",
t->getMetaClass()->getClassName(), t, d.hi, d.lo);
t = t->getNext();
}
}
#endif
IOFWCommand *cmd;
cmd = fHead;
while(cmd)
{
IOFWCommand *next;
next = cmd->getNext();
if(cmd->cancelOnReset())
{
cmd->cancel(kIOFireWireBusReset);
}
cmd = next;
}
}
void IOFireWireController::clockTick(OSObject *obj, IOTimerEventSource *src)
{
IOFireWireController *me = (IOFireWireController *)obj;
me->processTimeout(src);
}
void IOFireWireController::processTimeout(IOTimerEventSource *src)
{
while (fTimeoutQ.fHead)
{
AbsoluteTime now, dead;
clock_get_uptime(&now);
#if 0
IOLog("processTimeout, time is %llx\n", AbsoluteTime_to_scalar(&now));
{
IOFWCommand *t = fTimeoutQ.fHead;
while(t) {
AbsoluteTime d = t->getDeadline();
IOLog("%s:%p deadline %lx:%lx\n",
t->getMetaClass()->getClassName(), t, AbsoluteTime_to_scalar(&d));
t = t->getNext();
}
}
#endif
dead = fTimeoutQ.fHead->getDeadline();
if(CMP_ABSOLUTETIME(&dead, &now) == 1)
break;
fFWIM->handleInterrupts( NULL, 1 );
fFWIM->flushWaitingPackets();
if(!fTimeoutQ.fHead)
break;
if(CMP_ABSOLUTETIME(&dead, &fTimeoutQ.fHead->getDeadline()) != 0)
continue;
fTimeoutQ.fHead->cancel(kIOReturnTimeout);
};
if(fTimeoutQ.fHead)
{
src->wakeAtTime(fTimeoutQ.fHead->getDeadline());
}
else
{
src->cancelTimeout();
}
}