author | mikek |
Sun, 27 Jun 2010 21:43:55 +0100 | |
branch | GCC_SURGE |
changeset 181 | bd8f1e65581b |
parent 0 | a41df078684a |
permissions | -rw-r--r-- |
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). // All rights reserved. // This component and the accompanying materials are made available // under the terms of the License "Eclipse Public License v1.0" // which accompanies this distribution, and is available // at the URL "http://www.eclipse.org/legal/epl-v10.html". // // Initial Contributors: // Nokia Corporation - initial contribution. // // Contributors: // // Description: // f32test\testusbcldd\src\misc.cpp // // #include "dtestusblogdev.h" TUsbcInterface::TUsbcInterface(TUsbcInterfaceSet* aIfcSet, TUint8 aSetting) : iEndpoints(2), iInterfaceSet(aIfcSet), iSettingCode(aSetting) { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterface::TUsbcInterface()"))); } TUsbcInterface::~TUsbcInterface() { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterface::~TUsbcInterface()"))); iEndpoints.ResetAndDestroy(); } TUsbcInterfaceSet::TUsbcInterfaceSet(const DBase* aClientId, TUint8 aIfcNum) : iInterfaces(2), iClientId(aClientId), iInterfaceNumber(aIfcNum), iCurrentInterface(0) { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceSet::TUsbcInterfaceSet()"))); } TUsbcInterfaceSet::~TUsbcInterfaceSet() { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceSet::~TUsbcInterfaceSet()"))); iInterfaces.ResetAndDestroy(); } const TUsbcInterface* TUsbcInterfaceSet::CurrentInterface() const /** Returns a pointer to the currently selected (active) setting of this interface. @return A pointer to the currently selected (active) setting of this interface. */ { return iInterfaces[iCurrentInterface]; } TUsbcInterface* TUsbcInterfaceSet::CurrentInterface() /** Returns a pointer to the currently selected (active) setting of this interface. @return A pointer to the currently selected (active) setting of this interface. */ { return iInterfaces[iCurrentInterface]; } TUsbcLogicalEndpoint::TUsbcLogicalEndpoint(TUint aEndpointNum, const TUsbcEndpointInfo& aInfo, TUsbcInterface* aInterface) : iLEndpointNum(aEndpointNum), iInfo(aInfo), iInterface(aInterface) { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLogicalEndpoint::TUsbcLogicalEndpoint()"))); } TUsbcLogicalEndpoint::~TUsbcLogicalEndpoint() { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLogicalEndpoint::~TUsbcLogicalEndpoint: #%d"), iLEndpointNum)); } DTestUsbcEndpoint::DTestUsbcEndpoint() { } DTestUsbcEndpoint::~DTestUsbcEndpoint() { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Deleting buffer 0x%x"), iBuffer)); delete iBuffer; __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Buffer deleted"))); } TInt DTestUsbcEndpoint::Create(const TUsbcEndpointCaps& aCaps) { iCaps = aCaps; if (iBuffer == NULL) { __NEWPLATBUF(iBuffer, KEndpointBufferSize); if (iBuffer == NULL) return KErrNoMemory; } __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Allocated buffer 0x%x"), iBuffer)); return KErrNone; } void DTestUsbcEndpoint::DoCancel() { if (iRequestPending) { //Cancel client request iRequestPending = EFalse; Kern::RequestComplete(iClient, iClientStatus, KErrCancel); } if (iHostRequestPending) { //Cancel host request iHostRequestPending = EFalse; Kern::RequestComplete(iHost, iHostStatus, KErrCancel); } } TInt DTestUsbcEndpoint::NewRequest(DThread* aClient, TRequestStatus* aStatus, TEndpointTransferInfo& aInfo, TTransferType aType) { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DTestUsbcEndpoint::NewRequest"))); //Only supports one request pending per endpoint if (iRequestPending) { return ERequestAlreadyPending; } iClient = aClient; iClientStatus = aStatus; iClientTransferInfo = aInfo; iDataTransferred = 0; iRequestPending = ETrue; iRequestType = aType; //Copy data to local buffer if this is a write request if (iRequestType == ETransferTypeWrite) { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Write request"))); TInt err; __THREADREADPLATBUF(aClient, iClientTransferInfo.iDes, iBuffer, err); if (err != KErrNone) { iRequestPending = EFalse; return err; } } else { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Read request"))); } if (iHostRequestPending) { TryToComplete(); } return KErrNone; } TInt DTestUsbcEndpoint::NewHostRequest(DThread* aHost, TRequestStatus* aStatus, TEndpointTransferInfo& aInfo, TTransferType aType) { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DTestUsbcEndpoint::NewHostRequest"))); //Only supports one request pending per endpoint if (iHostRequestPending) { return ERequestAlreadyPending; } iHost = aHost; iHostStatus = aStatus; iHostTransferInfo = aInfo; iHostDataTransferred = 0; iHostRequestPending = ETrue; iHostRequestType = aType; //Copy data to local buffer if this is a write request if (iHostRequestType == ETransferTypeWrite) { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Write request"))); TInt err; __THREADREADPLATBUF(aHost, iHostTransferInfo.iDes, iBuffer, err); if (err != KErrNone) { iRequestPending = EFalse; return err; } } else { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("Read request"))); } if (iRequestPending) { TryToComplete(); } return KErrNone; } TInt DTestUsbcEndpoint::TryToComplete() { __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("DTestUsbcEndpoint::TryToComplete"))); TInt err = KErrNone; TInt len = iHostTransferInfo.iTransferSize - iHostDataTransferred; if (SupportsDir(KUsbEpDirBidirect)) { //Make sure host and client transfer types don't conflict if (iRequestType == iHostRequestType) { iRequestPending = EFalse; iHostRequestPending = EFalse; Kern::RequestComplete(iClient, iClientStatus, KErrUsbEpBadDirection); Kern::RequestComplete(iHost, iHostStatus, KErrUsbEpBadDirection); return KErrUsbEpBadDirection; } } if (SupportsDir(KUsbEpDirIn) || (SupportsDir(KUsbEpDirBidirect) && iRequestType == ETransferTypeWrite)) { err = CopyData(iDataTransferred, iHost, iHostTransferInfo.iDes, iHostDataTransferred, len); } else if (SupportsDir(KUsbEpDirOut) || (SupportsDir(KUsbEpDirBidirect) && iRequestType == ETransferTypeReadData)) { err = CopyData(iHostDataTransferred, iClient, iClientTransferInfo.iDes, iDataTransferred, len); } else { err = KErrNotSupported; } if (err != KErrNone) { //Problems copying data. Complete requests with error and return. iRequestPending = EFalse; iHostRequestPending = EFalse; Kern::RequestComplete(iClient, iClientStatus, err); Kern::RequestComplete(iHost, iHostStatus, err); return err; } iDataTransferred += len; iHostDataTransferred += len; iRequestPending = EFalse; Kern::RequestComplete(iClient, iClientStatus, KErrNone); iHostRequestPending = EFalse; Kern::RequestComplete(iHost, iHostStatus, KErrNone); return KErrNone; } /** Copies data from a source descriptor to a destination descriptor, both in user space. @param aSrcClient The thread that owns the source descriptor @param aSrc Pointer to the source descriptor @param aSrcOffset Offset in aSrc from where to start reading data @param aDestClient The thread that owns the destination descriptor @param aDest Pointer to the destination descriptor @param aDestOffset Offset in aDest from where to start writing data @param aLen Amount of bytes to copy @return KErrNone is successful, otherwise a standard Symbian error code */ TInt DTestUsbcEndpoint::CopyData(TInt aSrcOffset, DThread* aDestClient, TDesC8* aDest, TInt aDestOffset, TInt aLen) { TInt err; // Get the descriptor length in the client's context. TInt rxLen[2] = {0,0}; err=Kern::ThreadRawRead(aDestClient,aDest,&rxLen,sizeof(rxLen)); if (err!=KErrNone) return err; // copy mo more than max number of chars in receive buffer aLen = Min(aLen, rxLen[1]); while(aLen > 0) { TInt len = iBuffer->Length() - aSrcOffset; //Make sure we only copy aLen bytes, no more if (len > aLen) { len = aLen; } TPtrC8 src(iBuffer->Ptr() + aSrcOffset, len); err = __THREADWRITEOFFSET(aDestClient, aDest, src, aDestOffset); if (err != KErrNone) { return err; } aLen -= len; aSrcOffset += len; aDestOffset += len; } return KErrNone; } TInt DTestUsbcEndpoint::Halt() { iHalted = ETrue; if (iNotifyHost != NULL) { Kern::RequestComplete(iNotifyHost, iHostNotifyStatus, KErrNone); iNotifyHost = NULL; } return KErrNone; } TInt DTestUsbcEndpoint::Clear() { iHalted = EFalse; if (iRequestPending) { iRequestPending = EFalse; Kern::RequestComplete(iClient, iClientStatus, KErrNone); } if (iHostRequestPending) { iHostRequestPending = EFalse; Kern::RequestComplete(iHost, iHostStatus, KErrNone); } if (iClearCallback != NULL) { iClearCallback->EndpointStatusNotifyCallback(); } return KErrNone; } void DTestUsbcEndpoint::SetClearCallback(DLddTestUsbcChannel* aCallback) { iClearCallback = aCallback; } TBool DTestUsbcEndpoint::IsHalted() { return iHalted; } TInt DTestUsbcEndpoint::HostStatusNotify(DThread* aHost, TRequestStatus* aStatus) { const TRequestStatus s(KRequestPending); __THREADRAWWRITE(aHost, aStatus, (TUint8*)&s, (TInt)sizeof(TRequestStatus)); iNotifyHost = aHost; iHostNotifyStatus = aStatus; return KErrNone; } TBool DTestUsbcEndpoint::SupportsDir(TUint aDir) { if ((iCaps.iTypesAndDir & aDir) == aDir) { return ETrue; } return EFalse; } TBool DTestUsbcEndpoint::EndpointSuitable(const TUsbcEndpointInfo& aInfo) { return (!iReserve && (iCaps.iSizes == (TUint)aInfo.iSize) && ((iCaps.iTypesAndDir & aInfo.iDir) == aInfo.iDir) && ((iCaps.iTypesAndDir & aInfo.iType) == aInfo.iType)); }