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