--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/traceservices/tracefw/integ_test/ulogger/TEF/device-driver/src/d_usbc.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,3038 @@
+// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// e32\drivers\usbc\d_usbc.cpp
+// LDD for USB Device driver stack:
+// The channel object.
+//
+//
+
+/**
+ @file d_usbc.cpp
+ @internalTechnology
+*/
+
+#include <usbc.h>
+#include <e32utrace.h>
+#include "te_setfilterparameters.h"
+#include "te_utracecmds.h"
+
+
+_LIT(KUsbLddName, "Usbc");
+
+static const TInt KUsbRequestCallbackPriority = 2;
+
+
+// Quick sanity check on endpoint properties
+static TBool ValidateEndpoint(const TUsbcEndpointInfo* aEndpointInfo)
+ {
+ const TUint dir = aEndpointInfo->iDir;
+ const TInt size = aEndpointInfo->iSize;
+ if (size <= 0)
+ return EFalse;
+
+ switch (aEndpointInfo->iType)
+ {
+ case KUsbEpTypeControl:
+ if (dir != KUsbEpDirBidirect || size > 64)
+ return EFalse;
+ break;
+ case KUsbEpTypeIsochronous:
+ if ((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 1024)
+ return EFalse;
+ break;
+ case KUsbEpTypeBulk:
+ if ((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 512)
+ return EFalse;
+ break;
+ case KUsbEpTypeInterrupt:
+ if ((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 1024)
+ return EFalse;
+ break;
+ default:
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+
+/** Real entry point from the Kernel: return a new driver.
+ */
+DECLARE_STANDARD_LDD()
+ {
+ return new DUsbcLogDevice;
+ }
+
+
+/** Create a channel on the device.
+
+ @internalComponent
+*/
+TInt DUsbcLogDevice::Create(DLogicalChannelBase*& aChannel)
+ {
+
+ aChannel = new DLddUsbcChannel;
+ return aChannel ? KErrNone : KErrNoMemory;
+ }
+
+
+DUsbcLogDevice::DUsbcLogDevice()
+ {
+
+ iParseMask = KDeviceAllowUnit;
+ iUnitsMask = 0xffffffff; // Leave units decision to the Controller
+ iVersion = TVersion(KUsbcMajorVersion, KUsbcMinorVersion, KUsbcBuildVersion);
+ }
+
+
+TInt DUsbcLogDevice::Install()
+ {
+
+ // Only proceed if we have the Controller underneath us
+ if (!DUsbClientController::UsbcControllerPointer())
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf("LDD Install: USB Controller Not Present"));
+ return KErrGeneral;
+ }
+ return SetName(&KUsbLddName);
+ }
+
+
+//
+// Return the USB controller capabilities.
+//
+void DUsbcLogDevice::GetCaps(TDes8& aDes) const
+ {
+ TPckgBuf<TCapsDevUsbc> b;
+ b().version = iVersion;
+ Kern::InfoCopy(aDes, b);
+ }
+
+
+//
+// Constructor
+//
+DLddUsbcChannel::DLddUsbcChannel()
+ : iValidInterface(EFalse),
+ iAlternateSettingList(NULL),
+ iCompleteAllCallbackInfo(this, DLddUsbcChannel::EmergencyCompleteDfc, KUsbRequestCallbackPriority),
+ iStatusChangePtr(NULL),
+ iStatusCallbackInfo(this, DLddUsbcChannel::StatusChangeCallback, KUsbRequestCallbackPriority),
+ iEndpointStatusChangePtr(NULL),
+ iEndpointStatusCallbackInfo(this, DLddUsbcChannel::EndpointStatusChangeCallback,
+ KUsbRequestCallbackPriority),
+ iOtgFeatureChangePtr(NULL),
+ iOtgFeatureCallbackInfo(this, DLddUsbcChannel::OtgFeatureChangeCallback, KUsbRequestCallbackPriority),
+ iBufferBaseEp0(NULL),
+ iBufferSizeEp0(0),
+ iNumberOfEndpoints(0),
+ iHwChunkIN(NULL),
+ iHwChunkOUT(NULL),
+ iHwChunkEp0(NULL),
+ iDeviceState(EUsbcDeviceStateUndefined),
+ iOwnsDeviceControl(EFalse),
+ iAlternateSetting(0),
+ iDeviceStatusNeeded(EFalse),
+ iChannelClosing(EFalse)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("*** DLddUsbcChannel::DLddUsbcChannel CTOR"));
+ iClient = &Kern::CurrentThread();
+ iClient->Open();
+ for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
+ {
+ iEndpoint[i] = NULL;
+ }
+ for (TInt i = 1; i < KUsbcMaxRequests; i++)
+ {
+ iRequestStatus[i] = NULL;
+ }
+ }
+
+
+DLddUsbcChannel::~DLddUsbcChannel()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::~DLddUsbcChannel()"));
+ if (iController)
+ {
+ iStatusCallbackInfo.Cancel();
+ iEndpointStatusCallbackInfo.Cancel();
+ iOtgFeatureCallbackInfo.Cancel();
+ iCompleteAllCallbackInfo.Cancel();
+ AbortInterface();
+ DestroyAllInterfaces();
+ if (iOwnsDeviceControl)
+ {
+ iController->ReleaseDeviceControl(this);
+ iOwnsDeviceControl = EFalse;
+ }
+ iController->DeRegisterClient(this);
+ DestroyEp0();
+ delete iStatusFifo;
+ }
+ Kern::SafeClose((DObject*&)iClient, NULL);
+ }
+
+
+inline TBool DLddUsbcChannel::ValidEndpoint(TInt aEndpoint)
+ {
+ return (aEndpoint <= iNumberOfEndpoints && aEndpoint >= 0);
+ }
+
+
+//
+// Create channel
+//
+TInt DLddUsbcChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("LDD DoCreateL 1 Ver = %02d %02d %02d",
+ // aVer.iMajor, aVer.iMinor, aVer.iBuild));
+ if (!Kern::CurrentThreadHasCapability(ECapabilityCommDD,
+ __PLATSEC_DIAGNOSTIC_STRING("Checked by USBC.LDD (USB Driver)")))
+ {
+ return KErrPermissionDenied;
+ }
+
+ iController = DUsbClientController::UsbcControllerPointer();
+
+ if (!iController)
+ {
+ return KErrGeneral;
+ }
+
+ if (!iController->IsActive())
+ return KErrDisconnected;
+
+ iStatusFifo = new TUsbcDeviceStatusQueue;
+ if (iStatusFifo == NULL)
+ {
+ return KErrNoMemory;
+ }
+
+ if (!Kern::QueryVersionSupported(TVersion(KUsbcMajorVersion, KUsbcMinorVersion, KUsbcBuildVersion), aVer))
+ {
+ return KErrNotSupported;
+ }
+
+ // set up the correct DFC queue
+ SetDfcQ(iController->DfcQ(0)); // sets the channel's dfc queue
+ iCompleteAllCallbackInfo.SetDfcQ(iDfcQ);
+ iController->RegisterClientCallback(iCompleteAllCallbackInfo);
+ iStatusCallbackInfo.SetDfcQ(iDfcQ); // use the channel's dfcq for this dfc
+ iEndpointStatusCallbackInfo.SetDfcQ(iDfcQ); // use the channel's dfcq for this dfc
+ iOtgFeatureCallbackInfo.SetDfcQ(iDfcQ);
+ iMsgQ.Receive(); //start up the message q
+ iController->RegisterForStatusChange(iStatusCallbackInfo); // let the ldd start seeing device state changes
+ return KErrNone;
+ }
+
+
+void DLddUsbcChannel::HandleMsg(TMessageBase* aMsg)
+ {
+ TThreadMessage& m = *(TThreadMessage*)aMsg;
+ TInt id = m.iValue;
+ if (id == (TInt) ECloseMsg)
+ {
+ iChannelClosing = ETrue;
+ m.Complete(KErrNone, EFalse);
+ return;
+ }
+ else if (id == KMaxTInt)
+ {
+ // Cancel request
+ TInt mask = m.Int0();
+ TInt b = 1;
+ for(TInt reqNo = 0; reqNo <= KUsbcMaxRequests; reqNo++)
+ {
+ TRequestStatus* pS = iRequestStatus[reqNo];
+ if ((mask & b) && (pS != NULL))
+ {
+ TInt r = DoCancel(reqNo);
+ if (r == KErrNone)
+ r = KErrCancel;
+ Kern::RequestComplete(iClient,iRequestStatus[reqNo], r);
+ }
+ b <<= 1;
+ }
+ m.Complete(KErrNone, ETrue);
+ return;
+ }
+
+ if (!iController->IsActive())
+ {
+ if (id != RDevUsbcClient::EControlEnableUsbDriver)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::HandleMsg - Controller is not active"));
+ m.Complete(KErrDisconnected, ETrue);
+ return;
+ }
+ }
+ if (id < 0)
+ {
+ // DoRequest
+ TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
+ DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
+ m.Complete(KErrNone, ETrue);
+ }
+ else
+ {
+ // DoControl
+ TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
+ m.Complete(r, ETrue);
+ }
+ }
+
+
+//
+// Overriding DObject virtual
+//
+TInt DLddUsbcChannel::RequestUserHandle(DThread* aThread, TOwnerType /*aType*/)
+ {
+ __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::RequestUserHandle"));
+ // The USB client LDD is not designed for a channel to be shared between
+ // threads. It saves a pointer to the current thread when it is opened, and
+ // uses this to complete any asynchronous requests.
+ // It is therefore not acceptable for the handle to be duplicated and used
+ // by another thread:
+ if (aThread == iClient)
+ {
+ return KErrNone;
+ }
+ else
+ {
+ return KErrAccessDenied;
+ }
+ }
+// Asynchronous requests - overriding pure virtual
+//
+void DLddUsbcChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
+ {
+ // Check on request status
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest 0x%08x", aReqNo));
+ if (aReqNo <= KUsbcMaxRequests)
+ {
+ TInt r = KErrNone;
+ if (iRequestStatus[aReqNo] != NULL)
+ {
+ DestroyAllInterfaces();
+ PanicClientThread(ERequestAlreadyPending);
+ }
+ else
+ {
+ TBool needsCompletion;
+ iRequestStatus[aReqNo] = aStatus;
+
+ if (aReqNo > KUsbcMaxEpNumber)
+ {
+ r = DoOtherAsyncReq(aReqNo, a1, a2, needsCompletion);
+ }
+ else
+ {
+ r = DoTransferAsyncReq(aReqNo, a1, a2, needsCompletion);
+ }
+
+ if (needsCompletion)
+ {
+ Kern::RequestComplete(iClient, iRequestStatus[aReqNo], r);
+ }
+ }
+ }
+ else
+ {
+ Kern::RequestComplete(iClient, aStatus, KErrNotSupported);
+ }
+ }
+
+
+TInt DLddUsbcChannel::DoOtherAsyncReq(TInt aReqNo, TAny* a1, TAny* a2, TBool& aNeedsCompletion)
+ {
+ // The general assumption is that none of these will complete now.
+ // However, those that make this function return something other than
+ // KErrNone will get completed by the calling function.
+ // So, 1) If you are returning KErrNone but really need to complete because
+ // completion criteria can be met (for example, sufficient data is
+ // available in the buffer) and then set aNeedsCompletion = ETrue.
+ // 2) Do NOT complete here AT ALL.
+ //
+ aNeedsCompletion = EFalse;
+ TInt r = KErrNone;
+
+ switch (aReqNo)
+ {
+ case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlReqDeviceStatusNotify"));
+ if (a1 != NULL)
+ {
+ iDeviceStatusNeeded = ETrue;
+ iStatusChangePtr = a1;
+ aNeedsCompletion = AlternateDeviceStateTestComplete();
+ }
+ else
+ r = KErrArgument;
+ break;
+ }
+ case RDevUsbcClient::ERequestReEnumerate:
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("ERequestReEnumerate"));
+ // If successful, this will complete via the status notification.
+ r = iController->ReEnumerate();
+ break;
+ }
+ case RDevUsbcClient::ERequestEndpointStatusNotify:
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("ERequestEndpointStatusNotify"));
+ if (a1 != NULL)
+ {
+ iEndpointStatusChangePtr = a1;
+ iController->RegisterForEndpointStatusChange(iEndpointStatusCallbackInfo);
+ }
+ else
+ r = KErrArgument;
+ break;
+ }
+ case RDevUsbcClient::ERequestOtgFeaturesNotify:
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("ERequestOtgFeaturesNotify"));
+ if (a1 != NULL)
+ {
+ iOtgFeatureChangePtr = a1;
+ iController->RegisterForOtgFeatureChange(iOtgFeatureCallbackInfo);
+ }
+ else
+ r = KErrArgument;
+ break;
+ }
+ default:
+ r = KErrNotSupported;
+ }
+
+ aNeedsCompletion = aNeedsCompletion || (r != KErrNone);
+
+ return r;
+ }
+
+
+TInt DLddUsbcChannel::DoTransferAsyncReq(TInt aEndpointNum, TAny* a1, TAny* a2, TBool& aNeedsCompletion)
+ {
+ // The general assumption is that none of these will complete now.
+ // however, those that are returning something other than KErrNone will get completed
+ // by the calling function.
+ // So, 1) if you are returning KErrNone but really need to complete because completion criteria can be met
+ // (for example, sufficient data is available in the buffer) and then set aNeedsCompletion=ETrue..
+ // 2) Do NOT complete here AT ALL.
+ //
+ aNeedsCompletion = EFalse;
+ TInt r = KErrNone;
+ TUsbcEndpoint* pEndpoint = NULL;
+ TUsbcEndpointInfo* pEndpointInfo = NULL;
+ TEndpointTransferInfo* pTfr = NULL;
+
+ if (aEndpointNum == 0)
+ {
+ // ep0 requests
+ if (!(iValidInterface || iOwnsDeviceControl))
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest rejected: not configured (Ep0)"));
+ r = KErrUsbInterfaceNotReady;
+ goto exit;
+ }
+ }
+ else
+ {
+ // other eps
+ if (!(iValidInterface && (iDeviceState == EUsbcDeviceStateConfigured ||
+ iDeviceState == EUsbcDeviceStateSuspended))
+ )
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest rejected not configured (Ep %d)", aEndpointNum));
+ r = KErrUsbInterfaceNotReady;
+ goto exit;
+ }
+ }
+
+ if (!ValidEndpoint(aEndpointNum))
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Read: in error complete"));
+ r = KErrUsbEpNotInInterface;
+ goto exit;
+ }
+
+ if (a1 == NULL)
+ {
+ r = KErrArgument;
+ goto exit;
+ }
+
+ TEndpointTransferInfo transferInfo;
+ pTfr = &transferInfo;
+ r = Kern::ThreadRawRead(iClient, a1, pTfr, sizeof(TEndpointTransferInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ pEndpoint = iEndpoint[aEndpointNum];
+ if (!pEndpoint)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Read: in error complete"));
+ r = KErrUsbEpNotInInterface;
+ goto exit;
+ }
+
+ pEndpointInfo = pEndpoint->EndpointInfo();
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest %d", aEndpointNum));
+
+ switch (pTfr->iTransferType)
+ {
+
+ case ETransferTypeReadData:
+ case ETransferTypeReadPacket:
+ case ETransferTypeReadUntilShort:
+ case ETransferTypeReadOneOrMore:
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read"));
+ if (pEndpoint->iDmaBuffers->RxIsActive())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("**** ReadReq ep%d RxActive", aEndpointNum));
+ }
+ else
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("**** ReadReq ep%d RxInActive", aEndpointNum));
+ }
+
+ if (pEndpointInfo->iDir != KUsbEpDirOut &&
+ pEndpointInfo->iDir != KUsbEpDirBidirect)
+ {
+ // Trying to do the wrong thing
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Read: in error complete"));
+ r = KErrUsbEpBadDirection;
+ break;
+ }
+ // Set the length of data to zero now to catch all cases
+ TPtrC8 pZeroDesc(NULL, 0);
+ // Set client descriptor length to zero
+ r = Kern::ThreadDesWrite(iClient, pTfr->iDes, pZeroDesc, 0, 0, iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ pEndpoint->SetTransferInfo(pTfr);
+ if (pEndpoint->iDmaBuffers->IsReaderEmpty())
+ {
+ pEndpoint->SetClientReadPending(ETrue);
+ }
+ else
+ {
+ if (pTfr->iTransferType == ETransferTypeReadPacket)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read packet: data available complete"));
+ r = pEndpoint->CopyToClient(iClient);
+ aNeedsCompletion = ETrue;
+ break;
+ }
+ else if (pTfr->iTransferType == ETransferTypeReadData)
+ {
+ if (pTfr->iTransferSize <= pEndpoint->RxBytesAvailable())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
+ r = pEndpoint->CopyToClient(iClient);
+ aNeedsCompletion = ETrue;
+ break;
+ }
+ else
+ {
+ pEndpoint->SetClientReadPending(ETrue);
+ }
+ }
+ else if (pTfr->iTransferType == ETransferTypeReadOneOrMore)
+ {
+ if (pEndpoint->RxBytesAvailable() > 0)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
+ r = pEndpoint->CopyToClient(iClient);
+ aNeedsCompletion = ETrue;
+ break;
+ }
+ else
+ {
+ pEndpoint->SetClientReadPending(ETrue);
+ }
+ }
+ else if (pTfr->iTransferType == ETransferTypeReadUntilShort)
+ {
+ TInt nRx = pEndpoint->RxBytesAvailable();
+ TInt maxPacketSize = pEndpoint->EndpointInfo()->iSize;
+ if( (pTfr->iTransferSize <= nRx) ||
+ (nRx < maxPacketSize) ||
+ pEndpoint->iDmaBuffers->ShortPacketExists())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
+ r = pEndpoint->CopyToClient(iClient);
+ aNeedsCompletion = ETrue;
+ }
+ else
+ {
+ pEndpoint->SetClientReadPending(ETrue);
+ }
+ }
+ }
+ r = pEndpoint->TryToStartRead(EFalse);
+ if (r != KErrNone)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Read: couldn't start read"));
+ r = KErrNone; // Reader full isn't a userside error;
+ }
+ break;
+ }
+
+ case ETransferTypeWrite:
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 1"));
+ if (pEndpointInfo->iDir != KUsbEpDirIn &&
+ pEndpointInfo->iDir != KUsbEpDirBidirect)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Write: wrong direction complete"));
+ r = KErrUsbEpBadDirection;
+ break;
+ }
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 2"));
+
+ TAny* logicalSrc = pTfr->iDes;
+ TInt desLength = Kern::ThreadGetDesLength(iClient, logicalSrc);
+ if (desLength < pTfr->iTransferSize)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Write: user buffer too short"));
+ r = KErrUsbTransferSize;
+ break;
+ }
+
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 3 length=%d maxlength=%d",
+ // pTfr->iTransferSize, desLength));
+ // Zero length writes are acceptable
+ pEndpoint->SetClientWritePending(ETrue);
+ r = pEndpoint->TryToStartWrite(pTfr);
+ if (r != KErrNone)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Write: couldn't start write"));
+ pEndpoint->SetClientWritePending(EFalse);
+ }
+ break;
+ }
+
+ default:
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoTransferAsyncReq: pTfr->iTransferType = %d not supported",
+ // pTfr->iTransferType));
+ r = KErrNotSupported;
+ break;
+ }
+ exit:
+ aNeedsCompletion = aNeedsCompletion || (r != KErrNone);
+ return r;
+ }
+
+
+//
+// Cancel an outstanding request - overriding pure virtual
+//
+TInt DLddUsbcChannel::DoCancel(TInt aReqNo)
+ {
+ TInt r = KErrNone;
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoCancel: 0x%x", aReqNo));
+ if (aReqNo <= iNumberOfEndpoints)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoCancel endpoint: 0x%x", aReqNo));
+ iEndpoint[aReqNo]->CancelTransfer(iClient);
+ }
+ else if (aReqNo == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoCancel: ERequestAlternateDeviceStatusNotify 0x%x", aReqNo));
+ iDeviceStatusNeeded = EFalse;
+ iStatusFifo->FlushQueue();
+ if (iStatusChangePtr)
+ {
+ TInt deviceState = iController->GetDeviceStatus();
+ r = Kern::ThreadRawWrite(iClient, iStatusChangePtr, &deviceState, sizeof(deviceState), iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ iStatusChangePtr = NULL;
+ }
+ }
+ else if (aReqNo == RDevUsbcClient::ERequestReEnumerate)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestReEnumerate: 0x%x", aReqNo));
+ }
+ else if (aReqNo == RDevUsbcClient::ERequestEndpointStatusNotify)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestEndpointStatusNotify: 0x%x", aReqNo));
+ CancelNotifyEndpointStatus();
+ }
+ else if (aReqNo == RDevUsbcClient::ERequestOtgFeaturesNotify)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestOtgFeaturesNotify: 0x%x", aReqNo));
+ CancelNotifyOtgFeatures();
+ }
+ else
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoCancel Unknown! 0x%x", aReqNo));
+ }
+
+ return r;
+ }
+
+
+void DLddUsbcChannel::CancelNotifyEndpointStatus()
+ {
+ if (iEndpointStatusChangePtr)
+ {
+ TUint epBitmap = 0;
+ for (TInt i = 0; i <= iNumberOfEndpoints; i++)
+ {
+ TInt v = iController->GetEndpointStatus(this, iEndpoint[i]->RealEpNumber());
+ TUint b;
+ (v == EEndpointStateStalled) ? b = 1 : b = 0;
+ epBitmap |= b << i;
+ }
+ Kern::ThreadRawWrite(iClient, iEndpointStatusChangePtr, (TUint8*) &epBitmap, sizeof(epBitmap), iClient);
+ iEndpointStatusChangePtr = NULL;
+ }
+ iController->DeRegisterForEndpointStatusChange(this);
+ }
+
+
+void DLddUsbcChannel::CancelNotifyOtgFeatures()
+ {
+ if (iOtgFeatureChangePtr)
+ {
+ TUint8 features;
+ iController->GetCurrentOtgFeatures(features);
+ Kern::ThreadRawWrite(iClient, iOtgFeatureChangePtr, (TUint8*)&features, sizeof(features), iClient);
+ iOtgFeatureChangePtr = NULL;
+ }
+ iController->DeRegisterForOtgFeatureChange(this);
+ }
+
+
+TInt DLddUsbcChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DoControl: %d", aFunction));
+
+ TInt r = KErrNone;
+ TInt ep, param;
+ TUsbcEndpoint* pEndpoint;
+ TPtrC8 pZeroDesc(NULL, 0);
+ TEndpointDescriptorInfo epInfo;
+ TUsbcIfcInfo ifcInfo;
+ TCSDescriptorInfo desInfo;
+ TUsbcEndpointResource epRes;
+ TInt bandwidthPriority;
+
+ /****declare trace objects and variables*******/
+ CUTraces Testtracer;
+ int ret=1;
+ TUTrace TestTraceObject(UTracePrimary, UTraceSecondary, schema, context, pc);
+ TUTrace NegTraceObject1((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary+1), schema, context, pc);
+ TUTrace NegTraceObject2((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+2), schema, context, pc);
+ TUTrace MultTraceObject1((TPrimaryFilter)(UTracePrimary), (TSecondaryFilter)(UTraceSecondary+2),schema, context, pc );
+ TUTrace MultTraceObject2((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary),schema, context, pc );
+ TUTrace MultTraceObject3((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+1),schema, context, pc );
+ TUTrace MultTraceObject4((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary),schema, context, pc );
+ TUTrace MultTraceObject5((TPrimaryFilter)(UTracePrimary+2),schema, context, pc );
+
+
+ switch (aFunction)
+ {
+ case RDevUsbcClient::EControlEndpointZeroRequestError:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroRequestError"));
+
+ /****************UTRACE METHOD - ALL BASIC LOGGING*********************************/
+ for(int tracetag=0; tracetag!=NumberOfUTraceMacros&&ret;tracetag++)
+ {
+ ret = 0;
+ ret = Testtracer.DoTheTrace(tracetag);
+ }
+ for(int tracetag=0; tracetag!=NumberOfUTraceMacros&&ret;tracetag++)
+ {
+ ret = 0;
+ ret = Testtracer.DoTheSetTrace(tracetag, TestTraceObject);
+ }
+ for(int tracetag=0; tracetag!=NumberOfUTraceMacros&&ret;tracetag++)
+ {
+ ret = 0;
+ ret = Testtracer.DoTheStaticTrace(tracetag);
+ }
+
+ //put in extra logs for negative trace test
+
+ NegTraceObject1.Trace();
+ NegTraceObject2.Trace();
+
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary+1), schema, context, pc);
+ TestTraceObject.Trace();
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+2), schema, context, pc);
+ TestTraceObject.Trace();
+
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary+1), schema, context, pc);
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+2), schema, context, pc);
+
+
+
+
+ // for(int tracetag=0; tracetag!=NumberOfPrintfMacros&&ret;tracetag++)
+ // {
+ // ret = 0;
+ // ret = Testtracer.DoThePrintf(tracetag);
+ // }
+ // for(int tracetag=0; tracetag!=NumberOfPrintfMacros&&ret;tracetag++)
+ // {
+ // ret = 0;
+ // ret = Testtracer.DoTheStaticPrintf(tracetag);
+ // }
+
+
+
+ /****************End of Tracing**************************************/
+ r = KErrNone;
+ if (iOwnsDeviceControl || (iValidInterface && iDeviceState == EUsbcDeviceStateConfigured))
+ {
+ iController->Ep0Stall(this);
+ }
+ else
+ {
+ if (iDeviceState != EUsbcDeviceStateConfigured)
+ r = KErrUsbDeviceNotConfigured;
+ else
+ r = KErrUsbInterfaceNotReady;
+ }
+ break;
+
+ case RDevUsbcClient::EControlGetAlternateSetting:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetAlternateSetting"));
+ /****************UTRACE METHOD NONstatic 0*********************************/
+ Testtracer.DoTheSetTrace(0, TestTraceObject);
+
+ if (iValidInterface && iDeviceState == EUsbcDeviceStateConfigured)
+ {
+ r = iController->GetInterfaceNumber(this, param);
+ if (r == KErrNone)
+ {
+ r = Kern::ThreadRawWrite(iClient, a1, ¶m, sizeof(param), iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ }
+ }
+ else
+ {
+ if (iDeviceState != EUsbcDeviceStateConfigured)
+ r = KErrUsbDeviceNotConfigured;
+ else
+ r = KErrUsbInterfaceNotReady;
+ }
+ break;
+
+ case RDevUsbcClient::EControlDeviceStatus:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceStatus"));
+ param = iController->GetDeviceStatus();
+ r = Kern::ThreadRawWrite(iClient, a1, ¶m, sizeof(param), iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ break;
+
+ case RDevUsbcClient::EControlEndpointStatus:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointStatus"));
+ if (iValidInterface && ValidEndpoint((TInt) a1))
+ {
+ pEndpoint = iEndpoint[(TInt)a1];
+ if (pEndpoint == NULL)
+ r = KErrNotSupported;
+ else
+ {
+ param = iController->GetEndpointStatus(this, iEndpoint[(TInt)a1]->RealEpNumber());
+ r = Kern::ThreadRawWrite(iClient, a2, ¶m, sizeof(param), iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ }
+ }
+ else
+ {
+ if (iDeviceState != EUsbcDeviceStateConfigured)
+ r = KErrUsbDeviceNotConfigured;
+ else
+ r = KErrUsbInterfaceNotReady;
+ }
+ break;
+
+ case RDevUsbcClient::EControlQueryReceiveBuffer:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlQueryReceiveBuffer"));
+ if (iValidInterface && ValidEndpoint((TInt) a1))
+ {
+ pEndpoint=iEndpoint[(TInt) a1];
+ if (pEndpoint == NULL)
+ r = KErrNotSupported;
+ else if (pEndpoint->EndpointInfo()->iDir != KUsbEpDirIn)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" bytes = %d", pEndpoint->RxBytesAvailable()));
+ param = pEndpoint->RxBytesAvailable();
+ r = Kern::ThreadRawWrite(iClient, a2, ¶m, sizeof(param), iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ }
+ }
+ else
+ {
+ if (iDeviceState != EUsbcDeviceStateConfigured)
+ r = KErrUsbDeviceNotConfigured;
+ else
+ r = KErrUsbInterfaceNotReady;
+ }
+ break;
+
+ case RDevUsbcClient::EControlEndpointCaps:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointCaps"));
+ r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ iController->EndpointCaps(this, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlDeviceCaps:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceCaps"));
+ r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ iController->DeviceCaps(this, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSendEp0StatusPacket:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSendEp0StatusPacket"));
+ //**********************UTRACE METHOD NONstatic 2***********************/
+ Testtracer.DoTheSetTrace(2, TestTraceObject);
+
+ iController->SendEp0StatusPacket(this);
+ break;
+
+ case RDevUsbcClient::EControlHaltEndpoint:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlHaltEndpoint"));
+ if (iValidInterface && ValidEndpoint((TInt) a1))
+ {
+ r = iController->HaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
+ }
+ else
+ {
+ if (iDeviceState != EUsbcDeviceStateConfigured)
+ r = KErrUsbDeviceNotConfigured;
+ else
+ r = KErrUsbInterfaceNotReady;
+ }
+ break;
+
+ case RDevUsbcClient::EControlClearHaltEndpoint:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlClearHaltEndpoint"));
+ if (iValidInterface && ValidEndpoint((TInt) a1))
+ {
+ r = iController->ClearHaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
+ }
+ else
+ {
+ if (iDeviceState != EUsbcDeviceStateConfigured)
+ r = KErrUsbDeviceNotConfigured;
+ else
+ r = KErrUsbInterfaceNotReady;
+ }
+ break;
+
+ case RDevUsbcClient::EControlDumpRegisters:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlDumpRegisters"));
+ iController->DumpRegisters();
+ break;
+
+ case RDevUsbcClient::EControlReleaseDeviceControl:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseDeviceControl"));
+ //**********************UTRACE METHOD NONstatic 3***********************/
+ Testtracer.DoTheSetTrace(3, TestTraceObject);
+
+ iController->ReleaseDeviceControl(this);
+ iOwnsDeviceControl = EFalse;
+ break;
+
+ case RDevUsbcClient::EControlEndpointZeroMaxPacketSizes:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroMaxPacketSizes"));
+ //**********************UTRACE METHOD NONstatic 4***********************/
+ Testtracer.DoTheSetTrace(4, TestTraceObject);
+
+
+ r = iController->EndpointZeroMaxPacketSizes();
+ break;
+
+ case RDevUsbcClient::EControlSetEndpointZeroMaxPacketSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointZeroMaxPacketSize"));
+ //**********************UTRACE METHOD NONstatic 5***********************/
+ Testtracer.DoTheSetTrace(5, TestTraceObject);
+
+ r = iController->SetEndpointZeroMaxPacketSize(reinterpret_cast<TInt>(a1));
+ break;
+
+ case RDevUsbcClient::EControlGetEndpointZeroMaxPacketSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointZeroMaxPacketSize"));
+ //**********************UTRACE METHOD NONstatic 6***********************/
+ Testtracer.DoTheSetTrace(6, TestTraceObject);
+
+ r = iController->Ep0PacketSize();
+ break;
+
+ case RDevUsbcClient::EControlGetDeviceDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptor"));
+ //**********************UTRACE METHOD NONstatic 7***********************/
+ Testtracer.DoTheSetTrace(7, TestTraceObject);
+
+ r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ r = iController->GetDeviceDescriptor(iClient, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetDeviceDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceDescriptor"));
+ //**********************UTRACE METHOD NONstatic 8***********************/
+ Testtracer.DoTheSetTrace(8, TestTraceObject);
+
+ if (a1 != NULL)
+ r = iController->SetDeviceDescriptor(iClient, *((TDes8*) a1));
+ else
+ r = KErrArgument;
+ break;
+
+ case RDevUsbcClient::EControlGetDeviceDescriptorSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptorSize"));
+ //**********************UTRACE METHOD NONstatic 9***********************/
+ Testtracer.DoTheSetTrace(9, TestTraceObject);
+
+ if (a1 != NULL)
+ r = iController->GetDeviceDescriptorSize(iClient, *((TDes8*) a1));
+ else
+ r = KErrArgument;
+ break;
+
+ case RDevUsbcClient::EControlGetConfigurationDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptor"));
+ //**********************UTRACE METHOD NONstatic 10***********************/
+ Testtracer.DoTheSetTrace(10, TestTraceObject);
+
+ r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ r = iController->GetConfigurationDescriptor(iClient, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptorSize"));
+ //**********************UTRACE METHOD NONstatic 11***********************/
+ Testtracer.DoTheSetTrace(11, TestTraceObject);
+
+ if (a1 != NULL)
+ {
+ r = iController->GetConfigurationDescriptorSize(iClient, *((TDes8*) a1));
+ }
+ else
+ r = KErrArgument;
+ break;
+
+ case RDevUsbcClient::EControlSetConfigurationDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationDescriptor"));
+ //**********************UTRACE METHOD NONstatic 12***********************/
+ Testtracer.DoTheSetTrace(12, TestTraceObject);
+
+ r = iController->SetConfigurationDescriptor(iClient, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlGetInterfaceDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptor"));
+ //**********************UTRACE METHOD NONstatic 13***********************/
+ Testtracer.DoTheSetTrace(13, TestTraceObject);
+
+ r = iController->GetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
+ break;
+
+ case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptorSize"));
+ //**********************UTRACE METHOD NONstatic 14***********************/
+ Testtracer.DoTheSetTrace(14, TestTraceObject);
+
+ r = iController->GetInterfaceDescriptorSize(iClient, this, (TInt) a1, *(TDes8*) a2);
+ break;
+
+ case RDevUsbcClient::EControlSetInterfaceDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterfaceDescriptor"));
+ //**********************UTRACE METHOD NONstatic 15***********************/
+ Testtracer.DoTheSetTrace(15, TestTraceObject);
+
+ r = iController->SetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
+ break;
+
+ case RDevUsbcClient::EControlGetEndpointDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptor"));
+ //**********************UTRACE METHOD NONstatic 16***********************/
+ Testtracer.DoTheSetTrace(16, TestTraceObject);
+
+ r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
+ r = iController->GetEndpointDescriptor(iClient, this, epInfo.iSetting,
+ ep, *(TDes8*) epInfo.iArg);
+ break;
+
+ case RDevUsbcClient::EControlGetEndpointDescriptorSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptorSize"));
+ //**********************UTRACE METHOD NONstatic 17***********************/
+ Testtracer.DoTheSetTrace(17, TestTraceObject);
+
+ r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
+ r = iController->GetEndpointDescriptorSize(iClient, this, epInfo.iSetting,
+ ep, *(TDes8*) epInfo.iArg);
+ break;
+
+ case RDevUsbcClient::EControlSetEndpointDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointDescriptor"));
+ //**********************UTRACE METHOD NONstatic 18***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheSetTrace(18, TestTraceObject);
+
+ r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
+ r = iController->SetEndpointDescriptor(iClient, this, epInfo.iSetting,
+ ep, *(TDes8*)epInfo.iArg);
+ break;
+
+ case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceQualifierDescriptor"));
+ //**********************UTRACE METHOD NONstatic 19***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheSetTrace(19, TestTraceObject);
+
+ r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ r = iController->GetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceQualifierDescriptor"));
+ //**********************UTRACE METHOD NONstatic 20***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheSetTrace(20, TestTraceObject);
+
+ if (a1 != NULL)
+ r = iController->SetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
+ else
+ r = KErrArgument;
+ break;
+
+ case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetOtherSpeedConfigurationDescriptor"));
+ //**********************UTRACE METHOD NONstatic 21***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheSetTrace(21, TestTraceObject);
+
+ r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ r = iController->GetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetOtherSpeedConfigurationDescriptor"));
+ //**********************UTRACE METHOD NONstatic 22***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheSetTrace(22, TestTraceObject);
+
+ r = iController->SetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
+ break;
+
+
+ case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptor"));
+ //**********************UTRACE METHOD NONstatic 23***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheSetTrace(23, TestTraceObject);
+
+ r = iController->GetCSInterfaceDescriptorBlock(iClient, this, (TInt) a1, *((TDes8*) a2));
+ break;
+
+ case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptorSize"));
+ //**********************UTRACE METHOD STATIC 0***********************/
+ Testtracer.DoTheStaticTrace(0);
+
+ r = iController->GetCSInterfaceDescriptorBlockSize(iClient, this, (TInt) a1, *(TDes8*) a2);
+ break;
+
+ case RDevUsbcClient::EControlGetCSEndpointDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptor"));
+ //**********************UTRACE METHOD STATIC 1***********************/
+ Testtracer.DoTheStaticTrace(1);
+
+ r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
+ r = iController->GetCSEndpointDescriptorBlock(iClient, this, epInfo.iSetting,
+ ep, *(TDes8*) epInfo.iArg);
+ break;
+
+ case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptorSize"));
+ //**********************UTRACE METHOD STATIC 2***********************/
+ Testtracer.DoTheStaticTrace(2);
+
+ r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
+ r = iController->GetCSEndpointDescriptorBlockSize(iClient, this, epInfo.iSetting,
+ ep, *(TDes8*) epInfo.iArg);
+ break;
+
+ case RDevUsbcClient::EControlSignalRemoteWakeup:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSignalRemoteWakeup"));
+ //**********************UTRACE METHOD STATIC 3***********************/
+ Testtracer.DoTheStaticTrace(3);
+
+
+ r = iController->SignalRemoteWakeup();
+ break;
+
+ case RDevUsbcClient::EControlDeviceDisconnectFromHost:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceDisconnectFromHost"));
+ r = iController->UsbDisconnect();
+ break;
+
+ case RDevUsbcClient::EControlDeviceConnectToHost:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceConnectToHost"));
+ r = iController->UsbConnect();
+ break;
+
+ case RDevUsbcClient::EControlDevicePowerUpUdc:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlDevicePowerUpUdc"));
+ //**********************UTRACE METHOD STATIC 4***********************/
+ Testtracer.DoTheStaticTrace(4);
+
+ r = iController->PowerUpUdc();
+ break;
+
+ case RDevUsbcClient::EControlSetDeviceControl:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl"));
+ //**********************UTRACE METHOD STATIC 5***********************/
+ Testtracer.DoTheStaticTrace(5);
+
+ r = iController->SetDeviceControl(this);
+ if (r == KErrNone)
+ {
+ iOwnsDeviceControl = ETrue;
+ if (iEndpoint[0] == NULL)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl 11"));
+ r = SetupEp0();
+ if (r != KErrNone)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: SetupEp0() failed"));
+ iController->ReleaseDeviceControl(this);
+ DestroyEp0();
+ iOwnsDeviceControl = EFalse;
+ }
+ iEndpoint[0]->TryToStartRead(EFalse);
+ }
+ }
+ else
+ r = KErrInUse;
+ break;
+
+ case RDevUsbcClient::EControlCurrentlyUsingHighSpeed:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlCurrentlyUsingHighSpeed"));
+ //**********************UTRACE METHOD STATIC 6***********************/
+ Testtracer.DoTheStaticTrace(6);
+
+ r = iController->CurrentlyUsingHighSpeed();
+ break;
+
+ case RDevUsbcClient::EControlSetInterface:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterface"));
+ r = Kern::ThreadRawRead(iClient, a2, &ifcInfo, sizeof(ifcInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ bandwidthPriority = ifcInfo.iBandwidthPriority;
+ if ((bandwidthPriority & 0xffffff00) ||
+ ((bandwidthPriority & 0x0f) >= KUsbcDmaBufMaxPriorities) ||
+ (((bandwidthPriority >> 4) & 0x0f) >= KUsbcDmaBufMaxPriorities))
+ {
+ r = KErrArgument;
+ }
+ else
+ {
+ r = SetInterface((TInt) a1, &ifcInfo);
+ }
+ break;
+
+ case RDevUsbcClient::EControlReleaseInterface:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseInterface"));
+ //**********************UTRACE METHOD STATIC 7***********************/
+ Testtracer.DoTheStaticTrace(7);
+
+ r = iController->ReleaseInterface(this, (TInt) a1);
+ if (r == KErrNone)
+ {
+ DestroyInterface((TUint) a1);
+ }
+ else
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error in PIL: LDD interface won't be released."));
+ }
+ break;
+
+ case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSInterfaceDescriptor"));
+ //**********************UTRACE METHOD STATIC 8***********************/
+ Testtracer.DoTheStaticTrace(8);
+
+ r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ r = iController->SetCSInterfaceDescriptorBlock(iClient, this, desInfo.iSetting,
+ *reinterpret_cast<const TDes8*>(desInfo.iArg),
+ desInfo.iSize);
+ break;
+
+ case RDevUsbcClient::EControlSetCSEndpointDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSEndpointDescriptor"));
+ //**********************UTRACE METHOD STATIC 9***********************/
+ Testtracer.DoTheStaticTrace(9);
+
+ r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
+ if (r != KErrNone)
+ PanicClientThread(r);
+ ep = EpFromAlternateSetting(desInfo.iSetting, desInfo.iEndpoint);
+ r = iController->SetCSEndpointDescriptorBlock(iClient, this, desInfo.iSetting, ep,
+ *reinterpret_cast<const TDes8*>(desInfo.iArg),
+ desInfo.iSize);
+ break;
+
+ case RDevUsbcClient::EControlGetStringDescriptorLangId:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptorLangId"));
+ //**********************Trace Multiple logging test***********************/
+ Testtracer.DoTheTrace(3);
+ NegTraceObject1.Trace(aData, aSize);
+ MultTraceObject1.Trace(aData, aSize);
+ MultTraceObject2.Trace(aData, aSize);
+ NegTraceObject2.Trace(aData, aSize);
+ MultTraceObject3.Trace(aData, aSize);
+ MultTraceObject4.Trace(aData, aSize);
+ MultTraceObject5.Trace(aData, aSize);
+
+
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary), (TSecondaryFilter)(UTraceSecondary), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary+1), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary), (TSecondaryFilter)(UTraceSecondary+2), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+2), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+1), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), schema, context, pc);
+ TestTraceObject.Trace(aData, aSize);
+
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary), (TSecondaryFilter)(UTraceSecondary), schema, context, pc, aData, aSize);
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary+1), schema, context, pc, aData, aSize);
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary), (TSecondaryFilter)(UTraceSecondary+2), schema, context, pc, aData, aSize);
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary), schema, context, pc, aData, aSize);
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+2), schema, context, pc, aData, aSize);
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary+2), (TSecondaryFilter)(UTraceSecondary+1), schema, context, pc, aData, aSize);
+ TUTrace::Trace((TPrimaryFilter)(UTracePrimary+1), (TSecondaryFilter)(UTraceSecondary), schema, context, pc, aData, aSize);
+ TUTrace::TracePrimary((TPrimaryFilter)(UTracePrimary+2), schema, context, pc, aData, aSize);
+
+
+ r = iController->GetStringDescriptorLangId(iClient, *((TDes8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetStringDescriptorLangId:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptorLangId"));
+ //**********************UTRACE METHOD STATIC 10***********************/
+ Testtracer.DoTheStaticTrace(10);
+
+ r = iController->SetStringDescriptorLangId(reinterpret_cast<TUint>(a1));
+ break;
+
+ case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetManufacturerStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 11***********************/
+ Testtracer.DoTheStaticTrace(11);
+
+ r = iController->GetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetManufacturerStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 12***********************/
+ Testtracer.DoTheStaticTrace(12);
+
+ r = iController->SetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlRemoveManufacturerStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveManufacturerStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 13***********************/
+ Testtracer.DoTheStaticTrace(13);
+
+ r = iController->RemoveManufacturerStringDescriptor();
+ break;
+
+ case RDevUsbcClient::EControlGetProductStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetProductStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 14***********************/
+ Testtracer.DoTheStaticTrace(14);
+
+ r = iController->GetProductStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetProductStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetProductStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 15***********************/
+ Testtracer.DoTheStaticTrace(15);
+
+ r = iController->SetProductStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlRemoveProductStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveProductStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 16***********************/
+ Testtracer.DoTheStaticTrace(16);
+
+ r = iController->RemoveProductStringDescriptor();
+ break;
+
+ case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetSerialNumberStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 17***********************/
+ Testtracer.DoTheStaticTrace(17);
+
+ r = iController->GetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetSerialNumberStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 18***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheStaticTrace(18);
+
+ r = iController->SetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlRemoveSerialNumberStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveSerialNumberStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 19***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheStaticTrace(19);
+
+
+ r = iController->RemoveSerialNumberStringDescriptor();
+ break;
+
+ case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationStringDescriptor"));
+ //**********************UTRACE METHOD NONstatic 1***********************/
+ Testtracer.DoTheSetTrace(1, TestTraceObject);
+ r = iController->GetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 21***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheStaticTrace(21);
+
+ r = iController->SetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
+ break;
+
+ case RDevUsbcClient::EControlRemoveConfigurationStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveConfigurationStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 22***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheStaticTrace(22);
+
+
+ r = iController->RemoveConfigurationStringDescriptor();
+ break;
+
+ case RDevUsbcClient::EControlGetStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptor"));
+ //**********************UTRACE METHOD STATIC 23***********************/
+ // for(int i=0;i!=UTrace_Count;i++)
+ // Testtracer.DoTheStaticTrace(23);
+
+ r = iController->GetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
+ break;
+
+ case RDevUsbcClient::EControlSetStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptor"));
+ //**********************UTrace PRINTF METHODS+NEGATIVE TEST***********************/
+ Testtracer.DoThePrintf(8);
+ Testtracer.DoThePrintf(12);
+ Testtracer.DoTheStaticPrintf(8);
+ Testtracer.DoTheStaticPrintf(12);
+
+ //put in extra logs for negative trace printf test
+
+ NegTraceObject1.Printf("c-style \"string\" with number %i!", 9999);
+ NegTraceObject2.Printf("c-style \"string\" with number %i!", 9999);
+
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+1), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+1), context, pc, "static string no %i", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+2), context, pc, "static string no %i", 9999);
+
+
+
+
+
+
+ /****************End of Printf Tracing**************************************/
+
+
+ r = iController->SetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
+ break;
+
+ case RDevUsbcClient::EControlRemoveStringDescriptor:
+ //__KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveStringDescriptor"));
+ //**********************Trace Multiple logging test***********************/
+ Testtracer.DoThePrintf(8);
+ NegTraceObject1.Printf("c-style \"string\" with number %i!", 9999);
+ MultTraceObject1.Printf("c-style \"string\" with number %i!", 9999);
+ MultTraceObject2.Printf("c-style \"string\" with number %i!", 9999);
+ NegTraceObject2.Printf("c-style \"string\" with number %i!", 9999);
+ MultTraceObject3.Printf("c-style \"string\" with number %i!", 9999);
+ MultTraceObject4.Printf("c-style \"string\" with number %i!", 9999);
+ MultTraceObject5.Printf("c-style \"string\" with number %i!", 9999);
+
+
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);;
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+1), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+1), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+ TestTraceObject.Set((TPrimaryFilter)(UTracePrimary+2), schema, context, pc);
+ TestTraceObject.Printf("c-style \"string\" with number %i!", 9999);
+
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary), context, pc, "c-style \"string\" with number %i!", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+1), context, pc, "c-style \"string\" with number %i!", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary), context, pc, "c-style \"string\" with number %i!", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+2), context, pc, "c-style \"string\" with number %i!", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+2), context, pc, "c-style \"string\" with number %i!", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+2), context, pc, "c-style \"string\" with number %i!", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+1), context, pc, "c-style \"string\" with number %i!", 9999);
+ TUTrace::PrintfPrimary((TPrimaryFilter)(UTracePrimary+2), context, pc, "c-style \"string\" with number %i!", 9999);
+
+
+ r = iController->RemoveStringDescriptor((TUint8) (TInt) a1);
+ break;
+
+ case RDevUsbcClient::EControlAllocateEndpointResource:
+
+
+ epRes = (TUsbcEndpointResource)((TInt) a2);
+ if (!ValidEndpoint((TInt)a1))
+ {
+ r = KErrUsbEpNotInInterface;
+ }
+ else
+ {
+ r = iController->AllocateEndpointResource(this, iEndpoint[(TInt)a1]->RealEpNumber(), epRes);
+ }
+ break;
+
+ case RDevUsbcClient::EControlDeAllocateEndpointResource:
+ epRes = (TUsbcEndpointResource)((TInt) a2);
+ if (!ValidEndpoint((TInt)a1))
+ {
+ r = KErrUsbEpNotInInterface;
+ }
+ else
+ {
+ r = iController->DeAllocateEndpointResource(this, iEndpoint[(TInt)a1]->RealEpNumber(), epRes);
+ }
+ break;
+
+ case RDevUsbcClient::EControlQueryEndpointResourceUse:
+ epRes = (TUsbcEndpointResource)((TInt) a2);
+ if (!ValidEndpoint((TInt)a1))
+ {
+ r = KErrUsbEpNotInInterface;
+ }
+ else
+ {
+ r = iController->QueryEndpointResource(this, iEndpoint[(TInt)a1]->RealEpNumber(), epRes);
+ }
+ break;
+
+ case RDevUsbcClient::EControlSetOtgDescriptor:
+ {
+ r = iController->SetOtgDescriptor(iClient, *((const TDesC8*)a1));
+ }
+ break;
+
+ case RDevUsbcClient::EControlGetOtgDescriptor:
+ {
+ r = iController->GetOtgDescriptor(iClient, *((TDes8*)a1));
+ }
+ break;
+
+ case RDevUsbcClient::EControlGetOtgFeatures:
+ {
+ r = iController->GetOtgFeatures(iClient, *((TDes8*)a1));
+ }
+ break;
+
+ case RDevUsbcClient::EControlEnableUsbDriver:
+ {
+ iController->EnableClientStack();
+ }
+ break;
+
+ case RDevUsbcClient::EControlDisableUsbDriver:
+ {
+ iController->DisableClientStack();
+ }
+ break;
+
+ default:
+ //__KTRACE_OPT(KUSB, Kern::Printf("Function code not supported"));
+ r = KErrNotSupported;
+ }
+
+ return r;
+ }
+
+
+TInt DLddUsbcChannel::SetInterface(TInt aInterfaceNumber, TUsbcIfcInfo* aInfoBuf)
+ {
+ TUsbcInterfaceInfoBuf ifc_info_buf;
+ TUsbcInterfaceInfoBuf* const ifc_info_buf_ptr = aInfoBuf->iInterfaceData;
+ const TInt srcLen = Kern::ThreadGetDesLength(iClient, ifc_info_buf_ptr);
+ if (srcLen < ifc_info_buf.Length())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface can't copy"));
+ PanicClientThread(EDesOverflow);
+ }
+
+ TInt r = Kern::ThreadDesRead(iClient, ifc_info_buf_ptr, ifc_info_buf, 0, KChunkShiftBy0);
+ if (r != KErrNone)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface Copy failed reason=%d", r));
+ PanicClientThread(r);
+ }
+
+ TUsbcEndpointInfo* pEndpointData = ifc_info_buf().iEndpointData;
+
+ // If an alternate interface is being asked for then do nothing,
+ // just pass it down to the Controller.
+ const TInt num_endpoints = ifc_info_buf().iTotalEndpointsUsed;
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface num_endpoints=%d", num_endpoints));
+
+ // [The next 4 variables have to be initialized here because of the goto's that follow.]
+ // Default attribute for non-dma enabled buffering:
+ TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
+ const TUint32 bandwidthPriority = aInfoBuf->iBandwidthPriority;
+ // (IN & OUT eps need to have different cache attribs:
+ // IN will be uncached, OUT will be cached.)
+ TInt totalINBufferSize = 0;
+ TInt totalOUTBufferSize = 0;
+
+ TInt real_ep_numbers[6] = {-1, -1, -1, -1, -1, -1};
+
+ TUsbcAlternateSettingList* alternateSettingListRec = new TUsbcAlternateSettingList;
+ if (!alternateSettingListRec)
+ {
+ r = KErrNoMemory;
+ goto KillAll;
+ }
+
+ // chain in this alternate setting
+ alternateSettingListRec->iNext = iAlternateSettingList;
+ iAlternateSettingList = alternateSettingListRec;
+ alternateSettingListRec->iSetting = aInterfaceNumber;
+ alternateSettingListRec->iNumberOfEndpoints = num_endpoints;
+
+ // ep0
+ if (iEndpoint[0] == NULL)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface 11"));
+ r = SetupEp0();
+ if (r != KErrNone)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: SetupEp0() failed"));
+ goto KillAll;
+ }
+ }
+
+ // other endpoints
+ for (TInt i = 1; i <= num_endpoints; i++, pEndpointData++)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d", i));
+ if (!ValidateEndpoint(pEndpointData))
+ {
+ r = KErrUsbBadEndpoint;
+ goto KillAll;
+ }
+ TUsbcEndpoint* ep = new TUsbcEndpoint(this, iController, pEndpointData, i, bandwidthPriority);
+ alternateSettingListRec->iEndpoint[i] = ep;
+ if (!ep)
+ {
+ r = KErrNoMemory;
+ goto KillAll;
+ }
+ if (ep->Construct() != KErrNone)
+ {
+ r = KErrNoMemory;
+ goto KillAll;
+ }
+ if (pEndpointData->iDir == KUsbEpDirIn)
+ {
+ totalINBufferSize += ep->BufferTotalSize();
+ //__KTRACE_OPT(KUSB, Kern::Printf("IN buffering now %d", totalINBufferSize));
+ }
+ else if (pEndpointData->iDir == KUsbEpDirOut)
+ {
+ totalOUTBufferSize += ep->BufferTotalSize();
+ //__KTRACE_OPT(KUSB, Kern::Printf("OUT buffering now %d", totalOUTBufferSize));
+ }
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d rec=0x%08x ep==0x%08x",
+ // i, alternateSettingListRec, ep));
+ }
+
+ // See if PIL will accept this interface
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface Calling controller"));
+ r = iController->SetInterface(this,
+ iClient,
+ aInterfaceNumber,
+ ifc_info_buf().iClass,
+ aInfoBuf->iString,
+ (TInt) ifc_info_buf().iTotalEndpointsUsed,
+ (TUsbcEndpointInfo*) ifc_info_buf().iEndpointData,
+ &real_ep_numbers);
+
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface controller returned %d", r));
+ if (r != KErrNone)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf("SetInterface failed reason=%d", r));
+ goto KillAll;
+ }
+
+ // Record the 'real' endpoint number used by the PDD in both the Ep and
+ // the Req callback:
+ for (TInt i = 1; i <= num_endpoints; i++)
+ {
+ alternateSettingListRec->iEndpoint[i]->SetRealEpNumber(real_ep_numbers[i]);
+ }
+
+ if (totalOUTBufferSize != 0)
+ {
+ // maximally cached always
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface setting up OUT buffering size=%d", totalOUTBufferSize));
+ iHwChunkOUT = SetupInterfaceMemory(totalOUTBufferSize, iHwChunkOUT, KUsbEpDirOut, cacheAttribs);
+ if (iHwChunkOUT == NULL)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf("SetInterface can't get chunk for OUT buffering size=%d reason=%d",
+ // totalOUTBufferSize, r));
+ r = KErrNoMemory;
+ goto KillAll;
+ }
+ }
+ if (totalINBufferSize != 0)
+ {
+ cacheAttribs = EMapAttrSupRw;
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface setting up IN buffering size=%d", totalINBufferSize));
+ iHwChunkIN = SetupInterfaceMemory(totalINBufferSize, iHwChunkIN, KUsbEpDirIn, cacheAttribs);
+ if (iHwChunkIN == NULL)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf("SetInterface can't get chunk for IN buffering size=%d reason=%d",
+ // totalOUTBufferSize, r));
+ r = KErrNoMemory;
+ goto KillAll;
+ }
+ }
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface ready to exit"));
+
+ if (aInterfaceNumber == 0)
+ {
+ // make sure we're ready to go with the main interface
+ iValidInterface = ETrue;
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface SelectAlternateSetting"));
+ SelectAlternateSetting(0);
+ }
+
+ return KErrNone;
+
+ KillAll:
+ DestroyAllInterfaces();
+ DestroyEp0();
+ return r;
+ }
+
+
+DPlatChunkHw* DLddUsbcChannel::SetupInterfaceMemory(TInt aBufferSize, DPlatChunkHw* aHwChunk,
+ TUint aDirection, TUint32 aCacheAttribs)
+ {
+ TUint8* oldBase = NULL;
+ if (aHwChunk != NULL)
+ oldBase = reinterpret_cast<TUint8*>(aHwChunk->LinearAddress());
+
+ DPlatChunkHw* chunk = ReAllocate(aBufferSize, aHwChunk, aCacheAttribs);
+ if (chunk == NULL)
+ {
+ // lost all interfaces:
+ // Tell Controller to release Interface and h/w resources associated with this
+ iController->DeRegisterClient(this);
+ }
+ else
+ {
+ // Parcel out the memory between endpoints
+ TUint8* newBase = reinterpret_cast<TUint8*>(chunk->LinearAddress());
+ TBool needsRebase = (newBase != oldBase);
+ TUint8* pBuf = newBase;
+ TUint8* pBufIf = pBuf; // this is where an interface's ep buffering starts
+ TUsbcAlternateSettingList* asRec = iAlternateSettingList;
+ // the current interface
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory rebasing setting=%d", asRec->iSetting));
+ RebaseInterfaceMemory(asRec, pBuf, aDirection);
+ // now the others if a rebase has occured
+ if (needsRebase)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory rebasing "));
+ asRec = asRec->iNext;
+ while (asRec)
+ {
+ // Interfaces are not concurrent so they can all start at the same logical address
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory rebasing setting=%d", asRec->iSetting));
+ pBuf = pBufIf;
+ RebaseInterfaceMemory(asRec, pBuf, aDirection);
+ asRec = asRec->iNext;
+ }
+ }
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetInterface numberOfEndpoints"));
+ }
+ return chunk;
+ }
+
+
+TInt DLddUsbcChannel::SetupEp0()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 entry %x", this));
+ TInt ep0Size = iController->Ep0PacketSize();
+ TUsbcEndpointInfo ep0Info = TUsbcEndpointInfo(KUsbEpTypeControl, KUsbEpDirBidirect, ep0Size);
+ TUsbcEndpoint* ep0 = new TUsbcEndpoint(this, iController, &ep0Info, 0, 0);
+ if (ep0 == NULL)
+ {
+ return KErrNoMemory;
+ }
+ // In case we have to return early:
+ iEndpoint[0] = ep0;
+ TInt r = ep0->Construct();
+ if (r != KErrNone)
+ {
+ return KErrNoMemory;
+ }
+ TInt bufferSize = ep0->BufferTotalSize();
+ TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
+ iHwChunkEp0 = Allocate(bufferSize, cacheAttribs);
+ if (iHwChunkEp0 == NULL)
+ {
+ return KErrNoMemory;
+ }
+ iBufferSizeEp0 = bufferSize;
+ iBufferBaseEp0 = (TUint8*) iHwChunkEp0->LinearAddress();
+ ep0->SetBufferBase(iBufferBaseEp0);
+ ep0->SetRealEpNumber(0);
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 60 buffersize=%d", iBufferSizeEp0));
+ //__KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 exit bufferbase=0x%08x", iBufferBaseEp0));
+ return KErrNone;
+ }
+
+
+void DLddUsbcChannel::RebaseInterfaceMemory(TUsbcAlternateSettingList* aAlternateSettingListRec,
+ TUint8* aBase, TUint aDirection)
+ {
+ TUint8* pBuf = aBase;
+ //__KTRACE_OPT(KUSB, Kern::Printf("RebaseInterfaceMemory buffer base rec= 0x%08x", aAlternateSettingListRec));
+ for (TInt i = 1; i <= aAlternateSettingListRec->iNumberOfEndpoints; i++)
+ {
+ TUsbcEndpoint* ep = aAlternateSettingListRec->iEndpoint[i];
+ if (ep != NULL && (ep->EndpointInfo()->iDir == aDirection))
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("RebaseInterfaceMemory buffer base for ep%d 0x%08x 0x%08x",
+ // i, pBuf, ep));
+ pBuf = ep->SetBufferBase(pBuf);
+ }
+ else
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("RebaseInterfaceMemory ep%d wrong direction", i));
+ }
+ }
+ }
+
+
+void DLddUsbcChannel::DestroyAllInterfaces()
+ {
+ // Removes all interfaces
+ TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
+ while (alternateSettingListRec)
+ {
+ DestroyEndpoints(alternateSettingListRec);
+ iController->ReleaseInterface(this, alternateSettingListRec->iSetting);
+ TUsbcAlternateSettingList* alternateSettingListRecNext = alternateSettingListRec->iNext;
+ delete alternateSettingListRec;
+ alternateSettingListRec = alternateSettingListRecNext;
+ }
+ iNumberOfEndpoints = 0;
+ iAlternateSettingList = NULL;
+
+ ClosePhysicalChunk(iHwChunkIN);
+ ClosePhysicalChunk(iHwChunkOUT);
+
+ iValidInterface = EFalse;
+ }
+
+
+void DLddUsbcChannel::DestroyInterface(TUint aInterfaceNumber)
+ {
+ if (iAlternateSetting == aInterfaceNumber)
+ {
+ ResetInterface(KErrUsbInterfaceNotReady);
+ iValidInterface = EFalse;
+ iNumberOfEndpoints = 0;
+ for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
+ {
+ iEndpoint[i] = NULL;
+ }
+ }
+ TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
+ TUsbcAlternateSettingList* alternateSettingListRecOld = NULL;
+ while (alternateSettingListRec)
+ {
+ TUsbcAlternateSettingList* alternateSettingListRecNext = alternateSettingListRec->iNext;
+ if (alternateSettingListRec->iSetting == aInterfaceNumber)
+ {
+ // This record is to be deleted
+ if (alternateSettingListRecOld == NULL)
+ {
+ // The record to be deleted is at the list head
+ iAlternateSettingList = alternateSettingListRecNext;
+ }
+ else
+ {
+ // The record to be deleted is NOT at the list head
+ alternateSettingListRecOld->iNext = alternateSettingListRecNext;
+ }
+ DestroyEndpoints(alternateSettingListRec);
+ delete alternateSettingListRec;
+ break;
+ }
+ alternateSettingListRecOld = alternateSettingListRec;
+ alternateSettingListRec = alternateSettingListRecNext;
+ }
+
+ if (iAlternateSettingList == NULL)
+ {
+ // if no interfaces left destroy non-ep0 buffering
+ ClosePhysicalChunk(iHwChunkIN);
+ ClosePhysicalChunk(iHwChunkOUT);
+ }
+ }
+
+
+void DLddUsbcChannel::DestroyEp0()
+ {
+ delete iEndpoint[0];
+ iEndpoint[0] = NULL;
+ ClosePhysicalChunk(iHwChunkEp0);
+ }
+
+
+void DLddUsbcChannel::DestroyEndpoints(TUsbcAlternateSettingList* aListRec)
+ {
+ for (TInt i = 1; i < KMaxEndpointsPerClient; i++)
+ {
+ delete aListRec->iEndpoint[i];
+ aListRec->iEndpoint[i] = NULL;
+ }
+ }
+
+
+void DLddUsbcChannel::EndpointStatusChangeCallback(TAny* aDLddUsbcChannel)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback"));
+ DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
+ if (dUsbc->iChannelClosing)
+ return;
+ TUint endpointState = dUsbc->iEndpointStatusCallbackInfo.State();
+ const TInt reqNo = (TInt) RDevUsbcClient::ERequestEndpointStatusNotify;
+ if (dUsbc->iRequestStatus[reqNo])
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback Notify status"));
+ DThread* client = dUsbc->iClient;
+ // set client descriptor length to zero
+ TInt r = Kern::ThreadRawWrite(client, dUsbc->iEndpointStatusChangePtr, &endpointState,
+ sizeof(TUint), client);
+ if (r != KErrNone)
+ dUsbc->PanicClientThread(r);
+ Kern::RequestComplete(dUsbc->iClient, dUsbc->iRequestStatus[reqNo], r);
+ dUsbc->iEndpointStatusChangePtr = NULL;
+ }
+ }
+
+
+void DLddUsbcChannel::StatusChangeCallback(TAny* aDLddUsbcChannel)
+ {
+ DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
+ if (dUsbc->iChannelClosing)
+ return;
+
+ TUsbcDeviceState deviceState;
+ TInt i;
+ for (i = 0;
+ (i < KUsbcDeviceStateRequests) && ((deviceState = dUsbc->iStatusCallbackInfo.State(i)) != EUsbcNoState);
+ ++i)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallBack status=%d", deviceState));
+ if (deviceState & KUsbAlternateSetting)
+ {
+ dUsbc->ProcessAlternateSetting(deviceState);
+ }
+ else
+ {
+ dUsbc->ProcessDeviceState(deviceState);
+ }
+ // Only queue if userside is interested
+ if (dUsbc->iDeviceStatusNeeded)
+ {
+ dUsbc->iStatusFifo->AddStatusToQueue(deviceState);
+ const TInt reqNo = (TInt) RDevUsbcClient::ERequestAlternateDeviceStatusNotify;
+ if (dUsbc->AlternateDeviceStateTestComplete())
+ Kern::RequestComplete(dUsbc->iClient, dUsbc->iRequestStatus[reqNo], KErrNone);
+ }
+ }
+ // We don't want to be interrupted in the middle of this:
+ const TInt irqs = NKern::DisableInterrupts(2);
+ dUsbc->iStatusCallbackInfo.ResetState();
+ NKern::RestoreInterrupts(irqs);
+ }
+
+
+void DLddUsbcChannel::OtgFeatureChangeCallback(TAny* aDLddUsbcChannel)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback"));
+ DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
+ if (dUsbc->iChannelClosing)
+ return;
+
+ TUint8 features;
+ // No return value check. Assume OTG always supported here
+ dUsbc->iController->GetCurrentOtgFeatures(features);
+
+ const TInt reqNo = (TInt) RDevUsbcClient::ERequestOtgFeaturesNotify;
+ if (dUsbc->iRequestStatus[reqNo])
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback Notify status"));
+ TInt r = Kern::ThreadRawWrite(dUsbc->iClient, dUsbc->iOtgFeatureChangePtr,
+ &features, sizeof(TUint8), dUsbc->iClient);
+ if (r != KErrNone)
+ dUsbc->PanicClientThread(r);
+ Kern::RequestComplete(dUsbc->iClient, dUsbc->iRequestStatus[reqNo], r);
+ dUsbc->iOtgFeatureChangePtr = NULL;
+ }
+ }
+
+
+TInt DLddUsbcChannel::SelectAlternateSetting(TUint aAlternateSetting)
+ {
+ TInt r = KErrGeneral; // error code doesn't go userside
+ TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
+ while (alternateSettingListRec)
+ {
+ if (alternateSettingListRec->iSetting == aAlternateSetting)
+ {
+ // found the correct interface, now latch in new endpoint set
+ for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
+ {
+ iEndpoint[i] = NULL;
+ }
+ iNumberOfEndpoints = alternateSettingListRec->iNumberOfEndpoints;
+ r = KErrNone;
+ for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
+ {
+ iEndpoint[i] = alternateSettingListRec->iEndpoint[i];
+ }
+ }
+ alternateSettingListRec = alternateSettingListRec->iNext;
+ }
+ return r;
+ }
+
+
+TInt DLddUsbcChannel::EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint)
+ {
+ TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
+ while (alternateSettingListRec)
+ {
+ if (alternateSettingListRec->iSetting == aAlternateSetting)
+ {
+ if ((aEndpoint <= alternateSettingListRec->iNumberOfEndpoints) &&
+ (aEndpoint >= 0))
+ {
+ return alternateSettingListRec->iEndpoint[aEndpoint]->RealEpNumber();
+ }
+ else
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: aEndpoint %d wrong for aAlternateSetting %d",
+ // aEndpoint, aAlternateSetting));
+ return -1;
+ }
+ }
+ alternateSettingListRec = alternateSettingListRec->iNext;
+ }
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: no aAlternateSetting %d found", aAlternateSetting));
+ return -1;
+ }
+
+
+TInt DLddUsbcChannel::ProcessAlternateSetting(TUint aAlternateSetting)
+ {
+ ResetInterface(KErrUsbInterfaceChange); // kill any outstanding transfers
+ //__KTRACE_OPT(KUSB, Kern::Printf("ProcessAlternateSetting 0x%08x", aAlternateSetting));
+ TUint newSetting = aAlternateSetting&(~KUsbAlternateSetting);
+ //__KTRACE_OPT(KUSB, Kern::Printf("ProcessAlternateSetting selecting alternate setting 0x%08x", newSetting));
+ TInt r = SelectAlternateSetting(newSetting);
+ if (r != KErrNone)
+ return r;
+ StartEpReads();
+ iAlternateSetting = newSetting;
+ return KErrNone;
+ }
+
+
+TInt DLddUsbcChannel::ProcessDeviceState(TUsbcDeviceState aDeviceState)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("ProcessDeviceState(%d -> %d)", iDeviceState, aDeviceState));
+ if (iDeviceState == aDeviceState)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" No state change => nothing to be done."));
+ return KErrNone;
+ }
+ if (iDeviceState == EUsbcDeviceStateSuspended)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" Coming out of Suspend: old state = %d", iOldDeviceState));
+ iDeviceState = iOldDeviceState;
+ if (iDeviceState == aDeviceState)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" New state same as before Suspend => nothing to be done."));
+ return KErrNone;
+ }
+ }
+ TBool renumerateState = (aDeviceState == EUsbcDeviceStateConfigured);
+ TBool deconfigured = EFalse;
+ TInt cancellationCode = KErrNone;
+ if (aDeviceState == EUsbcDeviceStateSuspended)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" Suspending..."));
+ iOldDeviceState = iDeviceState;
+ // Put PSL into low power mode here
+ }
+ else
+ {
+ deconfigured = (iDeviceState == EUsbcDeviceStateConfigured &&
+ aDeviceState != EUsbcDeviceStateConfigured);
+ if (iDeviceState == EUsbcDeviceStateConfigured)
+ {
+ if (aDeviceState == EUsbcDeviceStateUndefined)
+ cancellationCode = KErrUsbCableDetached;
+ else if (aDeviceState == EUsbcDeviceStateAddress)
+ cancellationCode = KErrUsbDeviceNotConfigured;
+ else if (aDeviceState == EUsbcDeviceStateDefault)
+ cancellationCode = KErrUsbDeviceBusReset;
+ else
+ cancellationCode = KErrUsbDeviceNotConfigured;
+ }
+ }
+ //__KTRACE_OPT(KUSB, Kern::Printf(" %d --> %d", iDeviceState, aDeviceState));
+ iDeviceState = aDeviceState;
+ if (iValidInterface || iOwnsDeviceControl)
+ {
+ // This LDD may not own an interface. It could be some manager reenumerating
+ // after its subordinate LDDs have setup their interfaces.
+ if (deconfigured)
+ {
+ DeConfigure(cancellationCode);
+ }
+ else if (renumerateState)
+ {
+ // We are enumerated so let's start a read on every endpoint
+ ResetInterface(KErrUsbInterfaceChange);
+ // Select main interface & latch in new endpoint set
+ SelectAlternateSetting(0);
+ // Only after correct ifc setting has been chosen!
+ UpdateEndpointSizes();
+ // Here we go
+ StartEpReads();
+ }
+ }
+
+ const TInt reqNo = (TInt) RDevUsbcClient::ERequestReEnumerate;
+ if (renumerateState && iRequestStatus[reqNo])
+ {
+ // This lot must be done if we are reenumerated
+ Kern::RequestComplete(iClient, iRequestStatus[reqNo], KErrNone);
+ }
+
+ return KErrNone;
+ }
+
+
+void DLddUsbcChannel::UpdateEndpointSizes()
+ {
+ // First Ep0.
+ iEndpoint[0]->SetMaxPacketSize(iController->Ep0PacketSize());
+ // Then the regular ones.
+ TInt i = 0;
+ while ((++i <= KMaxEndpointsPerClient) && iEndpoint[i])
+ {
+ const TInt size = iController->EndpointPacketSize(this, iEndpoint[i]->RealEpNumber());
+ if (size < 0)
+ {
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: Packet size < 0 for ep %d", i));
+ continue;
+ }
+ iEndpoint[i]->SetMaxPacketSize(size);
+ }
+ __ASSERT_DEBUG(i == iNumberOfEndpoints + 1,
+ Kern::Printf(" Error: iNumberOfEndpoints wrong (%d)", iNumberOfEndpoints));
+ }
+
+
+DPlatChunkHw* DLddUsbcChannel::ReAllocate(TInt aBuffersize, DPlatChunkHw* aHwChunk, TUint32 aCacheAttribs)
+ {
+ DPlatChunkHw* chunk = aHwChunk;
+ if ((!chunk) || (chunk->iSize < aBuffersize))
+ {
+ if (chunk)
+ {
+ ClosePhysicalChunk(chunk);
+ }
+ //__KTRACE_OPT(KUSB, Kern::Printf("ReAllocate need to get new chunk"));
+ chunk = Allocate(aBuffersize, aCacheAttribs);
+ }
+ return chunk;
+ }
+
+
+DPlatChunkHw* DLddUsbcChannel::Allocate(TInt aBuffersize, TUint32 aCacheAttribs)
+ {
+ TUint32 physAddr = 0;
+ TUint32 size = Kern::RoundToPageSize(aBuffersize);
+
+ if (Epoc::AllocPhysicalRam(size, physAddr) != KErrNone)
+ return NULL;
+
+ DPlatChunkHw* HwChunk;
+ if (DPlatChunkHw::New(HwChunk, physAddr, aBuffersize, aCacheAttribs) != KErrNone)
+ {
+ Epoc::FreePhysicalRam(physAddr, size);
+ return NULL;
+ }
+
+ return HwChunk;
+ }
+
+
+TInt DLddUsbcChannel::DoRxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TBool aReEntrant)
+ {
+ TBool completeNow;
+ TInt err = aTUsbcEndpoint->CopyToClient(iClient, completeNow);
+ if (completeNow)
+ {
+ aTUsbcEndpoint->SetClientReadPending(EFalse);
+ Kern::RequestComplete(iClient,iRequestStatus[aEndpoint], err);
+ }
+ aTUsbcEndpoint->TryToStartRead(aReEntrant);
+ return err;
+ }
+
+
+void DLddUsbcChannel::DoRxCompleteNow(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint)
+ {
+ aTUsbcEndpoint->SetClientReadPending(EFalse);
+ Kern::RequestComplete(iClient,iRequestStatus[aEndpoint], KErrCancel);
+ }
+
+
+void DLddUsbcChannel::DoTxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TInt aError)
+ {
+ aTUsbcEndpoint->SetClientWritePending(EFalse);
+ Kern::RequestComplete(iClient,iRequestStatus[aEndpoint], aError);
+ }
+
+
+TBool DLddUsbcChannel::AlternateDeviceStateTestComplete()
+ {
+ TBool completeNow = EFalse;
+ const TInt reqNo = (TInt) RDevUsbcClient::ERequestAlternateDeviceStatusNotify;
+ if (iRequestStatus[reqNo])
+ {
+ // User req is outstanding
+ TUint32 deviceState;
+ if (iStatusFifo->GetDeviceQueuedStatus(deviceState) == KErrNone)
+ {
+ // Device state waiting to be sent userside
+ completeNow = ETrue;
+ //__KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallback Notify status"));
+ // set client descriptor length to zero
+ TInt r = Kern::ThreadRawWrite(iClient, iStatusChangePtr, &deviceState,
+ sizeof(TUint32), iClient);
+ if (r != KErrNone)
+ PanicClientThread(r);
+ iStatusChangePtr = NULL;
+ }
+ }
+ return completeNow;
+ }
+
+
+void DLddUsbcChannel::EmergencyCompleteDfc(TAny* aDLddUsbcChannel)
+ {
+ ((DLddUsbcChannel*) aDLddUsbcChannel)->DoEmergencyComplete();
+ }
+
+
+void DLddUsbcChannel::DeConfigure(TInt aErrorCode)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::DeConfigure()"));
+ // Called after deconfiguration. Cancels transfers on all endpoints.
+ ResetInterface(aErrorCode);
+ // Cancel the endpoint status notify request if it is outstanding.
+ const TInt KEpNotReq = RDevUsbcClient::ERequestEndpointStatusNotify;
+ if (iRequestStatus[KEpNotReq])
+ {
+ CancelNotifyEndpointStatus();
+ Kern::RequestComplete(iClient, iRequestStatus[KEpNotReq], aErrorCode);
+ }
+ // We have to reset the alternate setting number when the config goes away.
+ SelectAlternateSetting(0);
+ iAlternateSetting = 0;
+ }
+
+
+void DLddUsbcChannel::StartEpReads()
+ {
+ // Queued after enumeration. Starts reads on all endpoints.
+ // The endpoint itself decides if it can do a read
+ TInt i;
+ for (i = 0; i <= iNumberOfEndpoints; i++)
+ {
+ // The endpoint itself will decide if it can read
+ iEndpoint[i]->TryToStartRead(EFalse);
+ }
+ }
+
+
+void DLddUsbcChannel::ResetInterface(TInt aErrorCode)
+ {
+ // Called after change in alternate setting. Cancels transfers on all endpoints
+ if (iValidInterface || iOwnsDeviceControl)
+ {
+ for (TInt i = 0; i <= iNumberOfEndpoints; i++)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("Cancelling transfer ep=%d", i));
+ iEndpoint[i]->CancelTransfer(iClient); // Copies data userside
+ iEndpoint[i]->AbortTransfer(); // kills any ldd->pil outstanding transfers
+ iEndpoint[i]->iDmaBuffers->Flush();
+ if (iRequestStatus[i] != NULL)
+ Kern::RequestComplete(iClient, iRequestStatus[i], aErrorCode);
+ iEndpoint[i]->SetClientWritePending(EFalse);
+ iEndpoint[i]->SetClientReadPending(EFalse);
+ }
+ }
+ }
+
+
+void DLddUsbcChannel::AbortInterface()
+ {
+ // Called after when channel is closing
+ if (iValidInterface || iOwnsDeviceControl)
+ {
+ for (TInt i = 0; i <= iNumberOfEndpoints; i++)
+ {
+ iEndpoint[i]->AbortTransfer(); // kills any ldd->pil outstanding transfers
+ }
+ }
+ }
+
+
+void DLddUsbcChannel::ClosePhysicalChunk(DPlatChunkHw*& aHwChunk)
+ {
+ if (aHwChunk)
+ {
+ const TPhysAddr addr = aHwChunk->PhysicalAddress();
+ const TInt size = aHwChunk->iSize;
+ aHwChunk->Close(NULL);
+ Epoc::FreePhysicalRam(addr, size);
+ }
+ aHwChunk = NULL;
+ }
+
+
+TInt DLddUsbcChannel::DoEmergencyComplete()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::DoEmergencyComplete"));
+ // cancel any pending DFCs
+ // complete all client requests
+ for (TInt i = 0; i < KUsbcMaxRequests; i++)
+ {
+ if (iRequestStatus[i])
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("Complete request 0x%x", iRequestStatus[i]));
+ Kern::RequestComplete(iClient, iRequestStatus[i], KErrDisconnected);
+ }
+ }
+ iStatusCallbackInfo.Cancel();
+ iEndpointStatusCallbackInfo.Cancel();
+ iOtgFeatureCallbackInfo.Cancel();
+ return KErrNone;
+ }
+
+
+void DLddUsbcChannel::PanicClientThread(TInt aReason)
+ {
+ Kern::ThreadKill(iClient, EExitPanic, aReason, KUsbLDDKillCat);
+ }
+
+
+// ===============Endpoint====================
+
+// Constructor
+TUsbcEndpoint::TUsbcEndpoint(DLddUsbcChannel* aLDD, DUsbClientController* aController,
+ const TUsbcEndpointInfo* aEndpointInfo, TInt aEndpointNum,
+ TInt aBandwidthPriority)
+ : iController(aController),
+ iEndpointInfo(aEndpointInfo->iType, aEndpointInfo->iDir, aEndpointInfo->iSize),
+ iClientReadPending(EFalse),
+ iClientWritePending(EFalse),
+ iEndpointNumber(aEndpointNum),
+ iRealEpNumber(-1),
+ iLdd(aLDD),
+ iError(KErrNone),
+ iRequestCallbackInfo(NULL),
+ iBytesTransferred(0),
+ iBandwidthPriority(aBandwidthPriority)
+ {
+ ResetTransferInfo();
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::TUsbcEndpoint 2"));
+ }
+
+
+TInt TUsbcEndpoint::Construct()
+ {
+ iDmaBuffers = new TDmaBuf(&iEndpointInfo, iBandwidthPriority);
+ if (iDmaBuffers == NULL)
+ {
+ return KErrNoMemory;
+ }
+ const TInt r = iDmaBuffers->Construct(&iEndpointInfo);
+ if (r != KErrNone)
+ {
+ return r;
+ }
+ iRequestCallbackInfo = new TUsbcRequestCallback(iLdd,
+ iEndpointNumber,
+ TUsbcEndpoint::RequestCallback,
+ this,
+ iLdd->iDfcQ,
+ KUsbRequestCallbackPriority);
+ if (iRequestCallbackInfo == NULL)
+ {
+ return KErrNoMemory;
+ }
+ return KErrNone;
+ }
+
+
+TUsbcEndpoint::~TUsbcEndpoint()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::~TUsbcEndpoint(%d)", iEndpointNumber));
+ AbortTransfer();
+ delete iRequestCallbackInfo;
+ delete iDmaBuffers;
+ }
+
+
+void TUsbcEndpoint::RequestCallback(TAny* aTUsbcEndpoint)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::RequestCallback"));
+ ((TUsbcEndpoint*) aTUsbcEndpoint)->EndpointComplete();
+ }
+
+
+void TUsbcEndpoint::SetMaxPacketSize(TInt aSize)
+ {
+ iEndpointInfo.iSize = aSize;
+ iDmaBuffers->SetMaxPacketSize(aSize);
+ }
+
+
+TInt TUsbcEndpoint::EndpointComplete()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete ep=%d %d",
+ // iEndpointNumber, iRequestCallbackInfo->iEndpointNum));
+
+ if (iLdd->ChannelClosing())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("We're going home -> completions no longer accepted"));
+ return KErrNone;
+ }
+
+ TTransferDirection transferDir = iRequestCallbackInfo->iTransferDir;
+ TInt error = iRequestCallbackInfo->iError;
+
+ switch (transferDir)
+ {
+
+ case EControllerWrite:
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete Write 2"));
+ if (!iDmaBuffers->TxIsActive())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" TX completion but !iDmaBuffers->TxIsActive()"));
+ break;
+ }
+
+ iDmaBuffers->TxSetInActive();
+ TBool completeNow = EFalse;
+ iBytesTransferred += iRequestCallbackInfo->iTxBytes;
+ if (iClientWritePending)
+ {
+ //Complete Outstanding Write if necessary
+ iError = error;
+ if (iError != KErrNone)
+ {
+ completeNow = ETrue;
+ if (iError == KErrPrematureEnd) // Previous write could not be completed
+ iError = KErrNone;
+ }
+ else
+ {
+ if (iBytesTransferred == (TUint32) iTransferInfo.iTransferSize)
+ {
+ completeNow = ETrue;
+ }
+ else
+ {
+ iError = ContinueWrite();
+ if (iError != KErrNone)
+ completeNow = ETrue;
+ }
+ }
+ if (completeNow)
+ {
+ TxComplete();
+ ResetTransferInfo();
+ if (iEndpointNumber == 0)
+ {
+ iDmaBuffers->Flush();
+ TryToStartRead(EFalse);
+ }
+ }
+ }
+ break;
+ }
+
+ case EControllerRead:
+ {
+ // The first packet always contains the total #of bytes
+ const TInt byteCount = iRequestCallbackInfo->iPacketSize[0];
+ const TInt packetCount = iRequestCallbackInfo->iRxPackets;
+ iDmaBuffers->ReadXferComplete(byteCount, packetCount, error);
+
+ // We queue the dfc if we can complete the read, i.e. if we are reading a packet,
+ // or if we have enough data to satisfy a read data request.
+ if (iClientReadPending)
+ {
+ //Complete outstanding read
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete Read 3 (bytes "
+ // "available=%d)", iDmaBuffers->RxBytesAvailable()));
+ TInt bytesReqd = iTransferInfo.iTransferSize - iBytesTransferred;
+ TBool completeNow = EFalse;
+
+ if (iTransferInfo.iTransferType == ETransferTypeReadPacket ||
+ iTransferInfo.iTransferType == ETransferTypeReadOneOrMore)
+ {
+ // Always complete on a packet read
+ completeNow = ETrue;
+ }
+ else if (iTransferInfo.iTransferType == ETransferTypeReadData)
+ {
+ // Complete only if enough data is present
+ if (iDmaBuffers->RxBytesAvailable() >= bytesReqd)
+ completeNow = ETrue;
+ }
+ else if (iTransferInfo.iTransferType == ETransferTypeReadUntilShort)
+ {
+ // Complete if enough data is present or if a short packet has been delivered
+ const TInt maxPacketSize = iEndpointInfo.iSize;
+ const TInt lastPacketSize = iRequestCallbackInfo->iPacketSize[packetCount - 1];
+ if (lastPacketSize < maxPacketSize)
+ completeNow = ETrue;
+ else if (iDmaBuffers->RxBytesAvailable() >= bytesReqd)
+ completeNow = ETrue;
+ else
+ {
+ const TUint type = iEndpointInfo.iType;
+ if ((type == KUsbEpTypeBulk) && (lastPacketSize & (maxPacketSize - 1)))
+ {
+ completeNow = ETrue;
+ }
+ else if ((type != KUsbEpTypeBulk) &&
+ (lastPacketSize > maxPacketSize) &&
+ (lastPacketSize % maxPacketSize))
+ {
+ completeNow = ETrue;
+ }
+ }
+ }
+ if (completeNow)
+ {
+ iError = error;
+ RxComplete(EFalse);
+ iClientReadPending = EFalse;
+ }
+ }
+ iDmaBuffers->RxSetInActive();
+ if (error != KErrNone)
+ {
+ return error;
+ }
+ if (TryToStartRead(EFalse) != KErrNone)
+ {
+// if (iEndpointNumber != 0)
+// Kern::Printf("EndpointComplete couldn't start read on ep=%d", iEndpointNumber);
+ }
+ break;
+ }
+
+ default:
+ // shouldn't get here
+ break;
+ }
+
+ return KErrNone;
+ }
+
+
+void TUsbcEndpoint::TxComplete()
+ {
+ iLdd->DoTxComplete(this, iEndpointNumber, iError);
+ }
+
+
+TInt TUsbcEndpoint::RxComplete(TBool aReEntrant)
+ {
+ return iLdd->DoRxComplete(this, iEndpointNumber, aReEntrant);
+ }
+
+
+void TUsbcEndpoint::RxCompleteNow()
+ {
+ iLdd->DoRxCompleteNow(this, iEndpointNumber);
+ }
+
+
+TInt TUsbcEndpoint::CopyToClient(DThread* aClient)
+ {
+ TBool completeNow;
+ return CopyToClient(aClient, completeNow);
+ }
+
+
+TInt TUsbcEndpoint::CopyToClient(DThread* aClient, TBool& aCompleteNow)
+ {
+ TInt err;
+ TAny* des = iTransferInfo.iDes;
+ const TInt length = iTransferInfo.iTransferSize;
+ const TBool KReadData = EFalse;
+ const TBool KReadUntilShort = ETrue;
+
+ if (iTransferInfo.iTransferType == ETransferTypeReadPacket)
+ {
+ err = iDmaBuffers->RxCopyPacketToClient(aClient, des, length);
+ aCompleteNow = ETrue;
+ }
+ else if (iTransferInfo.iTransferType == ETransferTypeReadOneOrMore)
+ {
+ err = iDmaBuffers->RxCopyDataToClient(aClient, des, length, iBytesTransferred,
+ KReadData, aCompleteNow);
+ aCompleteNow = ETrue;
+ }
+ else if (iTransferInfo.iTransferType == ETransferTypeReadUntilShort)
+ {
+ err = iDmaBuffers->RxCopyDataToClient(aClient, des, length, iBytesTransferred,
+ KReadUntilShort, aCompleteNow);
+ }
+ else
+ {
+ err = iDmaBuffers->RxCopyDataToClient(aClient, des, length, iBytesTransferred,
+ KReadData, aCompleteNow);
+ }
+
+ if (aCompleteNow)
+ {
+ ResetTransferInfo();
+ SetClientReadPending(EFalse);
+ }
+
+ return err;
+ }
+
+
+TInt TUsbcEndpoint::TryToStartRead(TBool aReEntrant)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead 1 ep=%d", iEndpointNumber));
+ TInt r = KErrNone;
+ if (iEndpointInfo.iDir != KUsbEpDirOut &&
+ iEndpointInfo.iDir != KUsbEpDirBidirect)
+ {
+ // Verify ep direction
+ //__KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead wrong direction ep=%d", iEndpointNumber));
+ return KErrUsbEpBadDirection;
+ }
+
+ if (iEndpointNumber == 0)
+ {
+ // Can't issue an Ep0 read if reader or writer is active
+ if (iDmaBuffers->TxIsActive())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead ep0 Tx already active FATAL"));
+ return KErrUsbEpNotReady;
+ }
+ if (iDmaBuffers->RxIsActive())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead ep0 Rx already active non-FATAL"));
+ }
+ }
+
+ if (!(iDmaBuffers->RxIsActive()))
+ {
+ TUint8* bufferAddr;
+ TPhysAddr physAddr;
+ TUsbcPacketArray* indexArray;
+ TUsbcPacketArray* sizeArray;
+ TInt length;
+ r = iDmaBuffers->RxGetNextXfer(bufferAddr, indexArray, sizeArray, length, physAddr);
+ if (r == KErrNone)
+ {
+ iDmaBuffers->RxSetActive();
+ iRequestCallbackInfo->SetRxBufferInfo(bufferAddr, physAddr, indexArray, sizeArray, length);
+
+ //__KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead 2 bufferAddr=0x%08x", bufferAddr));
+
+ r = iController->SetupReadBuffer(*iRequestCallbackInfo);
+ if (r != KErrNone)
+ {
+ iDmaBuffers->RxSetInActive();
+ //__KTRACE_OPT(KPANIC, Kern::Printf(" Error: TryToStartRead controller rejects read"));
+ }
+ }
+ else
+ {
+ if (iClientReadPending)
+ {
+ // Deadlock, try to resolve it by draining buffer into descriptor
+ if (!aReEntrant)
+ {
+ RxComplete(ETrue);
+ }
+ else
+ {
+ // we are stuck, better complete userside otherwise the userside request will hang
+ RxCompleteNow();
+ }
+ }
+ }
+ }
+ return r;
+ }
+
+
+TInt TUsbcEndpoint::TryToStartWrite(TEndpointTransferInfo* pTfr)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TryToStartWrite 1 ep=%d", iEndpointNumber));
+ if (iEndpointInfo.iDir != KUsbEpDirIn &&
+ iEndpointInfo.iDir != KUsbEpDirBidirect)
+ {
+ // Verify ep direction
+ return KErrUsbEpBadDirection;
+ }
+ if (iEndpointNumber == 0)
+ {
+ // Can't issue an Ep0 write if unread data is available or writer is active
+ if (iDmaBuffers->TxIsActive() || !iDmaBuffers->IsReaderEmpty())
+ {
+ return KErrUsbEpNotReady;
+ }
+ if (iDmaBuffers->RxIsActive())
+ {
+ // if a reader is active then cancel the read
+ iDmaBuffers->RxSetInActive();
+ iController->CancelReadBuffer(iLdd, iRealEpNumber);
+ }
+ }
+ SetTransferInfo(pTfr);
+ ContinueWrite();
+ return KErrNone;
+ }
+
+
+TInt TUsbcEndpoint::ContinueWrite()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("ContinueWrite 2"));
+ TUint8* bufferAddr;
+ TPhysAddr physAddr;
+ TInt bufferLength;
+ TInt r = iDmaBuffers->TxGetNextXfer(bufferAddr, bufferLength, physAddr);
+ if (r != KErrNone) // probably already active
+ return r;
+ //__KTRACE_OPT(KUSB, Kern::Printf("ContinueWrite 3"));
+ iDmaBuffers->TxSetActive();
+ TBool zlpReqd = EFalse;
+ TUint32 transferSize = iTransferInfo.iTransferSize;
+ TAny* logicalSrc = iTransferInfo.iDes;
+ TInt length = Min(transferSize - iBytesTransferred, (TUint32) bufferLength);
+ if (iBytesTransferred+length>=transferSize)
+ {
+ // only send a zlp if this is the last buffer of the transfer
+ zlpReqd = iTransferInfo.iZlpReqd;
+ }
+ r = iDmaBuffers->TxStoreData(iLdd->Client(), logicalSrc, length, iBytesTransferred);
+ iDmaBuffers->TxSetActive();
+ iRequestCallbackInfo->SetTxBufferInfo(bufferAddr, physAddr, length);
+ iRequestCallbackInfo->iZlpReqd = zlpReqd;
+#if 0
+ for (TInt i = 0; i < iRequestCallbackInfo->iLength; i++)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("Buffer[%d] = 0x%02x", i, iRequestCallbackInfo->iBufferStart[i]));
+ }
+#endif
+ r = iController->SetupWriteBuffer(*iRequestCallbackInfo);
+ return r;
+ }
+
+
+void TUsbcEndpoint::CancelTransfer(DThread* aThread)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("CancelTransfer"));
+ if (iDmaBuffers != NULL)
+ {
+ if (iClientWritePending)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" (iClientWritePending)"));
+ iClientWritePending = EFalse;
+ iController->CancelWriteBuffer(iLdd, iRealEpNumber);
+ iDmaBuffers->TxSetInActive();
+ }
+ if (iClientReadPending)
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" (iClientReadPending)"));
+ iClientReadPending = EFalse;
+ CopyToClient(aThread);
+ }
+ }
+ }
+
+
+void TUsbcEndpoint::AbortTransfer()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("Abort Transfer"));
+ if (iDmaBuffers != NULL)
+ {
+ if (iDmaBuffers->TxIsActive())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" (iClientWritePending)"));
+ iController->CancelWriteBuffer(iLdd, iRealEpNumber);
+ iDmaBuffers->TxSetInActive();
+ }
+ if (iDmaBuffers->RxIsActive())
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf(" (iClientReadPending)"));
+ iController->CancelReadBuffer(iLdd, iRealEpNumber);
+ iDmaBuffers->RxSetInActive();
+ }
+ iRequestCallbackInfo->iDfc.Cancel();
+ }
+ }
+
+
+TUsbcClientCallback::TUsbcClientCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority)
+ : iOwner(aOwner), iDfc(aCallback, aOwner, aPriority)
+ {
+ }
+
+
+TUsbcRequestCallback::TUsbcRequestCallback(const DBase* aOwner, TInt aEndpointNum, TDfcFn aDfcFunc,
+ TUsbcEndpoint* aEndpoint, TDfcQue* aDfcQ, TInt aPriority)
+ : iEndpointNum(aEndpointNum),
+ iRealEpNum(-1),
+ iOwner(aOwner),
+ iDfc(aDfcFunc, aEndpoint, aDfcQ, aPriority),
+ iTransferDir(EControllerNone),
+ iBufferStart(NULL),
+ iPacketIndex(NULL), // actually TUint16 (*)[]
+ iPacketSize(NULL), // actually TUint16 (*)[]
+ iLength(0),
+ iZlpReqd(EFalse),
+ iTxBytes(0),
+ iRxPackets(0),
+ iError(KErrNone)
+ {
+ }
+
+
+TUsbcRequestCallback::~TUsbcRequestCallback()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcRequestCallback::~TUsbcRequestCallback()"));
+ iDfc.Cancel();
+ }
+
+
+TUsbcStatusCallback::TUsbcStatusCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority)
+ : iOwner(aOwner), iDfc(aCallback, aOwner, aPriority)
+ {
+ ResetState();
+ }
+
+
+TUsbcEndpointStatusCallback::TUsbcEndpointStatusCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority)
+ : iOwner(aOwner),
+ iDfc(aCallback, aOwner, aPriority),
+ iState(0)
+ {
+ }
+
+
+TUsbcOtgFeatureCallback::TUsbcOtgFeatureCallback(DBase* aOwner, TDfcFn aCallback, TInt aPriority)
+ : iOwner(aOwner),
+ iDfc(aCallback, aOwner, aPriority),
+ iValue(0)
+ {
+ }
+
+
+TUsbcAlternateSettingList::TUsbcAlternateSettingList()
+ : iNext(NULL),
+ iNumberOfEndpoints(0),
+ iSetting(0)
+ {
+ for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
+ {
+ iEndpoint[i] = NULL;
+ }
+ }
+
+
+TUsbcAlternateSettingList::~TUsbcAlternateSettingList()
+ {
+ //__KTRACE_OPT(KUSB, Kern::Printf("TUsbcAlternateSettingList::~TUsbcAlternateSettingList()"));
+ for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
+ {
+ delete iEndpoint[i];
+ }
+ }
+
+
+TUsbcDeviceStatusQueue::TUsbcDeviceStatusQueue()
+ {
+ FlushQueue();
+ }
+
+
+void TUsbcDeviceStatusQueue::FlushQueue()
+ {
+ for (TInt i = 0; i < KUsbDeviceStatusQueueDepth; i++)
+ {
+ iDeviceStatusQueue[i] = KUsbDeviceStatusNull;
+ }
+ iStatusQueueHead = 0;
+ }
+
+
+void TUsbcDeviceStatusQueue::AddStatusToQueue(TUint32 aDeviceStatus)
+ {
+ // Only add a new status if it is not a duplicate of the one at the head of the queue
+ if (!(iStatusQueueHead != 0 &&
+ iDeviceStatusQueue[iStatusQueueHead - 1] == aDeviceStatus))
+ {
+ if (iStatusQueueHead == KUsbDeviceStatusQueueDepth)
+ {
+ // Discard item at tail of queue
+ TUint32 status;
+ GetDeviceQueuedStatus(status);
+ }
+ iDeviceStatusQueue[iStatusQueueHead] = aDeviceStatus;
+ iStatusQueueHead++;
+ }
+ }
+
+
+TInt TUsbcDeviceStatusQueue::GetDeviceQueuedStatus(TUint32& aDeviceStatus)
+ {
+ TInt r = KErrNone;
+ if (iStatusQueueHead <= 0)
+ {
+ r = KErrGeneral;
+ aDeviceStatus = KUsbDeviceStatusNull;
+ }
+ else
+ {
+ aDeviceStatus = iDeviceStatusQueue[0];
+ for(TInt i = 1; i < KUsbDeviceStatusQueueDepth; i++)
+ {
+ TUint32 s = iDeviceStatusQueue[i];
+ iDeviceStatusQueue[i - 1] = s;
+ }
+ iStatusQueueHead--;
+ iDeviceStatusQueue[KUsbDeviceStatusQueueDepth - 1] = KUsbDeviceStatusNull;
+ }
+ return r;
+ }
+
+
+//---