usbdrv/peripheral/pdd/pil/src/controltransfersm.cpp
branchRCL_3
changeset 16 012cc2ee6408
parent 15 f92a4f87e424
equal deleted inserted replaced
15:f92a4f87e424 16:012cc2ee6408
     1 /*
       
     2   Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 
       
     3   All rights reserved.
       
     4 
       
     5   This program and the accompanying materials are made available 
       
     6   under the terms of the Eclipse Public License v1.0 which accompanies 
       
     7   this distribution, and is available at 
       
     8   http://www.eclipse.org/legal/epl-v10.html
       
     9 
       
    10   Initial Contributors:
       
    11   Nokia Corporation - initial contribution.
       
    12 
       
    13   Contributors:
       
    14 */
       
    15 
       
    16 #include "controltransfersm.h"
       
    17 
       
    18 // Bitmap of setup packet
       
    19 /*
       
    20 Offset 0, bmRequestType, 1 bytes
       
    21     1 Bit-Map
       
    22         D7 Data Phase Transfer Direction
       
    23         0 = Host to Device
       
    24         1 = Device to Host
       
    25     
       
    26         D6..5 Type
       
    27         0 = Standard
       
    28         1 = Class
       
    29         2 = Vendor
       
    30         3 = Reserved
       
    31     
       
    32         D4..0 Recipient
       
    33         0 = Device
       
    34         1 = Interface
       
    35         2 = Endpoint
       
    36         3 = Other
       
    37         4..31 = Reserved
       
    38 
       
    39 Offset 1, bRequest
       
    40 
       
    41 Offset 6, Count, 2 bytes
       
    42         Number of bytes to transfer if there is a data phase
       
    43 */
       
    44 
       
    45 #if defined(_DEBUG)
       
    46 
       
    47 #define CTSM_ID "ControlTransferSM "
       
    48 
       
    49 char* DebugName[] = 
       
    50     {
       
    51     "Setup",
       
    52     "Data Out",
       
    53     "Status In",
       
    54     "Data In",
       
    55     "Status Out"
       
    56     };
       
    57     
       
    58 #endif
       
    59 
       
    60 // Static data instance
       
    61 TUsbcSetup TSetupPkgParser::iSetupPkt;
       
    62 
       
    63 TSetupPkgParser::TSetupPkgParser()
       
    64     {
       
    65     iSetupPkt.iRequestType = 0;
       
    66     iSetupPkt.iRequest = 0;
       
    67     
       
    68     iSetupPkt.iValue  = 0;
       
    69     iSetupPkt.iIndex  = 0;
       
    70     iSetupPkt.iLength = 0;
       
    71     }
       
    72 
       
    73 // Code for TSetupPkgParser
       
    74 // we do a bitwise copy here.
       
    75 void TSetupPkgParser::Set(const TUint8* aSetupBuf)
       
    76     {
       
    77     // TUint8 index
       
    78     iSetupPkt.iRequestType = static_cast<const TUint8*>(aSetupBuf)[0];
       
    79     iSetupPkt.iRequest = static_cast<const TUint8*>(aSetupBuf)[1];
       
    80     // TUint16 index from here!
       
    81     iSetupPkt.iValue = SWAP_BYTES_16((reinterpret_cast<const TUint16*>(aSetupBuf))[1]);
       
    82     iSetupPkt.iIndex = SWAP_BYTES_16((reinterpret_cast<const TUint16*>(aSetupBuf))[2]);
       
    83     iSetupPkt.iLength = SWAP_BYTES_16((reinterpret_cast<const TUint16*>(aSetupBuf))[3]);
       
    84     
       
    85     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "TSetupPkgParser::Set"));
       
    86     }
       
    87 
       
    88 // return the next stage by decoding the setup packet 
       
    89 // the possible stage followed by a setup packet are:
       
    90 //      StatusIn (no data stage)
       
    91 //      DataOut  (host sent to peripheral)
       
    92 //      DataIn   (peripheral to host)
       
    93 UsbShai::TControlStage TSetupPkgParser::NextStage()
       
    94     {
       
    95     UsbShai::TControlStage ret = UsbShai::EControlTransferStageMax;
       
    96     
       
    97     // Take the data length out, 0 length means no data stage
       
    98     if (iSetupPkt.iLength == 0)
       
    99         {
       
   100         ret = UsbShai::EControlTransferStageStatusIn;
       
   101         }
       
   102     else if ((iSetupPkt.iRequestType & KUsbRequestType_DirMask) == KUsbRequestType_DirToDev)
       
   103         {
       
   104         // Dir to device means host will send data out
       
   105         ret = UsbShai::EControlTransferStageDataOut;
       
   106         }
       
   107     else
       
   108         {
       
   109         // Otherwise, there must be a datain stage follows
       
   110         ret = UsbShai::EControlTransferStageDataIn;
       
   111         } 
       
   112     
       
   113     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "TSetupPkgParser::NextStage %d", ret));
       
   114     
       
   115     return ret;
       
   116     }
       
   117 
       
   118 // Base class of stage sm
       
   119 TControlStageSm::TControlStageSm(DControlTransferManager& aTransferMgr):
       
   120     iTransferMgr(aTransferMgr)
       
   121     {    
       
   122     }
       
   123 
       
   124 void TControlStageSm::ChangeToStage(UsbShai::TControlStage aToStage)
       
   125     {
       
   126     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "<> TControlStageSm::ChangeToStage: %s",DebugName[aToStage]));
       
   127     iTransferMgr.iCurrentStage = aToStage;
       
   128     }
       
   129 
       
   130 void TControlStageSm::ClearPendingRead()
       
   131     {
       
   132     iTransferMgr.iReadPending = EFalse;
       
   133     }
       
   134     
       
   135 // Code for DControlTransferManager
       
   136 // 
       
   137 
       
   138 DControlTransferManager::DControlTransferManager(MControlTransferIf& aCtrTransIf):
       
   139     iCtrTransferIf(aCtrTransIf)
       
   140     {    
       
   141     for(int i=0; i<UsbShai::EControlTransferStageMax; i++)
       
   142         {
       
   143         iState[i] = NULL;
       
   144         }
       
   145     
       
   146     Reset();
       
   147     }
       
   148 
       
   149 TInt DControlTransferManager::SetupEndpointZeroRead()
       
   150     {
       
   151     if(iState[iCurrentStage]->IsRequstAllowed(TControlTransferRequestRead))
       
   152         {
       
   153         if(!iReadPending)
       
   154             {
       
   155             iReadPending = ETrue;
       
   156             return CtrTransferIf().ProcessSetupEndpointZeroRead();
       
   157             }
       
   158         else
       
   159             {
       
   160             // A read operation already on going, ignore this request
       
   161             return KErrNone;
       
   162             }
       
   163         }
       
   164     else
       
   165         {
       
   166         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID " !! SetupEndpointZeroRead discard"));
       
   167         return KErrNotReady;
       
   168         }
       
   169     }
       
   170     
       
   171 TInt DControlTransferManager::SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd)
       
   172     {
       
   173     if(iState[iCurrentStage]->IsRequstAllowed(TControlTransferRequestWrite))
       
   174         {
       
   175         return CtrTransferIf().ProcessSetupEndpointZeroWrite(aBuffer,aLength,aZlpReqd);
       
   176         }
       
   177     else
       
   178         {
       
   179         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID " !! SetupEndpointZeroWrite discard"));
       
   180         return KErrNotReady;
       
   181         }    
       
   182     }
       
   183     
       
   184 TInt DControlTransferManager::SendEp0ZeroByteStatusPacket()
       
   185     {
       
   186      if(iState[iCurrentStage]->IsRequstAllowed(TControlTransferRequestSendStatus))
       
   187         {
       
   188         iCurrentStage = UsbShai::EControlTransferStageSetup;
       
   189         return CtrTransferIf().ProcessSendEp0ZeroByteStatusPacket();
       
   190         }
       
   191     else
       
   192         {
       
   193         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID " !! SendEp0ZeroByteStatusPacket discard"));
       
   194         return KErrNotReady;
       
   195         }
       
   196     }
       
   197     
       
   198 TInt DControlTransferManager::StallEndpoint(TInt aRealEndpoint)
       
   199     {
       
   200     // Endpoint is stalled, we need to reset our state machine.
       
   201     Reset();
       
   202     return CtrTransferIf().ProcessStallEndpoint(aRealEndpoint);
       
   203     }
       
   204 
       
   205 void DControlTransferManager::Ep0SetupPacketProceed()
       
   206     {
       
   207     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID " !! Missed setup packet processed"));
       
   208     CtrTransferIf().ProcessEp0SetupPacketProceed();
       
   209     }
       
   210         
       
   211 void DControlTransferManager::Ep0DataPacketProceed()
       
   212     {
       
   213     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID " !! Missed data packet processed")); 
       
   214     CtrTransferIf().ProcessEp0DataPacketProceed();
       
   215     }
       
   216     
       
   217 void DControlTransferManager::Reset()
       
   218     {
       
   219     iCurrentStage = UsbShai::EControlTransferStageSetup;
       
   220     iReadPending = EFalse;
       
   221     }
       
   222     
       
   223 void DControlTransferManager::Ep0RequestComplete(TUint8* aBuf, 
       
   224                                              TInt aCount, 
       
   225                                              TInt aError, 
       
   226                                              UsbShai::TControlPacketType aPktType)
       
   227     {   
       
   228     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "> DControlTransferManager::Ep0RequestComplete, packet type: %s", DebugName[aPktType])); 
       
   229     // If a setup packet comes, update our local setup packet buffer first
       
   230     if(aPktType == UsbShai::EControlPacketTypeSetup)
       
   231         {
       
   232         iPacketParser.Set(aBuf);
       
   233         // This is the only place this variable to be reset.
       
   234         iDataTransfered = 0;
       
   235         }
       
   236     
       
   237     // RequestComplete will return ETrue if it can not handle a packet
       
   238     // And it knows that some other sm can handle it.
       
   239     // It will update the state to the one which can hanlde that packet first.        
       
   240     TBool furtherProcessNeeded = ETrue;
       
   241     while(furtherProcessNeeded)
       
   242         {        
       
   243         __KTRACE_OPT(KUSB, Kern::Printf("   We're at Stage:         %s", DebugName[iCurrentStage]));
       
   244         furtherProcessNeeded = iState[iCurrentStage]->RequestComplete(aCount,aError,aPktType);
       
   245         __KTRACE_OPT(KUSB, Kern::Printf("   We're moved to stage:   %s", DebugName[iCurrentStage]));
       
   246         }    
       
   247     
       
   248     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "< DControlTransferManager::Ep0RequestComplete")); 
       
   249     }
       
   250 
       
   251 // setup the state machine for a state
       
   252 void DControlTransferManager::AddState(UsbShai::TControlStage aStage,TControlStageSm& aStageSm)
       
   253     {
       
   254     if( (aStage >= UsbShai::EControlTransferStageSetup) && (aStage < UsbShai::EControlTransferStageMax))
       
   255         {
       
   256         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID " AddState(), Stage: %s", DebugName[aStage]));
       
   257         iState[aStage] = &aStageSm;
       
   258         }
       
   259     }
       
   260         
       
   261 // *************** Code for SETUP state machines **************************************
       
   262 //
       
   263 DSetupStageSm::DSetupStageSm(DControlTransferManager& aTransferMgr):
       
   264     TControlStageSm(aTransferMgr)
       
   265     {
       
   266     }
       
   267 
       
   268 // WE are waiting a SETUP packet
       
   269 TBool DSetupStageSm::RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType)
       
   270     {
       
   271     TBool ret = EFalse;
       
   272     
       
   273     __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "DSetupStageSm::RequestComplete"));
       
   274     
       
   275     if(aPktType != UsbShai::EControlPacketTypeSetup)
       
   276         {
       
   277         // we just discard any non-setup packet
       
   278         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DSetupStageSm - Non-Setup recieved"));
       
   279         return ret;
       
   280         }
       
   281     
       
   282     // change state to whatever returned from this call.
       
   283     ChangeToStage(iTransferMgr.PktParser().NextStage());
       
   284     
       
   285     // We're going to complete User's read request, consume the previous
       
   286     // read operation
       
   287     ClearPendingRead();
       
   288     
       
   289     // Setup packet are always need to be processed
       
   290     iTransferMgr.CtrTransferIf().ProcessSetupPacket(aPktSize,aError);
       
   291     
       
   292     return EFalse;
       
   293     }
       
   294 
       
   295 TBool DSetupStageSm::IsRequstAllowed(TControlTransferRequest aRequest)
       
   296     {
       
   297     // Allow user to read, No other operation is allowed
       
   298     TBool ret = (aRequest == TControlTransferRequestRead)?ETrue:EFalse;
       
   299     
       
   300     if( ! ret)
       
   301         {
       
   302         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "Warning: request %d was blocked at DSetupStageSm",aRequest));
       
   303         }
       
   304         
       
   305     return ret;
       
   306     }
       
   307 
       
   308     
       
   309 // *************** Code for DATA IN state machines **************************************
       
   310 
       
   311 DDataInStageSm::DDataInStageSm(DControlTransferManager& aTransferMgr):
       
   312     TControlStageSm(aTransferMgr)
       
   313     {
       
   314     }
       
   315 
       
   316 // We are waiting for a competion of DATA IN packet
       
   317 TBool DDataInStageSm::RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType)
       
   318     {
       
   319     TInt completionCode = aError;
       
   320     TBool furtherRequest = EFalse;
       
   321     
       
   322     switch(aPktType)
       
   323         {
       
   324         case UsbShai::EControlPacketTypeSetup:
       
   325             {
       
   326             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DDataInStageSm - Setup recieved"));
       
   327             // Something goes wrong, host is abandoning the unfinished control transfer
       
   328             completionCode = KErrGeneral;
       
   329             
       
   330             // Force SM restart at setup stage
       
   331             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   332             
       
   333             // this packet is partially processed here
       
   334             // need another SM to continue
       
   335             furtherRequest = ETrue;
       
   336             }
       
   337             break;
       
   338             
       
   339         case UsbShai::EControlPacketTypeDataIn:
       
   340             {
       
   341             // PSL notifing us that the data had been sent to host
       
   342             // next step is to wait for the status from Host
       
   343             ChangeToStage(UsbShai::EControlTransferStageStatusOut);
       
   344              
       
   345             // In USB spec, a compete control transfer must inclue a status stage
       
   346             // which is not case in reality,some PSL/Hardware will swallow the
       
   347             // Status out report, so, we just complete client normally.
       
   348             }
       
   349             break;
       
   350             
       
   351         default:
       
   352             {
       
   353             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DDataInStageSm -  %s recieved",DebugName[aPktType]));
       
   354             
       
   355             // Unexpected packet will be discard, and lead us reset state machine
       
   356             // so that we can wait for next SETUP packet.
       
   357             // Of course error will be report to any client if any there.
       
   358             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   359             completionCode = KErrGeneral;
       
   360             }
       
   361             break;
       
   362         }
       
   363     
       
   364     iTransferMgr.CtrTransferIf().ProcessDataInPacket(aPktSize,completionCode);
       
   365 
       
   366     return furtherRequest;
       
   367     }
       
   368 
       
   369 TBool DDataInStageSm::IsRequstAllowed(TControlTransferRequest aRequest)
       
   370     {
       
   371     // Only write is possible because host is waiting for data from us
       
   372     TBool ret = (aRequest == TControlTransferRequestWrite)?ETrue:EFalse;
       
   373     
       
   374     if( ! ret)
       
   375         {
       
   376         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "Warning: request %d was blocked at DDataInStageSm",aRequest));
       
   377         }
       
   378         
       
   379     return ret;
       
   380     };
       
   381     
       
   382 // *************** Code for STATUS OUT state machines **************************************
       
   383 DStatusOutStageSm::DStatusOutStageSm(DControlTransferManager& aTransferMgr):
       
   384     TControlStageSm(aTransferMgr)
       
   385     {
       
   386     }
       
   387 
       
   388 // We are waiting for a competion of STATUS OUT or a SETUP packet if PSL or hardware don't
       
   389 // complete a status in packet
       
   390 TBool DStatusOutStageSm::RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType)
       
   391     {
       
   392     TBool furtherRequest = EFalse;
       
   393     TInt completionCode = aError;
       
   394     
       
   395     switch(aPktType)
       
   396         {
       
   397         case UsbShai::EControlPacketTypeSetup:
       
   398             {
       
   399             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DStatusOutStageSm - Setup recieved"));
       
   400             // hw or PSL may not send back the status packet for a DATA OUT
       
   401             // and we're ok for this, just back to EControlTransferStageSetup stage           
       
   402             
       
   403             // Force SM restart at setup stage
       
   404             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   405             
       
   406             // this packet is partially processed here
       
   407             // need another SM to continue
       
   408             furtherRequest = ETrue;
       
   409             }
       
   410             break;
       
   411 
       
   412         case UsbShai::EControlPacketTypeStatusOut:
       
   413             {
       
   414             // Force SM restart at setup stage
       
   415             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   416             }
       
   417             break;
       
   418         
       
   419         default:
       
   420             {
       
   421             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DStatusOutStageSm -  %s recieved",DebugName[aPktType]));
       
   422 
       
   423             // Unexpected packet will be discard, and lead us reset state machine
       
   424             // so that we can wait for next SETUP packet.
       
   425             // Of course error will be report to any client if any there.            
       
   426             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   427             completionCode = KErrGeneral;
       
   428             }
       
   429             break;
       
   430         }
       
   431 
       
   432     iTransferMgr.CtrTransferIf().ProcessStatusOutPacket(completionCode);
       
   433         
       
   434     return furtherRequest;
       
   435     
       
   436     }
       
   437 
       
   438 TBool DStatusOutStageSm::IsRequstAllowed(TControlTransferRequest aRequest)
       
   439     {
       
   440     // Read is ok since client don't care the status out stage.
       
   441     // and this lead no hurt to anybody.
       
   442     TBool ret = (aRequest == TControlTransferRequestRead)?ETrue:EFalse;
       
   443     
       
   444     if( ! ret)
       
   445         {
       
   446         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "Warning: request %d was blocked at DStatusOutStageSm",aRequest));
       
   447         }
       
   448         
       
   449     return ret;
       
   450     };
       
   451 
       
   452 // *************** Code for DATA OUT state machines **************************************
       
   453 //
       
   454 DDataOutStageSm::DDataOutStageSm(DControlTransferManager& aTransferMgr):
       
   455     TControlStageSm(aTransferMgr)
       
   456     {
       
   457     }
       
   458 
       
   459 TBool DDataOutStageSm::RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType)
       
   460     {
       
   461     TBool furtherRequest = EFalse;
       
   462     TInt completionCode = aError;
       
   463     
       
   464     switch(aPktType)
       
   465         {
       
   466         case UsbShai::EControlPacketTypeSetup:
       
   467             {
       
   468             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DDataOutStageSm - Setup recieved"));
       
   469             // Host is abandon the previous Transfer 
       
   470             completionCode = KErrGeneral;
       
   471             
       
   472             // Force SM restart at setup stage
       
   473             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   474 
       
   475             // this packet is partially processed here
       
   476             // need another SM to continue
       
   477             furtherRequest = ETrue;
       
   478             }
       
   479             break;
       
   480             
       
   481         case UsbShai::EControlPacketTypeDataOut:
       
   482             {
       
   483             iTransferMgr.DataReceived(aPktSize);
       
   484             
       
   485             if(!iTransferMgr.IsMoreBytesNeeded())
       
   486                 {
       
   487                 // We had recieved enough bytes as indicated by the setup
       
   488                 // packet, Data stage is finished. enter STATUS IN state
       
   489                 ChangeToStage(UsbShai::EControlTransferStageStatusIn);       
       
   490                 }            
       
   491             }
       
   492             break;
       
   493         
       
   494         case UsbShai::EControlPacketTypeStatusIn:
       
   495             {
       
   496             // Status in had been sent to host
       
   497             // return and waiting for new SETUP
       
   498             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   499             }
       
   500             break;
       
   501             
       
   502         default:
       
   503             {
       
   504             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DDataOutStageSm -  %s recieved",DebugName[aPktType]));
       
   505             
       
   506             // Unexpected packet will be discard, and lead us reset state machine
       
   507             // so that we can wait for next SETUP packet.
       
   508             // Of course error will be report to any client if any there.
       
   509             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   510             completionCode = KErrGeneral;
       
   511             }
       
   512             break;
       
   513         }
       
   514     
       
   515     ClearPendingRead();
       
   516     iTransferMgr.CtrTransferIf().ProcessDataOutPacket(aPktSize,completionCode);
       
   517     
       
   518     return furtherRequest;
       
   519     }
       
   520 
       
   521 TBool DDataOutStageSm::IsRequstAllowed(TControlTransferRequest aRequest)
       
   522     {
       
   523     // only read operation is allowed in data out stage.
       
   524     TBool ret = (aRequest == TControlTransferRequestRead)?ETrue:EFalse;
       
   525     
       
   526     if( ! ret)
       
   527         {
       
   528         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "Warning: request %d was blocked at DDataOutStageSm",aRequest));
       
   529         }
       
   530         
       
   531     return ret;
       
   532     };
       
   533 
       
   534 // *************** Code for DATA OUT state machines **************************************
       
   535 //
       
   536 DStatusInStageSm::DStatusInStageSm(DControlTransferManager& aTransferMgr):
       
   537     TControlStageSm(aTransferMgr)
       
   538     {
       
   539     }
       
   540 
       
   541 TBool DStatusInStageSm::RequestComplete(TInt aPktSize, TInt aError, UsbShai::TControlPacketType aPktType)
       
   542     {
       
   543     TBool furtherRequest = EFalse;
       
   544     TInt completionCode = KErrNone;
       
   545     
       
   546     switch(aPktType)
       
   547         {
       
   548         case UsbShai::EControlPacketTypeSetup:
       
   549             {
       
   550             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DStatusInStageSm - Setup recieved"));
       
   551             // Status in is an optional for PSL
       
   552             // If we received a setup packet here, we assume the previous
       
   553             // status in packet had been successfully sent to host.
       
   554             
       
   555             // Force SM restart at setup stage
       
   556             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   557             
       
   558             // this packet is partially processed here
       
   559             // need another SM to continue
       
   560             furtherRequest = ETrue;
       
   561             }
       
   562             break;
       
   563             
       
   564         case UsbShai::EControlPacketTypeStatusIn:
       
   565             {
       
   566             // Status in had been recieved, monitor setup packet then.
       
   567             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   568             }
       
   569             break;
       
   570             
       
   571         default:
       
   572             {
       
   573             __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "ALERT: DStatusInStageSm -  %s recieved",DebugName[aPktType]));
       
   574 
       
   575             // Unexpected packet will be discard, and lead us reset state machine
       
   576             // so that we can wait for next SETUP packet.
       
   577             // Of course error will be report to any client if any there.
       
   578             ChangeToStage(UsbShai::EControlTransferStageSetup);
       
   579             completionCode = KErrGeneral;
       
   580             }
       
   581             break;
       
   582         }
       
   583     
       
   584     iTransferMgr.CtrTransferIf().ProcessStatusInPacket(completionCode);
       
   585     
       
   586     return furtherRequest;
       
   587     }
       
   588 
       
   589 TBool DStatusInStageSm::IsRequstAllowed(TControlTransferRequest aRequest)
       
   590     {
       
   591     // Read is ok even we are wait for the client to send a zero status packet
       
   592     TBool ret = ((aRequest == TControlTransferRequestSendStatus) || 
       
   593                 (aRequest == TControlTransferRequestRead))?ETrue:EFalse;
       
   594     
       
   595     if( ! ret)
       
   596         {
       
   597         __KTRACE_OPT(KUSB, Kern::Printf(CTSM_ID "Warning: request %d was blocked at DStatusInStageSm",aRequest));
       
   598         }
       
   599         
       
   600     return ret;
       
   601     }
       
   602     
       
   603 // End of file
       
   604