1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32utils/testusbcldd/src/misc.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,366 @@
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\misc.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "dtestusblogdev.h"
1.22 +
1.23 +TUsbcInterface::TUsbcInterface(TUsbcInterfaceSet* aIfcSet, TUint8 aSetting)
1.24 + : iEndpoints(2), iInterfaceSet(aIfcSet), iSettingCode(aSetting)
1.25 + {
1.26 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterface::TUsbcInterface()")));
1.27 + }
1.28 +
1.29 +
1.30 +TUsbcInterface::~TUsbcInterface()
1.31 + {
1.32 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterface::~TUsbcInterface()")));
1.33 + iEndpoints.ResetAndDestroy();
1.34 + }
1.35 +
1.36 +
1.37 +TUsbcInterfaceSet::TUsbcInterfaceSet(const DBase* aClientId, TUint8 aIfcNum)
1.38 + : iInterfaces(2), iClientId(aClientId), iInterfaceNumber(aIfcNum), iCurrentInterface(0)
1.39 + {
1.40 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceSet::TUsbcInterfaceSet()")));
1.41 + }
1.42 +
1.43 +
1.44 +TUsbcInterfaceSet::~TUsbcInterfaceSet()
1.45 + {
1.46 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceSet::~TUsbcInterfaceSet()")));
1.47 + iInterfaces.ResetAndDestroy();
1.48 + }
1.49 +
1.50 +const TUsbcInterface* TUsbcInterfaceSet::CurrentInterface() const
1.51 +/** Returns a pointer to the currently selected (active) setting of this interface.
1.52 +
1.53 + @return A pointer to the currently selected (active) setting of this interface.
1.54 +*/
1.55 + {
1.56 + return iInterfaces[iCurrentInterface];
1.57 + }
1.58 +
1.59 +
1.60 +TUsbcInterface* TUsbcInterfaceSet::CurrentInterface()
1.61 +/** Returns a pointer to the currently selected (active) setting of this interface.
1.62 +
1.63 + @return A pointer to the currently selected (active) setting of this interface.
1.64 +*/
1.65 + {
1.66 + return iInterfaces[iCurrentInterface];
1.67 + }
1.68 +
1.69 +TUsbcLogicalEndpoint::TUsbcLogicalEndpoint(TUint aEndpointNum, const TUsbcEndpointInfo& aInfo,
1.70 + TUsbcInterface* aInterface)
1.71 + : iLEndpointNum(aEndpointNum), iInfo(aInfo), iInterface(aInterface)
1.72 + {
1.73 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLogicalEndpoint::TUsbcLogicalEndpoint()")));
1.74 + }
1.75 +
1.76 +
1.77 +TUsbcLogicalEndpoint::~TUsbcLogicalEndpoint()
1.78 + {
1.79 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLogicalEndpoint::~TUsbcLogicalEndpoint: #%d"), iLEndpointNum));
1.80 + }
1.81 +
1.82 +DTestUsbcEndpoint::DTestUsbcEndpoint()
1.83 + {
1.84 + }
1.85 +
1.86 +DTestUsbcEndpoint::~DTestUsbcEndpoint()
1.87 + {
1.88 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Deleting buffer 0x%x"), iBuffer));
1.89 + delete iBuffer;
1.90 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Buffer deleted")));
1.91 + }
1.92 +
1.93 +TInt DTestUsbcEndpoint::Create(const TUsbcEndpointCaps& aCaps)
1.94 + {
1.95 + iCaps = aCaps;
1.96 + if (iBuffer == NULL)
1.97 + {
1.98 + __NEWPLATBUF(iBuffer, KEndpointBufferSize);
1.99 + if (iBuffer == NULL)
1.100 + return KErrNoMemory;
1.101 + }
1.102 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Allocated buffer 0x%x"), iBuffer));
1.103 + return KErrNone;
1.104 + }
1.105 +
1.106 +void DTestUsbcEndpoint::DoCancel()
1.107 + {
1.108 + if (iRequestPending)
1.109 + {
1.110 + //Cancel client request
1.111 + iRequestPending = EFalse;
1.112 + Kern::RequestComplete(iClient, iClientStatus, KErrCancel);
1.113 + }
1.114 + if (iHostRequestPending)
1.115 + {
1.116 + //Cancel host request
1.117 + iHostRequestPending = EFalse;
1.118 + Kern::RequestComplete(iHost, iHostStatus, KErrCancel);
1.119 + }
1.120 + }
1.121 +
1.122 +TInt DTestUsbcEndpoint::NewRequest(DThread* aClient, TRequestStatus* aStatus,
1.123 + TEndpointTransferInfo& aInfo, TTransferType aType)
1.124 + {
1.125 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DTestUsbcEndpoint::NewRequest")));
1.126 + //Only supports one request pending per endpoint
1.127 + if (iRequestPending)
1.128 + {
1.129 + return ERequestAlreadyPending;
1.130 + }
1.131 + iClient = aClient;
1.132 + iClientStatus = aStatus;
1.133 + iClientTransferInfo = aInfo;
1.134 + iDataTransferred = 0;
1.135 + iRequestPending = ETrue;
1.136 + iRequestType = aType;
1.137 +
1.138 + //Copy data to local buffer if this is a write request
1.139 + if (iRequestType == ETransferTypeWrite)
1.140 + {
1.141 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Write request")));
1.142 + TInt err;
1.143 + __THREADREADPLATBUF(aClient, iClientTransferInfo.iDes, iBuffer, err);
1.144 + if (err != KErrNone)
1.145 + {
1.146 + iRequestPending = EFalse;
1.147 + return err;
1.148 + }
1.149 + }
1.150 + else
1.151 + {
1.152 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Read request")));
1.153 + }
1.154 +
1.155 + if (iHostRequestPending)
1.156 + {
1.157 + TryToComplete();
1.158 + }
1.159 +
1.160 + return KErrNone;
1.161 + }
1.162 +
1.163 +TInt DTestUsbcEndpoint::NewHostRequest(DThread* aHost, TRequestStatus* aStatus,
1.164 + TEndpointTransferInfo& aInfo, TTransferType aType)
1.165 + {
1.166 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DTestUsbcEndpoint::NewHostRequest")));
1.167 + //Only supports one request pending per endpoint
1.168 + if (iHostRequestPending)
1.169 + {
1.170 + return ERequestAlreadyPending;
1.171 + }
1.172 + iHost = aHost;
1.173 + iHostStatus = aStatus;
1.174 + iHostTransferInfo = aInfo;
1.175 + iHostDataTransferred = 0;
1.176 + iHostRequestPending = ETrue;
1.177 + iHostRequestType = aType;
1.178 +
1.179 + //Copy data to local buffer if this is a write request
1.180 + if (iHostRequestType == ETransferTypeWrite)
1.181 + {
1.182 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Write request")));
1.183 + TInt err;
1.184 + __THREADREADPLATBUF(aHost, iHostTransferInfo.iDes, iBuffer, err);
1.185 + if (err != KErrNone)
1.186 + {
1.187 + iRequestPending = EFalse;
1.188 + return err;
1.189 + }
1.190 + }
1.191 + else
1.192 + {
1.193 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Read request")));
1.194 + }
1.195 +
1.196 + if (iRequestPending)
1.197 + {
1.198 + TryToComplete();
1.199 + }
1.200 +
1.201 + return KErrNone;
1.202 + }
1.203 +
1.204 +TInt DTestUsbcEndpoint::TryToComplete()
1.205 + {
1.206 + __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DTestUsbcEndpoint::TryToComplete")));
1.207 + TInt err = KErrNone;
1.208 + TInt len = iHostTransferInfo.iTransferSize - iHostDataTransferred;
1.209 +
1.210 + if (SupportsDir(KUsbEpDirBidirect))
1.211 + {
1.212 + //Make sure host and client transfer types don't conflict
1.213 + if (iRequestType == iHostRequestType)
1.214 + {
1.215 + iRequestPending = EFalse;
1.216 + iHostRequestPending = EFalse;
1.217 + Kern::RequestComplete(iClient, iClientStatus, KErrUsbEpBadDirection);
1.218 + Kern::RequestComplete(iHost, iHostStatus, KErrUsbEpBadDirection);
1.219 + return KErrUsbEpBadDirection;
1.220 + }
1.221 + }
1.222 +
1.223 + if (SupportsDir(KUsbEpDirIn) || (SupportsDir(KUsbEpDirBidirect) && iRequestType == ETransferTypeWrite))
1.224 + {
1.225 + err = CopyData(iDataTransferred, iHost, iHostTransferInfo.iDes, iHostDataTransferred, len);
1.226 + }
1.227 + else if (SupportsDir(KUsbEpDirOut) || (SupportsDir(KUsbEpDirBidirect) && iRequestType == ETransferTypeReadData))
1.228 + {
1.229 + err = CopyData(iHostDataTransferred, iClient, iClientTransferInfo.iDes, iDataTransferred, len);
1.230 + }
1.231 + else
1.232 + {
1.233 + err = KErrNotSupported;
1.234 + }
1.235 +
1.236 + if (err != KErrNone)
1.237 + {
1.238 + //Problems copying data. Complete requests with error and return.
1.239 + iRequestPending = EFalse;
1.240 + iHostRequestPending = EFalse;
1.241 + Kern::RequestComplete(iClient, iClientStatus, err);
1.242 + Kern::RequestComplete(iHost, iHostStatus, err);
1.243 + return err;
1.244 + }
1.245 + iDataTransferred += len;
1.246 + iHostDataTransferred += len;
1.247 +
1.248 + iRequestPending = EFalse;
1.249 + Kern::RequestComplete(iClient, iClientStatus, KErrNone);
1.250 + iHostRequestPending = EFalse;
1.251 + Kern::RequestComplete(iHost, iHostStatus, KErrNone);
1.252 + return KErrNone;
1.253 + }
1.254 +
1.255 +/**
1.256 +Copies data from a source descriptor to a destination descriptor, both in user space.
1.257 +
1.258 +@param aSrcClient The thread that owns the source descriptor
1.259 +@param aSrc Pointer to the source descriptor
1.260 +@param aSrcOffset Offset in aSrc from where to start reading data
1.261 +@param aDestClient The thread that owns the destination descriptor
1.262 +@param aDest Pointer to the destination descriptor
1.263 +@param aDestOffset Offset in aDest from where to start writing data
1.264 +@param aLen Amount of bytes to copy
1.265 +@return KErrNone is successful, otherwise a standard Symbian error code
1.266 +*/
1.267 +TInt DTestUsbcEndpoint::CopyData(TInt aSrcOffset, DThread* aDestClient, TDesC8* aDest,
1.268 + TInt aDestOffset, TInt aLen)
1.269 + {
1.270 + TInt err;
1.271 +
1.272 + // Get the descriptor length in the client's context.
1.273 + TInt rxLen[2] = {0,0};
1.274 + err=Kern::ThreadRawRead(aDestClient,aDest,&rxLen,sizeof(rxLen));
1.275 + if (err!=KErrNone)
1.276 + return err;
1.277 +
1.278 + // copy mo more than max number of chars in receive buffer
1.279 + aLen = Min(aLen, rxLen[1]);
1.280 +
1.281 + while(aLen > 0)
1.282 + {
1.283 + TInt len = iBuffer->Length() - aSrcOffset;
1.284 + //Make sure we only copy aLen bytes, no more
1.285 + if (len > aLen)
1.286 + {
1.287 + len = aLen;
1.288 + }
1.289 + TPtrC8 src(iBuffer->Ptr() + aSrcOffset, len);
1.290 + err = __THREADWRITEOFFSET(aDestClient, aDest, src, aDestOffset);
1.291 + if (err != KErrNone)
1.292 + {
1.293 + return err;
1.294 + }
1.295 + aLen -= len;
1.296 + aSrcOffset += len;
1.297 + aDestOffset += len;
1.298 + }
1.299 +
1.300 + return KErrNone;
1.301 + }
1.302 +
1.303 +TInt DTestUsbcEndpoint::Halt()
1.304 + {
1.305 + iHalted = ETrue;
1.306 + if (iNotifyHost != NULL)
1.307 + {
1.308 + Kern::RequestComplete(iNotifyHost, iHostNotifyStatus, KErrNone);
1.309 + iNotifyHost = NULL;
1.310 + }
1.311 + return KErrNone;
1.312 + }
1.313 +
1.314 +TInt DTestUsbcEndpoint::Clear()
1.315 + {
1.316 + iHalted = EFalse;
1.317 + if (iRequestPending)
1.318 + {
1.319 + iRequestPending = EFalse;
1.320 + Kern::RequestComplete(iClient, iClientStatus, KErrNone);
1.321 + }
1.322 + if (iHostRequestPending)
1.323 + {
1.324 + iHostRequestPending = EFalse;
1.325 + Kern::RequestComplete(iHost, iHostStatus, KErrNone);
1.326 + }
1.327 + if (iClearCallback != NULL)
1.328 + {
1.329 + iClearCallback->EndpointStatusNotifyCallback();
1.330 + }
1.331 + return KErrNone;
1.332 + }
1.333 +
1.334 +void DTestUsbcEndpoint::SetClearCallback(DLddTestUsbcChannel* aCallback)
1.335 + {
1.336 + iClearCallback = aCallback;
1.337 + }
1.338 +
1.339 +TBool DTestUsbcEndpoint::IsHalted()
1.340 + {
1.341 + return iHalted;
1.342 + }
1.343 +
1.344 +TInt DTestUsbcEndpoint::HostStatusNotify(DThread* aHost, TRequestStatus* aStatus)
1.345 + {
1.346 + const TRequestStatus s(KRequestPending);
1.347 + __THREADRAWWRITE(aHost, aStatus, (TUint8*)&s, (TInt)sizeof(TRequestStatus));
1.348 + iNotifyHost = aHost;
1.349 + iHostNotifyStatus = aStatus;
1.350 + return KErrNone;
1.351 + }
1.352 +
1.353 +TBool DTestUsbcEndpoint::SupportsDir(TUint aDir)
1.354 + {
1.355 + if ((iCaps.iTypesAndDir & aDir) == aDir)
1.356 + {
1.357 + return ETrue;
1.358 + }
1.359 + return EFalse;
1.360 + }
1.361 +
1.362 +TBool DTestUsbcEndpoint::EndpointSuitable(const TUsbcEndpointInfo& aInfo)
1.363 + {
1.364 + return (!iReserve &&
1.365 + (iCaps.iSizes == (TUint)aInfo.iSize) &&
1.366 + ((iCaps.iTypesAndDir & aInfo.iDir) == aInfo.iDir) &&
1.367 + ((iCaps.iTypesAndDir & aInfo.iType) == aInfo.iType));
1.368 + }
1.369 +