kernel/eka/drivers/iic/iic_channel.cpp
branchRCL_3
changeset 256 c1f20ce4abcf
parent 0 a41df078684a
child 257 3e88ff8f41d5
child 291 206a6eaaeb71
equal deleted inserted replaced
249:a179b74831c9 256:c1f20ce4abcf
   127 		}
   127 		}
   128 	}
   128 	}
   129 
   129 
   130 void DIicBusChannelMaster::CompleteRequest(TInt aResult)
   130 void DIicBusChannelMaster::CompleteRequest(TInt aResult)
   131 	{
   131 	{
       
   132 	// Ensure the timeout timer has been cancelled
       
   133 	CancelTimeOut();
       
   134 
   132 	TIicBusTransaction* nextTrans=NextTrans(iCurrentTransaction);
   135 	TIicBusTransaction* nextTrans=NextTrans(iCurrentTransaction);
   133 
   136 
   134 	if((aResult != KErrNone)||(nextTrans == NULL))
   137 	if((aResult != KErrNone)||(nextTrans == NULL))
   135 		EndTransaction(iTransaction,aResult,iTransaction->iCallback);
   138 		EndTransaction(iTransaction,aResult,iTransaction->iCallback);
   136 	else
   139 	else
   354 		}
   357 		}
   355 	}
   358 	}
   356 
   359 
   357 void DIicBusChannelMaster::CancelTimeOut()
   360 void DIicBusChannelMaster::CancelTimeOut()
   358 	{
   361 	{
       
   362 	// Silently cancel the timer and associated DFC
       
   363 	//
       
   364 	// NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
       
   365 	// TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
       
   366 	//
   359 	iTimeoutTimer.Cancel();
   367 	iTimeoutTimer.Cancel();
       
   368 	iSlaveTimeoutDfc->Cancel();
   360 	}
   369 	}
   361 
   370 
   362 void DIicBusChannelMaster::Complete(TInt aResult, TIicBusTransaction* aTransaction) //Completes a kernel message and receive the next one
   371 void DIicBusChannelMaster::Complete(TInt aResult, TIicBusTransaction* aTransaction) //Completes a kernel message and receive the next one
   363 	{
   372 	{
   364 	__KTRACE_OPT(KIIC, Kern::Printf("MsgB::Complete %08x, %d",this,aResult));
   373 	__KTRACE_OPT(KIIC, Kern::Printf("MsgB::Complete %08x, %d",this,aResult));
   479 		return KErrAccessDenied;
   488 		return KErrAccessDenied;
   480 
   489 
   481 	r=SetNotificationTrigger(0);			// Attempt to clear notification requests
   490 	r=SetNotificationTrigger(0);			// Attempt to clear notification requests
   482 	if((r!=KErrNone)&&(r!=KErrTimedOut))	// KErrTimedOut refers to an earlier transaction, and is for information only
   491 	if((r!=KErrNone)&&(r!=KErrTimedOut))	// KErrTimedOut refers to an earlier transaction, and is for information only
   483 		return r;
   492 		return r;
   484 	iTimeoutTimer.Cancel();
   493 	StopTimer();
   485 	r=DoRequest(EPowerDown);
   494 	r=DoRequest(EPowerDown);
   486 	if(r == KErrNone)
   495 	if(r == KErrNone)
   487 		{
   496 		{
   488 		TInt intState=__SPIN_LOCK_IRQSAVE(iSpinLock);
   497 		TInt intState=__SPIN_LOCK_IRQSAVE(iSpinLock);
   489 		iClient=NULL;
   498 		iClient=NULL;
   886 		}
   895 		}
   887 	}
   896 	}
   888 
   897 
   889 void DIicBusChannelSlave::StopTimer()
   898 void DIicBusChannelSlave::StopTimer()
   890 	{
   899 	{
       
   900 	// Silently cancel the timer and associated DFC
       
   901 	//
       
   902 	// NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
       
   903 	// TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
       
   904 	//
   891 	iTimeoutTimer.Cancel();
   905 	iTimeoutTimer.Cancel();
       
   906 	iClientTimeoutDfc->Cancel();
   892 	}
   907 	}
   893 
   908 
   894 TInt DIicBusChannelSlave::UpdateReqTrig(TInt8& aCbTrigVal, TInt& aCallbackRet)
   909 TInt DIicBusChannelSlave::UpdateReqTrig(TInt8& aCbTrigVal, TInt& aCallbackRet)
   895 	{
   910 	{
   896     __KTRACE_OPT(KIIC, Kern::Printf("UpdateReqTrig"));
   911     __KTRACE_OPT(KIIC, Kern::Printf("UpdateReqTrig"));
   899 	iAccumTrig |= iNotif->iTrigger;	// Update the accumulated event history, regardless of if the trigger was requested
   914 	iAccumTrig |= iNotif->iTrigger;	// Update the accumulated event history, regardless of if the trigger was requested
   900 
   915 
   901 	if(iNotif->iTrigger & EGeneralBusError)
   916 	if(iNotif->iTrigger & EGeneralBusError)
   902 		{
   917 		{
   903 		// In the event of a bus error, always cancel the timer and call the Client callback
   918 		// In the event of a bus error, always cancel the timer and call the Client callback
   904 		nextSteps |= (EStopTimer | EInvokeCb);
   919 		StopTimer();
   905 		iTimerState = EInactive;
   920 		iTimerState = EInactive;
       
   921 		nextSteps = EInvokeCb;
   906 		aCallbackRet = KErrGeneral;
   922 		aCallbackRet = KErrGeneral;
   907 		}
   923 		}
   908 	else if(iNotif->iTrigger == EAsyncCaptChan)
   924 	else if(iNotif->iTrigger == EAsyncCaptChan)
   909 		{
   925 		{
   910 		// For asynchronous channel capture, no timers are involved - just call the Client callback
   926 		// For asynchronous channel capture, no timers are involved - just call the Client callback
   911 		nextSteps |= EInvokeCb;
   927 		nextSteps = EInvokeCb;
   912 		aCallbackRet = KErrCompletion;
   928 		aCallbackRet = KErrCompletion;
   913 		}
   929 		}
   914 	else if((iNotif->iTrigger & iReqTrig) != 0)
   930 	else if((iNotif->iTrigger & iReqTrig) != 0)
   915 		{
   931 		{
   916 		// If a requested Rx event has occurred, clear all Rx flags from the requested triggers (similarly for Tx)
   932 		// If a requested Rx event has occurred, clear all Rx flags from the requested triggers (similarly for Tx)
   945 			// The next state in the state machine depends on if all the requested events have occurred
   961 			// The next state in the state machine depends on if all the requested events have occurred
   946 			if(iReqTrig == 0)
   962 			if(iReqTrig == 0)
   947 				{
   963 				{
   948 				// All triggers required have occurred, so transition to state EWaitForClient
   964 				// All triggers required have occurred, so transition to state EWaitForClient
   949 				iTimerState = EWaitForClient;
   965 				iTimerState = EWaitForClient;
   950 				nextSteps |= (EStopTimer | EInvokeCb | EStartTimer);
   966 				StopTimer();
       
   967 				nextSteps = (EInvokeCb | EStartTimer);
   951 				}
   968 				}
   952 			else
   969 			else
   953 				{
   970 				{
   954 				// The Client can request both Rx an Tx triggers; if only one has occurred, must wait for
   971 				// The Client can request both Rx an Tx triggers; if only one has occurred, must wait for
   955 				// the Master to generate the other - so remain in this state, do not cancel the timer or
   972 				// the Master to generate the other - so remain in this state, do not cancel the timer or
   984 		TInt8 callbackTrig=0;
  1001 		TInt8 callbackTrig=0;
   985 		TInt callbackRet=0;
  1002 		TInt callbackRet=0;
   986 		TInt nextSteps = UpdateReqTrig(callbackTrig, callbackRet);
  1003 		TInt nextSteps = UpdateReqTrig(callbackTrig, callbackRet);
   987 		if(nextSteps & EStopTimer)
  1004 		if(nextSteps & EStopTimer)
   988 			{
  1005 			{
   989 			iTimeoutTimer.Cancel();
  1006 			__ASSERT_DEBUG(NULL, Kern::Fault(KIicChannelPanic,__LINE__));
   990 			}
  1007 			}
   991 		if(nextSteps & EInvokeCb)
  1008 		if(nextSteps & EInvokeCb)
   992 			{
  1009 			{
   993 			(notif->iCallback)(notif->iChannelId, (TInt)callbackRet, callbackTrig, notif->iRxWords, notif->iTxWords, notif->iParam);
  1010 			(notif->iCallback)(notif->iChannelId, (TInt)callbackRet, callbackTrig, notif->iRxWords, notif->iTxWords, notif->iParam);
   994 			// Callback now processed, so re-initialise callback object members
  1011 			// Callback now processed, so re-initialise callback object members