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 +