os/kernelhwsrv/kerneltest/e32utils/testusbcldd/src/dlddtestusbcchannel.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32utils/testusbcldd/src/dlddtestusbcchannel.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1140 @@
     1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// f32test\testusbcldd\src\dlddtestusbcchannel.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include "usbcdesc.h"
    1.22 +#include "dtestusblogdev.h"
    1.23 +#include "testusbc.h"
    1.24 +
    1.25 +extern TDynamicDfcQue* gDfcQ;
    1.26 +
    1.27 +const TUsbcEndpointData DLddTestUsbcChannel::iEndpointData[] =
    1.28 +	{
    1.29 +		{{KUsbEpSize64,	(KUsbEpTypeControl | KUsbEpDirBidirect)}, EFalse},
    1.30 +		{{KUsbEpSize64,	(KUsbEpTypeBulk	   | KUsbEpDirOut)}, EFalse},
    1.31 +		{{KUsbEpSize64,	(KUsbEpTypeBulk	   | KUsbEpDirIn )}, EFalse},
    1.32 +		{{KUsbEpSize64,	(KUsbEpTypeBulk	   | KUsbEpDirOut)}, EFalse},
    1.33 +		{{KUsbEpSize64,	(KUsbEpTypeBulk	   | KUsbEpDirIn )}, EFalse},
    1.34 +		{{KUsbEpNotAvailable, KUsbEpNotAvailable}, EFalse}
    1.35 +	};
    1.36 +
    1.37 +// The EKA1 base class needs a DLogicalDevice* for its constructor
    1.38 +DLddTestUsbcChannel::DLddTestUsbcChannel(RPointerArray<DTestUsbcEndpoint>& aEndpoints) :
    1.39 +	iDescriptors(NULL),
    1.40 +	iIfcSet(this, 0),
    1.41 +	iEndpoints(aEndpoints),
    1.42 +	iDeviceState(EUsbcDeviceStateConfigured)
    1.43 +	{
    1.44 +	iClient = &Kern::CurrentThread();
    1.45 +	iClient->Open();
    1.46 +	}
    1.47 +
    1.48 +DLddTestUsbcChannel::~DLddTestUsbcChannel()
    1.49 +	{
    1.50 +	}
    1.51 +	
    1.52 +TInt DLddTestUsbcChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
    1.53 +    {
    1.54 +	TInt err = KErrNone;
    1.55 +    // Setup LDD for receiving client messages
    1.56 +    SetDfcQ(gDfcQ);
    1.57 +    iMsgQ.Receive();
    1.58 +
    1.59 +	_LIT(KEmptyString, "");
    1.60 +	err = iDescriptors.Init(
    1.61 +							TUsbcDeviceDescriptor::New(0, 0, 0, 0, 0, 0, 0, 0),
    1.62 +							TUsbcConfigDescriptor::New(0, ETrue, ETrue, 0),
    1.63 +							TUsbcLangIdDescriptor::New(0),
    1.64 +							TUsbcStringDescriptor::New(KEmptyString),
    1.65 +							TUsbcStringDescriptor::New(KEmptyString),
    1.66 +							TUsbcStringDescriptor::New(KEmptyString),
    1.67 +							TUsbcStringDescriptor::New(KEmptyString)
    1.68 +							);
    1.69 +    
    1.70 +    return err;
    1.71 +    }
    1.72 +
    1.73 +void DLddTestUsbcChannel::HandleMsg(TMessageBase* aMsg)
    1.74 +	{
    1.75 +	TThreadMessage& m = *(TThreadMessage*)aMsg;
    1.76 +	TInt id = m.iValue;
    1.77 +	if (id == (TInt)ECloseMsg)
    1.78 +		{
    1.79 +		m.Complete(KErrNone, EFalse);
    1.80 +		return;
    1.81 +		}
    1.82 +	else if (id == KMaxTInt)
    1.83 +		{
    1.84 +		// Cancel request.
    1.85 +		TInt mask = m.Int0();
    1.86 +		DTestUsbcEndpoint* pEndpoint = NULL;
    1.87 +		switch (mask)
    1.88 +			{
    1.89 +			case RDevUsbcClient::ERequestEp0Cancel:
    1.90 +				pEndpoint = iEndpoints[0];
    1.91 +				pEndpoint->DoCancel();
    1.92 +				break;
    1.93 +			case RDevUsbcClient::ERequestEp1Cancel:
    1.94 +				pEndpoint = iEndpoints[FindRealEndpoint(1)];
    1.95 +				pEndpoint->DoCancel();
    1.96 +				break;
    1.97 +			case RDevUsbcClient::ERequestEp2Cancel:
    1.98 +				pEndpoint = iEndpoints[FindRealEndpoint(2)];
    1.99 +				pEndpoint->DoCancel();
   1.100 +				break;
   1.101 +			case RDevUsbcClient::ERequestEp3Cancel:
   1.102 +				pEndpoint = iEndpoints[FindRealEndpoint(3)];
   1.103 +				pEndpoint->DoCancel();
   1.104 +				break;
   1.105 +			case RDevUsbcClient::ERequestEp4Cancel:
   1.106 +				pEndpoint = iEndpoints[FindRealEndpoint(4)];
   1.107 +				pEndpoint->DoCancel();
   1.108 +				break;
   1.109 +			case RDevUsbcClient::ERequestEp5Cancel:
   1.110 +				pEndpoint = iEndpoints[FindRealEndpoint(5)];
   1.111 +				pEndpoint->DoCancel();
   1.112 +				break;
   1.113 +			case RDevUsbcClient::ERequestAlternateDeviceStatusNotifyCancel:
   1.114 +				CancelAlternateDeviceStatusNotify();
   1.115 +				break;
   1.116 +			default:
   1.117 +				m.Complete(KErrNotSupported, ETrue);
   1.118 +				return;
   1.119 +			}
   1.120 +		m.Complete(KErrNone, ETrue);
   1.121 +		return;
   1.122 +		}
   1.123 +
   1.124 +	if (id < 0)
   1.125 +		{
   1.126 +		// DoRequest
   1.127 +		TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
   1.128 +		DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
   1.129 +		m.Complete(KErrNone, ETrue);
   1.130 +		}
   1.131 +	else
   1.132 +		{
   1.133 +		// DoControl
   1.134 +		TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
   1.135 +		m.Complete(r, ETrue);
   1.136 +		}
   1.137 +	}
   1.138 +
   1.139 +TInt DLddTestUsbcChannel::DoCancel(TInt /*aReqNo*/)
   1.140 +	{
   1.141 +	return KErrNone;
   1.142 +	}
   1.143 +
   1.144 +void DLddTestUsbcChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
   1.145 +	{
   1.146 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest 0x%08x"),aReqNo));
   1.147 +		TInt r = KErrNone;
   1.148 +		//If request is ep number then do a transfer request.
   1.149 +		if(aReqNo > KUsbcMaxEpNumber)
   1.150 +			{
   1.151 +			if (aReqNo == RDevTestUsbcClient::ETestRequestNotifyEndpointStatus)
   1.152 +				{
   1.153 +				__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestRequestNotifyEndpointStatus")));
   1.154 +				r = HostEndpointStatusNotify((TInt)a1, aStatus);
   1.155 +				}
   1.156 +			else if (aReqNo == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
   1.157 +				{
   1.158 +				__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ERequestAlternateDeviceStatusNotify")));
   1.159 +				r = SetAlternateDeviceStatusNotify(aStatus, (TUint*)a1);
   1.160 +				}
   1.161 +			else if (aReqNo == RDevUsbcClient::ERequestReEnumerate)
   1.162 +				{
   1.163 +				__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ERequestReEnumerate")));
   1.164 +				r = ReEnumerate((TRequestStatus*)a1);
   1.165 +				}
   1.166 +			else
   1.167 +				{
   1.168 +				Kern::RequestComplete(iClient, aStatus, KErrNotSupported);
   1.169 +				}
   1.170 +			}
   1.171 +		else
   1.172 +			{
   1.173 +			r = DoTransferAsyncReq(aReqNo, a1, a2, *aStatus);
   1.174 +			}
   1.175 +			
   1.176 +	if (r != KErrNone)
   1.177 +		{
   1.178 +		Kern::RequestComplete(iClient, aStatus, r);
   1.179 +		}			
   1.180 +	}
   1.181 +
   1.182 +TInt DLddTestUsbcChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
   1.183 +	{
   1.184 +	TInt r=KErrNone;
   1.185 +	TDes8& a1Buf = *((TDes8*)a1);
   1.186 +	TDes8& a2Buf = *((TDes8*)a2);
   1.187 +	TPtrC8 pZeroDesc(NULL,0);
   1.188 +
   1.189 +
   1.190 +	switch (aFunction)
   1.191 +		{
   1.192 +	case RDevUsbcClient::EControlEndpointZeroRequestError:
   1.193 +		{
   1.194 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlEndpointZeroRequestError")));
   1.195 +		r = KErrNone;
   1.196 +		break;
   1.197 +		}
   1.198 +	
   1.199 +	case RDevUsbcClient::EControlEndpointCaps:
   1.200 +		{
   1.201 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlEndpointCaps")));
   1.202 +		r = __THREADWRITE(iClient, a1, pZeroDesc);
   1.203 +		if(r == KErrNone)
   1.204 +			{
   1.205 +			TBuf8<KMaxTUint8> aBuf;
   1.206 +			memclr(&aBuf, sizeof(aBuf));
   1.207 +        	TPtr8 endpointCfg((TUint8*)&aBuf,0,sizeof(aBuf));
   1.208 +		
   1.209 +			r = Kern::ThreadDesRead(iClient,a1,endpointCfg,0,0);
   1.210 +			if(r == KErrNone)
   1.211 +				{
   1.212 +				endpointCfg.Copy(reinterpret_cast<const TUint8*>(iEndpointData), 
   1.213 +								 Min(endpointCfg.MaxLength(), 
   1.214 +								 sizeof(TUsbcEndpointData[5])));
   1.215 +				r = Kern::ThreadDesWrite(iClient,a1,endpointCfg,0,KTruncateToMaxLength,iClient);
   1.216 +				}
   1.217 +			}
   1.218 +			
   1.219 +		if(r != KErrNone)
   1.220 +			{
   1.221 +			__THREADPANIC(iClient, r);
   1.222 +			}
   1.223 +
   1.224 +		break;
   1.225 +		}
   1.226 +	
   1.227 +	case RDevUsbcClient::EControlDeviceCaps:
   1.228 +		{
   1.229 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlDeviceCaps")));
   1.230 +		r = __THREADWRITE(iClient, a1, pZeroDesc);
   1.231 +		if(r!=KErrNone) 
   1.232 +			{
   1.233 +			__THREADPANIC(iClient, r);
   1.234 +			}
   1.235 +		TUsbDeviceCaps caps;
   1.236 +		caps().iTotalEndpoints = KMaxEndpointsPerClient;
   1.237 +		caps().iConnect = ETrue;
   1.238 +		caps().iSelfPowered = ETrue;
   1.239 +		caps().iRemoteWakeup = ETrue;
   1.240 +		TBuf8<KMaxTUint8> aBuf;
   1.241 +        memclr(&aBuf, sizeof(aBuf));
   1.242 + 		TPtr8 cfg((TUint8*)&aBuf,0,sizeof(aBuf));
   1.243 + 		r=Kern::ThreadDesRead(iClient,a1,cfg,0,0);
   1.244 +		cfg = caps.Left(Min(caps.Length(), cfg.MaxLength()));
   1.245 +		r=Kern::ThreadDesWrite(iClient,a1,cfg,0,KTruncateToMaxLength,iClient);
   1.246 +		break;
   1.247 +		}
   1.248 +	
   1.249 +	case RDevUsbcClient::EControlDeviceStatus:
   1.250 +		{
   1.251 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlDeviceStatus")));
   1.252 +		r = __THREADRAWWRITE(iClient, a1, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState));
   1.253 +		if(r != KErrNone)
   1.254 +			{
   1.255 +			__THREADPANIC(iClient, r);
   1.256 +			}
   1.257 +		break;
   1.258 +		}
   1.259 +		
   1.260 +	case RDevUsbcClient::EControlHaltEndpoint:
   1.261 +		{
   1.262 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlHaltEndpoint")));
   1.263 +		r = HaltClearEndpoint(ETrue, (TInt)a1);
   1.264 +		break;
   1.265 +		}
   1.266 +	
   1.267 +	case RDevUsbcClient::EControlGetDeviceDescriptor:
   1.268 +		{
   1.269 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetDeviceDescriptor")));
   1.270 +		r = __THREADWRITE(iClient, a1, pZeroDesc);
   1.271 +		if(r != KErrNone)
   1.272 +			{
   1.273 +			__THREADPANIC(iClient, r);
   1.274 +			}
   1.275 +		r = iDescriptors.GetDeviceDescriptorTC(iClient, a1Buf);
   1.276 +		break;
   1.277 +		}
   1.278 +	
   1.279 +	case RDevUsbcClient::EControlSetDeviceDescriptor:
   1.280 +		{
   1.281 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetDeviceDescriptor")));
   1.282 +		r = iDescriptors.SetDeviceDescriptorTC(iClient, a1Buf);
   1.283 +		break;
   1.284 +		}
   1.285 +		
   1.286 +	case RDevUsbcClient::EControlGetDeviceDescriptorSize:
   1.287 +		{
   1.288 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetDeviceDescriptorSize")));
   1.289 +		if(a1 != NULL)
   1.290 +			{
   1.291 +			const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Device), sizeof(KUsbDescSize_Device));
   1.292 +			r = __THREADWRITE(iClient, a1, size);
   1.293 +			}
   1.294 +		else
   1.295 +			{
   1.296 +			r = KErrArgument;
   1.297 +			}
   1.298 +		break;
   1.299 +		}
   1.300 +	
   1.301 +	case RDevUsbcClient::EControlGetConfigurationDescriptor:
   1.302 +		{
   1.303 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetConfigurationDescriptor")));
   1.304 +		r = __THREADWRITE(iClient, a1, pZeroDesc);		// set client descriptor length to zero
   1.305 +		if(r != KErrNone)
   1.306 +			{
   1.307 +			__THREADPANIC(iClient, r);
   1.308 +			}
   1.309 +		r = iDescriptors.GetConfigurationDescriptorTC(iClient, a1Buf);
   1.310 +		break;
   1.311 +		}
   1.312 +	
   1.313 +	case RDevUsbcClient::EControlSetConfigurationDescriptor:
   1.314 +		{
   1.315 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetConfigurationDescriptor")));
   1.316 +		r = iDescriptors.SetConfigurationDescriptorTC(iClient, a1Buf);
   1.317 +		break;
   1.318 +		}
   1.319 +	
   1.320 +	case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
   1.321 +		{
   1.322 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetConfigurationDescriptorSize")));
   1.323 +		if(a1 != NULL)
   1.324 +			{
   1.325 +			const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Config), sizeof(KUsbDescSize_Config));
   1.326 +			r = __THREADWRITE(iClient, a1, size);
   1.327 +			}
   1.328 +		else
   1.329 +			{
   1.330 +			r=KErrArgument;
   1.331 +			}
   1.332 +		break;
   1.333 +		}
   1.334 +	
   1.335 +	case RDevUsbcClient::EControlGetInterfaceDescriptor:
   1.336 +		{
   1.337 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetInterfaceDescriptor")));
   1.338 +		r = iDescriptors.GetInterfaceDescriptorTC(iClient, a2Buf, 0, (TInt)a1);
   1.339 +		break;
   1.340 +		}
   1.341 +		
   1.342 +	case RDevUsbcClient::EControlSetInterfaceDescriptor:
   1.343 +		{
   1.344 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetInterfaceDescriptor")));
   1.345 +		TBuf8<KUsbDescSize_Interface> new_ifc;
   1.346 +		r = __THREADWRITE(iClient, a2, new_ifc);
   1.347 +		if (r != KErrNone)
   1.348 +			{
   1.349 +			break;
   1.350 +			}
   1.351 +		r = iDescriptors.SetInterfaceDescriptor(new_ifc, 0, (TInt)a1);
   1.352 +		break;
   1.353 +		}
   1.354 +		
   1.355 +	case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
   1.356 +		{
   1.357 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetInterfaceDescriptorSize")));
   1.358 +		if (a2 != NULL)
   1.359 +			{
   1.360 +			const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Interface), sizeof(KUsbDescSize_Interface));
   1.361 +			r = __THREADWRITE(iClient, a2, size);
   1.362 +			}
   1.363 +		else
   1.364 +			{
   1.365 +			r = KErrArgument;
   1.366 +			}
   1.367 +		break;
   1.368 +		}
   1.369 +		
   1.370 +	case RDevUsbcClient::EControlGetEndpointDescriptor:
   1.371 +		{
   1.372 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetEndpointDescriptor")));
   1.373 +		TEndpointDescriptorInfo info;
   1.374 +		r = __THREADRAWREAD(iClient, a1,(TUint8*)&info, (TInt)sizeof(info));
   1.375 +		if(r != KErrNone)
   1.376 +			{
   1.377 +			__THREADPANIC(iClient, r);
   1.378 +			}
   1.379 +		r = iDescriptors.GetEndpointDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, (TUint8)info.iEndpoint);
   1.380 +		}
   1.381 +	
   1.382 +	case RDevUsbcClient::EControlSetEndpointDescriptor:
   1.383 +		{
   1.384 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetEndpointDescriptor")));
   1.385 +		TEndpointDescriptorInfo info;
   1.386 +		r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TEndpointDescriptorInfo));
   1.387 +		if(r != KErrNone)
   1.388 +			__THREADPANIC(iClient, r);
   1.389 +		r = iDescriptors.SetEndpointDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, (TUint8)info.iEndpoint);
   1.390 +		break;
   1.391 +		}
   1.392 +	
   1.393 +	case RDevUsbcClient::EControlGetEndpointDescriptorSize:
   1.394 +		{
   1.395 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetEndpointDescriptorSize")));
   1.396 +		TEndpointDescriptorInfo info;
   1.397 +		r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TEndpointDescriptorInfo));
   1.398 +		if(r != KErrNone)
   1.399 +			__THREADPANIC(iClient, r);
   1.400 +		TInt s;
   1.401 +		TInt r = iDescriptors.GetEndpointDescriptorSize(0, info.iSetting, (TUint8)info.iEndpoint, s);
   1.402 +		if (r == KErrNone)
   1.403 +			{
   1.404 +			TPtrC8 size(reinterpret_cast<const TUint8*>(&s), sizeof(s));
   1.405 +			r = __THREADWRITE(iClient, &(info.iArg), size);
   1.406 +			}
   1.407 +		break;
   1.408 +		}
   1.409 +		
   1.410 +	case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
   1.411 +		{
   1.412 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetCSInterfaceDescriptor")));
   1.413 +		TCSDescriptorInfo info;
   1.414 +		r = __THREADRAWREAD(iClient, a1, (TUint8*)&info, (TInt)sizeof(TCSDescriptorInfo));
   1.415 +		if(r != KErrNone)
   1.416 +			__THREADPANIC(iClient, r);
   1.417 +		r = iDescriptors.SetCSInterfaceDescriptorTC(iClient, *((TDes8*)info.iArg), 0, info.iSetting, info.iSize);
   1.418 +		}
   1.419 +		break;
   1.420 +
   1.421 +	case RDevUsbcClient::EControlDeviceDisconnectFromHost:
   1.422 +		{
   1.423 +		r = KErrNone;
   1.424 +		break;
   1.425 +		}
   1.426 +		
   1.427 +	case RDevUsbcClient::EControlDeviceConnectToHost:
   1.428 +		{
   1.429 +		r = KErrNone;
   1.430 +		break;
   1.431 +		}
   1.432 +		
   1.433 +	case RDevUsbcClient::EControlDevicePowerUpUdc:
   1.434 +		{
   1.435 +		r = KErrNone;
   1.436 +		break;
   1.437 +		}
   1.438 +	
   1.439 +	case RDevUsbcClient::EControlSetInterface:
   1.440 +		{
   1.441 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetInterface")));
   1.442 +		TUsbcIfcInfo info;
   1.443 +		r = __THREADRAWREAD(iClient, a2, (TUint8*)&info, (TInt)sizeof(TUsbcIfcInfo));
   1.444 +		if(r != KErrNone)
   1.445 +			__THREADPANIC(iClient, r);
   1.446 +
   1.447 +		TUsbcInterfaceInfoBuf* interfaceData = info.iInterfaceData;
   1.448 +		TPtr8* ifcString = info.iString;
   1.449 +		r = SetInterface((TInt)a1, interfaceData, ifcString);
   1.450 +		}
   1.451 +		break;
   1.452 +		
   1.453 +	case RDevUsbcClient::EControlReleaseInterface:
   1.454 +		{
   1.455 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlReleaseInterface")));
   1.456 +		r = ReleaseInterface((TInt)a1);
   1.457 +		break;
   1.458 +		}
   1.459 +	
   1.460 +	case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
   1.461 +		{
   1.462 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
   1.463 +		r = iDescriptors.GetManufacturerStringDescriptorTC(iClient, a1Buf);
   1.464 +		break;
   1.465 +		}
   1.466 +		
   1.467 +	case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
   1.468 +		{
   1.469 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetManufacturerStringDescriptor")));
   1.470 +		r = iDescriptors.SetManufacturerStringDescriptorTC(iClient, a1Buf);
   1.471 +		break;
   1.472 +		}
   1.473 +		
   1.474 +	case RDevUsbcClient::EControlGetProductStringDescriptor:
   1.475 +		{
   1.476 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
   1.477 +		r = iDescriptors.GetProductStringDescriptorTC(iClient, a1Buf);
   1.478 +		break;
   1.479 +		}
   1.480 +
   1.481 +	case RDevUsbcClient::EControlSetProductStringDescriptor:
   1.482 +		{
   1.483 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetProductStringDescriptor")));
   1.484 +		r = iDescriptors.SetProductStringDescriptorTC(iClient, a1Buf);
   1.485 +		break;
   1.486 +		}
   1.487 +
   1.488 +	case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
   1.489 +		{
   1.490 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
   1.491 +		r = iDescriptors.GetSerialNumberStringDescriptorTC(iClient, a1Buf);
   1.492 +		break;
   1.493 +		}
   1.494 +
   1.495 +	case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
   1.496 +		{
   1.497 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetSerialNumberStringDescriptor")));
   1.498 +		r = iDescriptors.SetSerialNumberStringDescriptorTC(iClient, a1Buf);
   1.499 +		break;
   1.500 +		}
   1.501 +		
   1.502 +	case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
   1.503 +		{
   1.504 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlGetManufacturerStringDescriptor")));
   1.505 +		r = iDescriptors.GetConfigurationStringDescriptorTC(iClient, a1Buf);
   1.506 +		break;
   1.507 +		}
   1.508 +
   1.509 +	case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
   1.510 +		{
   1.511 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("EControlSetConfigurationStringDescriptor")));
   1.512 +		r = iDescriptors.SetConfigurationStringDescriptorTC(iClient, a1Buf);
   1.513 +		break;
   1.514 +		}
   1.515 +	case RDevUsbcClient::EControlEndpointStatus:
   1.516 +		{
   1.517 +		TInt ep = (TInt)a1;
   1.518 +		DTestUsbcEndpoint* pEndpoint = iEndpoints[FindRealEndpoint(ep)];
   1.519 +		TEndpointState state = EEndpointStateUnknown;
   1.520 +		if (pEndpoint->IsHalted())
   1.521 +			{
   1.522 +			state = EEndpointStateStalled;
   1.523 +			}
   1.524 +		else
   1.525 +			{
   1.526 +			state = EEndpointStateNotStalled;
   1.527 +			}
   1.528 +		__THREADRAWWRITE(iClient, a2, (TUint8*)&state, (TInt)sizeof(state));		
   1.529 +		break;
   1.530 +		}
   1.531 +		
   1.532 +	case RDevTestUsbcClient::ETestControlReqEndpointStatusNotify:
   1.533 +		{
   1.534 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestControlReqEndpointStatusNotify")));
   1.535 +		r = HostEndpointStatusNotify((TInt)a2, (TRequestStatus*)a1);
   1.536 +		break;
   1.537 +		}
   1.538 +	
   1.539 +	case RDevTestUsbcClient::ETestControlClearEndpoint:
   1.540 +		{
   1.541 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("ETestControlClearEndpoint")));
   1.542 +		r = ClearEndpoint((TInt)a1);
   1.543 +		break;
   1.544 +		}
   1.545 +		
   1.546 +	default:
   1.547 +		r = KErrNotSupported;
   1.548 +		}
   1.549 +		
   1.550 +	return r;
   1.551 +	}
   1.552 +
   1.553 +TInt DLddTestUsbcChannel::SetInterface(TInt aInterfaceNumber,
   1.554 +									   TUsbcInterfaceInfoBuf *aUserInterfaceInfoBuf,
   1.555 +									   TPtr8* aInterfaceString)
   1.556 +	{
   1.557 +// The Interface Descriptor string is no interest to us
   1.558 +// so leave that as is, the controller will have to take a local copy
   1.559 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Entry Interface#=%d Endpoints =%d"),aInterfaceNumber,(*aUserInterfaceInfoBuf)().iTotalEndpointsUsed));
   1.560 +	TInt r = KErrNone;
   1.561 +	TUsbcEndpointInfo* pEndpointData=NULL;
   1.562 +	TInt numberOfEndpoints=0;
   1.563 +	TUsbcInterfaceInfoBuf interfaceBuff;
   1.564 +	TInt bufLen=interfaceBuff.Length();
   1.565 +	TInt srcLen=__THREADDESLEN(iClient,aUserInterfaceInfoBuf);
   1.566 +	if(srcLen<bufLen)
   1.567 +		{
   1.568 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface can't copy")));
   1.569 +		__THREADPANIC(iClient,EDesOverflow);
   1.570 +		}
   1.571 +	r = __THREADREAD(iClient, aUserInterfaceInfoBuf, interfaceBuff);
   1.572 +	if(r!=KErrNone)
   1.573 +		{
   1.574 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Copy failed reason=%d"),r));
   1.575 +		__THREADPANIC(iClient,r);
   1.576 +		}
   1.577 +	pEndpointData=interfaceBuff().iEndpointData;
   1.578 +
   1.579 +// If an alternate interface is being asked for then do nothing
   1.580 +// just pass it down to the Controller
   1.581 +	numberOfEndpoints=interfaceBuff().iTotalEndpointsUsed;
   1.582 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface 10 numberOfEndpoints=%d"),numberOfEndpoints));
   1.583 +
   1.584 +// other endpoints
   1.585 +	for(TInt i=1;i<=numberOfEndpoints;i++,pEndpointData++)
   1.586 +		{
   1.587 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface for ep=%d"),i));
   1.588 +		if(!ValidateEndpoint(pEndpointData))
   1.589 +			{
   1.590 +			r=KErrUsbBadEndpoint;
   1.591 +			goto KillAll;
   1.592 +			}
   1.593 +		}
   1.594 +
   1.595 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface Calling controller")));
   1.596 +	r=SetInterface(aInterfaceNumber,
   1.597 +				   interfaceBuff().iClass,
   1.598 +				   aInterfaceString,
   1.599 +				   interfaceBuff().iTotalEndpointsUsed,
   1.600 +				   interfaceBuff().iEndpointData);
   1.601 +	
   1.602 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface controller returned %d"),r));
   1.603 +	if(r!=KErrNone)
   1.604 +		{
   1.605 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface failed reason=%d"),r));
   1.606 +		goto KillAll;
   1.607 +		}
   1.608 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("SetInterface ready to exit")));
   1.609 +
   1.610 +	return KErrNone;
   1.611 +
   1.612 +KillAll:
   1.613 +	return r;
   1.614 +	}
   1.615 +	
   1.616 +TInt DLddTestUsbcChannel::SetInterface(TInt aInterfaceNumber, TUsbcClassInfo& aClass,
   1.617 +									   TDesC8* aString, TInt aTotalEndpointsUsed,
   1.618 +									   const TUsbcEndpointInfo aEndpointData[])
   1.619 +	{
   1.620 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::SetInterface()")));
   1.621 +	for (TInt i = 0; i < aTotalEndpointsUsed; ++i)
   1.622 +		{
   1.623 +		if (aEndpointData[i].iType == KUsbEpTypeControl)
   1.624 +			{
   1.625 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  control endpoints not supported")));
   1.626 +			return KErrNotSupported;
   1.627 +			}
   1.628 +		}
   1.629 +	// create & setup new interface
   1.630 +	TUsbcInterface* ifc = CreateInterface(aInterfaceNumber);
   1.631 +	if (ifc == NULL)
   1.632 +		{
   1.633 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error (ifc == NULL)")));
   1.634 +		return KErrGeneral;
   1.635 +		}
   1.636 +	// Create logical endpoints
   1.637 +	if (CreateEndpoints(ifc, aTotalEndpointsUsed, aEndpointData) != KErrNone)
   1.638 +		{
   1.639 + 		DeleteInterface(aInterfaceNumber);
   1.640 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error (CreateEndpoints() != KErrNone)")));
   1.641 +		return KErrGeneral;
   1.642 +		}
   1.643 +	// create & setup interface, string, and endpoint descriptors
   1.644 +	const TInt r = SetupIfcDescriptor(ifc, aClass, aString, aEndpointData);
   1.645 +	if (r != KErrNone)
   1.646 +		{
   1.647 +		return r;
   1.648 +		}
   1.649 +	return KErrNone;
   1.650 +	}
   1.651 +	
   1.652 +TUsbcInterface* DLddTestUsbcChannel::CreateInterface(TInt aIfc)
   1.653 +	{
   1.654 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::CreateInterface(x, aIfc=%d)"), aIfc));
   1.655 +	if (aIfc != iIfcSet.iInterfaces.Count())
   1.656 +		{
   1.657 +		// 9.2.3: "Alternate settings range from zero to one less than the number of alternate
   1.658 +		// settings for a specific interface." (Thus we can here only append a setting.)
   1.659 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  invalid interface setting number (2): %d"), aIfc));
   1.660 +		return NULL;
   1.661 +		}
   1.662 +	TUsbcInterface* const ifc_ptr = new TUsbcInterface(&iIfcSet, (TUint8)aIfc);
   1.663 +	if (!ifc_ptr)
   1.664 +		{
   1.665 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: new TUsbcInterface(ifcset, aIfc) failed")));
   1.666 +		return NULL;
   1.667 +		}
   1.668 +	iIfcSet.iInterfaces.Append(ifc_ptr);
   1.669 +	return ifc_ptr;
   1.670 +	}
   1.671 +	
   1.672 +void DLddTestUsbcChannel::DeleteInterface(TInt aIfc)
   1.673 +	{
   1.674 +	if (iIfcSet.iInterfaces.Count() <= aIfc)
   1.675 +		{
   1.676 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: invalid interface setting: %d"), aIfc));
   1.677 +		return;
   1.678 +		}
   1.679 +	TUsbcInterface* const ifc_ptr = iIfcSet.iInterfaces[aIfc];
   1.680 +	iIfcSet.iInterfaces.Remove(aIfc);
   1.681 +	delete ifc_ptr;
   1.682 +	if (aIfc == iIfcSet.iCurrentInterface)
   1.683 +		{
   1.684 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" > Warning: deleting current interface setting")));
   1.685 +		iIfcSet.iCurrentInterface = 0;
   1.686 +		}
   1.687 +	}
   1.688 +	
   1.689 +TInt DLddTestUsbcChannel::CreateEndpoints(TUsbcInterface* aIfc, TInt aEndpointsUsed,
   1.690 +										  const TUsbcEndpointInfo aEndpointData[])
   1.691 +	{
   1.692 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::CreateEndpoints()")));
   1.693 +	
   1.694 +	for (TInt i = 0; i < aEndpointsUsed; ++i)
   1.695 +		{
   1.696 +		for (TInt j = 1; j <= KMaxEndpointsPerClient; ++j)
   1.697 +			{
   1.698 +			if (iEndpoints[j]->EndpointSuitable(aEndpointData[i]))
   1.699 +				{
   1.700 +				TUsbcLogicalEndpoint* const ep = new TUsbcLogicalEndpoint(j, aEndpointData[i], aIfc);
   1.701 +				if (!ep)
   1.702 +					{
   1.703 +					__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: new TUsbcLogicalEndpoint() failed")));
   1.704 +					aIfc->iEndpoints.ResetAndDestroy();
   1.705 +					for (TInt k = 1; k <= KMaxEndpointsPerClient; ++k)
   1.706 +						{
   1.707 +						iEndpoints[k]->iReserve = EFalse;
   1.708 +						}
   1.709 +					return KErrNoMemory;
   1.710 +					}
   1.711 +				iEndpoints[j]->iReserve = ETrue;
   1.712 +				iEndpoints[j]->SetClearCallback(this);
   1.713 +				aIfc->iEndpoints.Append(ep);
   1.714 +				break;
   1.715 +				}
   1.716 +			}
   1.717 +		}
   1.718 +	return KErrNone;
   1.719 +	}
   1.720 +
   1.721 +TBool DLddTestUsbcChannel::ValidateEndpoint(TUsbcEndpointInfo* aEndpointInfo)
   1.722 +	{ // Quick sanity check on endpoint properties
   1.723 +	TUint dir=aEndpointInfo->iDir;
   1.724 +	TInt size=aEndpointInfo->iSize;
   1.725 +	if(size <=0)
   1.726 +		return EFalse;
   1.727 +	switch (aEndpointInfo->iType)
   1.728 +		{
   1.729 +		case KUsbEpTypeControl:
   1.730 +			if(dir != KUsbEpDirBidirect || size > 64)
   1.731 +				return EFalse;
   1.732 +			break;
   1.733 +		case KUsbEpTypeIsochronous:
   1.734 +			if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 1023)
   1.735 +				return EFalse;
   1.736 +			break;
   1.737 +		case KUsbEpTypeBulk:
   1.738 +			if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 64)
   1.739 +				return EFalse;
   1.740 +			break;
   1.741 +		case KUsbEpTypeInterrupt:
   1.742 +			if((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 64)
   1.743 +				return EFalse;
   1.744 +			break;
   1.745 +		default:
   1.746 +			return EFalse;
   1.747 +		}
   1.748 +	return ETrue;
   1.749 +	}
   1.750 +
   1.751 +TInt DLddTestUsbcChannel::SetupIfcDescriptor(TUsbcInterface* aIfc, TUsbcClassInfo& aClass,
   1.752 +											 TDesC8* aString, const TUsbcEndpointInfo aEndpointData[])
   1.753 +	{
   1.754 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::SetupIfcDescriptor()")));
   1.755 +	
   1.756 +	// interface descriptor
   1.757 +	TUsbcDescriptorBase* d = TUsbcInterfaceDescriptor::New(aIfc->iInterfaceSet->iInterfaceNumber,
   1.758 +														   aIfc->iSettingCode,
   1.759 +														   aIfc->iEndpoints.Count(),
   1.760 +														   aClass);
   1.761 +	if (!d)
   1.762 +		{
   1.763 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc desc failed.")));
   1.764 +		return KErrNoMemory;
   1.765 +		}
   1.766 +	iDescriptors.InsertDescriptor(d);
   1.767 +
   1.768 +	// interface string descriptor
   1.769 +	if (aString)
   1.770 +		{
   1.771 +		// we don't know the length of the string, so we have to allocate memory dynamically
   1.772 +		TUint strlen = __THREADDESLEN(iClient, aString);
   1.773 +		if (strlen > KUsbStringDescStringMaxSize)
   1.774 +			{
   1.775 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: $ descriptor too long - string will be truncated")));
   1.776 +			strlen = KUsbStringDescStringMaxSize;
   1.777 +			}
   1.778 +		
   1.779 +		HBuf8Plat* stringbuf = NULL;
   1.780 +		__NEWPLATBUF(stringbuf, strlen);
   1.781 +		if (!stringbuf)
   1.782 +			{
   1.783 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc $ desc string failed.")));
   1.784 +			iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode);
   1.785 +			return KErrNoMemory;
   1.786 +			}
   1.787 +		
   1.788 +		TInt r;	
   1.789 +		__THREADREADPLATBUF(iClient, aString, stringbuf, r);
   1.790 +		if (r != KErrNone)
   1.791 +			{
   1.792 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  > Error: Thread read error!")));
   1.793 +			iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
   1.794 +											 aIfc->iSettingCode);
   1.795 +			delete stringbuf;
   1.796 +			return r;
   1.797 +			}
   1.798 +		TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*stringbuf);
   1.799 +		if (!sd)
   1.800 +			{
   1.801 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: Memory allocation for ifc $ desc failed.")));
   1.802 +			iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode);
   1.803 +			delete stringbuf;
   1.804 +			return KErrNoMemory;
   1.805 +			}
   1.806 +		iDescriptors.SetIfcStringDescriptor(sd, aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode);
   1.807 +		delete stringbuf;									// the (EPOC) descriptor was copied by New()
   1.808 +		}
   1.809 +
   1.810 +	// endpoint descriptors
   1.811 +	for (TInt i = 0; i < aIfc->iEndpoints.Count(); ++i)
   1.812 +		{
   1.813 +		// The reason for using another function argument for Endpoint Info - and not possibly (similar to the
   1.814 +		// Endpoint Address) "aIfc->iEndpoints[i]->iPEndpoint->iLEndpoint->iInfo" - is that at this time
   1.815 +		// there are no logical endpoints associated with our real endpoints, i.e. iLEndpoint is NULL!
   1.816 +		if (aEndpointData[i].iExtra)
   1.817 +			{
   1.818 +			// if non-standard endpoint descriptor requested...
   1.819 +			if (aEndpointData[i].iExtra != 2)
   1.820 +				{
   1.821 +				// ...then it must be a Audio Class endpoint descriptor. Else...
   1.822 +				__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > We only support EP desc extension of 2 bytes (not %d)"), aEndpointData[i].iExtra));
   1.823 +				iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
   1.824 +												 aIfc->iSettingCode);
   1.825 +				return KErrArgument;
   1.826 +				}
   1.827 +			d = TUsbcAudioEndpointDescriptor::New((TUint8)i, aEndpointData[i]);
   1.828 +			}
   1.829 +		else
   1.830 +			{
   1.831 +			d = TUsbcEndpointDescriptor::New((TUint8)i, aEndpointData[i]);
   1.832 +			}
   1.833 +		if (!d)
   1.834 +			{
   1.835 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Memory allocation for ep desc #%d failed."), i));
   1.836 +			iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
   1.837 +											 aIfc->iSettingCode);
   1.838 +			return KErrNoMemory;
   1.839 +			}
   1.840 +		iDescriptors.InsertDescriptor(d);
   1.841 +		}
   1.842 +
   1.843 +	return KErrNone;
   1.844 +	}
   1.845 +
   1.846 +/**
   1.847 +@internalTechnology
   1.848 +
   1.849 +   Releases an existing USB interface (one setting), complete with endpoints, descriptors, etc.,
   1.850 +   and removes it from the internal device configuration tree.
   1.851 +   
   1.852 +   @param aClientId A pointer to the LDD owning the interface.
   1.853 +   @param aInterfaceNumber The setting number of the interface setting to be deleted. This must be
   1.854 +   the highest numbered (or 'last') setting for this interface.
   1.855 +
   1.856 +   @return KErrNotFound if interface (not setting) for some reason cannot be found, KErrArgument if an
   1.857 +   invalid interface setting number is specified (not existing or existing but too small), KErrNone if
   1.858 +   interface successfully released or if this client doesn't own any interface.
   1.859 +*/
   1.860 +TInt DLddTestUsbcChannel::ReleaseInterface(TInt aInterfaceNumber)
   1.861 +	{
   1.862 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::ReleaseInterface(..., %d)"), aInterfaceNumber));
   1.863 +	const TInt setting_count = iIfcSet.iInterfaces.Count();
   1.864 +	if ((aInterfaceNumber != 0) && ((setting_count - 1) != aInterfaceNumber))
   1.865 +		{
   1.866 +		__KTRACE_OPT(KUSB,
   1.867 +					 Kern::Printf(__KSTRING(" > Error: interface settings must be released in descending order:\n\r%d settings exist, #%d was requested to be released: release %d first)"),
   1.868 +								  setting_count, aInterfaceNumber, setting_count - 1));
   1.869 +		return KErrArgument;
   1.870 +		}
   1.871 +	// Reset reserved status of the endpoints
   1.872 +	for (TInt i = 0; i < KMaxEndpointsPerClient+1; i++)
   1.873 +			{
   1.874 +			iEndpoints[i]->iReserve = EFalse;
   1.875 +			}
   1.876 + 	if (aInterfaceNumber == 0)
   1.877 + 		{
   1.878 + 		TInt m = iIfcSet.iInterfaces.Count();
   1.879 + 		while (m > 0)
   1.880 + 			{
   1.881 + 			m--;
   1.882 + 			// Delete the setting itself + its ifc & ep descriptors
   1.883 + 			DeleteInterface(m);
   1.884 + 			iDescriptors.DeleteIfcDescriptor(0, m);
   1.885 + 			}
   1.886 + 		}
   1.887 + 	else
   1.888 +		{		
   1.889 + 		// Delete the setting itself + its ifc & ep descriptors
   1.890 + 		DeleteInterface(aInterfaceNumber);
   1.891 + 		iDescriptors.DeleteIfcDescriptor(0, aInterfaceNumber);
   1.892 +		}
   1.893 +	// Delete the whole interface if all settings are gone
   1.894 +	if (iIfcSet.iInterfaces.Count() == 0)
   1.895 +		{
   1.896 +		DeleteInterfaceSet();
   1.897 +		}
   1.898 +	return KErrNone;
   1.899 +	}
   1.900 +	
   1.901 +void DLddTestUsbcChannel::DeleteInterfaceSet()
   1.902 +	{
   1.903 +	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DLddTestUsbcChannel::DeleteInterfaceSet")));
   1.904 +	iIfcSet.iInterfaceNumber = 0;
   1.905 +	iIfcSet.iCurrentInterface = 0;
   1.906 +	iIfcSet.iInterfaces.ResetAndDestroy();
   1.907 +	}
   1.908 +
   1.909 +TInt DLddTestUsbcChannel::DoTransferAsyncReq(TInt aEndpointNumber, TAny* a1, TAny* a2, TRequestStatus& aStatus)
   1.910 +	{
   1.911 +	TInt r = KErrNone;
   1.912 +	DTestUsbcEndpoint* pEndpoint = NULL;
   1.913 +	TEndpointTransferInfo *pTfr = NULL;
   1.914 +
   1.915 +
   1.916 +	if(!ValidEndpoint(aEndpointNumber))
   1.917 +		{
   1.918 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete")));
   1.919 +		return KErrUsbEpNotInInterface;
   1.920 +		}
   1.921 +
   1.922 +	if(a1 == NULL)
   1.923 +		{
   1.924 +		return KErrArgument;
   1.925 +		}
   1.926 +	
   1.927 +	TBool hostTransfer = EFalse;
   1.928 +	if(a2 != NULL)
   1.929 +		{
   1.930 +		hostTransfer = ETrue;
   1.931 +		}
   1.932 +
   1.933 +	TEndpointTransferInfo transferInfo;
   1.934 +	pTfr = (TEndpointTransferInfo*)&transferInfo;
   1.935 +	r = __THREADRAWREAD(iClient, a1, (TUint8*)&transferInfo, sizeof(TEndpointTransferInfo));
   1.936 +	if(r != KErrNone)
   1.937 +		{
   1.938 +		__THREADPANIC(iClient, r);
   1.939 +		}
   1.940 +	if (aEndpointNumber != 0)
   1.941 +		{
   1.942 +		if (hostTransfer)
   1.943 +			{
   1.944 +			pEndpoint = iEndpoints[aEndpointNumber];
   1.945 +			}
   1.946 +		else
   1.947 +			{
   1.948 +			pEndpoint = iEndpoints[FindRealEndpoint(aEndpointNumber)];
   1.949 +			}
   1.950 +		}
   1.951 +	else
   1.952 +		{
   1.953 +		pEndpoint = iEndpoints[0];
   1.954 +		}
   1.955 +	if(!pEndpoint)
   1.956 +		{
   1.957 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete")));
   1.958 +		return KErrUsbEpNotInInterface;
   1.959 +		}
   1.960 +
   1.961 +	switch(pTfr->iTransferType)
   1.962 +		{
   1.963 +    case ETransferTypeReadUntilShort:
   1.964 +	case ETransferTypeReadData:
   1.965 +		{
   1.966 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest Read")));
   1.967 +
   1.968 +		if(!hostTransfer && !pEndpoint->SupportsDir(KUsbEpDirOut) && !pEndpoint->SupportsDir(KUsbEpDirBidirect))
   1.969 +			{ // Trying to make the wrong thing
   1.970 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Read: in error complete")));
   1.971 +			r = KErrUsbEpBadDirection;
   1.972 +			break;
   1.973 +			}
   1.974 +
   1.975 +		// Set the length of data to zero now to catch all cases
   1.976 +		TPtrC8 pZeroDesc(NULL, 0);
   1.977 +		r = __THREADWRITE(iClient, pTfr->iDes, pZeroDesc);	 // set client descriptor length to zero
   1.978 +		if(r != KErrNone)
   1.979 +			__THREADPANIC(iClient, r);
   1.980 +		if (hostTransfer)
   1.981 +			r = pEndpoint->NewHostRequest(iClient, &aStatus, *pTfr, pTfr->iTransferType);
   1.982 +		else
   1.983 +			r = pEndpoint->NewRequest(iClient, &aStatus, *pTfr, pTfr->iTransferType);
   1.984 +		break;
   1.985 +		}
   1.986 +
   1.987 +	case ETransferTypeWrite:
   1.988 +		{
   1.989 +		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DoRequest Write 1")));
   1.990 +		if(!hostTransfer && !pEndpoint->SupportsDir(KUsbEpDirIn) && !pEndpoint->SupportsDir(KUsbEpDirBidirect))
   1.991 +			{
   1.992 +			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Write: wrong direction complete")));
   1.993 +			r = KErrUsbEpBadDirection;
   1.994 +			break;
   1.995 +			}
   1.996 +		if (hostTransfer)
   1.997 +			r = pEndpoint->NewHostRequest(iClient, &aStatus, *pTfr, ETransferTypeWrite);
   1.998 +		else
   1.999 +			r = pEndpoint->NewRequest(iClient, &aStatus, *pTfr, ETransferTypeWrite);
  1.1000 +		break;
  1.1001 +		}
  1.1002 +	default:
  1.1003 +		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("DoRequest Not supported complete")));
  1.1004 +		r = KErrNotSupported;
  1.1005 +		break;
  1.1006 +		}
  1.1007 +	return r;
  1.1008 +	}
  1.1009 +	
  1.1010 +TInt DLddTestUsbcChannel::HaltClearEndpoint(TBool aHalt, TInt aEndpointNumber)
  1.1011 +	{
  1.1012 +	DTestUsbcEndpoint* pEndpoint = NULL;
  1.1013 +	if (aEndpointNumber != 0)
  1.1014 +		{
  1.1015 +		pEndpoint = iEndpoints[FindRealEndpoint(aEndpointNumber)];
  1.1016 +		}
  1.1017 +	else
  1.1018 +		{
  1.1019 +		pEndpoint = iEndpoints[0];
  1.1020 +		}
  1.1021 +	TInt err;
  1.1022 +	if (aHalt)
  1.1023 +		{
  1.1024 +		err = pEndpoint->Halt();
  1.1025 +		}
  1.1026 +	else
  1.1027 +		{
  1.1028 +		err = pEndpoint->Clear();
  1.1029 +		}
  1.1030 +	return err;
  1.1031 +	}
  1.1032 +	
  1.1033 +TInt DLddTestUsbcChannel::HostEndpointStatusNotify(TInt aEndpointNumber, TRequestStatus* aStatus)
  1.1034 +	{
  1.1035 +	DTestUsbcEndpoint* pEndpoint = iEndpoints[aEndpointNumber];
  1.1036 +	return pEndpoint->HostStatusNotify(iClient, aStatus);
  1.1037 +	}
  1.1038 +	
  1.1039 +TInt DLddTestUsbcChannel::ClearEndpoint(TInt aEndpointNumber)
  1.1040 +	{
  1.1041 +	DTestUsbcEndpoint* pEndpoint = iEndpoints[aEndpointNumber];
  1.1042 +	return pEndpoint->Clear();
  1.1043 +	}
  1.1044 +
  1.1045 +TInt DLddTestUsbcChannel::EndpointStatusNotify(TUint* aEndpointMask, TRequestStatus* aStatus)
  1.1046 +	{
  1.1047 +	iEndpointStatusMask = aEndpointMask;
  1.1048 +	iEndpointStatusNotifyRequest = aStatus;
  1.1049 +	return KErrNone;
  1.1050 +	}
  1.1051 +
  1.1052 +void DLddTestUsbcChannel::EndpointStatusNotifyCallback()
  1.1053 +	{
  1.1054 +	if (iEndpointStatusNotifyRequest == NULL || iEndpointStatusMask == NULL)
  1.1055 +		{
  1.1056 +		return;
  1.1057 +		}
  1.1058 +	
  1.1059 +	//Get status for interface's endpoints.
  1.1060 +	//NOTE: currently we only support one interface.
  1.1061 +	TUsbcInterface* interface = iIfcSet.iInterfaces[0];
  1.1062 +	TUint bitmask = 0;
  1.1063 +	for (TInt i = interface->iEndpoints.Count() - 1; i >= 0; i--)
  1.1064 +		{
  1.1065 +		TUsbcLogicalEndpoint* logep = interface->iEndpoints[i];
  1.1066 +		DTestUsbcEndpoint* pEndpoint = iEndpoints[FindRealEndpoint(logep->iLEndpointNum)];
  1.1067 +		if (pEndpoint->IsHalted())
  1.1068 +			{
  1.1069 +			bitmask |= 1;
  1.1070 +			bitmask = bitmask << 1;
  1.1071 +			}
  1.1072 +		}
  1.1073 +	
  1.1074 +	//Write bitmask back to client space.
  1.1075 +	TInt r = __THREADRAWWRITE(iClient, (void*)iEndpointStatusMask, (TUint8*)&bitmask, (TInt)sizeof(bitmask));
  1.1076 +	
  1.1077 +	//Complete client request.
  1.1078 +	Kern::RequestComplete(iClient, iEndpointStatusNotifyRequest, r);
  1.1079 +		
  1.1080 +	iEndpointStatusMask = NULL;
  1.1081 +	iEndpointStatusNotifyRequest = NULL;
  1.1082 +	}
  1.1083 +	
  1.1084 +TBool DLddTestUsbcChannel::ValidEndpoint(TInt aEndpointNumber)
  1.1085 +	{
  1.1086 +	return (aEndpointNumber <= 5 && aEndpointNumber >= 0);
  1.1087 +	}
  1.1088 +
  1.1089 +TInt DLddTestUsbcChannel::FindRealEndpoint(TInt aEndpointNumber)
  1.1090 +	{
  1.1091 +	TUsbcInterface* pIfc = iIfcSet.CurrentInterface();
  1.1092 +	return pIfc->iEndpoints[aEndpointNumber - 1]->iLEndpointNum;
  1.1093 +	}
  1.1094 +
  1.1095 +void DLddTestUsbcChannel::AlternateDeviceStatusNotify()
  1.1096 +	{
  1.1097 +	if (iAlternateDeviceStatusNotifyRequest != NULL)
  1.1098 +		{
  1.1099 +		TInt r = __THREADRAWWRITE(iClient, (void*)iAlternateDeviceStatusNotifyValue, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState));
  1.1100 +		Kern::RequestComplete(iClient, iAlternateDeviceStatusNotifyRequest, r);
  1.1101 +		iAlternateDeviceStatusNotifyRequest = NULL;
  1.1102 +		}
  1.1103 +	}
  1.1104 +
  1.1105 +TInt DLddTestUsbcChannel::SetAlternateDeviceStatusNotify(TRequestStatus* aStatus, TUint* aValue)
  1.1106 +	{
  1.1107 +	if (iAlternateDeviceStatusNotifyRequest != NULL)
  1.1108 +		{
  1.1109 +		return KErrInUse;
  1.1110 +		}
  1.1111 +
  1.1112 +	TRequestStatus s;
  1.1113 +	s = KRequestPending;
  1.1114 +
  1.1115 +	__THREADRAWWRITE(iClient, (void*)aStatus, (TUint8*)&s, (TInt)sizeof(s));
  1.1116 +	iAlternateDeviceStatusNotifyRequest = aStatus;
  1.1117 +	iAlternateDeviceStatusNotifyValue = aValue;
  1.1118 +	return KErrNone;
  1.1119 +	}
  1.1120 +
  1.1121 +void DLddTestUsbcChannel::CancelAlternateDeviceStatusNotify()
  1.1122 +	{
  1.1123 +	if (iAlternateDeviceStatusNotifyRequest != NULL)
  1.1124 +		{
  1.1125 +		__THREADRAWWRITE(iClient, (void*)iAlternateDeviceStatusNotifyValue, (TUint8*)&iDeviceState, (TInt)sizeof(iDeviceState));
  1.1126 +		Kern::RequestComplete(iClient, iAlternateDeviceStatusNotifyRequest, KErrCancel);
  1.1127 +		iAlternateDeviceStatusNotifyRequest = NULL;
  1.1128 +		}
  1.1129 +	}
  1.1130 +
  1.1131 +TInt DLddTestUsbcChannel::ReEnumerate(TRequestStatus* aStatus)
  1.1132 +	{
  1.1133 +	SetDeviceState(EUsbcDeviceStateConfigured);
  1.1134 +	Kern::RequestComplete(iClient, aStatus, KErrNone);
  1.1135 +	return KErrNone;
  1.1136 +	}
  1.1137 +	
  1.1138 +void DLddTestUsbcChannel::SetDeviceState(TUsbcDeviceState aState)
  1.1139 +	{
  1.1140 +	iDeviceState = aState;
  1.1141 +	AlternateDeviceStatusNotify();
  1.1142 +	}
  1.1143 +