usbdrv/peripheral/ldd/perildd/src/d_usbc.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/usbc/d_usbc.cpp
       
    15 // LDD for USB Device driver stack:
       
    16 // The channel object.
       
    17 // 
       
    18 //
       
    19 
       
    20 /**
       
    21  @file d_usbc.cpp
       
    22  @internalTechnology
       
    23 */
       
    24 
       
    25 #include <usb/usbc.h>
       
    26 
       
    27 
       
    28 _LIT(KUsbLddName, "Usbc");
       
    29 
       
    30 static const TInt KUsbRequestCallbackPriority = 2;
       
    31 
       
    32 
       
    33 // Quick sanity check on endpoint properties
       
    34 static TBool ValidateEndpoint(const TUsbcEndpointInfo* aEndpointInfo)
       
    35     {
       
    36     const TUint dir = aEndpointInfo->iDir;
       
    37     const TInt size = aEndpointInfo->iSize;
       
    38     if (size <= 0)
       
    39         return EFalse;
       
    40 
       
    41     switch (aEndpointInfo->iType)
       
    42         {
       
    43     case UsbShai::KUsbEpTypeControl:
       
    44         if (dir != UsbShai::KUsbEpDirBidirect || size > 64)
       
    45             return EFalse;
       
    46         break;
       
    47     case UsbShai::KUsbEpTypeIsochronous:
       
    48         if ((dir != UsbShai::KUsbEpDirIn && dir != UsbShai::KUsbEpDirOut) || size > 1024)
       
    49             return EFalse;
       
    50         break;
       
    51     case UsbShai::KUsbEpTypeBulk:
       
    52         if ((dir != UsbShai::KUsbEpDirIn && dir != UsbShai::KUsbEpDirOut) || size > 512)
       
    53             return EFalse;
       
    54         break;
       
    55     case UsbShai::KUsbEpTypeInterrupt:
       
    56         if ((dir != UsbShai::KUsbEpDirIn && dir != UsbShai::KUsbEpDirOut) || size > 1024)
       
    57             return EFalse;
       
    58         break;
       
    59     default:
       
    60         return EFalse;
       
    61         }
       
    62     return ETrue;
       
    63     }
       
    64 
       
    65 
       
    66 /** Real entry point from the Kernel: return a new driver.
       
    67  */
       
    68 DECLARE_STANDARD_LDD()
       
    69     {
       
    70     return new DUsbcLogDevice;
       
    71     }
       
    72 
       
    73 
       
    74 /** Create a channel on the device.
       
    75 
       
    76     @internalComponent
       
    77 */
       
    78 TInt DUsbcLogDevice::Create(DLogicalChannelBase*& aChannel)
       
    79     {
       
    80     aChannel = new DLddUsbcChannel;
       
    81     return aChannel ? KErrNone : KErrNoMemory;
       
    82     }
       
    83 
       
    84 
       
    85 DUsbcLogDevice::DUsbcLogDevice()
       
    86       {
       
    87       iParseMask = KDeviceAllowUnit;
       
    88       iUnitsMask = 0xffffffff;                                // Leave units decision to the Controller
       
    89       iVersion = TVersion(KUsbcMajorVersion, KUsbcMinorVersion, KUsbcBuildVersion);
       
    90       }
       
    91 
       
    92 
       
    93 TInt DUsbcLogDevice::Install()
       
    94     {
       
    95     // Only proceed if we have the Controller underneath us
       
    96     if (!DUsbClientController::UsbcControllerPointer())
       
    97         {
       
    98         __KTRACE_OPT(KPANIC, Kern::Printf("LDD Install: USB Controller Not Present"));
       
    99         return KErrGeneral;
       
   100         }
       
   101     return SetName(&KUsbLddName);
       
   102     }
       
   103 
       
   104 
       
   105 //
       
   106 // Return the USB controller capabilities.
       
   107 //
       
   108 void DUsbcLogDevice::GetCaps(TDes8& aDes) const
       
   109     {
       
   110     TPckgBuf<TCapsDevUsbc> b;
       
   111     b().version = iVersion;
       
   112     Kern::InfoCopy(aDes, b);
       
   113     }
       
   114 
       
   115 
       
   116 //
       
   117 // Constructor
       
   118 //
       
   119 DLddUsbcChannel::DLddUsbcChannel()
       
   120     : iValidInterface(EFalse),
       
   121       iAlternateSettingList(NULL),
       
   122       iCompleteAllCallbackInfo(this, DLddUsbcChannel::EmergencyCompleteDfc, KUsbRequestCallbackPriority),
       
   123       iStatusChangePtr(NULL),
       
   124       iStatusCallbackInfo(this, DLddUsbcChannel::StatusChangeCallback, KUsbRequestCallbackPriority),
       
   125       iEndpointStatusChangePtr(NULL),
       
   126       iEndpointStatusCallbackInfo(this, DLddUsbcChannel::EndpointStatusChangeCallback,
       
   127                                   KUsbRequestCallbackPriority),
       
   128       iOtgFeatureChangePtr(NULL),
       
   129       iOtgFeatureCallbackInfo(this, DLddUsbcChannel::OtgFeatureChangeCallback, KUsbRequestCallbackPriority),
       
   130       iNumberOfEndpoints(0),
       
   131       iDeviceState(UsbShai::EUsbPeripheralStateUndefined),
       
   132       iOwnsDeviceControl(EFalse),
       
   133       iAlternateSetting(0),
       
   134       iDeviceStatusNeeded(EFalse),
       
   135       iChannelClosing(EFalse)
       
   136     {
       
   137     __KTRACE_OPT(KUSB, Kern::Printf("*** DLddUsbcChannel::DLddUsbcChannel CTOR"));
       
   138     iClient = &Kern::CurrentThread();
       
   139     iClient->Open();
       
   140     for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
       
   141         {
       
   142         iEndpoint[i] = NULL;
       
   143         }
       
   144     for (TInt i = 1; i < KUsbcMaxRequests; i++)
       
   145         {
       
   146         iRequestStatus[i] = NULL;
       
   147         }
       
   148     }
       
   149 
       
   150 
       
   151 DLddUsbcChannel::~DLddUsbcChannel()
       
   152     {
       
   153     __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::~DLddUsbcChannel()"));
       
   154     if (iController)
       
   155         {
       
   156         iController->DeRegisterClient(this);
       
   157         iStatusCallbackInfo.Cancel();
       
   158         iEndpointStatusCallbackInfo.Cancel();
       
   159         iOtgFeatureCallbackInfo.Cancel();
       
   160         iCompleteAllCallbackInfo.Cancel();
       
   161         AbortInterface();
       
   162         DestroyAllInterfaces();
       
   163         if (iOwnsDeviceControl)
       
   164             {
       
   165             iController->ReleaseDeviceControl(this);
       
   166             iOwnsDeviceControl = EFalse;
       
   167             }
       
   168         DestroyEp0();
       
   169         delete iStatusFifo;
       
   170         Kern::DestroyClientRequest(iStatusChangeReq);
       
   171         Kern::DestroyClientRequest(iEndpointStatusChangeReq);
       
   172         Kern::DestroyClientRequest(iOtgFeatureChangeReq);
       
   173 
       
   174         Kern::DestroyVirtualPinObject(iPinObj1);
       
   175         Kern::DestroyVirtualPinObject(iPinObj2);
       
   176         Kern::DestroyVirtualPinObject(iPinObj3);
       
   177 
       
   178         for (TInt i = 0; i < KUsbcMaxRequests; i++)
       
   179             {
       
   180             Kern::DestroyClientBufferRequest(iClientAsynchNotify[i]->iBufferRequest);
       
   181             delete iClientAsynchNotify[i];
       
   182             }
       
   183         }
       
   184     Kern::SafeClose((DObject*&)iClient, NULL);
       
   185     }
       
   186 
       
   187 
       
   188 inline TBool DLddUsbcChannel::ValidEndpoint(TInt aEndpoint)
       
   189     {
       
   190     return (aEndpoint <= iNumberOfEndpoints && aEndpoint >= 0);
       
   191     }
       
   192 
       
   193 
       
   194 //
       
   195 // Create channel
       
   196 //
       
   197 TInt DLddUsbcChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
       
   198     {
       
   199     __KTRACE_OPT(KUSB, Kern::Printf("LDD DoCreateL 1 Ver = %02d %02d %02d",
       
   200                                     aVer.iMajor, aVer.iMinor, aVer.iBuild));
       
   201     if (!Kern::CurrentThreadHasCapability(ECapabilityCommDD,
       
   202                                           __PLATSEC_DIAGNOSTIC_STRING("Checked by USBC.LDD (USB Driver)")))
       
   203         {
       
   204         return KErrPermissionDenied;
       
   205         }
       
   206 
       
   207     iController = DUsbClientController::UsbcControllerPointer();
       
   208 
       
   209     if (!iController)
       
   210         {
       
   211         return KErrGeneral;
       
   212         }
       
   213 
       
   214     iStatusFifo = new TUsbcDeviceStatusQueue;
       
   215     if (iStatusFifo == NULL)
       
   216         {
       
   217         return KErrNoMemory;
       
   218         }
       
   219 
       
   220       if (!Kern::QueryVersionSupported(TVersion(KUsbcMajorVersion, KUsbcMinorVersion, KUsbcBuildVersion), aVer))
       
   221         {
       
   222         return KErrNotSupported;
       
   223         }
       
   224 
       
   225     // set up the correct DFC queue
       
   226     SetDfcQ(iController->DfcQ(0));                            // sets the channel's dfc queue
       
   227     #ifdef DFC_REALTIME_STATE
       
   228         iDfcQ.SetRealtimeState(ERealtimeStateOn);
       
   229     #endif
       
   230     iCompleteAllCallbackInfo.SetDfcQ(iDfcQ);
       
   231     iStatusCallbackInfo.SetDfcQ(iDfcQ);                        // use the channel's dfcq for this dfc
       
   232     iEndpointStatusCallbackInfo.SetDfcQ(iDfcQ);                // use the channel's dfcq for this dfc
       
   233     iOtgFeatureCallbackInfo.SetDfcQ(iDfcQ);
       
   234     iMsgQ.Receive();                                        //start up the message q
       
   235     TInt r = iController->RegisterClientCallback(iCompleteAllCallbackInfo);
       
   236     if (r != KErrNone)
       
   237         return r;
       
   238     r = iController->RegisterForStatusChange(iStatusCallbackInfo);
       
   239     if (r != KErrNone)
       
   240         return r;
       
   241     r = iController->RegisterForEndpointStatusChange(iEndpointStatusCallbackInfo);
       
   242     if (r != KErrNone)
       
   243         return r;
       
   244     r = iController->RegisterForOtgFeatureChange(iOtgFeatureCallbackInfo);
       
   245     if (r != KErrNone)
       
   246         return r;
       
   247 
       
   248     r = Kern::CreateClientDataRequest(iStatusChangeReq);
       
   249     if (r != KErrNone)
       
   250         return r;
       
   251     r = Kern::CreateClientDataRequest(iEndpointStatusChangeReq);
       
   252     if (r != KErrNone)
       
   253         return r;
       
   254     r = Kern::CreateClientDataRequest(iOtgFeatureChangeReq);
       
   255     if (r != KErrNone)
       
   256         return r;
       
   257     
       
   258     Kern::CreateVirtualPinObject(iPinObj1);
       
   259     Kern::CreateVirtualPinObject(iPinObj2);
       
   260     Kern::CreateVirtualPinObject(iPinObj3);
       
   261 
       
   262     for (TInt i = 0; i < KUsbcMaxRequests; i++)
       
   263         {
       
   264             iClientAsynchNotify[i] = new TClientAsynchNotify;
       
   265             if(iClientAsynchNotify[i] == NULL)
       
   266                 return KErrNoMemory;
       
   267             r = Kern::CreateClientBufferRequest(iClientAsynchNotify[i]->iBufferRequest,1,TClientBufferRequest::EPinVirtual);
       
   268             if (r != KErrNone)
       
   269                 {
       
   270                 delete iClientAsynchNotify[i];
       
   271                 iClientAsynchNotify[i]=NULL;
       
   272                 return r;
       
   273                 }
       
   274         }
       
   275     
       
   276     return r;
       
   277     }
       
   278 
       
   279 
       
   280 
       
   281 void DLddUsbcChannel::CompleteBufferRequest(DThread* aThread, TInt aReqNo, TInt aReason)
       
   282 {
       
   283     iRequestStatus[aReqNo]=NULL;
       
   284     Kern::QueueBufferRequestComplete(aThread, iClientAsynchNotify[aReqNo]->iBufferRequest, aReason);
       
   285 }
       
   286 
       
   287 
       
   288 TClientBuffer * DLddUsbcChannel::GetClientBuffer(TInt aEndpoint)
       
   289 {
       
   290     return iClientAsynchNotify[aEndpoint]->iClientBuffer;
       
   291 }
       
   292 
       
   293 //Runs in client thread
       
   294 TInt DLddUsbcChannel::SendMsg(TMessageBase * aMsg)
       
   295 {
       
   296     TThreadMessage& m=* (TThreadMessage*)aMsg;
       
   297     TInt id = m.iValue;
       
   298     
       
   299     TInt r = KErrNone;
       
   300     //Cancel Request
       
   301     if (id == KMaxTInt)
       
   302         {
       
   303             r = DLogicalChannel::SendMsg(aMsg);
       
   304             return r;
       
   305         }
       
   306     if (id < 0)
       
   307         {
       
   308         // DoRequest
       
   309         TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
       
   310         r = PreSendRequest(aMsg,~id, pS, m.Ptr1(), m.Ptr2());
       
   311         if (r == KErrNone)
       
   312             {
       
   313             r = DLogicalChannel::SendMsg(aMsg);
       
   314             }
       
   315         }
       
   316     else
       
   317         {
       
   318         //SendControl
       
   319         r = SendControl(aMsg);
       
   320         }
       
   321     return r;
       
   322 }
       
   323 
       
   324 
       
   325 TInt DLddUsbcChannel::PreSendRequest(TMessageBase * aMsg,TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
       
   326 {
       
   327     TInt r = KErrNone;
       
   328     if (aReqNo >= KUsbcMaxRequests)
       
   329     {
       
   330         Kern::RequestComplete(aStatus, KErrNotSupported);
       
   331         return KErrNotSupported;
       
   332     }
       
   333     if (aReqNo > KUsbcMaxEpNumber)//DoOtherAsyncReq
       
   334     {
       
   335         switch (aReqNo)
       
   336         {
       
   337             case RDevUsbcClient::ERequestEndpointStatusNotify:
       
   338                 iEndpointStatusChangeReq->Reset();
       
   339                 iEndpointStatusChangeReq->SetStatus(aStatus);
       
   340                 iEndpointStatusChangeReq->SetDestPtr(a1);
       
   341             break;
       
   342             case RDevUsbcClient::ERequestOtgFeaturesNotify:
       
   343                 iOtgFeatureChangeReq->Reset();
       
   344                 iOtgFeatureChangeReq->SetStatus(aStatus);
       
   345                 iOtgFeatureChangeReq->SetDestPtr(a1);
       
   346             break;
       
   347             case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
       
   348                 iStatusChangeReq->Reset();
       
   349                 iStatusChangeReq->SetStatus(aStatus);
       
   350                 iStatusChangeReq->SetDestPtr(a1);
       
   351             break;
       
   352             case RDevUsbcClient::ERequestReEnumerate://WE use bufferrequest to complete even tho we dont add any buffers
       
   353                 iClientAsynchNotify[aReqNo]->Reset();
       
   354                 r=iClientAsynchNotify[aReqNo]->iBufferRequest->StartSetup(aStatus);
       
   355                 if (r != KErrNone)
       
   356                     return r;
       
   357                 iClientAsynchNotify[aReqNo]->iBufferRequest->EndSetup();
       
   358             break;
       
   359         }
       
   360     }
       
   361     else //DoTransferAsyncReq
       
   362     {
       
   363             if(a1 == NULL)
       
   364                 return KErrArgument;
       
   365             iClientAsynchNotify[aReqNo]->Reset();
       
   366             r=iClientAsynchNotify[aReqNo]->iBufferRequest->StartSetup(aStatus);
       
   367             if (r != KErrNone)
       
   368                 return r;
       
   369             kumemget(&iTfrInfo,a1,sizeof(TEndpointTransferInfo));
       
   370             r=iClientAsynchNotify[aReqNo]->iBufferRequest->AddBuffer(iClientAsynchNotify[aReqNo]->iClientBuffer, iTfrInfo.iDes);
       
   371             if (r != KErrNone)
       
   372                 return r;
       
   373             iClientAsynchNotify[aReqNo]->iBufferRequest->EndSetup();
       
   374             TThreadMessage& m=*(TThreadMessage*)aMsg;
       
   375             m.iArg[1] = (TAny*)&iTfrInfo; //Use Channel owned TransfereInfo structure 
       
   376     }
       
   377     return KErrNone;
       
   378 }
       
   379 
       
   380 
       
   381 void DLddUsbcChannel::HandleMsg(TMessageBase* aMsg)
       
   382     {
       
   383     TThreadMessage& m = *(TThreadMessage*)aMsg;
       
   384     TInt id = m.iValue;
       
   385     if (id == (TInt) ECloseMsg)
       
   386         {
       
   387         iChannelClosing = ETrue;
       
   388         m.Complete(KErrNone, EFalse);
       
   389         return;
       
   390         }
       
   391     else if (id == KMaxTInt)
       
   392         {
       
   393         // Cancel request
       
   394         TInt mask = m.Int0();
       
   395         TInt b = 1;
       
   396         for(TInt reqNo = 0; reqNo < KUsbcMaxRequests; reqNo++)
       
   397             {
       
   398             TRequestStatus* pS = iRequestStatus[reqNo];
       
   399             if ((mask & b) && (pS != NULL))
       
   400                 {
       
   401                 DoCancel(reqNo);
       
   402                 }
       
   403             b <<= 1;
       
   404             }
       
   405         m.Complete(KErrNone, ETrue);
       
   406         return;
       
   407         }
       
   408 
       
   409     if (id < 0)
       
   410         {
       
   411         // DoRequest
       
   412         TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
       
   413         DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
       
   414         m.Complete(KErrNone, ETrue);
       
   415         }
       
   416     else
       
   417         {
       
   418         // DoControl
       
   419         TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
       
   420         m.Complete(r, ETrue);
       
   421         }
       
   422     }
       
   423 
       
   424 
       
   425 //
       
   426 // Overriding DObject virtual
       
   427 //
       
   428 TInt DLddUsbcChannel::RequestUserHandle(DThread* aThread, TOwnerType /*aType*/)
       
   429     {
       
   430     __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::RequestUserHandle"));
       
   431     // The USB client LDD is not designed for a channel to be shared between
       
   432     // threads. It saves a pointer to the current thread when it is opened, and
       
   433     // uses this to complete any asynchronous requests.
       
   434     // It is therefore not acceptable for the handle to be duplicated and used
       
   435     // by another thread:
       
   436     if (aThread == iClient)
       
   437         {
       
   438         return KErrNone;
       
   439         }
       
   440     else
       
   441         {
       
   442         return KErrAccessDenied;
       
   443         }
       
   444     }
       
   445 
       
   446 
       
   447 //
       
   448 // Asynchronous requests - overriding pure virtual
       
   449 //
       
   450 void DLddUsbcChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
       
   451     {
       
   452     // Check on request status
       
   453     __KTRACE_OPT(KUSB, Kern::Printf("DoRequest 0x%08x", aReqNo));
       
   454         TInt r = KErrNone;
       
   455         if (iRequestStatus[aReqNo] != NULL)
       
   456             {
       
   457             DestroyAllInterfaces();
       
   458             PanicClientThread(ERequestAlreadyPending);
       
   459             }
       
   460         else
       
   461             {
       
   462             TBool needsCompletion;
       
   463             iRequestStatus[aReqNo] = aStatus;
       
   464 
       
   465             if (aReqNo > KUsbcMaxEpNumber)
       
   466                 {
       
   467                 r = DoOtherAsyncReq(aReqNo, a1, a2, needsCompletion);
       
   468                 if (needsCompletion)
       
   469                     {
       
   470                     switch (aReqNo)
       
   471                     {
       
   472                         case RDevUsbcClient::ERequestEndpointStatusNotify:
       
   473                             iRequestStatus[aReqNo]=NULL;
       
   474                             Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,r);
       
   475                         break;
       
   476                         case RDevUsbcClient::ERequestOtgFeaturesNotify:
       
   477                             iRequestStatus[aReqNo]=NULL;
       
   478                             Kern::QueueRequestComplete(iClient,iOtgFeatureChangeReq,r);
       
   479                         break;
       
   480                         case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
       
   481                             iRequestStatus[aReqNo]=NULL;
       
   482                             Kern::QueueRequestComplete(iClient,iStatusChangeReq,r);
       
   483                         break;
       
   484                         case RDevUsbcClient::ERequestReEnumerate:
       
   485                             iRequestStatus[aReqNo]=NULL;
       
   486                             Kern::QueueBufferRequestComplete(iClient, iClientAsynchNotify[aReqNo]->iBufferRequest, r);
       
   487                         break;
       
   488                     }
       
   489                   }
       
   490                 }
       
   491             else
       
   492                 {
       
   493                 r = DoTransferAsyncReq(aReqNo, a1, a2, needsCompletion);
       
   494                 if (needsCompletion)
       
   495                     {
       
   496                     //Kern::RequestComplete(iClient, iRequestStatus[aReqNo], r);
       
   497                     CompleteBufferRequest(iClient, aReqNo, r);
       
   498                     }
       
   499                 }
       
   500             }
       
   501     }
       
   502 
       
   503 
       
   504 
       
   505 TInt DLddUsbcChannel::DoOtherAsyncReq(TInt aReqNo, TAny* a1, TAny* a2, TBool& aNeedsCompletion)
       
   506     {
       
   507     // The general assumption is that none of these will complete now.
       
   508     // However, those that make this function return something other than
       
   509     // KErrNone will get completed by the calling function.
       
   510     // So, 1) If you are returning KErrNone but really need to complete because
       
   511     //        completion criteria can be met (for example, sufficient data is
       
   512     //        available in the buffer) and then set aNeedsCompletion = ETrue.
       
   513     //     2) Do NOT complete here AT ALL.
       
   514     //
       
   515     aNeedsCompletion = EFalse;
       
   516     TInt r = KErrNone;
       
   517 
       
   518     switch (aReqNo)
       
   519         {
       
   520     case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
       
   521         {
       
   522         __KTRACE_OPT(KUSB, Kern::Printf("EControlReqDeviceStatusNotify"));
       
   523         if (a1 != NULL)
       
   524             {
       
   525             iDeviceStatusNeeded = ETrue;
       
   526             iStatusChangePtr = a1;
       
   527             aNeedsCompletion = AlternateDeviceStateTestComplete();
       
   528             }
       
   529         else
       
   530             r = KErrArgument;
       
   531         break;
       
   532         }
       
   533     case RDevUsbcClient::ERequestReEnumerate:
       
   534         {
       
   535         __KTRACE_OPT(KUSB, Kern::Printf("ERequestReEnumerate"));
       
   536         // If successful, this will complete via the status notification.
       
   537         r = iController->ReEnumerate();
       
   538         break;
       
   539         }
       
   540     case RDevUsbcClient::ERequestEndpointStatusNotify:
       
   541         {
       
   542         __KTRACE_OPT(KUSB, Kern::Printf("ERequestEndpointStatusNotify"));
       
   543         if (a1 != NULL)
       
   544             {
       
   545             iEndpointStatusChangePtr = a1;
       
   546             }
       
   547         else
       
   548             r = KErrArgument;
       
   549         break;
       
   550             }
       
   551     case RDevUsbcClient::ERequestOtgFeaturesNotify:
       
   552         {
       
   553         __KTRACE_OPT(KUSB, Kern::Printf("ERequestOtgFeaturesNotify"));
       
   554         if (a1 != NULL)
       
   555             {
       
   556             iOtgFeatureChangePtr = a1;
       
   557             }
       
   558         else
       
   559             r = KErrArgument;
       
   560         break;
       
   561         }
       
   562     default:
       
   563         r = KErrNotSupported;
       
   564         }
       
   565 
       
   566     aNeedsCompletion = aNeedsCompletion || (r != KErrNone);
       
   567 
       
   568     return r;
       
   569     }
       
   570 
       
   571 
       
   572 TInt DLddUsbcChannel::DoTransferAsyncReq(TInt aEndpointNum, TAny* a1, TAny* a2, TBool& aNeedsCompletion)
       
   573     {
       
   574     // The general assumption is that none of these will complete now.
       
   575     // however, those that are returning something other than KErrNone will get completed
       
   576     // by the calling function.
       
   577     // So,    1) if you are returning KErrNone but really need to complete because completion criteria can be met
       
   578     //            (for example, sufficient data is available in the buffer) and then set aNeedsCompletion=ETrue..
       
   579     //        2) Do NOT complete here AT ALL.
       
   580     //
       
   581     aNeedsCompletion = EFalse;
       
   582     TInt r = KErrNone;
       
   583     TUsbcEndpoint* pEndpoint = NULL;
       
   584     TUsbcEndpointInfo* pEndpointInfo = NULL;
       
   585     TEndpointTransferInfo* pTfr = NULL;
       
   586 
       
   587     if (aEndpointNum == 0)
       
   588         {
       
   589         // ep0 requests
       
   590         if (!(iValidInterface || iOwnsDeviceControl))
       
   591             {
       
   592             __KTRACE_OPT(KUSB, Kern::Printf("DoRequest rejected: not configured (Ep0)"));
       
   593             r = KErrUsbInterfaceNotReady;
       
   594             goto exit;
       
   595             }
       
   596         }
       
   597     else
       
   598         {
       
   599         // other eps
       
   600         if (!(iValidInterface && (iDeviceState == UsbShai::EUsbPeripheralStateConfigured ||
       
   601                                   iDeviceState == UsbShai::EUsbPeripheralStateSuspended))
       
   602            )
       
   603             {
       
   604             __KTRACE_OPT(KUSB, Kern::Printf("DoRequest rejected not configured (Ep %d)", aEndpointNum));
       
   605             r = KErrUsbInterfaceNotReady;
       
   606             goto exit;
       
   607             }
       
   608         }
       
   609 
       
   610     if (!ValidEndpoint(aEndpointNum))
       
   611         {
       
   612         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DoRequest Read: in error complete"));
       
   613         r = KErrUsbEpNotInInterface;
       
   614         goto exit;
       
   615          }
       
   616 
       
   617     if (a1 == NULL)
       
   618         {
       
   619         r = KErrArgument;
       
   620         goto exit;
       
   621         }
       
   622     pTfr = (TEndpointTransferInfo *)a1;
       
   623 
       
   624     if (pTfr->iTransferSize < 0)
       
   625         {
       
   626         r = KErrArgument;
       
   627         goto exit;
       
   628         }
       
   629     pEndpoint = iEndpoint[aEndpointNum];
       
   630     if (!pEndpoint)
       
   631         {
       
   632         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DoRequest Read: in error complete"));
       
   633         r = KErrUsbEpNotInInterface;
       
   634         goto exit;
       
   635         }
       
   636 
       
   637     pEndpointInfo = pEndpoint->EndpointInfo();
       
   638     __KTRACE_OPT(KUSB, Kern::Printf("DoRequest %d", aEndpointNum));
       
   639 
       
   640     switch (pTfr->iTransferType)
       
   641         {
       
   642 
       
   643     case ETransferTypeReadData:
       
   644     case ETransferTypeReadPacket:
       
   645     case ETransferTypeReadUntilShort:
       
   646     case ETransferTypeReadOneOrMore:
       
   647         {
       
   648         __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read"));
       
   649         if (pEndpoint->iDmaBuffers->RxIsActive())
       
   650             {
       
   651             __KTRACE_OPT(KUSB, Kern::Printf("**** ReadReq ep%d RxActive", aEndpointNum));
       
   652             }
       
   653         else
       
   654             {
       
   655             __KTRACE_OPT(KUSB, Kern::Printf("**** ReadReq ep%d RxInActive", aEndpointNum));
       
   656             }
       
   657 
       
   658         if (pEndpointInfo->iDir != UsbShai::KUsbEpDirOut &&
       
   659             pEndpointInfo->iDir != UsbShai::KUsbEpDirBidirect)
       
   660             {
       
   661             // Trying to do the wrong thing
       
   662             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DoRequest Read: in error complete"));
       
   663             r = KErrUsbEpBadDirection;
       
   664             break;
       
   665             }
       
   666         // Set the length of data to zero now to catch all cases
       
   667         TPtrC8 pZeroDesc(NULL, 0);
       
   668         r=Kern::ThreadBufWrite(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer, pZeroDesc, 0, 0,iClient);
       
   669         if (r != KErrNone)
       
   670             PanicClientThread(r);
       
   671         pEndpoint->SetTransferInfo(pTfr);
       
   672         if (pEndpoint->iDmaBuffers->IsReaderEmpty())
       
   673             {
       
   674             pEndpoint->SetClientReadPending(ETrue);
       
   675             }
       
   676         else
       
   677             {
       
   678             if (pTfr->iTransferType == ETransferTypeReadPacket)
       
   679                 {
       
   680                 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read packet: data available complete"));
       
   681                 r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
       
   682                 aNeedsCompletion = ETrue;
       
   683                 break;
       
   684                 }
       
   685             else if (pTfr->iTransferType == ETransferTypeReadData)
       
   686                 {
       
   687                 if (pTfr->iTransferSize <= pEndpoint->RxBytesAvailable())
       
   688                     {
       
   689                     __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
       
   690                     r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
       
   691                     aNeedsCompletion = ETrue;
       
   692                     break;
       
   693                     }
       
   694                 else
       
   695                     {
       
   696                     pEndpoint->SetClientReadPending(ETrue);
       
   697                     }
       
   698                 }
       
   699             else if (pTfr->iTransferType == ETransferTypeReadOneOrMore)
       
   700                 {
       
   701                 if (pEndpoint->RxBytesAvailable() > 0)
       
   702                     {
       
   703                     __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
       
   704                     r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
       
   705                     aNeedsCompletion = ETrue;
       
   706                     break;
       
   707                     }
       
   708                 else
       
   709                     {
       
   710                     pEndpoint->SetClientReadPending(ETrue);
       
   711                     }
       
   712                 }
       
   713             else if (pTfr->iTransferType == ETransferTypeReadUntilShort)
       
   714                 {
       
   715                 TInt nRx = pEndpoint->RxBytesAvailable();
       
   716                 TInt maxPacketSize = pEndpoint->EndpointInfo()->iSize;
       
   717                 if( (pTfr->iTransferSize <= nRx) ||
       
   718                     (nRx < maxPacketSize) ||
       
   719                     pEndpoint->iDmaBuffers->ShortPacketExists())
       
   720                     {
       
   721                     __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
       
   722                     r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
       
   723                     aNeedsCompletion = ETrue;
       
   724                     }
       
   725                 else
       
   726                     {
       
   727                     pEndpoint->SetClientReadPending(ETrue);
       
   728                     }
       
   729                 }
       
   730             }
       
   731         r = pEndpoint->TryToStartRead(EFalse);
       
   732         if (r != KErrNone)
       
   733             {
       
   734             __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read: couldn't start read"));
       
   735             r = KErrNone;                                    // Reader full isn't a userside error;
       
   736             }
       
   737         break;
       
   738         }
       
   739 
       
   740     case ETransferTypeWrite:
       
   741         {
       
   742         __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 1"));
       
   743         if (pEndpointInfo->iDir != UsbShai::KUsbEpDirIn &&
       
   744             pEndpointInfo->iDir != UsbShai::KUsbEpDirBidirect)
       
   745             {
       
   746             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DoRequest Write: wrong direction complete"));
       
   747             r = KErrUsbEpBadDirection;
       
   748             break;
       
   749             }
       
   750         __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 2"));
       
   751 
       
   752 
       
   753         TInt desLength=iClientAsynchNotify[aEndpointNum]->iClientBuffer->Length();
       
   754         
       
   755         if (desLength < pTfr->iTransferSize)
       
   756             {
       
   757             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DoRequest Write: user buffer too short"));
       
   758             r = KErrUsbTransferSize;
       
   759             break;
       
   760             }
       
   761 
       
   762         __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 3 length=%d maxlength=%d",
       
   763                                         pTfr->iTransferSize, desLength));
       
   764         // Zero length writes are acceptable
       
   765         pEndpoint->SetClientWritePending(ETrue);
       
   766         r = pEndpoint->TryToStartWrite(pTfr);
       
   767         if (r != KErrNone)
       
   768             {
       
   769             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DoRequest Write: couldn't start write"));
       
   770             pEndpoint->SetClientWritePending(EFalse);
       
   771             }
       
   772         break;
       
   773         }
       
   774 
       
   775     default:
       
   776         __KTRACE_OPT(KPANIC, Kern::Printf("  Error: DoTransferAsyncReq: pTfr->iTransferType = %d not supported",
       
   777                                           pTfr->iTransferType));
       
   778         r = KErrNotSupported;
       
   779         break;
       
   780         }
       
   781  exit:
       
   782     aNeedsCompletion = aNeedsCompletion || (r != KErrNone);
       
   783     return r;
       
   784     }
       
   785 
       
   786 
       
   787 //
       
   788 // Cancel an outstanding request - overriding pure virtual
       
   789 //
       
   790 TInt DLddUsbcChannel::DoCancel(TInt aReqNo)
       
   791     {
       
   792     TInt r = KErrNone;
       
   793     __KTRACE_OPT(KUSB, Kern::Printf("DoCancel: 0x%x", aReqNo));
       
   794     if (aReqNo <= iNumberOfEndpoints)
       
   795         {
       
   796         __KTRACE_OPT(KUSB, Kern::Printf("DoCancel endpoint: 0x%x", aReqNo));
       
   797         iEndpoint[aReqNo]->CancelTransfer(iClient,iClientAsynchNotify[aReqNo]->iClientBuffer);
       
   798         }
       
   799     else if (aReqNo == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
       
   800         {
       
   801         __KTRACE_OPT(KUSB, Kern::Printf("DoCancel: ERequestAlternateDeviceStatusNotify 0x%x", aReqNo));
       
   802         iDeviceStatusNeeded = EFalse;
       
   803         iStatusFifo->FlushQueue();
       
   804         if (iStatusChangePtr)
       
   805             {
       
   806             iStatusChangeReq->Data()=iController->GetDeviceStatus();
       
   807             iStatusChangePtr = NULL;
       
   808 
       
   809             if (iStatusChangeReq->IsReady())
       
   810                 {
       
   811                 iRequestStatus[aReqNo] = NULL;
       
   812                 Kern::QueueRequestComplete(iClient, iStatusChangeReq, KErrCancel);
       
   813                 }
       
   814                 return KErrNone;
       
   815             }
       
   816         }
       
   817     else if (aReqNo == RDevUsbcClient::ERequestReEnumerate)
       
   818         {
       
   819         __KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestReEnumerate: 0x%x", aReqNo));
       
   820         }
       
   821     else if (aReqNo == RDevUsbcClient::ERequestEndpointStatusNotify)
       
   822         {
       
   823         __KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestEndpointStatusNotify: 0x%x", aReqNo));
       
   824         CancelNotifyEndpointStatus();
       
   825         if (iEndpointStatusChangeReq->IsReady())
       
   826             {
       
   827             iRequestStatus[aReqNo] = NULL;
       
   828             Kern::QueueRequestComplete(iClient, iEndpointStatusChangeReq, KErrCancel);
       
   829             }
       
   830         return KErrNone;
       
   831         }
       
   832     else if (aReqNo == RDevUsbcClient::ERequestOtgFeaturesNotify)
       
   833         {
       
   834         __KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestOtgFeaturesNotify: 0x%x", aReqNo));
       
   835         CancelNotifyOtgFeatures();
       
   836         if (iOtgFeatureChangeReq->IsReady())
       
   837             {
       
   838             iRequestStatus[aReqNo] = NULL;
       
   839             Kern::QueueRequestComplete(iClient, iOtgFeatureChangeReq, KErrCancel);
       
   840             }
       
   841         }
       
   842     else
       
   843         {
       
   844         __KTRACE_OPT(KUSB, Kern::Printf("DoCancel Unknown! 0x%x", aReqNo));
       
   845         }
       
   846 
       
   847         if (r == KErrNone)
       
   848             r = KErrCancel;
       
   849 
       
   850         CompleteBufferRequest(iClient, aReqNo, r);
       
   851     return r;
       
   852     }
       
   853 
       
   854 
       
   855 void DLddUsbcChannel::CancelNotifyEndpointStatus()
       
   856     {
       
   857     if (iEndpointStatusChangePtr)
       
   858         {
       
   859         TUint epBitmap = 0;
       
   860         for (TInt i = 0; i <= iNumberOfEndpoints; i++)
       
   861             {
       
   862             TInt v = iController->GetEndpointStatus(this, iEndpoint[i]->RealEpNumber());
       
   863             TUint b;
       
   864             (v == EEndpointStateStalled) ? b = 1 : b = 0;
       
   865             epBitmap |= b << i;
       
   866             }
       
   867         iEndpointStatusChangeReq->Data()=epBitmap;
       
   868         iEndpointStatusChangePtr = NULL;
       
   869         }
       
   870     }
       
   871 
       
   872 
       
   873 void DLddUsbcChannel::CancelNotifyOtgFeatures()
       
   874     {
       
   875     if (iOtgFeatureChangePtr)
       
   876         {
       
   877         TUint8 features;
       
   878         iController->GetCurrentOtgFeatures(features);
       
   879      iOtgFeatureChangeReq->Data()=features;
       
   880         iOtgFeatureChangePtr = NULL;
       
   881         }
       
   882     }
       
   883 
       
   884 TInt DLddUsbcChannel::PinMemory(TDesC8 *aDes, TVirtualPinObject *aPinObj)
       
   885     {
       
   886     TInt r = KErrNone;
       
   887     TInt  len,mlen;
       
   888     
       
   889     const TUint8*p = Kern::KUDesInfo(*aDes, len,mlen);
       
   890     r=Kern::PinVirtualMemory(aPinObj, (TLinAddr) p, len);
       
   891     return r;
       
   892     }
       
   893 
       
   894 //Called in Client thread context
       
   895 TInt DLddUsbcChannel::SendControl(TMessageBase* aMsg)
       
   896     {
       
   897     TThreadMessage& m=*(TThreadMessage*)aMsg;
       
   898     const TInt fn=m.iValue;
       
   899     TAny *const a1=m.Ptr0();
       
   900     TAny *const a2=m.Ptr1();
       
   901     TInt  kern_param;
       
   902     TEndpointDescriptorInfo epi;
       
   903     TUsbcIfcInfo ifc;
       
   904     TCSDescriptorInfo desInfo;
       
   905     TInt r = KErrNone;
       
   906 
       
   907     switch (fn)
       
   908         {
       
   909         
       
   910     case RDevUsbcClient::EControlDeviceStatus:
       
   911     case RDevUsbcClient::EControlGetAlternateSetting:
       
   912         m.iArg[0] = &kern_param;              // update message to point to kernel-side buffer
       
   913         break;
       
   914 
       
   915     case RDevUsbcClient::EControlQueryReceiveBuffer:
       
   916     case RDevUsbcClient::EControlEndpointStatus:
       
   917         m.iArg[1] = &kern_param;              // update message to point to kernel-side buffer
       
   918         break;
       
   919 
       
   920     case RDevUsbcClient::EControlEndpointCaps:
       
   921     case RDevUsbcClient::EControlDeviceCaps:
       
   922     case RDevUsbcClient::EControlGetDeviceDescriptor:
       
   923     case RDevUsbcClient::EControlSetDeviceDescriptor:
       
   924     case RDevUsbcClient::EControlGetDeviceDescriptorSize:
       
   925     case RDevUsbcClient::EControlGetConfigurationDescriptor:
       
   926     case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
       
   927     case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
       
   928     case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
       
   929     case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
       
   930     case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
       
   931     case RDevUsbcClient::EControlGetStringDescriptorLangId:
       
   932     case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
       
   933     case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
       
   934     case RDevUsbcClient::EControlGetProductStringDescriptor:
       
   935     case RDevUsbcClient::EControlSetProductStringDescriptor:
       
   936     case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:    
       
   937     case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
       
   938     case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
       
   939     case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
       
   940     case RDevUsbcClient::EControlSetOtgDescriptor:
       
   941     case RDevUsbcClient::EControlGetOtgDescriptor:
       
   942     case RDevUsbcClient::EControlGetOtgFeatures:
       
   943         r=PinMemory((TDesC8 *) a1, iPinObj1);
       
   944         if(r!=KErrNone)
       
   945             {
       
   946             PanicClientThread(r);
       
   947             return r;
       
   948             }
       
   949         break;
       
   950 
       
   951     case RDevUsbcClient::EControlGetInterfaceDescriptor:
       
   952     case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
       
   953     case RDevUsbcClient::EControlSetInterfaceDescriptor:
       
   954     case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
       
   955     case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
       
   956     case RDevUsbcClient::EControlGetStringDescriptor:
       
   957     case RDevUsbcClient::EControlSetStringDescriptor:
       
   958         r=PinMemory((TDesC8 *) a2, iPinObj1);
       
   959         if(r!=KErrNone)
       
   960             {
       
   961             PanicClientThread(r);
       
   962             return r;
       
   963             }
       
   964         break;
       
   965 
       
   966     case RDevUsbcClient::EControlGetEndpointDescriptor:
       
   967     case RDevUsbcClient::EControlGetEndpointDescriptorSize:
       
   968     case RDevUsbcClient::EControlSetEndpointDescriptor:
       
   969     case RDevUsbcClient::EControlGetCSEndpointDescriptor:
       
   970     case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
       
   971         if(a1!=NULL)
       
   972             {
       
   973             r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a1, sizeof(epi));
       
   974             if(r!=KErrNone)
       
   975                 {
       
   976                 PanicClientThread(r);
       
   977                 return r;
       
   978                 }
       
   979             kumemget(&epi, a1, sizeof(epi));
       
   980             r=PinMemory((TDesC8 *) epi.iArg, iPinObj2);
       
   981             if(r!=KErrNone)
       
   982                 {
       
   983                 Kern::UnpinVirtualMemory(iPinObj1);
       
   984                 PanicClientThread(r);
       
   985                 return r;
       
   986                 }
       
   987             }
       
   988         break;
       
   989 
       
   990     case RDevUsbcClient::EControlSetInterface:
       
   991         if(a2!=NULL)
       
   992             {
       
   993             r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a2, sizeof(ifc));
       
   994             if(r!=KErrNone)
       
   995                 {
       
   996                 PanicClientThread(r);
       
   997                 return r;
       
   998                 }    
       
   999             kumemget(&ifc, a2, sizeof(ifc));                
       
  1000             r=PinMemory((TDesC8 *) ifc.iInterfaceData, iPinObj2);
       
  1001             if(r!=KErrNone)
       
  1002                 {
       
  1003                 Kern::UnpinVirtualMemory(iPinObj1);
       
  1004                 PanicClientThread(r);
       
  1005                 return r;
       
  1006                 }
       
  1007             }
       
  1008         break;
       
  1009 
       
  1010     case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
       
  1011     case RDevUsbcClient::EControlSetCSEndpointDescriptor:
       
  1012         if(a1!=NULL)
       
  1013             {
       
  1014             r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a1, sizeof(desInfo));
       
  1015             if(r!=KErrNone)
       
  1016                 {
       
  1017                 PanicClientThread(r);
       
  1018                 return r;
       
  1019                 }
       
  1020             kumemget(&desInfo, a1, sizeof(desInfo));
       
  1021             r=PinMemory((TDesC8 *) desInfo.iArg, iPinObj2);
       
  1022             if(r!=KErrNone)
       
  1023                 {
       
  1024                 Kern::UnpinVirtualMemory(iPinObj1);
       
  1025                 PanicClientThread(r);
       
  1026                 return r;
       
  1027                 }
       
  1028             }
       
  1029         break;
       
  1030     }
       
  1031 
       
  1032 
       
  1033     //Send Message and wait for synchronous complete    
       
  1034     r = DLogicalChannel::SendMsg(aMsg);
       
  1035     
       
  1036     
       
  1037     
       
  1038     switch (fn)
       
  1039         {
       
  1040     case RDevUsbcClient::EControlDeviceStatus:
       
  1041     case RDevUsbcClient::EControlGetAlternateSetting:
       
  1042         umemput32(a1, &kern_param, sizeof(kern_param));
       
  1043         break;
       
  1044 
       
  1045     case RDevUsbcClient::EControlQueryReceiveBuffer:
       
  1046     case RDevUsbcClient::EControlEndpointStatus:
       
  1047         umemput32(a2, &kern_param, sizeof(kern_param));
       
  1048         break;
       
  1049 
       
  1050     case RDevUsbcClient::EControlDeviceCaps:
       
  1051     case RDevUsbcClient::EControlEndpointCaps:
       
  1052     case RDevUsbcClient::EControlGetDeviceDescriptor:
       
  1053     case RDevUsbcClient::EControlSetDeviceDescriptor:
       
  1054     case RDevUsbcClient::EControlGetDeviceDescriptorSize:
       
  1055     case RDevUsbcClient::EControlGetConfigurationDescriptor:
       
  1056     case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
       
  1057     case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
       
  1058     case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
       
  1059     case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
       
  1060     case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
       
  1061     case RDevUsbcClient::EControlGetStringDescriptorLangId:
       
  1062     case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
       
  1063     case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
       
  1064     case RDevUsbcClient::EControlGetProductStringDescriptor:
       
  1065     case RDevUsbcClient::EControlSetProductStringDescriptor:
       
  1066     case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:    
       
  1067     case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
       
  1068     case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
       
  1069     case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
       
  1070     case RDevUsbcClient::EControlSetOtgDescriptor:
       
  1071     case RDevUsbcClient::EControlGetOtgDescriptor:
       
  1072     case RDevUsbcClient::EControlGetOtgFeatures:
       
  1073         if(a1!=NULL)
       
  1074             {
       
  1075             Kern::UnpinVirtualMemory(iPinObj1);
       
  1076             }
       
  1077         break;
       
  1078 
       
  1079     case RDevUsbcClient::EControlGetInterfaceDescriptor:
       
  1080     case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
       
  1081     case RDevUsbcClient::EControlSetInterfaceDescriptor:
       
  1082     case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
       
  1083     case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
       
  1084     case RDevUsbcClient::EControlGetStringDescriptor:
       
  1085     case RDevUsbcClient::EControlSetStringDescriptor:
       
  1086         if(a2!=NULL)
       
  1087             {
       
  1088             Kern::UnpinVirtualMemory(iPinObj1);
       
  1089             }
       
  1090         break;
       
  1091     
       
  1092     case RDevUsbcClient::EControlGetEndpointDescriptor:
       
  1093     case RDevUsbcClient::EControlGetEndpointDescriptorSize:
       
  1094     case RDevUsbcClient::EControlSetEndpointDescriptor:
       
  1095     case RDevUsbcClient::EControlGetCSEndpointDescriptor:
       
  1096     case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
       
  1097     case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
       
  1098     case RDevUsbcClient::EControlSetCSEndpointDescriptor:
       
  1099         if(a1!=NULL)
       
  1100             {
       
  1101             Kern::UnpinVirtualMemory(iPinObj1);
       
  1102             Kern::UnpinVirtualMemory(iPinObj2);
       
  1103             }
       
  1104         break;
       
  1105 
       
  1106     case RDevUsbcClient::EControlSetInterface:
       
  1107         if(a2!=NULL)
       
  1108             {
       
  1109             Kern::UnpinVirtualMemory(iPinObj1);
       
  1110             Kern::UnpinVirtualMemory(iPinObj2);
       
  1111             }
       
  1112         break;
       
  1113         }
       
  1114 
       
  1115     return r;
       
  1116     }
       
  1117 
       
  1118 
       
  1119 TInt DLddUsbcChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
       
  1120     {
       
  1121     __KTRACE_OPT(KUSB, Kern::Printf("DoControl: %d", aFunction));
       
  1122 
       
  1123     TInt r = KErrNone;
       
  1124     TInt ep;
       
  1125     TUsbcEndpoint* pEndpoint;
       
  1126     TPtrC8 pZeroDesc(NULL, 0);
       
  1127     TEndpointDescriptorInfo epInfo;
       
  1128     TUsbcIfcInfo ifcInfo;
       
  1129     TCSDescriptorInfo desInfo;
       
  1130     TUsbcEndpointResource epRes;
       
  1131     TInt bandwidthPriority;
       
  1132 
       
  1133     switch (aFunction)
       
  1134         {
       
  1135     case RDevUsbcClient::EControlEndpointZeroRequestError:
       
  1136         __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroRequestError"));
       
  1137         r = KErrNone;
       
  1138         if (iOwnsDeviceControl || (iValidInterface && iDeviceState == UsbShai::EUsbPeripheralStateConfigured))
       
  1139             {
       
  1140             iController->Ep0Stall(this);
       
  1141             }
       
  1142         else
       
  1143             {
       
  1144             if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
       
  1145                 r = KErrUsbDeviceNotConfigured;
       
  1146             else
       
  1147                 r = KErrUsbInterfaceNotReady;
       
  1148             }
       
  1149         break;
       
  1150 
       
  1151     case RDevUsbcClient::EControlGetAlternateSetting:
       
  1152         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetAlternateSetting"));
       
  1153         if (iValidInterface && iDeviceState == UsbShai::EUsbPeripheralStateConfigured)
       
  1154             {
       
  1155             r = iController->GetInterfaceNumber(this, *(TInt*)a1);
       
  1156             }
       
  1157         else
       
  1158             {
       
  1159             if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
       
  1160                 r = KErrUsbDeviceNotConfigured;
       
  1161             else
       
  1162                 r = KErrUsbInterfaceNotReady;
       
  1163             }
       
  1164         break;
       
  1165 
       
  1166     case RDevUsbcClient::EControlDeviceStatus:
       
  1167         __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceStatus"));
       
  1168         *(TInt*)a1 = iController->GetDeviceStatus();
       
  1169         break;
       
  1170 
       
  1171     case RDevUsbcClient::EControlEndpointStatus:
       
  1172         __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointStatus"));
       
  1173         if (iValidInterface && ValidEndpoint((TInt) a1))
       
  1174             {
       
  1175             pEndpoint = iEndpoint[(TInt)a1];
       
  1176             if (pEndpoint == NULL)
       
  1177                 r = KErrNotSupported;
       
  1178             else
       
  1179                 {
       
  1180                 *(TInt*)a2 = iController->GetEndpointStatus(this, iEndpoint[(TInt)a1]->RealEpNumber());
       
  1181                 }
       
  1182             }
       
  1183         else
       
  1184             {
       
  1185             if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
       
  1186                 r = KErrUsbDeviceNotConfigured;
       
  1187             else
       
  1188                 r = KErrUsbInterfaceNotReady;
       
  1189             }
       
  1190         break;
       
  1191 
       
  1192     case RDevUsbcClient::EControlQueryReceiveBuffer:
       
  1193         __KTRACE_OPT(KUSB, Kern::Printf("EControlQueryReceiveBuffer"));
       
  1194         if (iValidInterface && ValidEndpoint((TInt) a1))
       
  1195             {
       
  1196             pEndpoint=iEndpoint[(TInt) a1];
       
  1197             if (pEndpoint == NULL)
       
  1198                 r = KErrNotSupported;
       
  1199             else if (pEndpoint->EndpointInfo()->iDir != UsbShai::KUsbEpDirIn)
       
  1200                 {
       
  1201                 __KTRACE_OPT(KUSB, Kern::Printf("  bytes = %d", pEndpoint->RxBytesAvailable()));
       
  1202                 *(TInt*)a2 = pEndpoint->RxBytesAvailable();
       
  1203                 }
       
  1204             }
       
  1205         else
       
  1206             {
       
  1207             if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
       
  1208                 r = KErrUsbDeviceNotConfigured;
       
  1209             else
       
  1210                 r = KErrUsbInterfaceNotReady;
       
  1211             }
       
  1212         break;
       
  1213 
       
  1214     case RDevUsbcClient::EControlEndpointCaps:
       
  1215         __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointCaps"));
       
  1216         r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
       
  1217         if (r != KErrNone)
       
  1218             PanicClientThread(r);
       
  1219         iController->EndpointCaps(this, *((TDes8*) a1));
       
  1220         break;
       
  1221 
       
  1222     case RDevUsbcClient::EControlDeviceCaps:
       
  1223         __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceCaps"));
       
  1224         r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
       
  1225         if (r != KErrNone)
       
  1226             PanicClientThread(r);
       
  1227         iController->DeviceCaps(this, *((TDes8*) a1));
       
  1228         break;
       
  1229 
       
  1230     case RDevUsbcClient::EControlSendEp0StatusPacket:
       
  1231         __KTRACE_OPT(KUSB, Kern::Printf("EControlSendEp0StatusPacket"));
       
  1232         iController->SendEp0StatusPacket(this);
       
  1233         break;
       
  1234 
       
  1235     case RDevUsbcClient::EControlHaltEndpoint:
       
  1236         __KTRACE_OPT(KUSB, Kern::Printf("EControlHaltEndpoint"));
       
  1237         if (iValidInterface && ValidEndpoint((TInt) a1))
       
  1238             {
       
  1239             r = iController->HaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
       
  1240             }
       
  1241         else
       
  1242             {
       
  1243             if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
       
  1244                 r = KErrUsbDeviceNotConfigured;
       
  1245             else
       
  1246                 r = KErrUsbInterfaceNotReady;
       
  1247             }
       
  1248         break;
       
  1249 
       
  1250     case RDevUsbcClient::EControlClearHaltEndpoint:
       
  1251         __KTRACE_OPT(KUSB, Kern::Printf("EControlClearHaltEndpoint"));
       
  1252         if (iValidInterface && ValidEndpoint((TInt) a1))
       
  1253             {
       
  1254             r = iController->ClearHaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
       
  1255             }
       
  1256         else
       
  1257             {
       
  1258             if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
       
  1259                 r = KErrUsbDeviceNotConfigured;
       
  1260             else
       
  1261                 r = KErrUsbInterfaceNotReady;
       
  1262             }
       
  1263         break;
       
  1264 
       
  1265     case RDevUsbcClient::EControlDumpRegisters:
       
  1266         __KTRACE_OPT(KUSB, Kern::Printf("EControlDumpRegisters"));
       
  1267         iController->DumpRegisters();
       
  1268         break;
       
  1269 
       
  1270     case RDevUsbcClient::EControlReleaseDeviceControl:
       
  1271         __KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseDeviceControl"));
       
  1272         iController->ReleaseDeviceControl(this);
       
  1273         iOwnsDeviceControl = EFalse;
       
  1274         break;
       
  1275 
       
  1276     case RDevUsbcClient::EControlEndpointZeroMaxPacketSizes:
       
  1277         __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroMaxPacketSizes"));
       
  1278         r = iController->EndpointZeroMaxPacketSizes();
       
  1279         break;
       
  1280 
       
  1281     case RDevUsbcClient::EControlSetEndpointZeroMaxPacketSize:
       
  1282         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointZeroMaxPacketSize"));
       
  1283         r = iController->SetEndpointZeroMaxPacketSize(reinterpret_cast<TInt>(a1));
       
  1284         break;
       
  1285 
       
  1286     case RDevUsbcClient::EControlGetEndpointZeroMaxPacketSize:
       
  1287         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointZeroMaxPacketSize"));
       
  1288         r = iController->Ep0PacketSize();
       
  1289         break;
       
  1290 
       
  1291     case RDevUsbcClient::EControlGetDeviceDescriptor:
       
  1292         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptor"));
       
  1293         r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
       
  1294         if (r != KErrNone)
       
  1295             PanicClientThread(r);
       
  1296         r = iController->GetDeviceDescriptor(iClient, *((TDes8*) a1));
       
  1297         break;
       
  1298 
       
  1299     case RDevUsbcClient::EControlSetDeviceDescriptor:
       
  1300         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceDescriptor"));
       
  1301         if (a1 != NULL)
       
  1302             r = iController->SetDeviceDescriptor(iClient, *((TDes8*) a1));
       
  1303         else
       
  1304             r = KErrArgument;
       
  1305         break;
       
  1306 
       
  1307     case RDevUsbcClient::EControlGetDeviceDescriptorSize:
       
  1308         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptorSize"));
       
  1309         if (a1 != NULL)
       
  1310             r = iController->GetDeviceDescriptorSize(iClient, *((TDes8*) a1));
       
  1311         else
       
  1312             r = KErrArgument;
       
  1313         break;
       
  1314 
       
  1315     case RDevUsbcClient::EControlGetConfigurationDescriptor:
       
  1316         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptor"));
       
  1317         r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
       
  1318         if (r != KErrNone)
       
  1319             PanicClientThread(r);
       
  1320         r = iController->GetConfigurationDescriptor(iClient, *((TDes8*) a1));
       
  1321         break;
       
  1322 
       
  1323     case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
       
  1324         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptorSize"));
       
  1325         if (a1 != NULL)
       
  1326             {
       
  1327             r = iController->GetConfigurationDescriptorSize(iClient, *((TDes8*) a1));
       
  1328             }
       
  1329         else
       
  1330             r = KErrArgument;
       
  1331         break;
       
  1332 
       
  1333     case RDevUsbcClient::EControlSetConfigurationDescriptor:
       
  1334         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationDescriptor"));
       
  1335         r = iController->SetConfigurationDescriptor(iClient, *((TDes8*) a1));
       
  1336         break;
       
  1337 
       
  1338     case RDevUsbcClient::EControlGetInterfaceDescriptor:
       
  1339         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptor"));
       
  1340         r = iController->GetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
       
  1341         break;
       
  1342 
       
  1343     case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
       
  1344         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptorSize"));
       
  1345         r = iController->GetInterfaceDescriptorSize(iClient, this, (TInt) a1, *(TDes8*) a2);
       
  1346         break;
       
  1347 
       
  1348     case RDevUsbcClient::EControlSetInterfaceDescriptor:
       
  1349         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterfaceDescriptor"));
       
  1350         r = iController->SetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
       
  1351         break;
       
  1352 
       
  1353     case RDevUsbcClient::EControlGetEndpointDescriptor:
       
  1354         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptor"));
       
  1355         r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
       
  1356         if (r != KErrNone)
       
  1357             PanicClientThread(r);
       
  1358         ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
       
  1359         r = iController->GetEndpointDescriptor(iClient, this, epInfo.iSetting,
       
  1360                                                ep, *(TDes8*) epInfo.iArg);
       
  1361         break;
       
  1362 
       
  1363     case RDevUsbcClient::EControlGetEndpointDescriptorSize:
       
  1364         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptorSize"));
       
  1365         r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
       
  1366         if (r != KErrNone)
       
  1367             PanicClientThread(r);
       
  1368         ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
       
  1369         r = iController->GetEndpointDescriptorSize(iClient, this, epInfo.iSetting,
       
  1370                                                    ep, *(TDes8*) epInfo.iArg);
       
  1371         break;
       
  1372 
       
  1373     case RDevUsbcClient::EControlSetEndpointDescriptor:
       
  1374         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointDescriptor"));
       
  1375         r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
       
  1376         if (r != KErrNone)
       
  1377             PanicClientThread(r);
       
  1378         ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
       
  1379         r = iController->SetEndpointDescriptor(iClient, this, epInfo.iSetting,
       
  1380                                                ep, *(TDes8*)epInfo.iArg);
       
  1381         break;
       
  1382 
       
  1383     case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
       
  1384         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceQualifierDescriptor"));
       
  1385         r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
       
  1386         if (r != KErrNone)
       
  1387             PanicClientThread(r);
       
  1388         r = iController->GetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
       
  1389         break;
       
  1390 
       
  1391     case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
       
  1392         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceQualifierDescriptor"));
       
  1393         if (a1 != NULL)
       
  1394             r = iController->SetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
       
  1395         else
       
  1396             r = KErrArgument;
       
  1397         break;
       
  1398 
       
  1399     case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
       
  1400         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetOtherSpeedConfigurationDescriptor"));
       
  1401         r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
       
  1402         if (r != KErrNone)
       
  1403             PanicClientThread(r);
       
  1404         r = iController->GetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
       
  1405         break;
       
  1406 
       
  1407     case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
       
  1408         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetOtherSpeedConfigurationDescriptor"));
       
  1409         r = iController->SetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
       
  1410         break;
       
  1411 
       
  1412 
       
  1413     case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
       
  1414         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptor"));
       
  1415         r = iController->GetCSInterfaceDescriptorBlock(iClient, this, (TInt) a1, *((TDes8*) a2));
       
  1416         break;
       
  1417 
       
  1418     case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
       
  1419         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptorSize"));
       
  1420         r = iController->GetCSInterfaceDescriptorBlockSize(iClient, this, (TInt) a1, *(TDes8*) a2);
       
  1421         break;
       
  1422 
       
  1423     case RDevUsbcClient::EControlGetCSEndpointDescriptor:
       
  1424         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptor"));
       
  1425         r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
       
  1426         if (r != KErrNone)
       
  1427             PanicClientThread(r);
       
  1428         ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
       
  1429         r = iController->GetCSEndpointDescriptorBlock(iClient, this, epInfo.iSetting,
       
  1430                                                       ep, *(TDes8*) epInfo.iArg);
       
  1431         break;
       
  1432 
       
  1433     case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
       
  1434         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptorSize"));
       
  1435         r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
       
  1436         if (r != KErrNone)
       
  1437             PanicClientThread(r);
       
  1438         ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
       
  1439         r = iController->GetCSEndpointDescriptorBlockSize(iClient, this, epInfo.iSetting,
       
  1440                                                           ep, *(TDes8*) epInfo.iArg);
       
  1441         break;
       
  1442 
       
  1443     case RDevUsbcClient::EControlSignalRemoteWakeup:
       
  1444         __KTRACE_OPT(KUSB, Kern::Printf("EControlSignalRemoteWakeup"));
       
  1445         r = iController->SignalRemoteWakeup();
       
  1446         break;
       
  1447 
       
  1448     case RDevUsbcClient::EControlDeviceDisconnectFromHost:
       
  1449         __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceDisconnectFromHost"));
       
  1450         r = iController->UsbDisconnect();
       
  1451         break;
       
  1452 
       
  1453     case RDevUsbcClient::EControlDeviceConnectToHost:
       
  1454         __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceConnectToHost"));
       
  1455         r = iController->UsbConnect();
       
  1456         break;
       
  1457 
       
  1458     case RDevUsbcClient::EControlDevicePowerUpUdc:
       
  1459         __KTRACE_OPT(KUSB, Kern::Printf("EControlDevicePowerUpUdc"));
       
  1460         r = iController->PowerUpUdc();
       
  1461         break;
       
  1462 
       
  1463     case RDevUsbcClient::EControlSetDeviceControl:
       
  1464         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl"));
       
  1465         r = iController->SetDeviceControl(this);
       
  1466         if (r == KErrNone)
       
  1467             {
       
  1468             iOwnsDeviceControl = ETrue;
       
  1469             if (iEndpoint[0] == NULL)
       
  1470                 {
       
  1471                 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl 11"));
       
  1472                 r = SetupEp0();
       
  1473                 if (r != KErrNone)
       
  1474                     {
       
  1475                     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: SetupEp0() failed"));
       
  1476                     iController->ReleaseDeviceControl(this);
       
  1477                     DestroyEp0();
       
  1478                     iOwnsDeviceControl = EFalse;
       
  1479                     }
       
  1480                 iEndpoint[0]->TryToStartRead(EFalse);
       
  1481                 }
       
  1482             }
       
  1483         else
       
  1484             r = KErrInUse;
       
  1485         break;
       
  1486 
       
  1487     case RDevUsbcClient::EControlCurrentlyUsingHighSpeed:
       
  1488         __KTRACE_OPT(KUSB, Kern::Printf("EControlCurrentlyUsingHighSpeed"));
       
  1489         r = iController->CurrentlyUsingHighSpeed();
       
  1490         break;
       
  1491 
       
  1492     case RDevUsbcClient::EControlSetInterface:
       
  1493         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterface"));
       
  1494         r = Kern::ThreadRawRead(iClient, a2, &ifcInfo, sizeof(ifcInfo));
       
  1495         if (r != KErrNone)
       
  1496             PanicClientThread(r);
       
  1497         if (iValidInterface && (iDeviceState == UsbShai::EUsbPeripheralStateConfigured))
       
  1498             {
       
  1499             r = KErrGeneral;
       
  1500             }
       
  1501         else
       
  1502             {
       
  1503             bandwidthPriority = ifcInfo.iBandwidthPriority;
       
  1504             if ((bandwidthPriority & 0xffffff00) ||
       
  1505                 ((bandwidthPriority & 0x0f) >= KUsbcDmaBufMaxPriorities) ||
       
  1506                 (((bandwidthPriority >> 4) & 0x0f) >= KUsbcDmaBufMaxPriorities))
       
  1507                 {
       
  1508                 r = KErrArgument;
       
  1509                 }
       
  1510             else
       
  1511                 {
       
  1512                 r = SetInterface((TInt) a1, &ifcInfo);
       
  1513                 }
       
  1514             }
       
  1515             
       
  1516         break;
       
  1517 
       
  1518     case RDevUsbcClient::EControlReleaseInterface:
       
  1519         __KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseInterface"));
       
  1520         r = iController->ReleaseInterface(this, (TInt) a1);
       
  1521         if (r == KErrNone)
       
  1522             {
       
  1523             DestroyInterface((TUint) a1);
       
  1524             }
       
  1525         else
       
  1526             {
       
  1527             __KTRACE_OPT(KPANIC, Kern::Printf("  Error in PIL: LDD interface won't be released."));
       
  1528             }
       
  1529         break;
       
  1530 
       
  1531     case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
       
  1532         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSInterfaceDescriptor"));
       
  1533         r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
       
  1534         if (r != KErrNone)
       
  1535             PanicClientThread(r);
       
  1536         r = iController->SetCSInterfaceDescriptorBlock(iClient, this, desInfo.iSetting,
       
  1537                                                        *reinterpret_cast<const TDes8*>(desInfo.iArg),
       
  1538                                                        desInfo.iSize);
       
  1539         break;
       
  1540 
       
  1541     case RDevUsbcClient::EControlSetCSEndpointDescriptor:
       
  1542         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSEndpointDescriptor"));
       
  1543         r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
       
  1544         if (r != KErrNone)
       
  1545             PanicClientThread(r);
       
  1546         ep = EpFromAlternateSetting(desInfo.iSetting, desInfo.iEndpoint);
       
  1547         r = iController->SetCSEndpointDescriptorBlock(iClient, this, desInfo.iSetting, ep,
       
  1548                                                       *reinterpret_cast<const TDes8*>(desInfo.iArg),
       
  1549                                                       desInfo.iSize);
       
  1550         break;
       
  1551 
       
  1552     case RDevUsbcClient::EControlGetStringDescriptorLangId:
       
  1553         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptorLangId"));
       
  1554         r = iController->GetStringDescriptorLangId(iClient, *((TDes8*) a1));
       
  1555         break;
       
  1556 
       
  1557     case RDevUsbcClient::EControlSetStringDescriptorLangId:
       
  1558         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptorLangId"));
       
  1559         r = iController->SetStringDescriptorLangId(reinterpret_cast<TUint>(a1));
       
  1560         break;
       
  1561 
       
  1562     case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
       
  1563         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetManufacturerStringDescriptor"));
       
  1564         r = iController->GetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
       
  1565         break;
       
  1566 
       
  1567     case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
       
  1568         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetManufacturerStringDescriptor"));
       
  1569         r = iController->SetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
       
  1570         break;
       
  1571 
       
  1572     case RDevUsbcClient::EControlRemoveManufacturerStringDescriptor:
       
  1573         __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveManufacturerStringDescriptor"));
       
  1574         r = iController->RemoveManufacturerStringDescriptor();
       
  1575         break;
       
  1576 
       
  1577     case RDevUsbcClient::EControlGetProductStringDescriptor:
       
  1578         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetProductStringDescriptor"));
       
  1579         r = iController->GetProductStringDescriptor(iClient, *((TPtr8*) a1));
       
  1580         break;
       
  1581 
       
  1582     case RDevUsbcClient::EControlSetProductStringDescriptor:
       
  1583         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetProductStringDescriptor"));
       
  1584         r = iController->SetProductStringDescriptor(iClient, *((TPtr8*) a1));
       
  1585         break;
       
  1586 
       
  1587     case RDevUsbcClient::EControlRemoveProductStringDescriptor:
       
  1588         __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveProductStringDescriptor"));
       
  1589         r = iController->RemoveProductStringDescriptor();
       
  1590         break;
       
  1591 
       
  1592     case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
       
  1593         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetSerialNumberStringDescriptor"));
       
  1594         r = iController->GetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
       
  1595         break;
       
  1596 
       
  1597     case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
       
  1598         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetSerialNumberStringDescriptor"));
       
  1599         r = iController->SetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
       
  1600         break;
       
  1601 
       
  1602     case RDevUsbcClient::EControlRemoveSerialNumberStringDescriptor:
       
  1603         __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveSerialNumberStringDescriptor"));
       
  1604         r = iController->RemoveSerialNumberStringDescriptor();
       
  1605         break;
       
  1606 
       
  1607     case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
       
  1608         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationStringDescriptor"));
       
  1609         r = iController->GetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
       
  1610         break;
       
  1611 
       
  1612     case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
       
  1613         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationStringDescriptor"));
       
  1614         r = iController->SetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
       
  1615         break;
       
  1616 
       
  1617     case RDevUsbcClient::EControlRemoveConfigurationStringDescriptor:
       
  1618         __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveConfigurationStringDescriptor"));
       
  1619         r = iController->RemoveConfigurationStringDescriptor();
       
  1620         break;
       
  1621 
       
  1622     case RDevUsbcClient::EControlGetStringDescriptor:
       
  1623         __KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptor"));
       
  1624         r = iController->GetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
       
  1625         break;
       
  1626 
       
  1627     case RDevUsbcClient::EControlSetStringDescriptor:
       
  1628         __KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptor"));
       
  1629         r = iController->SetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
       
  1630         break;
       
  1631 
       
  1632     case RDevUsbcClient::EControlRemoveStringDescriptor:
       
  1633         __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveStringDescriptor"));
       
  1634         r = iController->RemoveStringDescriptor((TUint8) (TInt) a1);
       
  1635         break;
       
  1636 
       
  1637     case RDevUsbcClient::EControlQueryEndpointResourceUse:
       
  1638         epRes = (TUsbcEndpointResource)((TInt) a2);
       
  1639         if (!ValidEndpoint((TInt)a1))
       
  1640             {
       
  1641             r = KErrUsbEpNotInInterface;
       
  1642             }
       
  1643         else
       
  1644             {
       
  1645             r = iController->QueryEndpointResource(this, iEndpoint[(TInt)a1]->RealEpNumber(), epRes);
       
  1646             }
       
  1647         break;
       
  1648 
       
  1649     case RDevUsbcClient::EControlSetOtgDescriptor:
       
  1650         {
       
  1651         r = iController->SetOtgDescriptor(iClient, *((const TDesC8*)a1));
       
  1652         }
       
  1653         break;
       
  1654 
       
  1655     case RDevUsbcClient::EControlGetOtgDescriptor:
       
  1656         {
       
  1657         r = iController->GetOtgDescriptor(iClient, *((TDes8*)a1));
       
  1658         }
       
  1659         break;
       
  1660 
       
  1661     case RDevUsbcClient::EControlGetOtgFeatures:
       
  1662         {
       
  1663         r = iController->GetOtgFeatures(iClient, *((TDes8*)a1));
       
  1664         }
       
  1665         break;
       
  1666 
       
  1667     default:
       
  1668         __KTRACE_OPT(KUSB, Kern::Printf("Function code not supported"));
       
  1669         r = KErrNotSupported;
       
  1670         }
       
  1671 
       
  1672     return r;
       
  1673     }
       
  1674 
       
  1675 
       
  1676 TInt DLddUsbcChannel::SetInterface(TInt aInterfaceNumber, TUsbcIfcInfo* aInfoBuf)
       
  1677     {
       
  1678     TUsbcInterfaceInfoBuf ifc_info_buf;
       
  1679     TUsbcInterfaceInfoBuf* const ifc_info_buf_ptr = aInfoBuf->iInterfaceData;
       
  1680     const TInt srcLen = Kern::ThreadGetDesLength(iClient, ifc_info_buf_ptr);
       
  1681     if (srcLen < ifc_info_buf.Length())
       
  1682         {
       
  1683         __KTRACE_OPT(KUSB, Kern::Printf("SetInterface can't copy"));
       
  1684         PanicClientThread(EDesOverflow);
       
  1685         }
       
  1686 
       
  1687     TInt r = Kern::ThreadDesRead(iClient, ifc_info_buf_ptr, ifc_info_buf, 0, KChunkShiftBy0);
       
  1688     if (r != KErrNone)
       
  1689         {
       
  1690         __KTRACE_OPT(KUSB, Kern::Printf("SetInterface Copy failed reason=%d", r));
       
  1691         PanicClientThread(r);
       
  1692         }
       
  1693 
       
  1694     TUsbcEndpointInfo* pEndpointData = ifc_info_buf().iEndpointData;
       
  1695 
       
  1696     // If an alternate interface is being asked for then do nothing,
       
  1697     // just pass it down to the Controller.
       
  1698     const TInt num_endpoints = ifc_info_buf().iTotalEndpointsUsed;
       
  1699     __KTRACE_OPT(KUSB, Kern::Printf("SetInterface num_endpoints=%d", num_endpoints));
       
  1700 
       
  1701     // [The next 4 variables have to be initialized here because of the goto's that follow.]
       
  1702     // Both IN and OUT buffers will be fully cached:
       
  1703     const TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
       
  1704     const TUint32 bandwidthPriority = aInfoBuf->iBandwidthPriority;
       
  1705 
       
  1706     // Supports ep0+5 endpoints
       
  1707     TInt real_ep_numbers[6] = {-1, -1, -1, -1, -1, -1};
       
  1708 
       
  1709     // See if PIL will accept this interface
       
  1710     __KTRACE_OPT(KUSB, Kern::Printf("SetInterface Calling controller"));
       
  1711     r = iController->SetInterface(this,
       
  1712                                   iClient,
       
  1713                                   aInterfaceNumber,
       
  1714                                   ifc_info_buf().iClass,
       
  1715                                   aInfoBuf->iString,
       
  1716                                   ifc_info_buf().iTotalEndpointsUsed,
       
  1717                                   ifc_info_buf().iEndpointData,
       
  1718                                   &real_ep_numbers,
       
  1719                                   ifc_info_buf().iFeatureWord);
       
  1720 
       
  1721     __KTRACE_OPT(KUSB, Kern::Printf("SetInterface controller returned %d", r));
       
  1722     if (r != KErrNone)
       
  1723         {
       
  1724         __KTRACE_OPT(KPANIC, Kern::Printf("SetInterface failed reason=%d", r));
       
  1725         return r;
       
  1726         }
       
  1727 
       
  1728     // [The next variable has to be initialized here because of the goto's that follow.]
       
  1729     TUsbcAlternateSettingList* alternateSettingListRec;
       
  1730 
       
  1731     // ep0
       
  1732     if (iEndpoint[0] == NULL)
       
  1733         {
       
  1734         __KTRACE_OPT(KUSB, Kern::Printf("SetInterface 11"));
       
  1735         r = SetupEp0();
       
  1736         if (r != KErrNone)
       
  1737             {
       
  1738             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: SetupEp0() failed"));
       
  1739             DestroyEp0();
       
  1740             goto F1;
       
  1741             }
       
  1742         }
       
  1743 
       
  1744     alternateSettingListRec = new TUsbcAlternateSettingList;
       
  1745     if (!alternateSettingListRec)
       
  1746         {
       
  1747         r = KErrNoMemory;
       
  1748         goto F1;
       
  1749         }
       
  1750 
       
  1751     __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::SetInterface num_endpoints=%d", num_endpoints));
       
  1752 
       
  1753     // other endpoints
       
  1754     // calculate the total buffer size
       
  1755     for (TInt i = 1; i <= num_endpoints; i++, pEndpointData++)
       
  1756         {
       
  1757         __KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d", i));
       
  1758         if (!ValidateEndpoint(pEndpointData))
       
  1759             {
       
  1760             r = KErrUsbBadEndpoint;
       
  1761             goto F2;
       
  1762             }
       
  1763 
       
  1764         TUsbcEndpoint* ep = new TUsbcEndpoint(this, iController, pEndpointData, i, bandwidthPriority);
       
  1765         alternateSettingListRec->iEndpoint[i] = ep;
       
  1766         if (!ep)
       
  1767             {
       
  1768             r = KErrNoMemory;
       
  1769             goto F2;
       
  1770             }
       
  1771         if (ep->Construct() != KErrNone)
       
  1772             {
       
  1773             r = KErrNoMemory;
       
  1774             goto F2;
       
  1775             }
       
  1776 
       
  1777         __KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d rec=0x%08x ep==0x%08x",
       
  1778                                         i, alternateSettingListRec, ep));
       
  1779         }
       
  1780 
       
  1781     // buf size of each endpoint
       
  1782     TInt bufSizes[KMaxEndpointsPerClient + 1];
       
  1783     TInt epNum[KMaxEndpointsPerClient + 1];
       
  1784 
       
  1785     // init
       
  1786     for( TInt i=0;i<KMaxEndpointsPerClient+1;i++ )
       
  1787         {
       
  1788         bufSizes[i] = -1;
       
  1789         epNum[i] = i;
       
  1790         }
       
  1791 
       
  1792     // Record the actual buf size of each endpoint
       
  1793     for( TInt i=1;i<=num_endpoints;i++ )
       
  1794         {
       
  1795         bufSizes[i] = alternateSettingListRec->iEndpoint[i]->BufferSize();
       
  1796         }
       
  1797 
       
  1798     __KTRACE_OPT(KUSB, Kern::Printf("Sort the endpoints:"));
       
  1799 
       
  1800     // sort the endpoint number by the bufsize decreasely
       
  1801     for( TInt i=1;i<num_endpoints;i++ )
       
  1802         {
       
  1803         TInt epMaxBuf = i;
       
  1804         for(TInt k=i+1;k<=num_endpoints;k++ )
       
  1805             {
       
  1806             if( bufSizes[epMaxBuf]<bufSizes[k])
       
  1807                 {
       
  1808                 epMaxBuf = k;
       
  1809                 }
       
  1810             }
       
  1811         TInt temp = bufSizes[i];
       
  1812         bufSizes[i] = bufSizes[epMaxBuf];
       
  1813         bufSizes[epMaxBuf] = temp;
       
  1814 
       
  1815         temp = epNum[i];
       
  1816         epNum[i] = epNum[epMaxBuf];
       
  1817         epNum[epMaxBuf] = temp;
       
  1818 
       
  1819         alternateSettingListRec->iEpNumDeOrderedByBufSize[i] = epNum[i];
       
  1820 
       
  1821         __KTRACE_OPT(KUSB, Kern::Printf(" %d:%d", epNum[i], bufSizes[i]));
       
  1822         }
       
  1823     alternateSettingListRec->iEpNumDeOrderedByBufSize[num_endpoints] = epNum[num_endpoints];
       
  1824     __KTRACE_OPT(KUSB, Kern::Printf(" %d:%d", epNum[num_endpoints], bufSizes[num_endpoints]));
       
  1825     __KTRACE_OPT(KUSB, Kern::Printf("\n"));
       
  1826 
       
  1827     // chain in this alternate setting
       
  1828     alternateSettingListRec->iNext = iAlternateSettingList;
       
  1829     iAlternateSettingList = alternateSettingListRec;
       
  1830     alternateSettingListRec->iSetting = aInterfaceNumber;
       
  1831     alternateSettingListRec->iNumberOfEndpoints = num_endpoints;
       
  1832 
       
  1833     // Record the 'real' endpoint number used by the PDD in both the Ep and
       
  1834     // the Req callback:
       
  1835     for (TInt i = 1; i <= num_endpoints; i++)
       
  1836         {
       
  1837         alternateSettingListRec->iEndpoint[i]->SetRealEpNumber(real_ep_numbers[i]);
       
  1838         }
       
  1839 
       
  1840     r = SetupInterfaceMemory(iHwChunks, cacheAttribs );
       
  1841     if( r==KErrNone )
       
  1842         {
       
  1843         __KTRACE_OPT(KUSB, Kern::Printf("SetInterface ready to exit"));
       
  1844     
       
  1845         if (aInterfaceNumber == 0)
       
  1846             {
       
  1847             // make sure we're ready to go with the main interface
       
  1848             iValidInterface = ETrue;
       
  1849             __KTRACE_OPT(KUSB, Kern::Printf("SetInterface SelectAlternateSetting"));
       
  1850             SelectAlternateSetting(0);
       
  1851             }
       
  1852         return KErrNone;
       
  1853         }
       
  1854     else
       
  1855         {
       
  1856         __KTRACE_OPT(KUSB, Kern::Printf("Destroying all interfaces"));
       
  1857         DestroyAllInterfaces();
       
  1858         DestroyEp0();
       
  1859         return r;
       
  1860         }
       
  1861 
       
  1862  F2:
       
  1863     delete alternateSettingListRec;
       
  1864     //Fall through
       
  1865  
       
  1866  F1:
       
  1867 #if _DEBUG
       
  1868     TInt r1 = iController->ReleaseInterface(this, aInterfaceNumber);
       
  1869     __KTRACE_OPT(KUSB, Kern::Printf("Release Interface controller returned %d", r1));
       
  1870 #else
       
  1871     (void)    iController->ReleaseInterface(this, aInterfaceNumber);
       
  1872 #endif
       
  1873     return r;
       
  1874     }
       
  1875 
       
  1876 // realloc the memory, and set the previous interfaces 
       
  1877 TInt DLddUsbcChannel::SetupInterfaceMemory(RArray<DPlatChunkHw*> &aHwChunks, 
       
  1878         TUint32 aCacheAttribs )
       
  1879     {
       
  1880     TUsbcAlternateSettingList* asRec = iAlternateSettingList;
       
  1881 
       
  1882     // if buffers has been changed
       
  1883     TBool chunkChanged = EFalse;
       
  1884     TInt numOfEp = asRec->iNumberOfEndpoints;
       
  1885  
       
  1886     // 1, collect all bufs' sizes for the current interface
       
  1887     //    to realloc all the chunks
       
  1888     __KTRACE_OPT(KUSB, Kern::Printf("Collect all buffer sizes:"));
       
  1889     RArray<TInt> bufSizes;
       
  1890     for(TInt i=1;i<=numOfEp;i++)
       
  1891         {
       
  1892         TInt nextEp = asRec->iEpNumDeOrderedByBufSize[i];
       
  1893         TInt epBufCount = asRec->iEndpoint[nextEp]->BufferNumber();
       
  1894         __KTRACE_OPT(KUSB, Kern::Printf(" ep %d, buf count %d", nextEp, epBufCount ));
       
  1895         for(TInt k=0;k<epBufCount;k++)
       
  1896             {
       
  1897             TInt epBufSize = asRec->iEndpoint[nextEp]->BufferSize();
       
  1898             TInt r = bufSizes.Append(epBufSize);
       
  1899             if(r!=KErrNone)
       
  1900                 {
       
  1901                 iController->DeRegisterClient(this);
       
  1902                 bufSizes.Close();
       
  1903                 return r;
       
  1904                 }
       
  1905             __KTRACE_OPT(KUSB,Kern::Printf(" %d", epBufSize ));
       
  1906             }
       
  1907         __KTRACE_OPT(KUSB, Kern::Printf("\n"));
       
  1908 
       
  1909         }
       
  1910    
       
  1911     // 2, alloc the buffer decreasely, biggest-->smallest
       
  1912     //   2.1 check the existing chunks
       
  1913     TInt bufCount = bufSizes.Count();
       
  1914     __KTRACE_OPT(KUSB, Kern::Printf(" ep buf number needed %d", bufCount ));
       
  1915     __KTRACE_OPT(KUSB, Kern::Printf(" chunks available %d", aHwChunks.Count() ));
       
  1916 
       
  1917     TInt chunkInd = 0;
       
  1918     while( (chunkInd<aHwChunks.Count())&& (chunkInd<bufCount))
       
  1919         {
       
  1920         TUint8* oldAddr = NULL;
       
  1921         oldAddr = reinterpret_cast<TUint8*>(aHwChunks[chunkInd]->LinearAddress());
       
  1922 
       
  1923         DPlatChunkHw* chunk = ReAllocate(bufSizes[chunkInd], aHwChunks[chunkInd], aCacheAttribs);
       
  1924         if (chunk == NULL)
       
  1925             {
       
  1926             __KTRACE_OPT(KUSB, Kern::Printf("Failed to alloc chunks size %d!", bufSizes[chunkInd]));
       
  1927             // lost all interfaces:
       
  1928             // Tell Controller to release Interface and h/w resources associated with this
       
  1929             iController->DeRegisterClient(this);
       
  1930             bufSizes.Close();
       
  1931             return KErrNoMemory;
       
  1932             }
       
  1933         else
       
  1934             {
       
  1935             // Parcel out the memory between endpoints
       
  1936             TUint8* newAddr = reinterpret_cast<TUint8*>(chunk->LinearAddress());
       
  1937             __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory alloc new chunk=0x%x, size=%d", newAddr,bufSizes[chunkInd]));
       
  1938             // The check is important to avoid chunkChanged to be corrupted.
       
  1939             // This code change is to fix the problem that one chunk is used by multiple interfaces.
       
  1940             if(!chunkChanged)
       
  1941                 {
       
  1942                 chunkChanged = (newAddr != oldAddr);
       
  1943                 }            
       
  1944             aHwChunks[chunkInd] = chunk;
       
  1945             }
       
  1946         chunkInd++;
       
  1947         }
       
  1948     
       
  1949     //   2.2 in case available chunks are not enough
       
  1950     while( chunkInd<bufCount)
       
  1951         {
       
  1952         DPlatChunkHw* chunk = NULL;
       
  1953         chunk = Allocate( bufSizes[chunkInd], aCacheAttribs);
       
  1954         if (chunk == NULL)
       
  1955             {
       
  1956             __KTRACE_OPT(KUSB, Kern::Printf("Failed to alloc chunk, size %d!", bufSizes[chunkInd]));
       
  1957             // lost all interfaces:
       
  1958             // Tell Controller to release Interface and h/w resources associated with this
       
  1959             iController->DeRegisterClient(this);
       
  1960             bufSizes.Close();
       
  1961             return KErrNoMemory;
       
  1962             }
       
  1963         else
       
  1964             {
       
  1965             // Parcel out the memory between endpoints
       
  1966             __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory alloc new chunk=0x%x, size=%d",
       
  1967                                     reinterpret_cast<TUint8*>(chunk->LinearAddress()), bufSizes[chunkInd]));
       
  1968             TInt r = aHwChunks.Append(chunk);
       
  1969             if(r!=KErrNone)
       
  1970                 {
       
  1971                 ClosePhysicalChunk(chunk);
       
  1972                 iController->DeRegisterClient(this);
       
  1973                 bufSizes.Close();
       
  1974                 return r;
       
  1975                 }
       
  1976             }
       
  1977         chunkInd++;
       
  1978         }
       
  1979 
       
  1980     // 3, Set the the bufs of the interfaces
       
  1981     
       
  1982     ReSetInterfaceMemory(asRec, aHwChunks);
       
  1983 
       
  1984     if(chunkChanged)
       
  1985         {
       
  1986         __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory readdressing."));
       
  1987         asRec = asRec->iNext;
       
  1988         while (asRec)
       
  1989             {
       
  1990             // Interfaces are not concurrent so they can all start at the same logical address
       
  1991             __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory readdressing setting=%d", asRec->iSetting));
       
  1992             ReSetInterfaceMemory(asRec, aHwChunks);
       
  1993             asRec = asRec->iNext;
       
  1994             }
       
  1995         }
       
  1996     return KErrNone;
       
  1997     }
       
  1998 
       
  1999 TInt DLddUsbcChannel::SetupEp0()
       
  2000     {
       
  2001     __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 entry %x", this));
       
  2002     TInt ep0Size = iController->Ep0PacketSize();
       
  2003     TUsbcEndpointInfo ep0Info = TUsbcEndpointInfo(UsbShai::KUsbEpTypeControl, UsbShai::KUsbEpDirBidirect, ep0Size);
       
  2004     TUsbcEndpoint* ep0 = new TUsbcEndpoint(this, iController, &ep0Info, 0, 0);
       
  2005     if (ep0 == NULL)
       
  2006         {
       
  2007         return KErrNoMemory;
       
  2008         }
       
  2009     // In case we have to return early:
       
  2010     iEndpoint[0] = ep0;
       
  2011     TInt r = ep0->Construct();
       
  2012     if (r != KErrNone)
       
  2013         {
       
  2014         return KErrNoMemory;
       
  2015         }
       
  2016 
       
  2017     TInt bufferNum = ep0->BufferNumber();
       
  2018     TInt bufferSize = ep0->BufferSize();
       
  2019     TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
       
  2020 
       
  2021     for(TInt i=0;i<bufferNum;i++)
       
  2022         {
       
  2023         DPlatChunkHw* chunk = Allocate(bufferSize, cacheAttribs );
       
  2024         if(chunk==NULL)
       
  2025             {
       
  2026             return KErrNoMemory;
       
  2027             }
       
  2028         TInt r = iHwChunksEp0.Append(chunk);
       
  2029         if(r!=KErrNone)
       
  2030             {
       
  2031             ClosePhysicalChunk(chunk);
       
  2032             return r;
       
  2033             }
       
  2034         TUint8 * buf;
       
  2035         buf = (TUint8*) chunk->LinearAddress();
       
  2036         ep0->SetBufferAddr( i, buf);
       
  2037         __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 60 buffer number %d", i));
       
  2038         __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 60 buffer size %d", bufferSize));
       
  2039         }
       
  2040 
       
  2041     ep0->SetRealEpNumber(0);
       
  2042     return KErrNone;
       
  2043     }
       
  2044 
       
  2045 // Set buffer address of the interface
       
  2046 // Precondition: Enough chunks available.
       
  2047 void DLddUsbcChannel::ReSetInterfaceMemory(TUsbcAlternateSettingList* aAlternateSettingListRec,
       
  2048         RArray<DPlatChunkHw*> &aHwChunks)
       
  2049     {
       
  2050     TUsbcAlternateSettingList* asRec = aAlternateSettingListRec;
       
  2051 
       
  2052     // set all the interfaces
       
  2053     TInt chunkInd = 0;
       
  2054     TInt numOfEp = asRec->iNumberOfEndpoints;
       
  2055 
       
  2056     for (TInt i = 1; i <= numOfEp; i++)
       
  2057         {
       
  2058         TInt nextEp = asRec->iEpNumDeOrderedByBufSize[i];
       
  2059         TInt epBufCount = asRec->iEndpoint[nextEp]->BufferNumber();
       
  2060         for(TInt k=0;k<epBufCount;k++)
       
  2061             {
       
  2062             TUsbcEndpoint* ep = asRec->iEndpoint[nextEp];
       
  2063             if (ep != NULL )
       
  2064                 {
       
  2065                 TUint8* pBuf = NULL;
       
  2066                 pBuf = reinterpret_cast<TUint8*>(aHwChunks[chunkInd]->LinearAddress());
       
  2067                 ep->SetBufferAddr( k, pBuf);
       
  2068                 __KTRACE_OPT(KUSB, Kern::Printf("  ep %d, buf %d, addr 0x%x", nextEp, k, pBuf ));
       
  2069                 chunkInd++;
       
  2070                 __ASSERT_DEBUG(chunkInd<=aHwChunks.Count(),
       
  2071                                Kern::Printf("  Error: available chunks %d, run out at epInd%d, bufInd%d",
       
  2072                                        aHwChunks.Count(), i, k));
       
  2073                 __ASSERT_DEBUG(chunkInd<=aHwChunks.Count(),
       
  2074                                    Kern::Fault("usbc.ldd", __LINE__));
       
  2075                 }
       
  2076             }
       
  2077         }
       
  2078 
       
  2079     }
       
  2080 
       
  2081 void DLddUsbcChannel::DestroyAllInterfaces()
       
  2082     {
       
  2083     // Removes all interfaces
       
  2084     TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
       
  2085     while (alternateSettingListRec)
       
  2086         {
       
  2087         iController->ReleaseInterface(this, alternateSettingListRec->iSetting);
       
  2088         TUsbcAlternateSettingList* alternateSettingListRecNext = alternateSettingListRec->iNext;
       
  2089         delete alternateSettingListRec;
       
  2090         alternateSettingListRec = alternateSettingListRecNext;
       
  2091         }
       
  2092     iNumberOfEndpoints = 0;
       
  2093     iAlternateSettingList = NULL;
       
  2094 
       
  2095     for(TInt i=0;i<iHwChunks.Count();i++)
       
  2096         {
       
  2097         ClosePhysicalChunk( iHwChunks[i]);
       
  2098         }
       
  2099     iHwChunks.Close();
       
  2100 
       
  2101     iValidInterface = EFalse;
       
  2102     }
       
  2103 
       
  2104 
       
  2105 void DLddUsbcChannel::DestroyInterface(TUint aInterfaceNumber)
       
  2106     {
       
  2107     if (iAlternateSetting == aInterfaceNumber)
       
  2108         {
       
  2109         ResetInterface(KErrUsbInterfaceNotReady);
       
  2110         iValidInterface = EFalse;
       
  2111         iNumberOfEndpoints = 0;
       
  2112         for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
       
  2113             {
       
  2114             iEndpoint[i] = NULL;
       
  2115             }
       
  2116         }
       
  2117     TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
       
  2118     TUsbcAlternateSettingList* alternateSettingListRecOld = NULL;
       
  2119     while (alternateSettingListRec)
       
  2120         {
       
  2121         TUsbcAlternateSettingList* alternateSettingListRecNext = alternateSettingListRec->iNext;
       
  2122         if (alternateSettingListRec->iSetting == aInterfaceNumber)
       
  2123             {
       
  2124             // This record is to be deleted
       
  2125             if (alternateSettingListRecOld == NULL)
       
  2126                 {
       
  2127                 // The record to be deleted is at the list head
       
  2128                 iAlternateSettingList = alternateSettingListRecNext;
       
  2129                 }
       
  2130             else
       
  2131                 {
       
  2132                 // The record to be deleted is NOT at the list head
       
  2133                 alternateSettingListRecOld->iNext = alternateSettingListRecNext;
       
  2134                 }
       
  2135             delete alternateSettingListRec;
       
  2136             break;
       
  2137             }
       
  2138         alternateSettingListRecOld = alternateSettingListRec;
       
  2139         alternateSettingListRec = alternateSettingListRecNext;
       
  2140         }
       
  2141 
       
  2142     if (iAlternateSettingList == NULL)
       
  2143         {
       
  2144         // if no interfaces left destroy non-ep0 buffering
       
  2145         for(TInt i=0;i<iHwChunks.Count();i++)
       
  2146             {
       
  2147             ClosePhysicalChunk( iHwChunks[i]);
       
  2148             }
       
  2149         iHwChunks.Close();
       
  2150         }
       
  2151     }
       
  2152 
       
  2153 
       
  2154 void DLddUsbcChannel::DestroyEp0()
       
  2155     {
       
  2156     delete iEndpoint[0];
       
  2157     iEndpoint[0] = NULL;
       
  2158     for(TInt i=0;i<iHwChunksEp0.Count();i++)
       
  2159         {
       
  2160         ClosePhysicalChunk( iHwChunksEp0[i] );
       
  2161         }
       
  2162     iHwChunksEp0.Close();
       
  2163     }
       
  2164 
       
  2165 
       
  2166 void DLddUsbcChannel::EndpointStatusChangeCallback(TAny* aDLddUsbcChannel)
       
  2167     {
       
  2168     __KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback"));
       
  2169     DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
       
  2170     if (dUsbc->iChannelClosing)
       
  2171         return;
       
  2172     TUint endpointState = dUsbc->iEndpointStatusCallbackInfo.State();
       
  2173     const TInt reqNo = (TInt) RDevUsbcClient::ERequestEndpointStatusNotify;
       
  2174     if (dUsbc->iRequestStatus[reqNo])
       
  2175         {
       
  2176         __KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback Notify status"));
       
  2177         DThread* client = dUsbc->iClient;
       
  2178         
       
  2179         dUsbc->iEndpointStatusChangeReq->Data() = endpointState;
       
  2180         dUsbc->iRequestStatus[reqNo] = NULL;
       
  2181         Kern::QueueRequestComplete(client,dUsbc->iEndpointStatusChangeReq,KErrNone);
       
  2182         dUsbc->iEndpointStatusChangePtr = NULL;
       
  2183         }
       
  2184     }
       
  2185 
       
  2186 
       
  2187 void DLddUsbcChannel::StatusChangeCallback(TAny* aDLddUsbcChannel)
       
  2188     {
       
  2189     DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
       
  2190     if (dUsbc->iChannelClosing)
       
  2191         return;
       
  2192 
       
  2193     TUsbcDeviceState deviceState;
       
  2194     TInt i;
       
  2195      for (i = 0;
       
  2196           (i < KUsbcDeviceStateRequests) && ((deviceState = dUsbc->iStatusCallbackInfo.State(i)) != UsbShai::EUsbPeripheralNoState);
       
  2197           ++i)
       
  2198         {
       
  2199          __KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallBack status=%d", deviceState));
       
  2200         if (deviceState & KUsbAlternateSetting)
       
  2201             {
       
  2202             dUsbc->ProcessAlternateSetting(deviceState);
       
  2203             }
       
  2204         else
       
  2205             {
       
  2206             dUsbc->ProcessDeviceState(deviceState);
       
  2207             }
       
  2208         // Only queue if userside is interested
       
  2209         if (dUsbc->iDeviceStatusNeeded)
       
  2210             {
       
  2211             dUsbc->iStatusFifo->AddStatusToQueue(deviceState);
       
  2212             const TInt reqNo = (TInt) RDevUsbcClient::ERequestAlternateDeviceStatusNotify;
       
  2213             if (dUsbc->AlternateDeviceStateTestComplete())
       
  2214                 {
       
  2215                     dUsbc->iRequestStatus[reqNo]=NULL;
       
  2216                     Kern::QueueRequestComplete(dUsbc->iClient,dUsbc->iStatusChangeReq,KErrNone);
       
  2217                 }
       
  2218             }
       
  2219         }
       
  2220      // We don't want to be interrupted in the middle of this:
       
  2221     const TInt irqs = NKern::DisableInterrupts(2);
       
  2222      dUsbc->iStatusCallbackInfo.ResetState();
       
  2223     NKern::RestoreInterrupts(irqs);
       
  2224     }
       
  2225 
       
  2226 
       
  2227 void DLddUsbcChannel::OtgFeatureChangeCallback(TAny* aDLddUsbcChannel)
       
  2228     {
       
  2229     __KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback"));
       
  2230     DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
       
  2231     if (dUsbc->iChannelClosing)
       
  2232         return;
       
  2233 
       
  2234     TUint8 features;
       
  2235     // No return value check. Assume OTG always supported here
       
  2236     dUsbc->iController->GetCurrentOtgFeatures(features);
       
  2237 
       
  2238     const TInt reqNo = (TInt) RDevUsbcClient::ERequestOtgFeaturesNotify;
       
  2239     if (dUsbc->iRequestStatus[reqNo])
       
  2240         {
       
  2241         __KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback Notify status"));
       
  2242         dUsbc->iOtgFeatureChangeReq->Data()=features;
       
  2243         dUsbc->iRequestStatus[reqNo] = NULL;
       
  2244         Kern::QueueRequestComplete(dUsbc->iClient,dUsbc->iOtgFeatureChangeReq,KErrNone);
       
  2245         dUsbc->iOtgFeatureChangePtr = NULL;
       
  2246         }
       
  2247     }
       
  2248 
       
  2249 
       
  2250 TInt DLddUsbcChannel::SelectAlternateSetting(TUint aAlternateSetting)
       
  2251     {
       
  2252     TInt r = KErrGeneral;                                    // error code doesn't go userside
       
  2253     TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
       
  2254     while (alternateSettingListRec)
       
  2255         {
       
  2256         if (alternateSettingListRec->iSetting == aAlternateSetting)
       
  2257             {
       
  2258             // found the correct interface, now latch in new endpoint set
       
  2259             for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
       
  2260                 {
       
  2261                 iEndpoint[i] = NULL;
       
  2262                 }
       
  2263             iNumberOfEndpoints = alternateSettingListRec->iNumberOfEndpoints;
       
  2264             r = KErrNone;
       
  2265             for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
       
  2266                 {
       
  2267                 iEndpoint[i] = alternateSettingListRec->iEndpoint[i];
       
  2268                 }
       
  2269             // Only after correct alternate setting has been chosen.
       
  2270             UpdateEndpointSizes();
       
  2271             }
       
  2272         alternateSettingListRec = alternateSettingListRec->iNext;
       
  2273         }
       
  2274     return r;
       
  2275     }
       
  2276 
       
  2277 
       
  2278 TInt DLddUsbcChannel::EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint)
       
  2279     {
       
  2280     TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
       
  2281     while (alternateSettingListRec)
       
  2282         {
       
  2283         if (alternateSettingListRec->iSetting == aAlternateSetting)
       
  2284             {
       
  2285             if ((aEndpoint <= alternateSettingListRec->iNumberOfEndpoints) &&
       
  2286                 (aEndpoint >= 0))
       
  2287                 {
       
  2288                 return alternateSettingListRec->iEndpoint[aEndpoint]->RealEpNumber();
       
  2289                 }
       
  2290             else
       
  2291                 {
       
  2292                 __KTRACE_OPT(KPANIC, Kern::Printf("  Error: aEndpoint %d wrong for aAlternateSetting %d",
       
  2293                                                   aEndpoint, aAlternateSetting));
       
  2294                 return -1;
       
  2295                 }
       
  2296             }
       
  2297         alternateSettingListRec = alternateSettingListRec->iNext;
       
  2298         }
       
  2299     __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no aAlternateSetting %d found", aAlternateSetting));
       
  2300     return -1;
       
  2301     }
       
  2302 
       
  2303 
       
  2304 TInt DLddUsbcChannel::ProcessAlternateSetting(TUint aAlternateSetting)
       
  2305     {
       
  2306     ResetInterface(KErrUsbInterfaceChange);                    // kill any outstanding transfers
       
  2307     __KTRACE_OPT(KUSB, Kern::Printf("ProcessAlternateSetting 0x%08x", aAlternateSetting));
       
  2308     TUint newSetting = aAlternateSetting&(~KUsbAlternateSetting);
       
  2309     __KTRACE_OPT(KUSB, Kern::Printf("ProcessAlternateSetting selecting alternate setting 0x%08x", newSetting));
       
  2310     TInt r = SelectAlternateSetting(newSetting);
       
  2311     if (r != KErrNone)
       
  2312         return r;
       
  2313     StartEpReads();
       
  2314     iAlternateSetting = newSetting;
       
  2315     return KErrNone;
       
  2316     }
       
  2317 
       
  2318 
       
  2319 TInt DLddUsbcChannel::ProcessDeviceState(TUsbcDeviceState aDeviceState)
       
  2320     {
       
  2321     __KTRACE_OPT(KUSB, Kern::Printf("ProcessDeviceState(%d -> %d)", iDeviceState, aDeviceState));
       
  2322     if (iDeviceState == aDeviceState)
       
  2323         {
       
  2324         __KTRACE_OPT(KUSB, Kern::Printf("  No state change => nothing to be done."));
       
  2325         return KErrNone;
       
  2326         }
       
  2327     if (iDeviceState == UsbShai::EUsbPeripheralStateSuspended)
       
  2328         {
       
  2329         __KTRACE_OPT(KUSB, Kern::Printf("  Coming out of Suspend: old state = %d", iOldDeviceState));
       
  2330         iDeviceState = iOldDeviceState;
       
  2331         if (iDeviceState == aDeviceState)
       
  2332             {
       
  2333             __KTRACE_OPT(KUSB, Kern::Printf("  New state same as before Suspend => nothing to be done."));
       
  2334             return KErrNone;
       
  2335             }
       
  2336         }
       
  2337     TBool renumerateState = (aDeviceState == UsbShai::EUsbPeripheralStateConfigured);
       
  2338     TBool deconfigured = EFalse;
       
  2339     TInt cancellationCode = KErrNone;
       
  2340     if (aDeviceState == UsbShai::EUsbPeripheralStateSuspended)
       
  2341         {
       
  2342         __KTRACE_OPT(KUSB, Kern::Printf("  Suspending..."));
       
  2343         iOldDeviceState = iDeviceState;
       
  2344         // Put PSL into low power mode here
       
  2345         }
       
  2346     else
       
  2347         {
       
  2348         deconfigured = (iDeviceState == UsbShai::EUsbPeripheralStateConfigured &&
       
  2349                         aDeviceState != UsbShai::EUsbPeripheralStateConfigured);
       
  2350         if (iDeviceState == UsbShai::EUsbPeripheralStateConfigured)
       
  2351             {
       
  2352             if (aDeviceState == UsbShai::EUsbPeripheralStateUndefined)
       
  2353                 cancellationCode = KErrUsbCableDetached;
       
  2354             else if (aDeviceState == UsbShai::EUsbPeripheralStateAddress)
       
  2355                 cancellationCode = KErrUsbDeviceNotConfigured;
       
  2356             else if (aDeviceState == UsbShai::EUsbPeripheralStateDefault)
       
  2357                 cancellationCode = KErrUsbDeviceBusReset;
       
  2358             else
       
  2359                 cancellationCode = KErrUsbDeviceNotConfigured;
       
  2360             }
       
  2361         }
       
  2362     __KTRACE_OPT(KUSB, Kern::Printf("  %d --> %d", iDeviceState, aDeviceState));
       
  2363     iDeviceState = aDeviceState;
       
  2364     if (iValidInterface || iOwnsDeviceControl)
       
  2365         {
       
  2366         // This LDD may not own an interface. It could be some manager reenumerating
       
  2367         // after its subordinate LDDs have setup their interfaces.
       
  2368         if (deconfigured)
       
  2369             {
       
  2370             DeConfigure(cancellationCode);
       
  2371             }
       
  2372         else if (renumerateState)
       
  2373             {
       
  2374             // Update size of Ep0.
       
  2375             iEndpoint[0]->SetMaxPacketSize(iController->Ep0PacketSize());
       
  2376             // First cancel transfers on all endpoints
       
  2377             ResetInterface(KErrUsbInterfaceChange);
       
  2378             // Select main interface & latch in new endpoint set
       
  2379             SelectAlternateSetting(0);
       
  2380             // Here we go
       
  2381             StartEpReads();
       
  2382             }
       
  2383         }
       
  2384 
       
  2385     const TInt reqNo = (TInt) RDevUsbcClient::ERequestReEnumerate;
       
  2386     if (renumerateState && iRequestStatus[reqNo])
       
  2387         {
       
  2388         // This lot must be done if we are reenumerated
       
  2389         CompleteBufferRequest(iClient, reqNo, KErrNone);
       
  2390         }
       
  2391 
       
  2392     return KErrNone;
       
  2393     }
       
  2394 
       
  2395 
       
  2396 void DLddUsbcChannel::UpdateEndpointSizes()
       
  2397     {
       
  2398     // The regular ones.
       
  2399     TInt i = 0;
       
  2400     while ((++i <= KMaxEndpointsPerClient) && iEndpoint[i])
       
  2401         {
       
  2402         const TInt size = iController->EndpointPacketSize(this, iEndpoint[i]->RealEpNumber());
       
  2403         if (size < 0)
       
  2404             {
       
  2405             __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Packet size < 0 for ep %d", i));
       
  2406             continue;
       
  2407             }
       
  2408         iEndpoint[i]->SetMaxPacketSize(size);
       
  2409         }
       
  2410     __ASSERT_DEBUG(i == iNumberOfEndpoints + 1,
       
  2411                    Kern::Printf("  Error: iNumberOfEndpoints wrong (%d)", iNumberOfEndpoints));
       
  2412     }
       
  2413 
       
  2414 
       
  2415 DPlatChunkHw* DLddUsbcChannel::ReAllocate(TInt aBuffersize, DPlatChunkHw* aHwChunk, TUint32 aCacheAttribs)
       
  2416     {
       
  2417     DPlatChunkHw* chunk = aHwChunk;
       
  2418     if ((!chunk) || (chunk->iSize < aBuffersize))
       
  2419         {
       
  2420         if (chunk)
       
  2421             {
       
  2422             ClosePhysicalChunk(chunk);
       
  2423             }
       
  2424         __KTRACE_OPT(KUSB, Kern::Printf("ReAllocate need to get new chunk"));
       
  2425         chunk = Allocate(aBuffersize, aCacheAttribs);
       
  2426         }
       
  2427     return chunk;
       
  2428     }
       
  2429 
       
  2430 
       
  2431 DPlatChunkHw* DLddUsbcChannel::Allocate(TInt aBuffersize, TUint32 aCacheAttribs)
       
  2432     {
       
  2433     TUint32 physAddr = 0;
       
  2434     TUint32 size = Kern::RoundToPageSize(aBuffersize);
       
  2435 
       
  2436     if (Epoc::AllocPhysicalRam(size, physAddr) != KErrNone)
       
  2437         return NULL;
       
  2438 
       
  2439     DPlatChunkHw* HwChunk;
       
  2440     if (DPlatChunkHw::New(HwChunk, physAddr, aBuffersize, aCacheAttribs) != KErrNone)
       
  2441         {
       
  2442         Epoc::FreePhysicalRam(physAddr, size);
       
  2443         return NULL;
       
  2444         }
       
  2445 
       
  2446     return HwChunk;
       
  2447     }
       
  2448 
       
  2449 
       
  2450 TInt DLddUsbcChannel::DoRxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TBool aReEntrant)
       
  2451     {
       
  2452     TBool completeNow;
       
  2453     TInt err = aTUsbcEndpoint->CopyToClient(iClient, completeNow,iClientAsynchNotify[aEndpoint]->iClientBuffer);
       
  2454     if (completeNow)
       
  2455         {
       
  2456         aTUsbcEndpoint->SetClientReadPending(EFalse);
       
  2457         CompleteBufferRequest(iClient, aEndpoint, err);
       
  2458         }
       
  2459     aTUsbcEndpoint->TryToStartRead(aReEntrant);
       
  2460     return err;
       
  2461     }
       
  2462 
       
  2463 
       
  2464 void DLddUsbcChannel::DoRxCompleteNow(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint)
       
  2465     {
       
  2466     aTUsbcEndpoint->SetClientReadPending(EFalse);
       
  2467     CompleteBufferRequest(iClient, aEndpoint, KErrCancel);
       
  2468     }
       
  2469 
       
  2470 
       
  2471 void DLddUsbcChannel::DoTxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TInt aError)
       
  2472     {
       
  2473     aTUsbcEndpoint->SetClientWritePending(EFalse);
       
  2474     CompleteBufferRequest(iClient, aEndpoint, aError);
       
  2475     }
       
  2476 
       
  2477 
       
  2478 TBool DLddUsbcChannel::AlternateDeviceStateTestComplete()
       
  2479     {
       
  2480     TBool completeNow = EFalse;
       
  2481     const TInt reqNo = (TInt) RDevUsbcClient::ERequestAlternateDeviceStatusNotify;
       
  2482     if (iRequestStatus[reqNo])
       
  2483         {
       
  2484         // User req is outstanding
       
  2485         TUint32 deviceState;
       
  2486         if (iStatusFifo->GetDeviceQueuedStatus(deviceState) == KErrNone)
       
  2487             {
       
  2488             // Device state waiting to be sent userside
       
  2489             completeNow = ETrue;
       
  2490             __KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallback Notify status"));
       
  2491             iStatusChangeReq->Data()=deviceState;
       
  2492             iStatusChangePtr = NULL;
       
  2493             }
       
  2494         }
       
  2495     return completeNow;
       
  2496     }
       
  2497 
       
  2498 
       
  2499 void DLddUsbcChannel::EmergencyCompleteDfc(TAny* aDLddUsbcChannel)
       
  2500     {
       
  2501     ((DLddUsbcChannel*) aDLddUsbcChannel)->DoEmergencyComplete();
       
  2502     }
       
  2503 
       
  2504 
       
  2505 void DLddUsbcChannel::DeConfigure(TInt aErrorCode)
       
  2506     {
       
  2507     __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::DeConfigure()"));
       
  2508     // Called after deconfiguration. Cancels transfers on all endpoints.
       
  2509     ResetInterface(aErrorCode);
       
  2510     // Cancel the endpoint status notify request if it is outstanding.
       
  2511     const TInt KEpNotReq = RDevUsbcClient::ERequestEndpointStatusNotify;
       
  2512     if (iRequestStatus[KEpNotReq])
       
  2513         {
       
  2514         CancelNotifyEndpointStatus();
       
  2515         iRequestStatus[KEpNotReq]=NULL;
       
  2516         Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,aErrorCode);
       
  2517         }
       
  2518     // We have to reset the alternate setting number when the config goes away.
       
  2519      SelectAlternateSetting(0);
       
  2520     iAlternateSetting = 0;
       
  2521     }
       
  2522 
       
  2523 
       
  2524 void DLddUsbcChannel::StartEpReads()
       
  2525     {
       
  2526     // Queued after enumeration. Starts reads on all endpoints.
       
  2527     // The endpoint itself decides if it can do a read
       
  2528     TInt i;
       
  2529     for (i = 0; i <= iNumberOfEndpoints; i++)
       
  2530         {
       
  2531         // The endpoint itself will decide if it can read
       
  2532         iEndpoint[i]->TryToStartRead(EFalse);
       
  2533         }
       
  2534     }
       
  2535 
       
  2536 
       
  2537 void DLddUsbcChannel::ResetInterface(TInt aErrorCode)
       
  2538     {
       
  2539     // Called after change in alternate setting.  Cancels transfers on all endpoints
       
  2540     if (iValidInterface || iOwnsDeviceControl)
       
  2541         {
       
  2542         // Reset each endpoint except ep0
       
  2543         for (TInt i = 1; i <= iNumberOfEndpoints; i++)
       
  2544             {
       
  2545             __KTRACE_OPT(KUSB, Kern::Printf("Cancelling transfer ep=%d", i));
       
  2546             iEndpoint[i]->CancelTransfer(iClient,iClientAsynchNotify[i]->iClientBuffer);            // Copies data userside
       
  2547             iEndpoint[i]->AbortTransfer();                    // kills any ldd->pil outstanding transfers
       
  2548             iEndpoint[i]->iDmaBuffers->Flush();
       
  2549             if (iRequestStatus[i] != NULL)
       
  2550                 CompleteBufferRequest(iClient, i, aErrorCode);
       
  2551             iEndpoint[i]->SetClientWritePending(EFalse);
       
  2552             iEndpoint[i]->SetClientReadPending(EFalse);
       
  2553             }
       
  2554         }
       
  2555     }
       
  2556 
       
  2557 
       
  2558 void DLddUsbcChannel::AbortInterface()
       
  2559     {
       
  2560     // Called after when channel is closing
       
  2561     if (iValidInterface || iOwnsDeviceControl)
       
  2562         {
       
  2563         for (TInt i = 0; i <= iNumberOfEndpoints; i++)
       
  2564             {
       
  2565             if (iEndpoint[i])
       
  2566                 {
       
  2567                 // kills any LDD->PDD outstanding transfers
       
  2568                 iEndpoint[i]->AbortTransfer();
       
  2569                 }
       
  2570             }
       
  2571         }
       
  2572     }
       
  2573 
       
  2574 
       
  2575 void DLddUsbcChannel::ClosePhysicalChunk(DPlatChunkHw*& aHwChunk)
       
  2576     {
       
  2577     if (aHwChunk)
       
  2578         {
       
  2579          const TPhysAddr addr = aHwChunk->PhysicalAddress();
       
  2580          const TInt size = aHwChunk->iSize;
       
  2581         aHwChunk->Close(NULL);
       
  2582          Epoc::FreePhysicalRam(addr, size);
       
  2583         }
       
  2584     aHwChunk = NULL;
       
  2585     }
       
  2586 
       
  2587 
       
  2588 TInt DLddUsbcChannel::DoEmergencyComplete()
       
  2589     {
       
  2590     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::DoEmergencyComplete"));
       
  2591     // cancel any pending DFCs
       
  2592     // complete all client requests
       
  2593     for (TInt i = 0; i < KUsbcMaxRequests; i++)
       
  2594         {
       
  2595         if (iRequestStatus[i])
       
  2596             {
       
  2597             __KTRACE_OPT(KUSB, Kern::Printf("Complete request 0x%x", iRequestStatus[i]));
       
  2598 
       
  2599             if (i == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
       
  2600                 {
       
  2601 
       
  2602                 iDeviceStatusNeeded = EFalse;
       
  2603                 iStatusFifo->FlushQueue();
       
  2604 
       
  2605                 if (iStatusChangePtr)
       
  2606                     {
       
  2607                     iStatusChangeReq->Data() = iController->GetDeviceStatus();
       
  2608                     iStatusChangePtr = NULL;
       
  2609 
       
  2610                     if (iStatusChangeReq->IsReady())
       
  2611                         {
       
  2612                         iRequestStatus[i] = NULL;
       
  2613                         Kern::QueueRequestComplete(iClient, iStatusChangeReq,
       
  2614                                 KErrDisconnected);
       
  2615                         }
       
  2616                     }
       
  2617 
       
  2618                 }
       
  2619             else if (i == RDevUsbcClient::ERequestEndpointStatusNotify)
       
  2620                 {
       
  2621                     
       
  2622                    if (iEndpointStatusChangePtr)
       
  2623                     {
       
  2624                     TUint epBitmap = 0;
       
  2625                     for (TInt i = 0; i <= iNumberOfEndpoints; i++)
       
  2626                         {
       
  2627                         TInt v = iController->GetEndpointStatus(this, iEndpoint[i]->RealEpNumber());
       
  2628                         TUint b;
       
  2629                         (v == EEndpointStateStalled) ? b = 1 : b = 0;
       
  2630                         epBitmap |= b << i;
       
  2631                         }    
       
  2632 
       
  2633                     iEndpointStatusChangeReq->Data() = epBitmap;
       
  2634                     iEndpointStatusChangePtr = NULL;
       
  2635                     }
       
  2636 
       
  2637                 if (iEndpointStatusChangeReq->IsReady())
       
  2638                     {
       
  2639                     iRequestStatus[i] = NULL;
       
  2640                     Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,KErrDisconnected);
       
  2641                     }
       
  2642 
       
  2643                 }
       
  2644             else if (i == RDevUsbcClient::ERequestOtgFeaturesNotify)
       
  2645                 {
       
  2646                     
       
  2647                 if (iOtgFeatureChangePtr)
       
  2648                     {
       
  2649                     TUint8 features;
       
  2650                     iController->GetCurrentOtgFeatures(features);
       
  2651                     iOtgFeatureChangeReq->Data()=features;
       
  2652                     iOtgFeatureChangePtr = NULL;
       
  2653                     }
       
  2654                     
       
  2655                 if (iOtgFeatureChangeReq->IsReady())
       
  2656                     {
       
  2657                     iRequestStatus[i] = NULL;
       
  2658                     Kern::QueueRequestComplete(iClient, iOtgFeatureChangeReq,
       
  2659                             KErrDisconnected);
       
  2660                     }
       
  2661 
       
  2662                 }
       
  2663             else
       
  2664                 {
       
  2665                 CompleteBufferRequest(iClient, i, KErrDisconnected);
       
  2666                 }
       
  2667 
       
  2668             }
       
  2669         }
       
  2670 
       
  2671     iStatusCallbackInfo.Cancel();
       
  2672     iEndpointStatusCallbackInfo.Cancel();
       
  2673     iOtgFeatureCallbackInfo.Cancel();
       
  2674     return KErrNone;
       
  2675     }
       
  2676 
       
  2677 
       
  2678 void DLddUsbcChannel::PanicClientThread(TInt aReason)
       
  2679     {
       
  2680     Kern::ThreadKill(iClient, EExitPanic, aReason, KUsbLDDKillCat);
       
  2681     }
       
  2682 
       
  2683 
       
  2684 // ===============Endpoint====================
       
  2685 
       
  2686 // Constructor
       
  2687 TUsbcEndpoint::TUsbcEndpoint(DLddUsbcChannel* aLDD, DUsbClientController* aController,
       
  2688                              const TUsbcEndpointInfo* aEndpointInfo, TInt aEndpointNum,
       
  2689                              TInt aBandwidthPriority)
       
  2690     : iController(aController),
       
  2691       iEndpointInfo(aEndpointInfo->iType, aEndpointInfo->iDir, aEndpointInfo->iSize),
       
  2692       iClientReadPending(EFalse),
       
  2693       iClientWritePending(EFalse),
       
  2694       iEndpointNumber(aEndpointNum),
       
  2695       iRealEpNumber(-1),
       
  2696       iLdd(aLDD),
       
  2697       iError(KErrNone),
       
  2698       iRequestCallbackInfo(NULL),
       
  2699       iBytesTransferred(0),
       
  2700       iBandwidthPriority(aBandwidthPriority)
       
  2701     {
       
  2702      ResetTransferInfo();
       
  2703     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::TUsbcEndpoint 2"));
       
  2704     }
       
  2705 
       
  2706 
       
  2707 TInt TUsbcEndpoint::Construct()
       
  2708     {
       
  2709     iDmaBuffers = new TDmaBuf(&iEndpointInfo, iBandwidthPriority);
       
  2710     if (iDmaBuffers == NULL)
       
  2711         {
       
  2712         return KErrNoMemory;
       
  2713         }
       
  2714     const TInt r = iDmaBuffers->Construct(&iEndpointInfo);
       
  2715     if (r != KErrNone)
       
  2716         {
       
  2717         return r;
       
  2718         }
       
  2719     iRequestCallbackInfo = new TUsbcRequestCallback(iLdd,
       
  2720                                                     iEndpointNumber,
       
  2721                                                     TUsbcEndpoint::RequestCallback,
       
  2722                                                     this,
       
  2723                                                     iLdd->iDfcQ,
       
  2724                                                     KUsbRequestCallbackPriority);
       
  2725     if (iRequestCallbackInfo == NULL)
       
  2726         {
       
  2727         return KErrNoMemory;
       
  2728         }
       
  2729     return KErrNone;
       
  2730     }
       
  2731 
       
  2732 
       
  2733 TUsbcEndpoint::~TUsbcEndpoint()
       
  2734     {
       
  2735     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::~TUsbcEndpoint(%d)", iEndpointNumber));
       
  2736     AbortTransfer();
       
  2737     delete iRequestCallbackInfo;
       
  2738     delete iDmaBuffers;
       
  2739     }
       
  2740 
       
  2741 
       
  2742 void TUsbcEndpoint::RequestCallback(TAny* aTUsbcEndpoint)
       
  2743     {
       
  2744     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::RequestCallback"));
       
  2745     ((TUsbcEndpoint*) aTUsbcEndpoint)->EndpointComplete();
       
  2746     }
       
  2747 
       
  2748 
       
  2749 void TUsbcEndpoint::SetMaxPacketSize(TInt aSize)
       
  2750     {
       
  2751     iEndpointInfo.iSize = aSize;
       
  2752     iDmaBuffers->SetMaxPacketSize(aSize);
       
  2753     }
       
  2754 
       
  2755 
       
  2756 TInt TUsbcEndpoint::EndpointComplete()
       
  2757     {
       
  2758     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete ep=%d %d",
       
  2759                                     iEndpointNumber, iRequestCallbackInfo->iEndpointNum));
       
  2760 
       
  2761     if (iLdd->ChannelClosing())
       
  2762         {
       
  2763         __KTRACE_OPT(KUSB, Kern::Printf("We're going home -> completions no longer accepted"));
       
  2764         return KErrNone;
       
  2765         }
       
  2766 
       
  2767     UsbShai::TTransferDirection transferDir = iRequestCallbackInfo->iTransferDir;
       
  2768     TInt error = iRequestCallbackInfo->iError;
       
  2769 
       
  2770     switch (transferDir)
       
  2771         {
       
  2772 
       
  2773     case UsbShai::EControllerWrite:
       
  2774         {
       
  2775         __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete Write 2"));
       
  2776         if (!iDmaBuffers->TxIsActive())
       
  2777             {
       
  2778             __KTRACE_OPT(KUSB, Kern::Printf("  TX completion but !iDmaBuffers->TxIsActive()"));
       
  2779             break;
       
  2780             }
       
  2781 
       
  2782         iDmaBuffers->TxSetInActive();
       
  2783         TBool completeNow = EFalse;
       
  2784         iBytesTransferred += iRequestCallbackInfo->iTxBytes;
       
  2785         if (iClientWritePending)
       
  2786             {
       
  2787             //Complete Outstanding Write if necessary
       
  2788             iError = error;
       
  2789             if (iError != KErrNone)
       
  2790                 {
       
  2791                 completeNow = ETrue;
       
  2792                 if (iError == KErrPrematureEnd)                // Previous write could not be completed
       
  2793                     iError = KErrNone;
       
  2794                 }
       
  2795             else
       
  2796                 {
       
  2797                 if (iBytesTransferred == (TUint32) iTransferInfo.iTransferSize)
       
  2798                     {
       
  2799                     completeNow = ETrue;
       
  2800                     }
       
  2801                 else
       
  2802                     {
       
  2803                     iError = ContinueWrite();
       
  2804                     if (iError != KErrNone)
       
  2805                         completeNow = ETrue;
       
  2806                     }
       
  2807                 }
       
  2808             if (completeNow)
       
  2809                 {
       
  2810                 TxComplete();
       
  2811                 ResetTransferInfo();
       
  2812                 if (iEndpointNumber == 0)
       
  2813                     {
       
  2814                     iDmaBuffers->Flush();
       
  2815                     TryToStartRead(EFalse);
       
  2816                     }
       
  2817                 }
       
  2818             }
       
  2819         break;
       
  2820         }
       
  2821 
       
  2822     case UsbShai::EControllerRead:
       
  2823         {
       
  2824         // The first packet always contains the total #of bytes
       
  2825         const TInt byteCount = iRequestCallbackInfo->iPacketSize[0];
       
  2826         const TInt packetCount = iRequestCallbackInfo->iRxPackets;
       
  2827         iDmaBuffers->ReadXferComplete(byteCount, packetCount, error);
       
  2828 
       
  2829         // We queue the dfc if we can complete the read, i.e. if we are reading a packet,
       
  2830         // or if we have enough data to satisfy a read data request.
       
  2831         if (iClientReadPending)
       
  2832             {
       
  2833             //Complete outstanding read
       
  2834             __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete Read 3 (bytes "
       
  2835                                             "available=%d)", iDmaBuffers->RxBytesAvailable()));
       
  2836             TInt bytesReqd = iTransferInfo.iTransferSize - iBytesTransferred;
       
  2837             TBool completeNow = EFalse;
       
  2838 
       
  2839             if (iTransferInfo.iTransferType == ETransferTypeReadPacket ||
       
  2840                 iTransferInfo.iTransferType == ETransferTypeReadOneOrMore)
       
  2841                 {
       
  2842                 // Always complete on a packet read
       
  2843                 completeNow = ETrue;
       
  2844                 }
       
  2845             else if (iTransferInfo.iTransferType == ETransferTypeReadData)
       
  2846                 {
       
  2847                 // Complete only if enough data is present
       
  2848                 if (iDmaBuffers->RxBytesAvailable() >= bytesReqd)
       
  2849                     completeNow = ETrue;
       
  2850                 }
       
  2851             else if (iTransferInfo.iTransferType == ETransferTypeReadUntilShort)
       
  2852                 {
       
  2853                 // Complete if enough data is present or if a short packet has been delivered
       
  2854                 const TInt maxPacketSize = iEndpointInfo.iSize;
       
  2855                 const TInt lastPacketSize = iRequestCallbackInfo->iPacketSize[packetCount - 1];
       
  2856                 if (lastPacketSize < maxPacketSize)
       
  2857                     completeNow = ETrue;
       
  2858                 else if (iDmaBuffers->RxBytesAvailable() >= bytesReqd)
       
  2859                     completeNow = ETrue;
       
  2860                 else
       
  2861                     {
       
  2862                     const TUint type = iEndpointInfo.iType;
       
  2863                     if ((type == UsbShai::KUsbEpTypeBulk) && (lastPacketSize & (maxPacketSize - 1)))
       
  2864                         {
       
  2865                         completeNow = ETrue;
       
  2866                         }
       
  2867                     else if ((type != UsbShai::KUsbEpTypeBulk) &&
       
  2868                              (lastPacketSize > maxPacketSize) &&
       
  2869                              (lastPacketSize % maxPacketSize))
       
  2870                         {
       
  2871                         completeNow = ETrue;
       
  2872                         }
       
  2873                     }
       
  2874                 }
       
  2875             if (completeNow)
       
  2876                 {
       
  2877                 iError = error;
       
  2878                 RxComplete(EFalse);
       
  2879                 iClientReadPending = EFalse;
       
  2880                 }
       
  2881             }
       
  2882         iDmaBuffers->RxSetInActive();
       
  2883         if (error != KErrNone)
       
  2884             {
       
  2885             return error;
       
  2886             }
       
  2887         if (TryToStartRead(EFalse) != KErrNone)
       
  2888             {
       
  2889 //            if (iEndpointNumber != 0)
       
  2890 //                Kern::Printf("EndpointComplete couldn't start read on ep=%d", iEndpointNumber);
       
  2891             }
       
  2892         break;
       
  2893         }
       
  2894 
       
  2895     default:
       
  2896         // shouldn't get here
       
  2897         break;
       
  2898         }
       
  2899 
       
  2900     return KErrNone;
       
  2901     }
       
  2902 
       
  2903 
       
  2904 void TUsbcEndpoint::TxComplete()
       
  2905     {
       
  2906     iLdd->DoTxComplete(this, iEndpointNumber, iError);
       
  2907     }
       
  2908 
       
  2909 
       
  2910 TInt TUsbcEndpoint::RxComplete(TBool aReEntrant)
       
  2911     {
       
  2912     return iLdd->DoRxComplete(this, iEndpointNumber, aReEntrant);
       
  2913     }
       
  2914 
       
  2915 
       
  2916 void TUsbcEndpoint::RxCompleteNow()
       
  2917     {
       
  2918     iLdd->DoRxCompleteNow(this, iEndpointNumber);
       
  2919     }
       
  2920 
       
  2921 
       
  2922 TInt TUsbcEndpoint::CopyToClient(DThread* aClient, TClientBuffer *aTcb)
       
  2923     {
       
  2924     TBool completeNow;
       
  2925     return CopyToClient(aClient, completeNow,aTcb);
       
  2926     }
       
  2927 
       
  2928 
       
  2929 TInt TUsbcEndpoint::CopyToClient(DThread* aClient, TBool& aCompleteNow, TClientBuffer *aTcb)
       
  2930     {
       
  2931     TInt err;
       
  2932     const TInt length = iTransferInfo.iTransferSize;
       
  2933     const TBool KReadData = EFalse;
       
  2934     const TBool KReadUntilShort = ETrue;
       
  2935 
       
  2936     __KTRACE_OPT(KUSB, Kern::Printf("CopyToClient: length = %d", length));
       
  2937 
       
  2938     if (iTransferInfo.iTransferType == ETransferTypeReadPacket)
       
  2939         {
       
  2940         err = iDmaBuffers->RxCopyPacketToClient(aClient, aTcb, length);
       
  2941         aCompleteNow = ETrue;
       
  2942         }
       
  2943     else if (iTransferInfo.iTransferType == ETransferTypeReadOneOrMore)
       
  2944         {
       
  2945         err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
       
  2946                                               KReadData, aCompleteNow);
       
  2947         aCompleteNow = ETrue;
       
  2948         }
       
  2949     else if (iTransferInfo.iTransferType == ETransferTypeReadUntilShort)
       
  2950         {
       
  2951         err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
       
  2952                                               KReadUntilShort, aCompleteNow);
       
  2953         }
       
  2954     else
       
  2955         {
       
  2956         err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
       
  2957                                               KReadData, aCompleteNow);
       
  2958         }
       
  2959 
       
  2960     if (aCompleteNow)
       
  2961         {
       
  2962         ResetTransferInfo();
       
  2963         SetClientReadPending(EFalse);
       
  2964         }
       
  2965 
       
  2966     return err;
       
  2967     }
       
  2968 
       
  2969 
       
  2970 TInt TUsbcEndpoint::TryToStartRead(TBool aReEntrant)
       
  2971     {
       
  2972     __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead 1 ep=%d", iEndpointNumber));
       
  2973     TInt r = KErrNone;
       
  2974     if (iEndpointInfo.iDir != UsbShai::KUsbEpDirOut &&
       
  2975         iEndpointInfo.iDir != UsbShai::KUsbEpDirBidirect)
       
  2976         {
       
  2977         // Verify ep direction
       
  2978         __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead wrong direction ep=%d", iEndpointNumber));
       
  2979         return KErrUsbEpBadDirection;
       
  2980         }
       
  2981 
       
  2982     if (iEndpointNumber == 0)
       
  2983         {
       
  2984         // Can't issue an Ep0 read if reader or writer is active
       
  2985         if (iDmaBuffers->TxIsActive())
       
  2986             {
       
  2987             __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead ep0 Tx already active FATAL"));
       
  2988             return KErrUsbEpNotReady;
       
  2989             }
       
  2990         if (iDmaBuffers->RxIsActive())
       
  2991             {
       
  2992             __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead ep0 Rx already active non-FATAL"));
       
  2993             }
       
  2994         }
       
  2995 
       
  2996     if (!(iDmaBuffers->RxIsActive()))
       
  2997         {
       
  2998         TUint8* bufferAddr;
       
  2999         TPhysAddr physAddr;
       
  3000         TUsbcPacketArray* indexArray;
       
  3001         TUsbcPacketArray* sizeArray;
       
  3002         TInt length;
       
  3003         r = iDmaBuffers->RxGetNextXfer(bufferAddr, indexArray, sizeArray, length, physAddr);
       
  3004         if (r == KErrNone)
       
  3005             {
       
  3006             iDmaBuffers->RxSetActive();
       
  3007             iRequestCallbackInfo->SetRxBufferInfo(bufferAddr, physAddr, indexArray, sizeArray, length);
       
  3008 
       
  3009             __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead 2 bufferAddr=0x%08x", bufferAddr));
       
  3010 
       
  3011             r = iController->SetupReadBuffer(*iRequestCallbackInfo);
       
  3012             if (r != KErrNone)
       
  3013                 {
       
  3014                 iDmaBuffers->RxSetInActive();
       
  3015                 __KTRACE_OPT(KPANIC, Kern::Printf("  Error: TryToStartRead controller rejects read"));
       
  3016                 }
       
  3017             }
       
  3018         else
       
  3019             {
       
  3020             if (iClientReadPending)
       
  3021                 {
       
  3022                 // Deadlock, try to resolve it by draining buffer into descriptor
       
  3023                 if (!aReEntrant)
       
  3024                     {
       
  3025                     RxComplete(ETrue);
       
  3026                     }
       
  3027                 else
       
  3028                     {
       
  3029                     // we are stuck, better complete userside otherwise the userside request will hang
       
  3030                     RxCompleteNow();
       
  3031                     }
       
  3032                 }
       
  3033             }
       
  3034         }
       
  3035     return r;
       
  3036     }
       
  3037 
       
  3038 
       
  3039 TInt TUsbcEndpoint::TryToStartWrite(TEndpointTransferInfo* pTfr)
       
  3040     {
       
  3041     __KTRACE_OPT(KUSB, Kern::Printf("TryToStartWrite 1 ep=%d", iEndpointNumber));
       
  3042     if (iEndpointInfo.iDir != UsbShai::KUsbEpDirIn &&
       
  3043         iEndpointInfo.iDir != UsbShai::KUsbEpDirBidirect)
       
  3044         {
       
  3045         // Verify ep direction
       
  3046         return KErrUsbEpBadDirection;
       
  3047         }
       
  3048     if (iEndpointNumber == 0)
       
  3049         {
       
  3050         // Can't issue an Ep0 write if unread data is available or writer is active
       
  3051         if (iDmaBuffers->TxIsActive() || !iDmaBuffers->IsReaderEmpty())
       
  3052             {
       
  3053             return KErrUsbEpNotReady;
       
  3054             }
       
  3055         if (iDmaBuffers->RxIsActive())
       
  3056             {
       
  3057             // if a reader is active then cancel the read
       
  3058             iDmaBuffers->RxSetInActive();
       
  3059             iController->CancelReadBuffer(iLdd, iRealEpNumber);
       
  3060             }
       
  3061         }
       
  3062     SetTransferInfo(pTfr);
       
  3063     ContinueWrite();
       
  3064     return KErrNone;
       
  3065     }
       
  3066 
       
  3067 
       
  3068 TInt TUsbcEndpoint::ContinueWrite()
       
  3069     {
       
  3070     __KTRACE_OPT(KUSB, Kern::Printf("ContinueWrite 2"));
       
  3071     TUint8* bufferAddr;
       
  3072     TPhysAddr physAddr;
       
  3073     TInt bufferLength;
       
  3074     TInt r = iDmaBuffers->TxGetNextXfer(bufferAddr, bufferLength, physAddr);
       
  3075     if (r != KErrNone)                                            // probably already active
       
  3076         return r;
       
  3077     __KTRACE_OPT(KUSB, Kern::Printf("ContinueWrite 3"));
       
  3078     iDmaBuffers->TxSetActive();
       
  3079     TBool zlpReqd = EFalse;
       
  3080     TUint32 transferSize = iTransferInfo.iTransferSize;
       
  3081     TInt length = Min(transferSize - iBytesTransferred, (TUint32) bufferLength);
       
  3082     if (iBytesTransferred+length>=transferSize)
       
  3083         {
       
  3084         // only send a zlp if this is the last buffer of the transfer
       
  3085         zlpReqd = iTransferInfo.iZlpReqd;
       
  3086         }
       
  3087     r = iDmaBuffers->TxStoreData(iLdd->Client(), iLdd->GetClientBuffer(iEndpointNumber), length, iBytesTransferred);
       
  3088     if (r != KErrNone)
       
  3089         return r;
       
  3090     iDmaBuffers->TxSetActive();
       
  3091     iRequestCallbackInfo->SetTxBufferInfo(bufferAddr, physAddr, length);
       
  3092     iRequestCallbackInfo->iZlpReqd = zlpReqd;
       
  3093 #if 0
       
  3094     for (TInt i = 0; i < iRequestCallbackInfo->iLength; i++)
       
  3095         {
       
  3096         __KTRACE_OPT(KUSB, Kern::Printf("Buffer[%d] = 0x%02x", i, iRequestCallbackInfo->iBufferStart[i]));
       
  3097         }
       
  3098 #endif
       
  3099     r = iController->SetupWriteBuffer(*iRequestCallbackInfo);
       
  3100     return r;
       
  3101     }
       
  3102 
       
  3103 
       
  3104 void TUsbcEndpoint::CancelTransfer(DThread* aThread, TClientBuffer *aTcb)
       
  3105     {
       
  3106     __KTRACE_OPT(KUSB, Kern::Printf("CancelTransfer"));
       
  3107     if (iDmaBuffers != NULL)
       
  3108         {
       
  3109         if (iClientWritePending)
       
  3110             {
       
  3111             __KTRACE_OPT(KUSB, Kern::Printf("  (iClientWritePending)"));
       
  3112             iClientWritePending = EFalse;
       
  3113             iController->CancelWriteBuffer(iLdd, iRealEpNumber);
       
  3114             iDmaBuffers->TxSetInActive();
       
  3115             }
       
  3116         if (iClientReadPending)
       
  3117             {
       
  3118             __KTRACE_OPT(KUSB, Kern::Printf("  (iClientReadPending)"));
       
  3119             iClientReadPending = EFalse;
       
  3120             CopyToClient(aThread,aTcb);
       
  3121             }
       
  3122         }
       
  3123     }
       
  3124 
       
  3125 
       
  3126 void TUsbcEndpoint::AbortTransfer()
       
  3127     {
       
  3128     __KTRACE_OPT(KUSB, Kern::Printf("Abort Transfer"));
       
  3129     if (iDmaBuffers != NULL)
       
  3130         {
       
  3131         if (iDmaBuffers->TxIsActive())
       
  3132             {
       
  3133             __KTRACE_OPT(KUSB, Kern::Printf("  (iClientWritePending)"));
       
  3134             iController->CancelWriteBuffer(iLdd, iRealEpNumber);
       
  3135             iDmaBuffers->TxSetInActive();
       
  3136             }
       
  3137         if (iDmaBuffers->RxIsActive())
       
  3138             {
       
  3139             __KTRACE_OPT(KUSB, Kern::Printf("  (iClientReadPending)"));
       
  3140             iController->CancelReadBuffer(iLdd, iRealEpNumber);
       
  3141             iDmaBuffers->RxSetInActive();
       
  3142             }
       
  3143         iRequestCallbackInfo->iDfc.Cancel();
       
  3144         }
       
  3145     }
       
  3146 
       
  3147 
       
  3148 TUsbcAlternateSettingList::TUsbcAlternateSettingList()
       
  3149     : iNext(NULL),
       
  3150       iNumberOfEndpoints(0),
       
  3151       iSetting(0)
       
  3152     {
       
  3153     for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
       
  3154         {
       
  3155         iEpNumDeOrderedByBufSize[i] = -1;
       
  3156         iEndpoint[i] = NULL;
       
  3157         }
       
  3158     }
       
  3159 
       
  3160 
       
  3161 TUsbcAlternateSettingList::~TUsbcAlternateSettingList()
       
  3162     {
       
  3163     __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAlternateSettingList::~TUsbcAlternateSettingList()"));
       
  3164     for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
       
  3165         {
       
  3166         delete iEndpoint[i];
       
  3167         }
       
  3168     }
       
  3169 
       
  3170 
       
  3171 TUsbcDeviceStatusQueue::TUsbcDeviceStatusQueue()
       
  3172     {
       
  3173     FlushQueue();
       
  3174     }
       
  3175 
       
  3176 
       
  3177 void TUsbcDeviceStatusQueue::FlushQueue()
       
  3178     {
       
  3179     for (TInt i = 0; i < KUsbDeviceStatusQueueDepth; i++)
       
  3180         {
       
  3181         iDeviceStatusQueue[i] = KUsbDeviceStatusNull;
       
  3182         }
       
  3183     iStatusQueueHead = 0;
       
  3184     }
       
  3185 
       
  3186 
       
  3187 void TUsbcDeviceStatusQueue::AddStatusToQueue(TUint32 aDeviceStatus)
       
  3188     {
       
  3189     // Only add a new status if it is not a duplicate of the one at the head of the queue
       
  3190     if (!(iStatusQueueHead != 0 &&
       
  3191           iDeviceStatusQueue[iStatusQueueHead - 1] == aDeviceStatus))
       
  3192         {
       
  3193         if (iStatusQueueHead == KUsbDeviceStatusQueueDepth)
       
  3194             {
       
  3195             // Discard item at tail of queue
       
  3196             TUint32 status;
       
  3197             GetDeviceQueuedStatus(status);
       
  3198             }
       
  3199         iDeviceStatusQueue[iStatusQueueHead] = aDeviceStatus;
       
  3200         iStatusQueueHead++;
       
  3201         }
       
  3202     }
       
  3203 
       
  3204 
       
  3205 TInt TUsbcDeviceStatusQueue::GetDeviceQueuedStatus(TUint32& aDeviceStatus)
       
  3206     {
       
  3207     TInt r = KErrNone;
       
  3208     if (iStatusQueueHead <= 0)
       
  3209         {
       
  3210         r = KErrGeneral;
       
  3211         aDeviceStatus = KUsbDeviceStatusNull;
       
  3212         }
       
  3213     else
       
  3214         {
       
  3215         aDeviceStatus = iDeviceStatusQueue[0];
       
  3216         for(TInt i = 1; i < KUsbDeviceStatusQueueDepth; i++)
       
  3217             {
       
  3218             TUint32 s = iDeviceStatusQueue[i];
       
  3219             iDeviceStatusQueue[i - 1] = s;
       
  3220             }
       
  3221         iStatusQueueHead--;
       
  3222         iDeviceStatusQueue[KUsbDeviceStatusQueueDepth - 1] = KUsbDeviceStatusNull;
       
  3223         }
       
  3224     return r;
       
  3225     }
       
  3226 
       
  3227 void TClientAsynchNotify::Reset()
       
  3228 {
       
  3229     iBufferRequest->Reset();
       
  3230     iClientBuffer=NULL;
       
  3231 }
       
  3232 
       
  3233 //---