bthci/bthci2/hcicmdq/src/HciCmdQController.cpp
changeset 51 20ac952a623c
parent 33 4e80e1b997a8
equal deleted inserted replaced
48:22de2e391156 51:20ac952a623c
   117 
   117 
   118 	__ASSERT_ALWAYS(iSentCommandQ.IsEmpty(), PANIC(KHCICmdQPanic, ESentCommandQNotEmptyInDestructor));
   118 	__ASSERT_ALWAYS(iSentCommandQ.IsEmpty(), PANIC(KHCICmdQPanic, ESentCommandQNotEmptyInDestructor));
   119 	__ASSERT_ALWAYS(iResendCommandQ.IsEmpty(), PANIC(KHCICmdQPanic, EResendCommandQNotEmptyInDestructor));
   119 	__ASSERT_ALWAYS(iResendCommandQ.IsEmpty(), PANIC(KHCICmdQPanic, EResendCommandQNotEmptyInDestructor));
   120 		
   120 		
   121 	delete iQStarvationTimer;
   121 	delete iQStarvationTimer;
   122 	delete iSendingCommand;
   122 	DeleteCommand(iSendingCommand);
   123 	delete iQdpPlugin;
   123 	delete iQdpPlugin;
   124 
   124 
   125 	// Delete async CallBacks.	If running, these should be cancelled by the
   125 	// Delete async CallBacks.	If running, these should be cancelled by the
   126 	// d'tor of CAsyncOneShot.
   126 	// d'tor of CAsyncOneShot.
   127 	delete iAsyncCallBackForReset;
   127 	delete iAsyncCallBackForReset;
   691 	THCIEventCode eventCode(aEvent.EventCode());
   691 	THCIEventCode eventCode(aEvent.EventCode());
   692 	if (eventCode == ECommandCompleteEvent)
   692 	if (eventCode == ECommandCompleteEvent)
   693 		{
   693 		{
   694 
   694 
   695 		const THCICommandCompleteEvent& event(THCICommandCompleteEvent::Cast(aEvent));
   695 		const THCICommandCompleteEvent& event(THCICommandCompleteEvent::Cast(aEvent));
   696 		UpdateCommandCredits(event.NumHCICommandPackets());
   696 		UpdateCommandCredits(event.NumHCICommandPackets(), event.CommandOpcode() == KNopOpcode);
   697 
   697 
   698 		if (event.CommandOpcode() == KNopOpcode)
   698 		if (event.CommandOpcode() == KNopOpcode)
   699 			{
   699 			{
   700 			// This is a special command complete event that does not
   700 			// This is a special command complete event that does not
   701 			// complete an event. Command_Opcode, 0x0000 is a NOP, and
   701 			// complete an event. Command_Opcode, 0x0000 is a NOP, and
   707 			}
   707 			}
   708 		}
   708 		}
   709 	else if (eventCode == ECommandStatusEvent)
   709 	else if (eventCode == ECommandStatusEvent)
   710 		{
   710 		{
   711 		TCommandStatusEvent& event = TCommandStatusEvent::Cast(aEvent);
   711 		TCommandStatusEvent& event = TCommandStatusEvent::Cast(aEvent);
   712 		UpdateCommandCredits(event.NumHCICommandPackets());
   712 		UpdateCommandCredits(event.NumHCICommandPackets(), event.CommandOpcode() == KNopOpcode);
   713 
   713 
   714 		if (event.CommandOpcode() == KNopOpcode)
   714 		if (event.CommandOpcode() == KNopOpcode)
   715 			{
   715 			{
   716 			// Same as above for NOP command complete event.
   716 			// Same as above for NOP command complete event.
   717 			
   717 			
   953 	}
   953 	}
   954 	
   954 	
   955 /**
   955 /**
   956 Updates the command credits counter and maintains the EInsufficientCreditBlock
   956 Updates the command credits counter and maintains the EInsufficientCreditBlock
   957 */
   957 */
   958 inline void CHCICmdQController::UpdateCommandCredits(TUint8 aCommandCredits)
   958 inline void CHCICmdQController::UpdateCommandCredits(TUint8 aCommandCredits, TBool aNOP)
   959 	{
   959 	{
   960 	iCommandCredits = aCommandCredits;
   960 	// Assume no credits until we decide otherwise
   961 	
   961 	iCommandCredits = 0;
       
   962 
       
   963 	if (aCommandCredits > 0)
       
   964 		{
       
   965 		// We need to workaround a problem with multiple command credits to ensure that
       
   966 		// we don't update the credits before the controller has processed all of the 
       
   967 		// commands we have sent it.
       
   968 		TDblQueIter<CHCICommandQItem> qIter(iSentCommandQ);
       
   969 		CHCICommandQItem* cmd = NULL;
       
   970 		TUint count = 0;
       
   971 
       
   972 		while (qIter != NULL)
       
   973 			{
       
   974 			// Count all the commands that we have sent that expect a command status but
       
   975 			// haven't had one yet or expects a command complete event.
       
   976 			cmd = qIter++;
       
   977 			if ((cmd->Command().ExpectsCommandStatusEvent() && !cmd->ReceivedCmdStatusEvent()) || 
       
   978 				cmd->Command().ExpectsCommandCompleteEvent())
       
   979 				{
       
   980 				count++;
       
   981 				}
       
   982 			}
       
   983 
       
   984 		if (((count == 0) && aNOP) || ((count == 1) && !aNOP))
       
   985 			{
       
   986 			// The credits are updated before the matching command is removed from the sent
       
   987 			// queue and therefore we only update the credits when we have 1 command that has
       
   988 			// not yet been processed or we have 0 commands and this update is due to a NOP
       
   989 			// event.
       
   990 			iCommandCredits = aCommandCredits;
       
   991 			}
       
   992 		}
       
   993 
   962 	if (iCommandCredits > 0)
   994 	if (iCommandCredits > 0)
   963 		{
   995 		{
   964 		// We clear block flags when sending priority commands, so there may be some
   996 		// We clear block flags when sending priority commands, so there may be some
   965 		// commands blocked on insufficient credits, but the block flag not set
   997 		// commands blocked on insufficient credits, but the block flag not set
   966 		// anymore. Hence we want to schedule the callback irrespectably of the status
   998 		// anymore. Hence we want to schedule the callback irrespectably of the status
  1715 	LOG_FUNC	
  1747 	LOG_FUNC	
  1716 
  1748 
  1717 	// Ensure we are in a state that allows commands to be added.
  1749 	// Ensure we are in a state that allows commands to be added.
  1718 	if(!CanAddCommands())
  1750 	if(!CanAddCommands())
  1719 		{
  1751 		{
  1720 		delete &aQueItem;
  1752 	    CHCICommandQItem* pQueItem = &aQueItem;
       
  1753         DeleteCommand(pQueItem);
  1721 		User::Leave(KErrHardwareNotAvailable);
  1754 		User::Leave(KErrHardwareNotAvailable);
  1722 		}
  1755 		}
  1723 		
  1756 		
  1724 	// Assign a unique CommandQId.
  1757 	// Assign a unique CommandQId.
  1725 	aQueItem.SetCommandQId(NextCommandQueueItemId());
  1758 	aQueItem.SetCommandQId(NextCommandQueueItemId());