--- a/kernel/eka/drivers/iic/iic_channel.cpp Thu Aug 19 11:14:22 2010 +0300
+++ b/kernel/eka/drivers/iic/iic_channel.cpp Tue Aug 31 16:34:26 2010 +0300
@@ -129,6 +129,9 @@
void DIicBusChannelMaster::CompleteRequest(TInt aResult)
{
+ // Ensure the timeout timer has been cancelled
+ CancelTimeOut();
+
TIicBusTransaction* nextTrans=NextTrans(iCurrentTransaction);
if((aResult != KErrNone)||(nextTrans == NULL))
@@ -356,7 +359,13 @@
void DIicBusChannelMaster::CancelTimeOut()
{
+ // Silently cancel the timer and associated DFC
+ //
+ // NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
+ // TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
+ //
iTimeoutTimer.Cancel();
+ iSlaveTimeoutDfc->Cancel();
}
void DIicBusChannelMaster::Complete(TInt aResult, TIicBusTransaction* aTransaction) //Completes a kernel message and receive the next one
@@ -481,7 +490,7 @@
r=SetNotificationTrigger(0); // Attempt to clear notification requests
if((r!=KErrNone)&&(r!=KErrTimedOut)) // KErrTimedOut refers to an earlier transaction, and is for information only
return r;
- iTimeoutTimer.Cancel();
+ StopTimer();
r=DoRequest(EPowerDown);
if(r == KErrNone)
{
@@ -888,7 +897,13 @@
void DIicBusChannelSlave::StopTimer()
{
+ // Silently cancel the timer and associated DFC
+ //
+ // NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
+ // TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
+ //
iTimeoutTimer.Cancel();
+ iClientTimeoutDfc->Cancel();
}
TInt DIicBusChannelSlave::UpdateReqTrig(TInt8& aCbTrigVal, TInt& aCallbackRet)
@@ -901,14 +916,15 @@
if(iNotif->iTrigger & EGeneralBusError)
{
// In the event of a bus error, always cancel the timer and call the Client callback
- nextSteps |= (EStopTimer | EInvokeCb);
+ StopTimer();
iTimerState = EInactive;
+ nextSteps = EInvokeCb;
aCallbackRet = KErrGeneral;
}
else if(iNotif->iTrigger == EAsyncCaptChan)
{
// For asynchronous channel capture, no timers are involved - just call the Client callback
- nextSteps |= EInvokeCb;
+ nextSteps = EInvokeCb;
aCallbackRet = KErrCompletion;
}
else if((iNotif->iTrigger & iReqTrig) != 0)
@@ -947,7 +963,8 @@
{
// All triggers required have occurred, so transition to state EWaitForClient
iTimerState = EWaitForClient;
- nextSteps |= (EStopTimer | EInvokeCb | EStartTimer);
+ StopTimer();
+ nextSteps = (EInvokeCb | EStartTimer);
}
else
{
@@ -986,7 +1003,7 @@
TInt nextSteps = UpdateReqTrig(callbackTrig, callbackRet);
if(nextSteps & EStopTimer)
{
- iTimeoutTimer.Cancel();
+ __ASSERT_DEBUG(NULL, Kern::Fault(KIicChannelPanic,__LINE__));
}
if(nextSteps & EInvokeCb)
{