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