--- a/bthci/bthci2/hcicmdq/src/HciCmdQController.cpp Thu Sep 23 17:06:47 2010 +0300
+++ b/bthci/bthci2/hcicmdq/src/HciCmdQController.cpp Wed Oct 13 16:20:29 2010 +0300
@@ -119,7 +119,7 @@
__ASSERT_ALWAYS(iResendCommandQ.IsEmpty(), PANIC(KHCICmdQPanic, EResendCommandQNotEmptyInDestructor));
delete iQStarvationTimer;
- delete iSendingCommand;
+ DeleteCommand(iSendingCommand);
delete iQdpPlugin;
// Delete async CallBacks. If running, these should be cancelled by the
@@ -693,7 +693,7 @@
{
const THCICommandCompleteEvent& event(THCICommandCompleteEvent::Cast(aEvent));
- UpdateCommandCredits(event.NumHCICommandPackets());
+ UpdateCommandCredits(event.NumHCICommandPackets(), event.CommandOpcode() == KNopOpcode);
if (event.CommandOpcode() == KNopOpcode)
{
@@ -709,7 +709,7 @@
else if (eventCode == ECommandStatusEvent)
{
TCommandStatusEvent& event = TCommandStatusEvent::Cast(aEvent);
- UpdateCommandCredits(event.NumHCICommandPackets());
+ UpdateCommandCredits(event.NumHCICommandPackets(), event.CommandOpcode() == KNopOpcode);
if (event.CommandOpcode() == KNopOpcode)
{
@@ -955,10 +955,42 @@
/**
Updates the command credits counter and maintains the EInsufficientCreditBlock
*/
-inline void CHCICmdQController::UpdateCommandCredits(TUint8 aCommandCredits)
+inline void CHCICmdQController::UpdateCommandCredits(TUint8 aCommandCredits, TBool aNOP)
{
- iCommandCredits = aCommandCredits;
-
+ // Assume no credits until we decide otherwise
+ iCommandCredits = 0;
+
+ if (aCommandCredits > 0)
+ {
+ // We need to workaround a problem with multiple command credits to ensure that
+ // we don't update the credits before the controller has processed all of the
+ // commands we have sent it.
+ TDblQueIter<CHCICommandQItem> qIter(iSentCommandQ);
+ CHCICommandQItem* cmd = NULL;
+ TUint count = 0;
+
+ while (qIter != NULL)
+ {
+ // Count all the commands that we have sent that expect a command status but
+ // haven't had one yet or expects a command complete event.
+ cmd = qIter++;
+ if ((cmd->Command().ExpectsCommandStatusEvent() && !cmd->ReceivedCmdStatusEvent()) ||
+ cmd->Command().ExpectsCommandCompleteEvent())
+ {
+ count++;
+ }
+ }
+
+ if (((count == 0) && aNOP) || ((count == 1) && !aNOP))
+ {
+ // The credits are updated before the matching command is removed from the sent
+ // queue and therefore we only update the credits when we have 1 command that has
+ // not yet been processed or we have 0 commands and this update is due to a NOP
+ // event.
+ iCommandCredits = aCommandCredits;
+ }
+ }
+
if (iCommandCredits > 0)
{
// We clear block flags when sending priority commands, so there may be some
@@ -1717,7 +1749,8 @@
// Ensure we are in a state that allows commands to be added.
if(!CanAddCommands())
{
- delete &aQueItem;
+ CHCICommandQItem* pQueItem = &aQueItem;
+ DeleteCommand(pQueItem);
User::Leave(KErrHardwareNotAvailable);
}