usbdrv/peripheral/pdd/pil/src/chapter9.cpp
branchRCL_3
changeset 16 012cc2ee6408
parent 15 f92a4f87e424
equal deleted inserted replaced
15:f92a4f87e424 16:012cc2ee6408
     1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32/drivers/usbcc/chapter9.cpp
       
    15 // Platform independent layer (PIL) of the USB Device controller driver:
       
    16 // Processing of USB spec chapter 9 standard requests.
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file chapter9.cpp
       
    22  @internalTechnology
       
    23 */
       
    24 
       
    25 #include <usb/usbc.h>
       
    26 
       
    27 #include "controltransfersm.h"
       
    28 
       
    29 //#define ENABLE_EXCESSIVE_DEBUG_OUTPUT
       
    30 //
       
    31 // === USB Controller member function implementation - PSL API (protected) ========================
       
    32 //
       
    33 
       
    34 /** Used to synchronize the Ep0 state machine between the PSL and PIL.
       
    35     Accepts a SETUP packet and returns the next Ep0 state.
       
    36 
       
    37     @param aSetupBuf The SETUP packet just received by the PSL.
       
    38     @return The next Ep0 state.
       
    39 
       
    40     @publishedPartner @released
       
    41 */
       
    42 UsbShai::TControlStage DUsbClientController::EnquireEp0NextStage(const TUint8* aSetupBuf) const
       
    43     {
       
    44     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EnquireEp0NextState()"));
       
    45 
       
    46     // This function may be called by the PSL from within an ISR -- so we have
       
    47     // to take care what we do here (and also in all functions that get called
       
    48     // from here).
       
    49 
       
    50     if (SWAP_BYTES_16((reinterpret_cast<const TUint16*>(aSetupBuf)[3])) == 0) // iLength
       
    51         {
       
    52         __KTRACE_OPT(KUSB, Kern::Printf("  --> EControlTransferStageStatusIn"));
       
    53         return UsbShai::EControlTransferStageStatusIn;                            // No-data Control => Status_IN
       
    54         }
       
    55     else if ((aSetupBuf[0] & KUsbRequestType_DirMask) == KUsbRequestType_DirToDev)
       
    56         {
       
    57         __KTRACE_OPT(KUSB, Kern::Printf("  --> EControlTransferStageDataOut"));
       
    58         return UsbShai::EControlTransferStageDataOut;                            // Control Write => Data_OUT
       
    59         }
       
    60     else
       
    61         {
       
    62         __KTRACE_OPT(KUSB, Kern::Printf("  --> EControlTransferStageDataIn"));
       
    63         return UsbShai::EControlTransferStageDataIn;                                // Control Read => Data_IN
       
    64         }
       
    65     }
       
    66 
       
    67 //
       
    68 // About iLastError.
       
    69 // This member is used to remember the last error happend during a
       
    70 // processXXX likewise function.
       
    71 //
       
    72 // Before entry of each ProcessXXX, iLastError will be cleared to KErrNone.
       
    73 //
       
    74 
       
    75 // --- The USB Spec Chapter 9 Standard Endpoint Zero Device Requests ---
       
    76 // Record error happend with iLastError, the value already been set to zero
       
    77 // before entering ProcessSetupPacket call.
       
    78 void DUsbClientController::ProcessGetDeviceStatus(const TUsbcSetup& aPacket)
       
    79     {
       
    80     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetDeviceStatus()"));
       
    81     if ( iDeviceState < UsbShai::EUsbPeripheralStateAddress)
       
    82         {
       
    83         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
    84         iLastError = KErrGeneral;
       
    85         }
       
    86     else
       
    87         {
       
    88         // We always assume Device is bus-powered, even though mobile phone almost always
       
    89         // has a battry there, because self-powered device can not required more then 100ma current
       
    90         // which is not acceptable for Usb charging.
       
    91         TBool selfPowered = EFalse;         
       
    92         
       
    93         /*  FIXME: modify selfPowered to make it compilance with following rule.
       
    94            
       
    95              1. If current draw exceeds 100mA, the device must report itself 
       
    96                 as bus-powered during enumeration.
       
    97              
       
    98              2. In all cases, the GetStatus(DEVICE) call must accurately report 
       
    99                 whether the device is currently operating on self- or bus-power.
       
   100                 
       
   101              3. A device that is actively drawing more than 100mA from USB must 
       
   102                 report itself as bus-powered in the GetStatus(DEVICE) call.
       
   103              
       
   104              4. Peripherals that return "Self-powered" in the GetStatus(DEVICE) 
       
   105                 call are prohibited from drawing more than 100mA at any time.
       
   106         */
       
   107         /*   
       
   108         TBuf8<KUsbDescSize_Config> config;
       
   109         
       
   110         if(iDescriptors.GetConfigurationDescriptorTC(&Kern::CurrentThread(),config) == KErrNone)
       
   111             {
       
   112             TUint8 maxPower = config[8];
       
   113             if(maxPower <= 50)
       
   114                 {
       
   115                 selfPowered = EFalse;
       
   116                 }
       
   117             }
       
   118         */
       
   119         
       
   120         const TUint16 status = ((selfPowered ? KUsbDevStat_SelfPowered : 0) |
       
   121                         (iRmWakeupStatus_Enabled ? KUsbDevStat_RemoteWakeup : 0));
       
   122         __KTRACE_OPT(KUSB, Kern::Printf("  Reporting device status: 0x%02x", status));
       
   123         *reinterpret_cast<TUint16*>(iEp0_TxBuf) = SWAP_BYTES_16(status);
       
   124         if (iConTransferMgr->SetupEndpointZeroWrite(iEp0_TxBuf, sizeof(status)) == KErrNone)
       
   125             {
       
   126             iEp0WritePending = ETrue;
       
   127             }
       
   128         else
       
   129             {
       
   130             __KTRACE_OPT(KUSB, Kern::Printf("  Wrong: Write to Ep0 Failed"));
       
   131             }
       
   132         }
       
   133     }
       
   134 
       
   135 void DUsbClientController::ProcessGetInterfaceStatus(const TUsbcSetup& aPacket)
       
   136     {
       
   137     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetInterfaceStatus()"));
       
   138     if ( iDeviceState < UsbShai::EUsbPeripheralStateConfigured)
       
   139         {
       
   140         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   141         iLastError = KErrGeneral;
       
   142         }
       
   143     else
       
   144         {
       
   145         if (InterfaceExists(aPacket.iIndex) == EFalse)
       
   146             {
       
   147             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface does not exist"));
       
   148             iLastError = KErrGeneral;
       
   149             }
       
   150         else
       
   151             {        
       
   152             const TUint16 status = 0x0000;                            // as of USB Spec 2.0
       
   153             __KTRACE_OPT(KUSB, Kern::Printf("  Reporting interface status: 0x%02x", status));
       
   154             *reinterpret_cast<TUint16*>(iEp0_TxBuf) = SWAP_BYTES_16(status);
       
   155             if (iConTransferMgr->SetupEndpointZeroWrite(iEp0_TxBuf, sizeof(status)) == KErrNone)
       
   156                 {
       
   157                 iEp0WritePending = ETrue;
       
   158                 }
       
   159             else
       
   160                 {
       
   161                 __KTRACE_OPT(KUSB, Kern::Printf("  Wrong: Write to Ep0 Failed"));
       
   162                 }
       
   163             }
       
   164         }
       
   165     }
       
   166 
       
   167 
       
   168 void DUsbClientController::ProcessGetEndpointStatus(const TUsbcSetup& aPacket)
       
   169     {
       
   170     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetEndpointStatus()"));
       
   171     if (
       
   172         ((iDeviceState < UsbShai::EUsbPeripheralStateAddress) ||
       
   173          (iDeviceState == UsbShai::EUsbPeripheralStateAddress && (aPacket.iIndex & KUsbEpAddress_Portmask) != 0)))
       
   174         {
       
   175         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   176         iLastError = KErrGeneral;
       
   177         }
       
   178     else
       
   179         {
       
   180         if (EndpointExists(aPacket.iIndex) == EFalse)
       
   181             {
       
   182             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint does not exist"));
       
   183             iLastError = KErrGeneral;
       
   184             }
       
   185         else
       
   186             {
       
   187             const TInt ep = EpAddr2Idx(aPacket.iIndex);
       
   188             const TUint16 status = (iRealEndpoints[ep].iHalt) ?     KUsbEpStat_Halt : 0;
       
   189             __KTRACE_OPT(KUSB, Kern::Printf("  Reporting endpoint status 0x%02x for real endpoint %d",
       
   190                                             status, ep));
       
   191             *reinterpret_cast<TUint16*>(iEp0_TxBuf) = SWAP_BYTES_16(status);
       
   192             if (iConTransferMgr->SetupEndpointZeroWrite(iEp0_TxBuf, 2) == KErrNone)
       
   193                 {
       
   194                 iEp0WritePending = ETrue;
       
   195                 }
       
   196             else
       
   197                 {
       
   198                 __KTRACE_OPT(KUSB, Kern::Printf("  Wrong: Write to Ep0 Failed"));
       
   199                 }
       
   200             }
       
   201         }
       
   202     }
       
   203 
       
   204 
       
   205 void DUsbClientController::ProcessSetClearDevFeature(const TUsbcSetup& aPacket)
       
   206     {
       
   207     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetClearDevFeature()"));
       
   208     if ( iDeviceState < UsbShai::EUsbPeripheralStateDefault)
       
   209         {
       
   210         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   211         iLastError = KErrGeneral;
       
   212         return;
       
   213         }
       
   214 
       
   215     TInt test_sel = 0;
       
   216 
       
   217     if (aPacket.iRequest == KUsbRequest_SetFeature)
       
   218         {
       
   219         switch (aPacket.iValue)
       
   220             {
       
   221             case KUsbFeature_RemoteWakeup:
       
   222                 if ( iDeviceState < UsbShai::EUsbPeripheralStateAddress)
       
   223                     {
       
   224                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   225                     iLastError = KErrGeneral;                
       
   226                     }
       
   227                 else
       
   228                     {
       
   229                     iRmWakeupStatus_Enabled = ETrue;
       
   230                     }
       
   231                 break;
       
   232                 
       
   233             case KUsbFeature_TestMode:
       
   234                 if (!iHighSpeed)
       
   235                     {
       
   236                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported in High-Speed mode"));
       
   237                     iLastError = KErrGeneral;
       
   238                     }
       
   239                 else if (LowByte(aPacket.iIndex) != 0)
       
   240                     {
       
   241                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Lower byte of wIndex must be zero"));
       
   242                     iLastError = KErrGeneral;
       
   243                     }
       
   244                 else
       
   245                     {
       
   246                     test_sel = HighByte(aPacket.iIndex);
       
   247                     if ((test_sel < UsbShai::EUsbTestSelector_Test_J) || (test_sel > UsbShai::EUsbTestSelector_Test_Force_Enable))
       
   248                         {
       
   249                         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid test selector: %d", test_sel));
       
   250                         iLastError = KErrGeneral;
       
   251                         }
       
   252                     }
       
   253                 break;
       
   254                 
       
   255             case KUsbFeature_B_HnpEnable:
       
   256                 if (!iOtgSupport)
       
   257                     {
       
   258                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported on a OTG device"));
       
   259                     iLastError = KErrGeneral;
       
   260                     }            
       
   261                 else if (!(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
       
   262                     {
       
   263                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only valid if OTG device supports HNP"));
       
   264                     iLastError = KErrGeneral;
       
   265                     }
       
   266                 else
       
   267                     {
       
   268                     iOtgFuncMap |= KUsbOtgAttr_B_HnpEnable;
       
   269                     OtgFeaturesNotify();
       
   270                     }
       
   271                 break;
       
   272                 
       
   273             case KUsbFeature_A_HnpSupport:
       
   274                 if (!iOtgSupport)
       
   275                     {
       
   276                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported on a OTG device"));
       
   277                     iLastError = KErrGeneral;
       
   278                     }
       
   279                 else if (!(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
       
   280                     {
       
   281                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only valid if OTG device supports HNP"));
       
   282                     iLastError = KErrGeneral;
       
   283                     }
       
   284                 else
       
   285                     {
       
   286                     iOtgFuncMap |= KUsbOtgAttr_A_HnpSupport;
       
   287                     OtgFeaturesNotify();
       
   288                     }
       
   289                 break;
       
   290                 
       
   291             case KUsbFeature_A_AltHnpSupport:
       
   292                 if (!iOtgSupport)
       
   293                     {
       
   294                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported on a OTG device"));
       
   295                     iLastError = KErrGeneral;
       
   296                     }
       
   297                 else if (!(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
       
   298                     {
       
   299                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only valid if OTG device supports HNP"));
       
   300                     iLastError = KErrGeneral;
       
   301                     }
       
   302                 else
       
   303                     {
       
   304                     iOtgFuncMap |= KUsbOtgAttr_A_AltHnpSupport;
       
   305                     OtgFeaturesNotify();
       
   306                     }
       
   307                 break;
       
   308                 
       
   309             default:
       
   310                 __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown feature requested"));
       
   311                 iLastError = KErrGeneral;                
       
   312             }
       
   313         }
       
   314     else // KUsbRequest_ClearFeature
       
   315         {
       
   316         switch (aPacket.iValue)
       
   317             {
       
   318             case KUsbFeature_RemoteWakeup:
       
   319                 if ( iDeviceState < UsbShai::EUsbPeripheralStateAddress)
       
   320                     {
       
   321                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   322                     iLastError = KErrGeneral;
       
   323                     }
       
   324                 else
       
   325                     {
       
   326                     iRmWakeupStatus_Enabled = EFalse;
       
   327                     }
       
   328                 break;
       
   329                 
       
   330             default:
       
   331                 __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown feature requested"));
       
   332                 iLastError = KErrGeneral;
       
   333             }
       
   334         }
       
   335     
       
   336     if(iLastError == KErrNone)
       
   337         {
       
   338         // Sent out status packet if no error found.
       
   339         iConTransferMgr->SendEp0ZeroByteStatusPacket();                            // success: zero bytes data during status stage
       
   340         
       
   341         // 9.4.9: "The transition to test mode of an upstream facing port must not happen until
       
   342         // after the status stage of the request."
       
   343         if (test_sel)
       
   344             {
       
   345             __KTRACE_OPT(KPANIC, Kern::Printf("  Entering HS Test Mode %d", test_sel));
       
   346             iController.EnterTestMode((UsbShai::TUsbTestModeSelector)test_sel);
       
   347             }
       
   348         }
       
   349     }
       
   350 
       
   351 
       
   352 void DUsbClientController::ProcessSetClearIfcFeature(const TUsbcSetup& aPacket)
       
   353     {
       
   354     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetClearIfcFeature()"));
       
   355     if ( iDeviceState < UsbShai::EUsbPeripheralStateConfigured)
       
   356         {
       
   357         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   358         iLastError = KErrGeneral;
       
   359         }
       
   360     else
       
   361         {
       
   362         // No interface features defined in USB spec, thus
       
   363         iLastError = KErrGeneral;
       
   364         }
       
   365     }
       
   366 
       
   367 
       
   368 void DUsbClientController::ProcessSetClearEpFeature(const TUsbcSetup& aPacket)
       
   369     {
       
   370     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetClearEpFeature()"));
       
   371     if (
       
   372         ((iDeviceState < UsbShai::EUsbPeripheralStateAddress) ||
       
   373          (iDeviceState == UsbShai::EUsbPeripheralStateAddress && (aPacket.iIndex & KUsbEpAddress_Portmask) != 0)))
       
   374         {
       
   375         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   376         iLastError = KErrGeneral;
       
   377         }
       
   378     else if (aPacket.iValue != KUsbFeature_EndpointHalt)
       
   379         {
       
   380         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown feature requested"));
       
   381         iLastError = KErrGeneral;
       
   382         }
       
   383     else if (EndpointExists(aPacket.iIndex) == EFalse)
       
   384         {
       
   385         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint does not exist"));
       
   386         iLastError = KErrGeneral;
       
   387         }
       
   388     else
       
   389         {
       
   390         const TInt ep = EpAddr2Idx(aPacket.iIndex);
       
   391         if (iRealEndpoints[ep].iLEndpoint->iInfo.iType == UsbShai::KUsbEpTypeControl ||
       
   392             iRealEndpoints[ep].iLEndpoint->iInfo.iType == UsbShai::KUsbEpTypeIsochronous)
       
   393             {
       
   394             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint is Control or Isochronous"));
       
   395             iLastError = KErrGeneral;
       
   396             }
       
   397         else
       
   398             {
       
   399             SetClearHaltFeature(ep, aPacket.iRequest);
       
   400         
       
   401             // success: zero bytes data during status stage
       
   402             iConTransferMgr->SendEp0ZeroByteStatusPacket();
       
   403             }
       
   404         }
       
   405     }
       
   406 
       
   407 
       
   408 void DUsbClientController::ProcessSetAddress(const TUsbcSetup& aPacket)
       
   409     {
       
   410     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetAddress()"));
       
   411     if ( iDeviceState > UsbShai::EUsbPeripheralStateAddress)
       
   412         {
       
   413         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   414         iLastError = KErrGeneral;
       
   415         }
       
   416     else
       
   417         {
       
   418         const TUint16 addr = aPacket.iValue;
       
   419         
       
   420         if (addr > 127)
       
   421             {
       
   422             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad address value: %d (>127)", addr));
       
   423             iLastError = KErrGeneral;
       
   424             }
       
   425         else if (addr == 0)
       
   426             {
       
   427             // Enter Default state (from Default or Address)
       
   428             NextDeviceState(UsbShai::EUsbPeripheralStateDefault);
       
   429             }
       
   430         
       
   431         __KTRACE_OPT(KUSB, Kern::Printf("  USB address: %d", addr));
       
   432         
       
   433         // If controller support hw acceleration,call set address first and then status
       
   434         if(iControllerProperties.iControllerCaps & UsbShai::KDevCapSetAddressAcceleration)
       
   435             {
       
   436             iController.SetDeviceAddress(addr);
       
   437             }
       
   438 
       
   439         // The spec says, under section 9.4.6:
       
   440         // "Stages after the initial Setup packet assume the same device address as the Setup packet. The USB
       
   441         // device does not change its device address until after the Status stage of this request is completed
       
   442         // successfully. Note that this is a difference between this request and all other requests. For all other
       
   443         // requests, the operation indicated must be completed before the Status stage."
       
   444         // Therefore, here we first send the status packet and only then actually execute the request.
       
   445         iConTransferMgr->SendEp0ZeroByteStatusPacket();
       
   446         
       
   447         // If controller doesn't support hw acceleration, call set address after status
       
   448         if((iControllerProperties.iControllerCaps & UsbShai::KDevCapSetAddressAcceleration) == 0)
       
   449             {
       
   450             iController.SetDeviceAddress(addr);
       
   451             }
       
   452         }
       
   453     }
       
   454 
       
   455 
       
   456 void DUsbClientController::ProcessGetDescriptor(const TUsbcSetup& aPacket)
       
   457     {
       
   458     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetDescriptor()"));
       
   459     if ( iDeviceState < UsbShai::EUsbPeripheralStateDefault)
       
   460         {
       
   461         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   462         iLastError = KErrGeneral;
       
   463         return ;
       
   464         }
       
   465 
       
   466     // Make sure we assume the correct speed
       
   467     __ASSERT_DEBUG((iHighSpeed == CurrentlyUsingHighSpeed()), Kern::Fault(KUsbPILPanicCat, __LINE__));
       
   468 
       
   469     TInt size = 0;
       
   470     const TInt result = iDescriptors.FindDescriptor(HighByte(aPacket.iValue), // Type
       
   471                                                     LowByte(aPacket.iValue), // Index
       
   472                                                     aPacket.iIndex, // Language ID
       
   473                                                     size);
       
   474 
       
   475     if ((result != KErrNone) || (size == 0))
       
   476         {
       
   477         // This doesn't have to be an error - protocol-wise it's OK.
       
   478         __KTRACE_OPT(KUSB, Kern::Printf("  Couldn't retrieve descriptor"));
       
   479         iLastError = KErrGeneral;
       
   480         return;
       
   481         }
       
   482 
       
   483     __KTRACE_OPT(KUSB, Kern::Printf("  Descriptor found, size: %d (requested: %d)",
       
   484                                     size, aPacket.iLength));
       
   485     if (size > KUsbcBufSz_Ep0Tx)
       
   486         {
       
   487         // This should actually not be possible (i.e. we should never get here).
       
   488         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ep0_Tx buffer too small"));
       
   489         }
       
   490     if (size > aPacket.iLength)
       
   491         {
       
   492         // Send only as much data as requested by the host
       
   493         size = aPacket.iLength;
       
   494         }
       
   495 
       
   496 #ifdef ENABLE_EXCESSIVE_DEBUG_OUTPUT
       
   497     __KTRACE_OPT(KUSB,
       
   498                  Kern::Printf("  Data: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x ...",
       
   499                               iEp0_TxBuf[0], iEp0_TxBuf[1], iEp0_TxBuf[2], iEp0_TxBuf[3],
       
   500                               iEp0_TxBuf[4], iEp0_TxBuf[5], iEp0_TxBuf[6], iEp0_TxBuf[7]));
       
   501 #endif
       
   502     // If we're about to send less bytes than expected by the host AND our number is a
       
   503     // multiple of the packet size, in order to indicate the end of the control transfer,
       
   504     // we must finally send a zero length data packet (ZLP):
       
   505     const TBool zlp = ((size < aPacket.iLength) && (size % iEp0MaxPacketSize == 0));
       
   506     if (iConTransferMgr->SetupEndpointZeroWrite(iEp0_TxBuf, size, zlp) == KErrNone)
       
   507         {
       
   508         iEp0WritePending = ETrue;
       
   509         }
       
   510     else
       
   511         {
       
   512         __KTRACE_OPT(KUSB, Kern::Printf("  Wrong: Write to Ep0 Failed"));
       
   513         }
       
   514     }
       
   515 
       
   516 
       
   517 void DUsbClientController::ProcessSetDescriptor(const TUsbcSetup& aPacket)
       
   518     {
       
   519     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetDescriptor()"));
       
   520 #ifndef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
       
   521     iLastError = KErrGeneral;
       
   522     return;
       
   523 #else
       
   524     if ( iDeviceState < UsbShai::EUsbPeripheralStateAddress)
       
   525         {
       
   526         // Error: Invalid device state!
       
   527         iLastError = KErrGeneral;
       
   528         }
       
   529     else if (aPacket.iLength > KUsbcBufSz_Ep0Rx)
       
   530         {
       
   531         // Error: Our Rx buffer is too small! (Raise a defect to make it larger)
       
   532         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ep0_Rx buffer too small"));
       
   533         iLastError = KErrGeneral;
       
   534         }
       
   535     else
       
   536         {
       
   537         SetEp0DataOutVars();
       
   538         iConTransferMgr->SetupEndpointZeroRead();
       
   539         }
       
   540 #endif
       
   541     }
       
   542 
       
   543 void DUsbClientController::ProcessGetConfiguration(const TUsbcSetup& aPacket)
       
   544     {
       
   545     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetConfiguration()"));
       
   546     if ( iDeviceState < UsbShai::EUsbPeripheralStateAddress)
       
   547         {
       
   548         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   549         iLastError = KErrGeneral;
       
   550         }
       
   551     else if ( iDeviceState == UsbShai::EUsbPeripheralStateAddress && iCurrentConfig != 0)
       
   552         {
       
   553         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DeviceState Address && Config != 0"));
       
   554         iLastError = KErrGeneral;
       
   555         }
       
   556     else if ( iDeviceState == UsbShai::EUsbPeripheralStateConfigured && iCurrentConfig == 0)
       
   557         {
       
   558         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DeviceState Configured && Config == 0"));
       
   559         iLastError = KErrGeneral;
       
   560         }
       
   561     else
       
   562         {
       
   563         if (aPacket.iLength != 1)                                // "unspecified behavior"
       
   564             {
       
   565             __KTRACE_OPT(KUSB, Kern::Printf("  Warning: wLength != 1 (= %d)", aPacket.iLength));
       
   566             }
       
   567         __KTRACE_OPT(KUSB, Kern::Printf("  Reporting configuration value %d", iCurrentConfig));
       
   568         if (iConTransferMgr->SetupEndpointZeroWrite(&iCurrentConfig, sizeof(iCurrentConfig)) == KErrNone)
       
   569             {
       
   570             iEp0WritePending = ETrue;
       
   571             }
       
   572         else
       
   573             {
       
   574             __KTRACE_OPT(KUSB, Kern::Printf("  Wrong: Write to Ep0 Failed"));
       
   575             }
       
   576         }
       
   577     }
       
   578 
       
   579 
       
   580 /** Changes the device's configuration value, including interface setup and/or
       
   581     teardown and state change notification of higher-layer clients.
       
   582     May also be called by the PSL in special cases - therefore publishedPartner.
       
   583 
       
   584     @param aPacket The received Ep0 SET_CONFIGURATION setup request packet.
       
   585     @return KErrGeneral in case of a protocol error, KErrNone otherwise.
       
   586 
       
   587     @publishedPartner @released
       
   588 */
       
   589 TInt DUsbClientController::ProcessSetConfiguration(const TUsbcSetup& aPacket)
       
   590     {
       
   591     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetConfiguration()"));
       
   592 
       
   593     // This function may be called by the PSL from within an ISR -- so we have
       
   594     // to take care what we do here (and also in all functions that get called
       
   595     // from here).
       
   596     const TInt value = aPacket.iValue;
       
   597     
       
   598     if ( iDeviceState < UsbShai::EUsbPeripheralStateAddress)
       
   599         {
       
   600         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   601         iLastError = KErrGeneral;
       
   602         }    
       
   603     else if (value > 1)                                            // we support only one configuration
       
   604         {
       
   605         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Configuration value too large: %d", value));
       
   606         iLastError = KErrGeneral;
       
   607         }
       
   608     else
       
   609         {
       
   610         __KTRACE_OPT(KUSB, Kern::Printf("  Configuration value: %d", value));
       
   611         ChangeConfiguration(value);
       
   612 
       
   613         // In 9.4.5 under GET_STATUS we read, that after SET_CONFIGURATION the HALT feature
       
   614         // for all endpoints is reset to zero.
       
   615         TInt num = 0;
       
   616         (TAny) DoForEveryEndpointInUse(&DUsbClientController::ClearHaltFeature, num);
       
   617         __KTRACE_OPT(KUSB, Kern::Printf("  Called ClearHaltFeature() for %d endpoints", num));
       
   618         // success: zero bytes data during status stage
       
   619         iConTransferMgr->SendEp0ZeroByteStatusPacket();
       
   620         }
       
   621         
       
   622     return iLastError;
       
   623     }
       
   624 
       
   625 void DUsbClientController::ProcessGetInterface(const TUsbcSetup& aPacket)
       
   626     {
       
   627     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessGetInterface()"));
       
   628     
       
   629     const TInt number = aPacket.iIndex;
       
   630     
       
   631     if ( iDeviceState < UsbShai::EUsbPeripheralStateConfigured)
       
   632         {
       
   633         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   634         iLastError = KErrGeneral;
       
   635         }
       
   636     else if (iCurrentConfig == 0)
       
   637         {
       
   638         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Device not configured"));
       
   639         iLastError = KErrGeneral;
       
   640         }    
       
   641     else if (!InterfaceExists(number))
       
   642         {
       
   643         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad interface index: %d", number));
       
   644         iLastError = KErrGeneral;
       
   645         }
       
   646     else
       
   647         {
       
   648         // Send alternate setting code of iCurrentInterface of Interface(set) <number> of the current
       
   649         // config (iCurrentConfig).
       
   650         const TUint8 setting = InterfaceNumber2InterfacePointer(number)->iCurrentInterface;
       
   651         __KTRACE_OPT(KUSB, Kern::Printf("  Reporting interface setting %d", setting));
       
   652         if (iConTransferMgr->SetupEndpointZeroWrite(&setting, 1) == KErrNone)
       
   653             {
       
   654             iEp0WritePending = ETrue;
       
   655             }
       
   656         else
       
   657             {
       
   658             __KTRACE_OPT(KUSB, Kern::Printf("  Wrong: Write to Ep0 Failed"));
       
   659             }
       
   660         }
       
   661     }
       
   662 
       
   663 
       
   664 void DUsbClientController::ProcessSetInterface(const TUsbcSetup& aPacket)
       
   665     {
       
   666     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSetInterface()"));
       
   667     
       
   668     const TInt number = aPacket.iIndex;
       
   669     
       
   670     if ( iDeviceState < UsbShai::EUsbPeripheralStateConfigured)
       
   671         {
       
   672         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   673         iLastError = KErrGeneral;
       
   674         }
       
   675     else if (iCurrentConfig == 0)
       
   676         {
       
   677         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Device not configured"));
       
   678         iLastError = KErrGeneral;
       
   679         }    
       
   680     else if (!InterfaceExists(number))
       
   681         {
       
   682         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Bad interface index: %d", number));
       
   683         iLastError = KErrGeneral;
       
   684         }
       
   685     else
       
   686         {
       
   687         const TInt setting = aPacket.iValue;
       
   688         TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(number);
       
   689         RPointerArray<TUsbcInterface>& ifcs = ifcset_ptr->iInterfaces;
       
   690         if (setting >= ifcs.Count())
       
   691             {
       
   692             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Alt Setting >= bNumAltSettings: %d", setting));
       
   693             iLastError = KErrGeneral;
       
   694             }
       
   695         else
       
   696             {
       
   697             __KTRACE_OPT(KUSB, Kern::Printf("  Interface setting:: %d", setting));
       
   698             // Set iCurrentInterface of Interface(set) <number> of the current config
       
   699             // (iCurrentConfig) to alternate setting <setting>.
       
   700             ChangeInterface(ifcs[setting]);
       
   701             // In 9.4.5 under GET_STATUS we read, that after SET_INTERFACE the HALT feature
       
   702             // for all endpoints (of the now current interface setting) is reset to zero.
       
   703             RPointerArray<TUsbcLogicalEndpoint>& eps = ifcset_ptr->CurrentInterface()->iEndpoints;
       
   704             const TInt num_eps = eps.Count();
       
   705             for (TInt i = 0; i < num_eps; i++)
       
   706                 {
       
   707                 const TInt ep_num = EpAddr2Idx(eps[i]->iPEndpoint->iEndpointAddr);
       
   708                 (TAny) ClearHaltFeature(ep_num);
       
   709                 }
       
   710             // success: zero bytes data during status stage
       
   711             iConTransferMgr->SendEp0ZeroByteStatusPacket();    
       
   712             }
       
   713         }
       
   714     }
       
   715 
       
   716 
       
   717 void DUsbClientController::ProcessSynchFrame(const TUsbcSetup& aPacket)
       
   718     {
       
   719     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSynchFrame()"));
       
   720     
       
   721     const TInt ep = aPacket.iIndex;
       
   722     
       
   723     if ( iDeviceState < UsbShai::EUsbPeripheralStateConfigured)
       
   724         {
       
   725         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
   726         iLastError = KErrGeneral;
       
   727         }    
       
   728     else if (EndpointExists(ep) == EFalse)
       
   729         {
       
   730         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint does not exist"));
       
   731         iLastError = KErrGeneral;
       
   732         }
       
   733     else if (iRealEndpoints[EpAddr2Idx(ep)].iLEndpoint->iInfo.iType != UsbShai::KUsbEpTypeIsochronous)
       
   734         {
       
   735         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint is not isochronous"));
       
   736         iLastError = KErrGeneral;
       
   737         }
       
   738     else 
       
   739         {
       
   740         // We always send 0:
       
   741         *reinterpret_cast<TUint16*>(iEp0_TxBuf) = 0x00;
       
   742         if (iConTransferMgr->SetupEndpointZeroWrite(iEp0_TxBuf, 2) == KErrNone)
       
   743             {
       
   744             iEp0WritePending = ETrue;
       
   745             }
       
   746         else
       
   747             {
       
   748             __KTRACE_OPT(KUSB, Kern::Printf("  Wrong: Write to Ep0 Failed"));
       
   749             }
       
   750         }
       
   751     }
       
   752 
       
   753 
       
   754 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
       
   755 void DUsbClientController::ProceedSetDescriptor()
       
   756     {
       
   757     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProceedSetDescriptor()"));
       
   758     // iEp0DataReceived already reflects the current buffer state
       
   759     if (iEp0DataReceived < iConTransferMgr->PktParser().DataLength())
       
   760         {
       
   761         // Not yet all data received => proceed
       
   762         return;
       
   763         }
       
   764     if (iEp0DataReceived > iConTransferMgr->PktParser().DataLength())
       
   765         {
       
   766         // Error: more data received than expected
       
   767         // but we don't care...
       
   768         }
       
   769     const TUint8 type = HighByte(iConTransferMgr->PktParser().Value());
       
   770     if (type == KUsbDescType_String)
       
   771         {
       
   772         // set/add new string descriptor
       
   773         }
       
   774     else
       
   775         {
       
   776         // set/add new ordinary descriptor
       
   777         }
       
   778     TUint8 index = LowByte(iConTransferMgr->PktParser().Value());
       
   779     TUint16 langid = iConTransferMgr->PktParser().Index();
       
   780     TUint16 length_total = iConTransferMgr->PktParser().DataLength();
       
   781 
       
   782     iConTransferMgr->SendEp0ZeroByteStatusPacket();
       
   783     }
       
   784 #endif
       
   785 
       
   786 
       
   787 // --- Secondary (Helper) Functions
       
   788 
       
   789 void DUsbClientController::SetClearHaltFeature(TInt aRealEndpoint, TUint8 aRequest)
       
   790     {
       
   791     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetClearHaltFeature()"));
       
   792     if (aRequest == KUsbRequest_SetFeature)
       
   793         {
       
   794         if (iRealEndpoints[aRealEndpoint].iHalt)
       
   795             {
       
   796             // (This condition is not really an error)
       
   797             __KTRACE_OPT(KUSB, Kern::Printf("  Warning: HALT feature already set"));
       
   798             return;
       
   799             }
       
   800         __KTRACE_OPT(KUSB, Kern::Printf("  setting HALT feature for real endpoint %d",
       
   801                                         aRealEndpoint));
       
   802         iController.StallEndpoint(aRealEndpoint);
       
   803         iRealEndpoints[aRealEndpoint].iHalt = ETrue;
       
   804         }
       
   805     else                                                    // KUsbRequest_ClearFeature
       
   806         {
       
   807         if (iRealEndpoints[aRealEndpoint].iHalt == EFalse)
       
   808             {
       
   809             // In this case, before we return, the data toggles are reset to DATA0.
       
   810             __KTRACE_OPT(KUSB, Kern::Printf("  Warning: HALT feature already cleared"));
       
   811             iController.ResetDataToggle(aRealEndpoint);
       
   812             return;
       
   813             }
       
   814         __KTRACE_OPT(KUSB, Kern::Printf("  clearing HALT feature for real endpoint %d",
       
   815                                         aRealEndpoint));
       
   816         iController.ResetDataToggle(aRealEndpoint);
       
   817         iController.ClearStallEndpoint(aRealEndpoint);
       
   818         iRealEndpoints[aRealEndpoint].iHalt = EFalse;
       
   819         }
       
   820     EpStatusNotify(aRealEndpoint);                            // only called if actually something changed
       
   821     }
       
   822 
       
   823 
       
   824 TInt DUsbClientController::ClearHaltFeature(TInt aRealEndpoint)
       
   825     {
       
   826     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ClearHaltFeature()"));
       
   827     if (iRealEndpoints[aRealEndpoint].iHalt != EFalse)
       
   828         {
       
   829         iController.ClearStallEndpoint(aRealEndpoint);
       
   830         iRealEndpoints[aRealEndpoint].iHalt = EFalse;
       
   831         }
       
   832     return KErrNone;
       
   833     }
       
   834 
       
   835 
       
   836 void DUsbClientController::ChangeConfiguration(TUint16 aValue)
       
   837     {
       
   838     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ChangeConfiguration()"));
       
   839     // New configuration is the same as the old one: 0
       
   840     if (iCurrentConfig == 0 && aValue == 0)
       
   841         {
       
   842         // no-op
       
   843         __KTRACE_OPT(KUSB, Kern::Printf("  Configuration: New == Old == 0 --> exiting"));
       
   844         return;
       
   845         }
       
   846     // New configuration is the same as the old one (but not 0)
       
   847     if (iCurrentConfig == aValue)
       
   848         {
       
   849         // no-op
       
   850         __KTRACE_OPT(KUSB, Kern::Printf("  Configuration: New == Old == %d --> exiting", aValue));
       
   851         return;
       
   852         }
       
   853     // Device is already configured
       
   854     if (iCurrentConfig != 0)
       
   855         {
       
   856         __KTRACE_OPT(KUSB, Kern::Printf("  Device was configured: %d", iCurrentConfig));
       
   857         // Tear down all interface(set)s of the old configuration
       
   858         RPointerArray<TUsbcInterfaceSet>& ifcsets = CurrentConfig()->iInterfaceSets;
       
   859         for (TInt i = 0; i < ifcsets.Count(); ++i)
       
   860             {
       
   861             __KTRACE_OPT(KUSB, Kern::Printf("  Tearing down InterfaceSet %d", i));
       
   862             InterfaceSetTeardown(ifcsets[i]);
       
   863             }
       
   864         iCurrentConfig = 0;
       
   865         // Enter Address state (from Configured)
       
   866         if (iDeviceState == UsbShai::EUsbPeripheralStateConfigured)
       
   867             NextDeviceState(UsbShai::EUsbPeripheralStateAddress);
       
   868         }
       
   869     // Device gets a new configuration
       
   870     if (aValue != 0)
       
   871         {
       
   872         __KTRACE_OPT(KUSB, Kern::Printf("  Device gets new configuration..."));
       
   873         // Setup all alternate settings 0 of all interfaces
       
   874         // (Don't separate the next two lines of code.)
       
   875         iCurrentConfig = aValue;
       
   876         RPointerArray<TUsbcInterfaceSet>& ifcsets = CurrentConfig()->iInterfaceSets;
       
   877         const TInt n = ifcsets.Count();
       
   878         for (TInt i = 0; i < n; ++i)
       
   879             {
       
   880             __KTRACE_OPT(KUSB, Kern::Printf("  Setting up InterfaceSet %d", i));
       
   881             InterfaceSetup(ifcsets[i]->iInterfaces[0]);
       
   882             }
       
   883         // Enter Configured state (from Address or Configured)
       
   884         NextDeviceState(UsbShai::EUsbPeripheralStateConfigured);
       
   885         }
       
   886     __KTRACE_OPT(KUSB, Kern::Printf("  New configuration: %d", iCurrentConfig));
       
   887     return;
       
   888     }
       
   889 
       
   890 
       
   891 void DUsbClientController::InterfaceSetup(TUsbcInterface* aIfc)
       
   892     {
       
   893     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::InterfaceSetup()"));
       
   894     const TInt num_eps = aIfc->iEndpoints.Count();
       
   895     for (TInt i = 0; i < num_eps; i++)
       
   896         {
       
   897         // Prepare this endpoint for I/O
       
   898         TUsbcLogicalEndpoint* const ep = aIfc->iEndpoints[i];
       
   899         // (TUsbcLogicalEndpoint's FS/HS endpoint sizes and interval values got
       
   900         //  adjusted in its constructor.)
       
   901         if (iHighSpeed)
       
   902             {
       
   903             __KTRACE_OPT(KUSB, Kern::Printf("  Setting Ep info size to %d (HS)", ep->iEpSize_Hs));
       
   904             ep->iInfo.iSize = ep->iEpSize_Hs;
       
   905             }
       
   906         else
       
   907             {
       
   908             __KTRACE_OPT(KUSB, Kern::Printf("  Setting Ep info size to %d (FS)", ep->iEpSize_Fs));
       
   909             ep->iInfo.iSize = ep->iEpSize_Fs;
       
   910             }
       
   911         const TInt idx = EpAddr2Idx(ep->iPEndpoint->iEndpointAddr);
       
   912         if (iController.ConfigureEndpoint(idx, ep->iInfo) != KErrNone)
       
   913             {
       
   914             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint %d configuration failed", idx));
       
   915             continue;
       
   916             }
       
   917         // Should there be a problem with it then we could try resetting the ep
       
   918         // data toggle at this point (or before the Configure) as well.
       
   919         __KTRACE_OPT(KUSB, Kern::Printf("  Connecting real ep addr 0x%02x & logical ep #%d",
       
   920                                         ep->iPEndpoint->iEndpointAddr, ep->iLEndpointNum));
       
   921         ep->iPEndpoint->iLEndpoint = ep;
       
   922         }
       
   923     aIfc->iInterfaceSet->iCurrentInterface = aIfc->iSettingCode;
       
   924     return;
       
   925     }
       
   926 
       
   927 
       
   928 void DUsbClientController::InterfaceSetTeardown(TUsbcInterfaceSet* aIfcSet)
       
   929     {
       
   930     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::InterfaceSetTeardown()"));
       
   931     if (aIfcSet->iInterfaces.Count() == 0)
       
   932         {
       
   933         __KTRACE_OPT(KUSB, Kern::Printf("  No interfaces exist - returning"));
       
   934         return;
       
   935         }
       
   936     RPointerArray<TUsbcLogicalEndpoint>& eps = aIfcSet->CurrentInterface()->iEndpoints;
       
   937     const TInt num_eps = eps.Count();
       
   938     for (TInt i = 0; i < num_eps; i++)
       
   939         {
       
   940         TUsbcLogicalEndpoint* const ep = eps[i];
       
   941         const TInt idx = EpAddr2Idx(ep->iPEndpoint->iEndpointAddr);
       
   942 
       
   943         CancelTransferRequests(idx);
       
   944 
       
   945         if (!ep->iPEndpoint->iLEndpoint)
       
   946             {
       
   947             __KTRACE_OPT(KUSB, Kern::Printf("  real ep %d not configured: skipping", idx));
       
   948             continue;
       
   949             }
       
   950         if (iController.ResetDataToggle(idx) != KErrNone)
       
   951             {
       
   952             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint %d data toggle reset failed", idx));
       
   953             }
       
   954         if (iController.DeConfigureEndpoint(idx) != KErrNone)
       
   955             {
       
   956             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint %d de-configuration failed", idx));
       
   957             }
       
   958 
       
   959         __KTRACE_OPT(KUSB, Kern::Printf("  disconnecting real ep & logical ep"));
       
   960         ep->iPEndpoint->iLEndpoint = NULL;
       
   961         }
       
   962     if (aIfcSet->CurrentInterface() != 0)
       
   963         {
       
   964         __KTRACE_OPT(KUSB, Kern::Printf("  Resetting alternate interface setting to 0"));
       
   965         //Add this mutex to protect the interface set data structure
       
   966         if (NKern::CurrentContext() == EThread)
       
   967             {
       
   968             NKern::FMWait(&iMutex);
       
   969             }
       
   970         
       
   971         aIfcSet->iCurrentInterface = 0;
       
   972         if (NKern::CurrentContext() == EThread)
       
   973             {
       
   974             NKern::FMSignal(&iMutex);
       
   975             }        
       
   976         }
       
   977     return;
       
   978     }
       
   979 
       
   980 
       
   981 void DUsbClientController::ChangeInterface(TUsbcInterface* aIfc)
       
   982     {
       
   983     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ChangeInterface()"));
       
   984     TUsbcInterfaceSet* ifcset = aIfc->iInterfaceSet;
       
   985     const TUint8 setting = aIfc->iSettingCode;
       
   986     if (ifcset->iCurrentInterface == setting)
       
   987         {
       
   988         __KTRACE_OPT(KUSB, Kern::Printf("  New Ifc == old Ifc: nothing to do"));
       
   989         return;
       
   990         }
       
   991     __KTRACE_OPT(KUSB, Kern::Printf("  Setting new interface setting #%d", setting));
       
   992     InterfaceSetTeardown(ifcset);
       
   993     InterfaceSetup(aIfc);
       
   994     StatusNotify(static_cast<UsbShai::TUsbPeripheralState>(KUsbAlternateSetting | setting), ifcset->iClientId);
       
   995     }
       
   996 
       
   997 
       
   998 // aFunction gets called, successively, with the endpoint index of every ep in-use as its argument.
       
   999 // (BTW: The declaration "type (class::*name)(params)" makes <name> a "pointer to element function".)
       
  1000 //
       
  1001 TInt DUsbClientController::DoForEveryEndpointInUse(TInt (DUsbClientController::*aFunction)(TInt), TInt& aCount)
       
  1002     {
       
  1003     __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DoForEveryEndpointInUse()"));
       
  1004     aCount = 0;
       
  1005     TUsbcConfiguration* const config = CurrentConfig();
       
  1006     if (!config)
       
  1007         {
       
  1008         __KTRACE_OPT(KUSB, Kern::Printf("  Device is not configured - returning"));
       
  1009         return KErrNone;
       
  1010         }
       
  1011     RPointerArray<TUsbcInterfaceSet>& ifcsets = config->iInterfaceSets;
       
  1012     const TInt num_ifcsets = ifcsets.Count();
       
  1013     for (TInt i = 0; i < num_ifcsets; i++)
       
  1014         {
       
  1015         RPointerArray<TUsbcLogicalEndpoint>& eps = ifcsets[i]->CurrentInterface()->iEndpoints;
       
  1016         const TInt num_eps = eps.Count();
       
  1017         for (TInt j = 0; j < num_eps; j++)
       
  1018             {
       
  1019             const TInt ep_num = EpAddr2Idx(eps[j]->iPEndpoint->iEndpointAddr);
       
  1020             const TInt result = (this->*aFunction)(ep_num);
       
  1021             ++aCount;
       
  1022             if (result != KErrNone)
       
  1023                 {
       
  1024                 return result;
       
  1025                 }
       
  1026             }
       
  1027         }
       
  1028     return KErrNone;
       
  1029     }
       
  1030 
       
  1031 // Data Tx is done.
       
  1032 void DUsbClientController::ProcessDataInPacket(TInt aCount,TInt aErrCode)
       
  1033     {
       
  1034     // Clear Error Code
       
  1035     iLastError = KErrNone;
       
  1036     
       
  1037     // For tx, no premature end is allowed.
       
  1038     if(aErrCode != KErrNone)
       
  1039         {
       
  1040         // something wrong in hardware, we can do nothing as remedy
       
  1041         // just stall the endpoint.
       
  1042         iConTransferMgr->StallEndpoint(KEp0_In);
       
  1043         iConTransferMgr->SetupEndpointZeroRead();
       
  1044         
       
  1045         // set err code to Error general if end point is stalled
       
  1046         iLastError = KErrGeneral;
       
  1047         }
       
  1048     else
       
  1049         {
       
  1050         // no longer a write pending
       
  1051         iEp0WritePending = EFalse;
       
  1052         
       
  1053         // If it was a client who set up this transmission, we report to that client
       
  1054         if (iEp0ClientDataTransmitting)
       
  1055             {
       
  1056             iEp0ClientDataTransmitting = EFalse;
       
  1057             TUsbcRequestCallback* const p = iRequestCallbacks[KEp0_Tx];
       
  1058             
       
  1059             if (p)
       
  1060                 {
       
  1061                 __ASSERT_DEBUG((p->iTransferDir == UsbShai::EControllerWrite), Kern::Fault(KUsbPILPanicCat, __LINE__));
       
  1062                 p->iError = aErrCode;
       
  1063                 p->iTxBytes = aCount;
       
  1064                 
       
  1065                 // tell the client that the sending is done
       
  1066                 // later, it is possible that a status out packet comes in,
       
  1067                 // just ignore it.
       
  1068                 ProcessDataTransferDone(*p);
       
  1069                 }
       
  1070             else
       
  1071                 {
       
  1072                 // we should never goes here
       
  1073                 iConTransferMgr->StallEndpoint(KEp0_In);
       
  1074                 
       
  1075                 // request not found
       
  1076                 iLastError = KErrNotFound;
       
  1077                 }
       
  1078             }
       
  1079         // else
       
  1080         //   it is our own who sending the data, no more action needed
       
  1081         }
       
  1082     }
       
  1083 
       
  1084 // Status Rx is done    
       
  1085 void DUsbClientController::ProcessStatusOutPacket(TInt aErrCode)
       
  1086     {
       
  1087     // Clear Error Code
       
  1088     iLastError = KErrNone;
       
  1089     
       
  1090     // Dangdang, psl saying a status out packet recieved from
       
  1091     // host, but, we already completed user's writting request, just ignore it.
       
  1092     
       
  1093     // any way, receiving this means no write is pending.
       
  1094     iEp0WritePending = EFalse;
       
  1095     }
       
  1096     
       
  1097 // Data Rx is (partial) done
       
  1098 void DUsbClientController::ProcessDataOutPacket(TInt aCount,TInt aErrCode)
       
  1099     {
       
  1100     // Clear Error Code
       
  1101     iLastError = KErrNone;
       
  1102     
       
  1103     if (aErrCode != KErrNone && aErrCode != KErrPrematureEnd)
       
  1104         {
       
  1105         // something wrong in hardware, we can do nothing as remedy
       
  1106         // just stall the endpoint.
       
  1107         iConTransferMgr->StallEndpoint(KEp0_Out);
       
  1108         iConTransferMgr->SetupEndpointZeroRead();
       
  1109         
       
  1110         // set err code to Error general if end point is stalled
       
  1111         iLastError = KErrGeneral;       
       
  1112         }
       
  1113     else
       
  1114         {
       
  1115         // Trim aCount with iEp0MaxPacketSize per packet
       
  1116         if (aCount > iEp0MaxPacketSize)
       
  1117             {
       
  1118             aCount = iEp0MaxPacketSize;
       
  1119             }
       
  1120                
       
  1121         iEp0DataReceived += aCount;
       
  1122         
       
  1123         if (iEp0ClientId == NULL)
       
  1124             {
       
  1125             // it is us( not an app), who owns this transaction
       
  1126             switch( iConTransferMgr->PktParser().Request())
       
  1127                 {
       
  1128 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST                
       
  1129                 case KUsbRequest_SetDescriptor:
       
  1130                     {
       
  1131                     memcpy(iEp0_RxCollectionBuf + iEp0DataReceived, iEp0_RxBuf, aCount);                    
       
  1132                     
       
  1133                     // Status will be sent in side this function
       
  1134                     // if we had recieved enough bytes
       
  1135                     ProceedSetDescriptor();
       
  1136                     }
       
  1137                     break;
       
  1138 #endif                    
       
  1139                 default:
       
  1140                     {
       
  1141                     iConTransferMgr->StallEndpoint(KEp0_In);
       
  1142                     ResetEp0DataOutVars();
       
  1143                     
       
  1144                     // set err code to Error general if end point is stalled
       
  1145                     iLastError = KErrGeneral;
       
  1146                     }
       
  1147                     break;
       
  1148                 }
       
  1149             
       
  1150             if (iEp0DataReceived >= iConTransferMgr->PktParser().DataLength())
       
  1151                 {                
       
  1152                 // all data seems now to be here
       
  1153                 ResetEp0DataOutVars();
       
  1154                 }                
       
  1155             }
       
  1156         else
       
  1157             {
       
  1158             // it is an application who is requesting this data
       
  1159             // pass the data on to a client
       
  1160             
       
  1161             // it is the client's responsibility of sending a status
       
  1162             // packet back to host to indicate the whole transfer is
       
  1163             // done
       
  1164             
       
  1165             // Find the client Request callback
       
  1166             TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
       
  1167             TUsbcRequestCallback* p;
       
  1168             while ((p = iter++) != NULL)
       
  1169                 {
       
  1170                 if (p->Owner() == iEp0ClientId)
       
  1171                     {
       
  1172                     memcpy(p->iBufferStart, iEp0_RxBuf, aCount);
       
  1173                     p->iError = KErrNone;
       
  1174                     *(p->iPacketSize) = aCount;
       
  1175                     p->iRxPackets = 1;
       
  1176                     *(p->iPacketIndex) = 0;
       
  1177                     break;
       
  1178                     }
       
  1179                 }
       
  1180             
       
  1181             // pass data to client if found one.
       
  1182             if ( p != NULL)
       
  1183                 {
       
  1184                 ProcessDataTransferDone(*p);
       
  1185                     
       
  1186                 if (iEp0DataReceived >= iConTransferMgr->PktParser().DataLength())
       
  1187                     {
       
  1188                     // all data seems now to be here
       
  1189                     ResetEp0DataOutVars();
       
  1190                     }
       
  1191                 
       
  1192                 iLastError = KErrNone;
       
  1193                 
       
  1194                 }
       
  1195             else
       
  1196                 {
       
  1197                 // that's bad, we found a client is request this data
       
  1198                 // but no matching request callback found.
       
  1199                 
       
  1200                 iEp0_RxExtraCount = aCount;
       
  1201                 //iEp0_RxExtraData = ETrue;
       
  1202                 //iEp0_RxExtraError = aErrCode;
       
  1203                 iEp0DataReceived -= aCount;
       
  1204                 
       
  1205                 // No status packet will be send to host since no client is reading this data,
       
  1206                 // waiting client to send a status packet.
       
  1207                 
       
  1208                 iLastError = KErrNotFound;
       
  1209                 }
       
  1210             }
       
  1211         }
       
  1212     }
       
  1213 
       
  1214 // Status Tx is done    
       
  1215 void DUsbClientController::ProcessStatusInPacket(TInt aErrCode)
       
  1216     {
       
  1217     // Clear Error Code
       
  1218     iLastError = KErrNone; 
       
  1219 
       
  1220     // it is time to start a new read
       
  1221     iEp0WritePending = EFalse;
       
  1222     }
       
  1223 
       
  1224 //
       
  1225 // Setup Rx is done
       
  1226 //
       
  1227 void DUsbClientController::ProcessSetupPacket(TInt aCount,TInt aErrCode)
       
  1228     {
       
  1229     
       
  1230     if (aErrCode != KErrNone)
       
  1231         {
       
  1232         // something wrong in hardware, we can do nothing as remedy
       
  1233         // just stall the endpoint.
       
  1234         iConTransferMgr->StallEndpoint(KEp0_Out);
       
  1235         iConTransferMgr->SetupEndpointZeroRead();
       
  1236         
       
  1237         // set err code to Error general if end point is stalled
       
  1238         iLastError = KErrGeneral;       
       
  1239         }
       
  1240     
       
  1241     TUsbcSetup packet;
       
  1242     Buffer2Setup(iEp0_RxBuf, packet);
       
  1243     
       
  1244     // Clear Error Code
       
  1245     iLastError = KErrNone;
       
  1246     
       
  1247     // If this is a standard request, we can handle it here
       
  1248     // not need to bother app layer
       
  1249     if ((packet.iRequestType & KUsbRequestType_TypeMask) == KUsbRequestType_TypeStd)
       
  1250         {
       
  1251         // Fixme: this may not needed any more
       
  1252         iEp0ReceivedNonStdRequest = EFalse;
       
  1253         ProcessStandardRequest(aCount,packet);
       
  1254         }
       
  1255     else
       
  1256         {
       
  1257         // Fixme: This may not needed anymore
       
  1258         iEp0ReceivedNonStdRequest = ETrue;
       
  1259         ProcessNonStandardRequest(aCount,packet);
       
  1260         }
       
  1261     }
       
  1262 
       
  1263 #define USB_PROCESS_REQUEST(request,param) \
       
  1264     do \
       
  1265     { \
       
  1266     Process ## request(param); \
       
  1267     if (iLastError != KErrNone) \
       
  1268         { \
       
  1269         __KTRACE_OPT(KUSB, \
       
  1270                     Kern::Printf("  ProcessEp0SetupReceived: Stalling Ep0")); \
       
  1271         iConTransferMgr->StallEndpoint(KEp0_In); \
       
  1272         } \
       
  1273     }while(0)
       
  1274     
       
  1275     
       
  1276 //
       
  1277 // Standard request
       
  1278 // Please note that:Macro USB_PROCESS_REQUEST(xxx) will stall endpoint
       
  1279 // if anything wrong during the process, in which case status packet is 
       
  1280 // not needed.
       
  1281 //
       
  1282 void DUsbClientController::ProcessStandardRequest(TInt /*aCount*/,const TUsbcSetup& aPacket)
       
  1283     {
       
  1284     switch (aPacket.iRequest)
       
  1285         {
       
  1286         case KUsbRequest_GetStatus:
       
  1287             switch (aPacket.iRequestType & KUsbRequestType_DestMask)
       
  1288                 { // Recipient
       
  1289                 case KUsbRequestType_DestDevice:
       
  1290                     USB_PROCESS_REQUEST(GetDeviceStatus,aPacket);
       
  1291                     break;
       
  1292                     
       
  1293                 case KUsbRequestType_DestIfc:
       
  1294                     USB_PROCESS_REQUEST(GetInterfaceStatus,aPacket);
       
  1295                     break;
       
  1296                     
       
  1297                 case KUsbRequestType_DestEp:
       
  1298                     USB_PROCESS_REQUEST(GetEndpointStatus,aPacket);
       
  1299                     break;
       
  1300                     
       
  1301                 default:
       
  1302                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: GET STATUS - Other or Unknown recipient"));
       
  1303                     __KTRACE_OPT(KPANIC, Kern::Printf("  -> DUsbClientController::ProcessEp0SetupReceived: "
       
  1304                                                       "Stalling Ep0"));
       
  1305                     iConTransferMgr->StallEndpoint(KEp0_In);
       
  1306                     iLastError = KErrGeneral;
       
  1307                     break;
       
  1308                 }
       
  1309                 break;
       
  1310         
       
  1311         case KUsbRequest_ClearFeature:
       
  1312         case KUsbRequest_SetFeature:
       
  1313             switch (aPacket.iRequestType & KUsbRequestType_DestMask)
       
  1314                 { // Recipient
       
  1315                 case KUsbRequestType_DestDevice:
       
  1316                     USB_PROCESS_REQUEST(SetClearDevFeature,aPacket);
       
  1317                     break;
       
  1318                 case KUsbRequestType_DestIfc:
       
  1319                     // will 100% stall endpoint
       
  1320                     USB_PROCESS_REQUEST(SetClearIfcFeature,aPacket);
       
  1321                     break;
       
  1322                 case KUsbRequestType_DestEp:
       
  1323                     USB_PROCESS_REQUEST(SetClearEpFeature,aPacket);
       
  1324                     break;
       
  1325                 default:
       
  1326                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: SET/CLEAR FEATURE - "
       
  1327                                                       "Other or Unknown recipient"));
       
  1328                     __KTRACE_OPT(KPANIC, Kern::Printf("  -> Stalling Ep0"));
       
  1329                     iConTransferMgr->StallEndpoint(KEp0_In);
       
  1330                     iLastError = KErrGeneral;
       
  1331                     break;
       
  1332                 }
       
  1333                 break;
       
  1334                 
       
  1335         case KUsbRequest_SetAddress:
       
  1336             USB_PROCESS_REQUEST(SetAddress,aPacket);
       
  1337             break;
       
  1338             
       
  1339         case KUsbRequest_GetDescriptor:
       
  1340             USB_PROCESS_REQUEST(GetDescriptor,aPacket);
       
  1341             break;
       
  1342             
       
  1343         case KUsbRequest_SetDescriptor:
       
  1344             USB_PROCESS_REQUEST(SetDescriptor,aPacket);
       
  1345             break;
       
  1346             
       
  1347         case KUsbRequest_GetConfig:
       
  1348             USB_PROCESS_REQUEST(GetConfiguration,aPacket);
       
  1349             break;
       
  1350             
       
  1351         case KUsbRequest_SetConfig:
       
  1352             USB_PROCESS_REQUEST(SetConfiguration,aPacket);
       
  1353             break;
       
  1354             
       
  1355         case KUsbRequest_GetInterface:
       
  1356             USB_PROCESS_REQUEST(GetInterface,aPacket);
       
  1357             break;
       
  1358             
       
  1359         case KUsbRequest_SetInterface:
       
  1360             USB_PROCESS_REQUEST(SetInterface,aPacket);
       
  1361             break;
       
  1362             
       
  1363         case KUsbRequest_SynchFrame:
       
  1364             USB_PROCESS_REQUEST(SynchFrame,aPacket);
       
  1365             break;
       
  1366             
       
  1367         default:
       
  1368             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown/unsupported Std Setup Request"));
       
  1369             __KTRACE_OPT(KPANIC, Kern::Printf("  -> Stalling Ep0"));
       
  1370             iConTransferMgr->StallEndpoint(KEp0_In);
       
  1371             iLastError = KErrGeneral;
       
  1372             break;
       
  1373         }       
       
  1374     }
       
  1375 
       
  1376 #undef USB_PROCESS_REQUEST
       
  1377     
       
  1378 //
       
  1379 // class- or vendor-specific request    
       
  1380 // we dont send back any status to host in PIL for class- or vendor-specific request
       
  1381 // if no client is waiting, stall the endpoint
       
  1382 // if client is not ready, just record them and waiting for client to read them
       
  1383 // (and, send a status packet)
       
  1384 //
       
  1385 void DUsbClientController::ProcessNonStandardRequest(TInt aCount,const TUsbcSetup& aPacket)
       
  1386     {
       
  1387     // Find out which client can handle this request
       
  1388     const DBase* client = FindNonStandardRequestClient(aPacket.iRequestType & KUsbRequestType_DestMask,aPacket);
       
  1389         
       
  1390     // If client is valide
       
  1391     if (client != NULL)
       
  1392         {
       
  1393         // Try to relay aPacket to the real recipient
       
  1394         TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
       
  1395         TUsbcRequestCallback* p;
       
  1396         
       
  1397         // Find out the request callback with match the client 
       
  1398         // returned from last FindNonStandardRequestClient().
       
  1399         while ((p = iter++) != NULL)
       
  1400             {
       
  1401             if (p->Owner() == client)
       
  1402                 {
       
  1403                 __ASSERT_DEBUG((p->iEndpointNum == 0), Kern::Fault(KUsbPILPanicCat, __LINE__));
       
  1404                 __ASSERT_DEBUG((p->iTransferDir == UsbShai::EControllerRead), Kern::Fault(KUsbPILPanicCat, __LINE__));
       
  1405                 __KTRACE_OPT(KUSB, Kern::Printf("  Found Ep0 read request"));
       
  1406                 if (aPacket.iLength != 0)
       
  1407                     {
       
  1408                     if ((aPacket.iRequestType & KUsbRequestType_DirMask) == KUsbRequestType_DirToDev)
       
  1409                         {
       
  1410                         // Data transfer & direction OUT => there'll be a DATA_OUT stage
       
  1411                         __KTRACE_OPT(KUSB, Kern::Printf("  Next is DATA_OUT: setting up DataOutVars"));
       
  1412                         SetEp0DataOutVars(client);
       
  1413                         }
       
  1414                     else if ((aPacket.iRequestType & KUsbRequestType_DirMask) == KUsbRequestType_DirToHost)
       
  1415                         {
       
  1416                         // For possible later use (ZLP).
       
  1417                         iEp0_TxNonStdCount = aPacket.iLength;
       
  1418                         }
       
  1419                     }
       
  1420                     
       
  1421                 // Found the request callback, jump out now
       
  1422                 break;                
       
  1423                 }
       
  1424             }
       
  1425             
       
  1426         // if a request callback matching the client is found,
       
  1427         // complete the request
       
  1428         if( p != NULL)
       
  1429             {
       
  1430             __KTRACE_OPT(KUSB, Kern::Printf("  Ep0 read request completed to client"));
       
  1431             memcpy(p->iBufferStart, iEp0_RxBuf, aCount);
       
  1432             p->iError = KErrNone;
       
  1433             *(p->iPacketSize) = aCount;
       
  1434             p->iRxPackets = 1;
       
  1435             *(p->iPacketIndex) = 0;
       
  1436             ProcessDataTransferDone(*p);            
       
  1437             }
       
  1438         else
       
  1439             {            
       
  1440             __KTRACE_OPT(KUSB, Kern::Printf("  Ep0 read request not found: setting RxExtra vars (Setup)"));
       
  1441             iEp0_RxExtraCount = aCount;
       
  1442             //iEp0_RxExtraData = ETrue;
       
  1443             //iEp0_RxExtraError = aErrCode;
       
  1444             iSetupPacketPending = ETrue;
       
  1445             
       
  1446             // For setup packet,a zero bytes status is always needed
       
  1447             iLastError = KErrNotFound;           
       
  1448             }
       
  1449         }
       
  1450     else // if (client == NULL)
       
  1451         {
       
  1452         // Pil don't know how to deal with non-standard request, stall endpoint
       
  1453         __KTRACE_OPT(KPANIC, Kern::Printf("  Ep0 request error: Stalling Ep0"));
       
  1454         iConTransferMgr->StallEndpoint(KEp0_In);
       
  1455         iLastError = KErrGeneral;
       
  1456         }
       
  1457     }
       
  1458     
       
  1459 const DBase* DUsbClientController::FindNonStandardRequestClient(TUint8 aPacketTypeDestination,const TUsbcSetup& aPacket)
       
  1460     {
       
  1461     const DBase* client = NULL;
       
  1462     
       
  1463     switch (aPacketTypeDestination)
       
  1464         { // Recipient
       
  1465         case KUsbRequestType_DestDevice:
       
  1466             {
       
  1467             client = iEp0DeviceControl;
       
  1468             }
       
  1469             break;
       
  1470             
       
  1471         case KUsbRequestType_DestIfc:
       
  1472             {
       
  1473             //Add this mutex to protect the interface set data structure
       
  1474             if (NKern::CurrentContext() == EThread)
       
  1475                 {
       
  1476                 NKern::FMWait(&iMutex);
       
  1477                 }
       
  1478                 
       
  1479             if ( iDeviceState < UsbShai::EUsbPeripheralStateConfigured)
       
  1480                 {
       
  1481                 __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
  1482                 }
       
  1483             else
       
  1484                 {
       
  1485                 const TUsbcInterfaceSet* const ifcset_ptr =
       
  1486                     InterfaceNumber2InterfacePointer(aPacket.iIndex);
       
  1487                     
       
  1488                 //In some rare case, ifcset_ptr is not NULL but the ifcset_ptr->iInterfaces.Count() is 0,
       
  1489                 //so panic will happen when excute the following line. so I add the conditon
       
  1490                 //0 != ifcset_ptr->iInterfaces.Count() here.
       
  1491                 if (ifcset_ptr && 0 != ifcset_ptr->iInterfaces.Count())
       
  1492                     {
       
  1493                     if (ifcset_ptr->CurrentInterface()->iNoEp0Requests)
       
  1494                         {
       
  1495                         __KTRACE_OPT(KUSB, Kern::Printf("  Recipient says: NoEp0RequestsPlease"));
       
  1496                         }
       
  1497                     else
       
  1498                         {
       
  1499                         client = ifcset_ptr->iClientId;
       
  1500                         }
       
  1501                     }
       
  1502                 else
       
  1503                     {
       
  1504                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface 0x%02x does not exist",
       
  1505                                                       aPacket.iIndex));
       
  1506                     }
       
  1507                 }
       
  1508                 
       
  1509             if (NKern::CurrentContext() == EThread)
       
  1510                 {
       
  1511                 NKern::FMSignal(&iMutex);
       
  1512                 }
       
  1513             }
       
  1514             break;
       
  1515                         
       
  1516         case KUsbRequestType_DestEp:
       
  1517             {
       
  1518             //Add this mutex to protect the interface set data structure
       
  1519             if (NKern::CurrentContext() == EThread)
       
  1520                 {
       
  1521                 NKern::FMWait(&iMutex);
       
  1522                 }
       
  1523             if ( iDeviceState < UsbShai::EUsbPeripheralStateConfigured)
       
  1524                 {
       
  1525                 __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
       
  1526                 }
       
  1527             else if (EndpointExists(aPacket.iIndex) == EFalse)
       
  1528                 {
       
  1529                 __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Endpoint 0x%02x does not exist",
       
  1530                                                   aPacket.iIndex));
       
  1531                 }
       
  1532             else
       
  1533                 {
       
  1534                 const TInt idx = EpAddr2Idx(aPacket.iIndex);
       
  1535                 const TUsbcInterfaceSet* const ifcset_ptr =
       
  1536                     iRealEndpoints[idx].iLEndpoint->iInterface->iInterfaceSet;
       
  1537                 if (ifcset_ptr->CurrentInterface()->iNoEp0Requests)
       
  1538                     {
       
  1539                     __KTRACE_OPT(KUSB, Kern::Printf("  Recipient says: NoEp0RequestsPlease"));
       
  1540                     }
       
  1541                 else
       
  1542                     {
       
  1543                     client = ifcset_ptr->iClientId;
       
  1544                     }
       
  1545                 }
       
  1546             if (NKern::CurrentContext() == EThread)
       
  1547                 {
       
  1548                 NKern::FMSignal(&iMutex);
       
  1549                 }
       
  1550             }
       
  1551             break;
       
  1552             
       
  1553         default:
       
  1554             {
       
  1555             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Other or Unknown recipient"));
       
  1556             break;
       
  1557             }
       
  1558         }
       
  1559         
       
  1560     return client;
       
  1561     }
       
  1562 
       
  1563 TInt DUsbClientController::ProcessSetupEndpointZeroRead()
       
  1564     {
       
  1565     __KTRACE_OPT(KPANIC, Kern::Printf("DUsbClientController:: Read EP0 Issued"));
       
  1566     return iController.SetupEndpointZeroRead();
       
  1567     }
       
  1568     
       
  1569 TInt DUsbClientController::ProcessSetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd)
       
  1570     {
       
  1571     __KTRACE_OPT(KPANIC, Kern::Printf("DUsbClientController:: Write EP0 Issued"));
       
  1572     return iController.SetupEndpointZeroWrite(aBuffer,aLength,aZlpReqd);
       
  1573     }
       
  1574     
       
  1575 TInt DUsbClientController::ProcessSendEp0ZeroByteStatusPacket()
       
  1576     {
       
  1577     __KTRACE_OPT(KPANIC, Kern::Printf("DUsbClientController:: Zero Status to EP0 Issued"));
       
  1578     return iController.SendEp0ZeroByteStatusPacket();
       
  1579     }
       
  1580     
       
  1581 TInt DUsbClientController::ProcessStallEndpoint(TInt aRealEndpoint)
       
  1582     {
       
  1583     __KTRACE_OPT(KPANIC, Kern::Printf("DUsbClientController:: EP0(%d) Stall Issued",aRealEndpoint));
       
  1584     return iController.StallEndpoint(aRealEndpoint);
       
  1585     }
       
  1586 
       
  1587 void DUsbClientController::ProcessEp0SetupPacketProceed()
       
  1588     {
       
  1589     __KTRACE_OPT(KPANIC, Kern::Printf("DUsbClientController:: Missed setup packet procced"));
       
  1590     iController.Ep0ReadSetupPktProceed();
       
  1591     }
       
  1592     
       
  1593 void DUsbClientController::ProcessEp0DataPacketProceed()
       
  1594     {
       
  1595     __KTRACE_OPT(KPANIC, Kern::Printf("DUsbClientController:: Missed data packet procced"));
       
  1596     iController.Ep0ReadDataPktProceed();
       
  1597     }
       
  1598     
       
  1599 // -eof-