--- a/usbdrv/peripheral/ldd/perildd/src/d_usbc.cpp Tue Aug 31 17:01:47 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3233 +0,0 @@
-// 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 the License "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// e32/drivers/usbc/d_usbc.cpp
-// LDD for USB Device driver stack:
-// The channel object.
-//
-//
-
-/**
- @file d_usbc.cpp
- @internalTechnology
-*/
-
-#include <usb/usbc.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 UsbShai::KUsbEpTypeControl:
- if (dir != UsbShai::KUsbEpDirBidirect || size > 64)
- return EFalse;
- break;
- case UsbShai::KUsbEpTypeIsochronous:
- if ((dir != UsbShai::KUsbEpDirIn && dir != UsbShai::KUsbEpDirOut) || size > 1024)
- return EFalse;
- break;
- case UsbShai::KUsbEpTypeBulk:
- if ((dir != UsbShai::KUsbEpDirIn && dir != UsbShai::KUsbEpDirOut) || size > 512)
- return EFalse;
- break;
- case UsbShai::KUsbEpTypeInterrupt:
- if ((dir != UsbShai::KUsbEpDirIn && dir != UsbShai::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),
- iNumberOfEndpoints(0),
- iDeviceState(UsbShai::EUsbPeripheralStateUndefined),
- 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)
- {
- iController->DeRegisterClient(this);
- iStatusCallbackInfo.Cancel();
- iEndpointStatusCallbackInfo.Cancel();
- iOtgFeatureCallbackInfo.Cancel();
- iCompleteAllCallbackInfo.Cancel();
- AbortInterface();
- DestroyAllInterfaces();
- if (iOwnsDeviceControl)
- {
- iController->ReleaseDeviceControl(this);
- iOwnsDeviceControl = EFalse;
- }
- DestroyEp0();
- delete iStatusFifo;
- Kern::DestroyClientRequest(iStatusChangeReq);
- Kern::DestroyClientRequest(iEndpointStatusChangeReq);
- Kern::DestroyClientRequest(iOtgFeatureChangeReq);
-
- Kern::DestroyVirtualPinObject(iPinObj1);
- Kern::DestroyVirtualPinObject(iPinObj2);
- Kern::DestroyVirtualPinObject(iPinObj3);
-
- for (TInt i = 0; i < KUsbcMaxRequests; i++)
- {
- Kern::DestroyClientBufferRequest(iClientAsynchNotify[i]->iBufferRequest);
- delete iClientAsynchNotify[i];
- }
- }
- 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;
- }
-
- 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
- #ifdef DFC_REALTIME_STATE
- iDfcQ.SetRealtimeState(ERealtimeStateOn);
- #endif
- iCompleteAllCallbackInfo.SetDfcQ(iDfcQ);
- 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
- TInt r = iController->RegisterClientCallback(iCompleteAllCallbackInfo);
- if (r != KErrNone)
- return r;
- r = iController->RegisterForStatusChange(iStatusCallbackInfo);
- if (r != KErrNone)
- return r;
- r = iController->RegisterForEndpointStatusChange(iEndpointStatusCallbackInfo);
- if (r != KErrNone)
- return r;
- r = iController->RegisterForOtgFeatureChange(iOtgFeatureCallbackInfo);
- if (r != KErrNone)
- return r;
-
- r = Kern::CreateClientDataRequest(iStatusChangeReq);
- if (r != KErrNone)
- return r;
- r = Kern::CreateClientDataRequest(iEndpointStatusChangeReq);
- if (r != KErrNone)
- return r;
- r = Kern::CreateClientDataRequest(iOtgFeatureChangeReq);
- if (r != KErrNone)
- return r;
-
- Kern::CreateVirtualPinObject(iPinObj1);
- Kern::CreateVirtualPinObject(iPinObj2);
- Kern::CreateVirtualPinObject(iPinObj3);
-
- for (TInt i = 0; i < KUsbcMaxRequests; i++)
- {
- iClientAsynchNotify[i] = new TClientAsynchNotify;
- if(iClientAsynchNotify[i] == NULL)
- return KErrNoMemory;
- r = Kern::CreateClientBufferRequest(iClientAsynchNotify[i]->iBufferRequest,1,TClientBufferRequest::EPinVirtual);
- if (r != KErrNone)
- {
- delete iClientAsynchNotify[i];
- iClientAsynchNotify[i]=NULL;
- return r;
- }
- }
-
- return r;
- }
-
-
-
-void DLddUsbcChannel::CompleteBufferRequest(DThread* aThread, TInt aReqNo, TInt aReason)
-{
- iRequestStatus[aReqNo]=NULL;
- Kern::QueueBufferRequestComplete(aThread, iClientAsynchNotify[aReqNo]->iBufferRequest, aReason);
-}
-
-
-TClientBuffer * DLddUsbcChannel::GetClientBuffer(TInt aEndpoint)
-{
- return iClientAsynchNotify[aEndpoint]->iClientBuffer;
-}
-
-//Runs in client thread
-TInt DLddUsbcChannel::SendMsg(TMessageBase * aMsg)
-{
- TThreadMessage& m=* (TThreadMessage*)aMsg;
- TInt id = m.iValue;
-
- TInt r = KErrNone;
- //Cancel Request
- if (id == KMaxTInt)
- {
- r = DLogicalChannel::SendMsg(aMsg);
- return r;
- }
- if (id < 0)
- {
- // DoRequest
- TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
- r = PreSendRequest(aMsg,~id, pS, m.Ptr1(), m.Ptr2());
- if (r == KErrNone)
- {
- r = DLogicalChannel::SendMsg(aMsg);
- }
- }
- else
- {
- //SendControl
- r = SendControl(aMsg);
- }
- return r;
-}
-
-
-TInt DLddUsbcChannel::PreSendRequest(TMessageBase * aMsg,TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
-{
- TInt r = KErrNone;
- if (aReqNo >= KUsbcMaxRequests)
- {
- Kern::RequestComplete(aStatus, KErrNotSupported);
- return KErrNotSupported;
- }
- if (aReqNo > KUsbcMaxEpNumber)//DoOtherAsyncReq
- {
- switch (aReqNo)
- {
- case RDevUsbcClient::ERequestEndpointStatusNotify:
- iEndpointStatusChangeReq->Reset();
- iEndpointStatusChangeReq->SetStatus(aStatus);
- iEndpointStatusChangeReq->SetDestPtr(a1);
- break;
- case RDevUsbcClient::ERequestOtgFeaturesNotify:
- iOtgFeatureChangeReq->Reset();
- iOtgFeatureChangeReq->SetStatus(aStatus);
- iOtgFeatureChangeReq->SetDestPtr(a1);
- break;
- case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
- iStatusChangeReq->Reset();
- iStatusChangeReq->SetStatus(aStatus);
- iStatusChangeReq->SetDestPtr(a1);
- break;
- case RDevUsbcClient::ERequestReEnumerate://WE use bufferrequest to complete even tho we dont add any buffers
- iClientAsynchNotify[aReqNo]->Reset();
- r=iClientAsynchNotify[aReqNo]->iBufferRequest->StartSetup(aStatus);
- if (r != KErrNone)
- return r;
- iClientAsynchNotify[aReqNo]->iBufferRequest->EndSetup();
- break;
- }
- }
- else //DoTransferAsyncReq
- {
- if(a1 == NULL)
- return KErrArgument;
- iClientAsynchNotify[aReqNo]->Reset();
- r=iClientAsynchNotify[aReqNo]->iBufferRequest->StartSetup(aStatus);
- if (r != KErrNone)
- return r;
- kumemget(&iTfrInfo,a1,sizeof(TEndpointTransferInfo));
- r=iClientAsynchNotify[aReqNo]->iBufferRequest->AddBuffer(iClientAsynchNotify[aReqNo]->iClientBuffer, iTfrInfo.iDes);
- if (r != KErrNone)
- return r;
- iClientAsynchNotify[aReqNo]->iBufferRequest->EndSetup();
- TThreadMessage& m=*(TThreadMessage*)aMsg;
- m.iArg[1] = (TAny*)&iTfrInfo; //Use Channel owned TransfereInfo structure
- }
- 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))
- {
- DoCancel(reqNo);
- }
- b <<= 1;
- }
- m.Complete(KErrNone, 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));
- 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);
- if (needsCompletion)
- {
- switch (aReqNo)
- {
- case RDevUsbcClient::ERequestEndpointStatusNotify:
- iRequestStatus[aReqNo]=NULL;
- Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,r);
- break;
- case RDevUsbcClient::ERequestOtgFeaturesNotify:
- iRequestStatus[aReqNo]=NULL;
- Kern::QueueRequestComplete(iClient,iOtgFeatureChangeReq,r);
- break;
- case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
- iRequestStatus[aReqNo]=NULL;
- Kern::QueueRequestComplete(iClient,iStatusChangeReq,r);
- break;
- case RDevUsbcClient::ERequestReEnumerate:
- iRequestStatus[aReqNo]=NULL;
- Kern::QueueBufferRequestComplete(iClient, iClientAsynchNotify[aReqNo]->iBufferRequest, r);
- break;
- }
- }
- }
- else
- {
- r = DoTransferAsyncReq(aReqNo, a1, a2, needsCompletion);
- if (needsCompletion)
- {
- //Kern::RequestComplete(iClient, iRequestStatus[aReqNo], r);
- CompleteBufferRequest(iClient, aReqNo, r);
- }
- }
- }
- }
-
-
-
-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;
- }
- else
- r = KErrArgument;
- break;
- }
- case RDevUsbcClient::ERequestOtgFeaturesNotify:
- {
- __KTRACE_OPT(KUSB, Kern::Printf("ERequestOtgFeaturesNotify"));
- if (a1 != NULL)
- {
- iOtgFeatureChangePtr = a1;
- }
- 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 == UsbShai::EUsbPeripheralStateConfigured ||
- iDeviceState == UsbShai::EUsbPeripheralStateSuspended))
- )
- {
- __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;
- }
- pTfr = (TEndpointTransferInfo *)a1;
-
- if (pTfr->iTransferSize < 0)
- {
- r = KErrArgument;
- goto exit;
- }
- 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 != UsbShai::KUsbEpDirOut &&
- pEndpointInfo->iDir != UsbShai::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);
- r=Kern::ThreadBufWrite(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer, 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,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
- 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,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
- 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,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
- 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,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
- aNeedsCompletion = ETrue;
- }
- else
- {
- pEndpoint->SetClientReadPending(ETrue);
- }
- }
- }
- r = pEndpoint->TryToStartRead(EFalse);
- if (r != KErrNone)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("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 != UsbShai::KUsbEpDirIn &&
- pEndpointInfo->iDir != UsbShai::KUsbEpDirBidirect)
- {
- __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Write: wrong direction complete"));
- r = KErrUsbEpBadDirection;
- break;
- }
- __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 2"));
-
-
- TInt desLength=iClientAsynchNotify[aEndpointNum]->iClientBuffer->Length();
-
- 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,iClientAsynchNotify[aReqNo]->iClientBuffer);
- }
- else if (aReqNo == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("DoCancel: ERequestAlternateDeviceStatusNotify 0x%x", aReqNo));
- iDeviceStatusNeeded = EFalse;
- iStatusFifo->FlushQueue();
- if (iStatusChangePtr)
- {
- iStatusChangeReq->Data()=iController->GetDeviceStatus();
- iStatusChangePtr = NULL;
-
- if (iStatusChangeReq->IsReady())
- {
- iRequestStatus[aReqNo] = NULL;
- Kern::QueueRequestComplete(iClient, iStatusChangeReq, KErrCancel);
- }
- return KErrNone;
- }
- }
- 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();
- if (iEndpointStatusChangeReq->IsReady())
- {
- iRequestStatus[aReqNo] = NULL;
- Kern::QueueRequestComplete(iClient, iEndpointStatusChangeReq, KErrCancel);
- }
- return KErrNone;
- }
- else if (aReqNo == RDevUsbcClient::ERequestOtgFeaturesNotify)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestOtgFeaturesNotify: 0x%x", aReqNo));
- CancelNotifyOtgFeatures();
- if (iOtgFeatureChangeReq->IsReady())
- {
- iRequestStatus[aReqNo] = NULL;
- Kern::QueueRequestComplete(iClient, iOtgFeatureChangeReq, KErrCancel);
- }
- }
- else
- {
- __KTRACE_OPT(KUSB, Kern::Printf("DoCancel Unknown! 0x%x", aReqNo));
- }
-
- if (r == KErrNone)
- r = KErrCancel;
-
- CompleteBufferRequest(iClient, aReqNo, r);
- 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;
- }
- iEndpointStatusChangeReq->Data()=epBitmap;
- iEndpointStatusChangePtr = NULL;
- }
- }
-
-
-void DLddUsbcChannel::CancelNotifyOtgFeatures()
- {
- if (iOtgFeatureChangePtr)
- {
- TUint8 features;
- iController->GetCurrentOtgFeatures(features);
- iOtgFeatureChangeReq->Data()=features;
- iOtgFeatureChangePtr = NULL;
- }
- }
-
-TInt DLddUsbcChannel::PinMemory(TDesC8 *aDes, TVirtualPinObject *aPinObj)
- {
- TInt r = KErrNone;
- TInt len,mlen;
-
- const TUint8*p = Kern::KUDesInfo(*aDes, len,mlen);
- r=Kern::PinVirtualMemory(aPinObj, (TLinAddr) p, len);
- return r;
- }
-
-//Called in Client thread context
-TInt DLddUsbcChannel::SendControl(TMessageBase* aMsg)
- {
- TThreadMessage& m=*(TThreadMessage*)aMsg;
- const TInt fn=m.iValue;
- TAny *const a1=m.Ptr0();
- TAny *const a2=m.Ptr1();
- TInt kern_param;
- TEndpointDescriptorInfo epi;
- TUsbcIfcInfo ifc;
- TCSDescriptorInfo desInfo;
- TInt r = KErrNone;
-
- switch (fn)
- {
-
- case RDevUsbcClient::EControlDeviceStatus:
- case RDevUsbcClient::EControlGetAlternateSetting:
- m.iArg[0] = &kern_param; // update message to point to kernel-side buffer
- break;
-
- case RDevUsbcClient::EControlQueryReceiveBuffer:
- case RDevUsbcClient::EControlEndpointStatus:
- m.iArg[1] = &kern_param; // update message to point to kernel-side buffer
- break;
-
- case RDevUsbcClient::EControlEndpointCaps:
- case RDevUsbcClient::EControlDeviceCaps:
- case RDevUsbcClient::EControlGetDeviceDescriptor:
- case RDevUsbcClient::EControlSetDeviceDescriptor:
- case RDevUsbcClient::EControlGetDeviceDescriptorSize:
- case RDevUsbcClient::EControlGetConfigurationDescriptor:
- case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
- case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
- case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
- case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
- case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
- case RDevUsbcClient::EControlGetStringDescriptorLangId:
- case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
- case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
- case RDevUsbcClient::EControlGetProductStringDescriptor:
- case RDevUsbcClient::EControlSetProductStringDescriptor:
- case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
- case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
- case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
- case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
- case RDevUsbcClient::EControlSetOtgDescriptor:
- case RDevUsbcClient::EControlGetOtgDescriptor:
- case RDevUsbcClient::EControlGetOtgFeatures:
- r=PinMemory((TDesC8 *) a1, iPinObj1);
- if(r!=KErrNone)
- {
- PanicClientThread(r);
- return r;
- }
- break;
-
- case RDevUsbcClient::EControlGetInterfaceDescriptor:
- case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
- case RDevUsbcClient::EControlSetInterfaceDescriptor:
- case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
- case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
- case RDevUsbcClient::EControlGetStringDescriptor:
- case RDevUsbcClient::EControlSetStringDescriptor:
- r=PinMemory((TDesC8 *) a2, iPinObj1);
- if(r!=KErrNone)
- {
- PanicClientThread(r);
- return r;
- }
- break;
-
- case RDevUsbcClient::EControlGetEndpointDescriptor:
- case RDevUsbcClient::EControlGetEndpointDescriptorSize:
- case RDevUsbcClient::EControlSetEndpointDescriptor:
- case RDevUsbcClient::EControlGetCSEndpointDescriptor:
- case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
- if(a1!=NULL)
- {
- r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a1, sizeof(epi));
- if(r!=KErrNone)
- {
- PanicClientThread(r);
- return r;
- }
- kumemget(&epi, a1, sizeof(epi));
- r=PinMemory((TDesC8 *) epi.iArg, iPinObj2);
- if(r!=KErrNone)
- {
- Kern::UnpinVirtualMemory(iPinObj1);
- PanicClientThread(r);
- return r;
- }
- }
- break;
-
- case RDevUsbcClient::EControlSetInterface:
- if(a2!=NULL)
- {
- r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a2, sizeof(ifc));
- if(r!=KErrNone)
- {
- PanicClientThread(r);
- return r;
- }
- kumemget(&ifc, a2, sizeof(ifc));
- r=PinMemory((TDesC8 *) ifc.iInterfaceData, iPinObj2);
- if(r!=KErrNone)
- {
- Kern::UnpinVirtualMemory(iPinObj1);
- PanicClientThread(r);
- return r;
- }
- }
- break;
-
- case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
- case RDevUsbcClient::EControlSetCSEndpointDescriptor:
- if(a1!=NULL)
- {
- r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a1, sizeof(desInfo));
- if(r!=KErrNone)
- {
- PanicClientThread(r);
- return r;
- }
- kumemget(&desInfo, a1, sizeof(desInfo));
- r=PinMemory((TDesC8 *) desInfo.iArg, iPinObj2);
- if(r!=KErrNone)
- {
- Kern::UnpinVirtualMemory(iPinObj1);
- PanicClientThread(r);
- return r;
- }
- }
- break;
- }
-
-
- //Send Message and wait for synchronous complete
- r = DLogicalChannel::SendMsg(aMsg);
-
-
-
- switch (fn)
- {
- case RDevUsbcClient::EControlDeviceStatus:
- case RDevUsbcClient::EControlGetAlternateSetting:
- umemput32(a1, &kern_param, sizeof(kern_param));
- break;
-
- case RDevUsbcClient::EControlQueryReceiveBuffer:
- case RDevUsbcClient::EControlEndpointStatus:
- umemput32(a2, &kern_param, sizeof(kern_param));
- break;
-
- case RDevUsbcClient::EControlDeviceCaps:
- case RDevUsbcClient::EControlEndpointCaps:
- case RDevUsbcClient::EControlGetDeviceDescriptor:
- case RDevUsbcClient::EControlSetDeviceDescriptor:
- case RDevUsbcClient::EControlGetDeviceDescriptorSize:
- case RDevUsbcClient::EControlGetConfigurationDescriptor:
- case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
- case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
- case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
- case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
- case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
- case RDevUsbcClient::EControlGetStringDescriptorLangId:
- case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
- case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
- case RDevUsbcClient::EControlGetProductStringDescriptor:
- case RDevUsbcClient::EControlSetProductStringDescriptor:
- case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
- case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
- case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
- case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
- case RDevUsbcClient::EControlSetOtgDescriptor:
- case RDevUsbcClient::EControlGetOtgDescriptor:
- case RDevUsbcClient::EControlGetOtgFeatures:
- if(a1!=NULL)
- {
- Kern::UnpinVirtualMemory(iPinObj1);
- }
- break;
-
- case RDevUsbcClient::EControlGetInterfaceDescriptor:
- case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
- case RDevUsbcClient::EControlSetInterfaceDescriptor:
- case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
- case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
- case RDevUsbcClient::EControlGetStringDescriptor:
- case RDevUsbcClient::EControlSetStringDescriptor:
- if(a2!=NULL)
- {
- Kern::UnpinVirtualMemory(iPinObj1);
- }
- break;
-
- case RDevUsbcClient::EControlGetEndpointDescriptor:
- case RDevUsbcClient::EControlGetEndpointDescriptorSize:
- case RDevUsbcClient::EControlSetEndpointDescriptor:
- case RDevUsbcClient::EControlGetCSEndpointDescriptor:
- case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
- case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
- case RDevUsbcClient::EControlSetCSEndpointDescriptor:
- if(a1!=NULL)
- {
- Kern::UnpinVirtualMemory(iPinObj1);
- Kern::UnpinVirtualMemory(iPinObj2);
- }
- break;
-
- case RDevUsbcClient::EControlSetInterface:
- if(a2!=NULL)
- {
- Kern::UnpinVirtualMemory(iPinObj1);
- Kern::UnpinVirtualMemory(iPinObj2);
- }
- break;
- }
-
- return r;
- }
-
-
-TInt DLddUsbcChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("DoControl: %d", aFunction));
-
- TInt r = KErrNone;
- TInt ep;
- TUsbcEndpoint* pEndpoint;
- TPtrC8 pZeroDesc(NULL, 0);
- TEndpointDescriptorInfo epInfo;
- TUsbcIfcInfo ifcInfo;
- TCSDescriptorInfo desInfo;
- TUsbcEndpointResource epRes;
- TInt bandwidthPriority;
-
- switch (aFunction)
- {
- case RDevUsbcClient::EControlEndpointZeroRequestError:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroRequestError"));
- r = KErrNone;
- if (iOwnsDeviceControl || (iValidInterface && iDeviceState == UsbShai::EUsbPeripheralStateConfigured))
- {
- iController->Ep0Stall(this);
- }
- else
- {
- if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
- r = KErrUsbDeviceNotConfigured;
- else
- r = KErrUsbInterfaceNotReady;
- }
- break;
-
- case RDevUsbcClient::EControlGetAlternateSetting:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetAlternateSetting"));
- if (iValidInterface && iDeviceState == UsbShai::EUsbPeripheralStateConfigured)
- {
- r = iController->GetInterfaceNumber(this, *(TInt*)a1);
- }
- else
- {
- if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
- r = KErrUsbDeviceNotConfigured;
- else
- r = KErrUsbInterfaceNotReady;
- }
- break;
-
- case RDevUsbcClient::EControlDeviceStatus:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceStatus"));
- *(TInt*)a1 = iController->GetDeviceStatus();
- 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
- {
- *(TInt*)a2 = iController->GetEndpointStatus(this, iEndpoint[(TInt)a1]->RealEpNumber());
- }
- }
- else
- {
- if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
- 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 != UsbShai::KUsbEpDirIn)
- {
- __KTRACE_OPT(KUSB, Kern::Printf(" bytes = %d", pEndpoint->RxBytesAvailable()));
- *(TInt*)a2 = pEndpoint->RxBytesAvailable();
- }
- }
- else
- {
- if (iDeviceState != UsbShai::EUsbPeripheralStateConfigured)
- 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"));
- 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 != UsbShai::EUsbPeripheralStateConfigured)
- 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 != UsbShai::EUsbPeripheralStateConfigured)
- 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"));
- iController->ReleaseDeviceControl(this);
- iOwnsDeviceControl = EFalse;
- break;
-
- case RDevUsbcClient::EControlEndpointZeroMaxPacketSizes:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroMaxPacketSizes"));
- r = iController->EndpointZeroMaxPacketSizes();
- break;
-
- case RDevUsbcClient::EControlSetEndpointZeroMaxPacketSize:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointZeroMaxPacketSize"));
- r = iController->SetEndpointZeroMaxPacketSize(reinterpret_cast<TInt>(a1));
- break;
-
- case RDevUsbcClient::EControlGetEndpointZeroMaxPacketSize:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointZeroMaxPacketSize"));
- r = iController->Ep0PacketSize();
- break;
-
- case RDevUsbcClient::EControlGetDeviceDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptor"));
- 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"));
- if (a1 != NULL)
- r = iController->SetDeviceDescriptor(iClient, *((TDes8*) a1));
- else
- r = KErrArgument;
- break;
-
- case RDevUsbcClient::EControlGetDeviceDescriptorSize:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptorSize"));
- if (a1 != NULL)
- r = iController->GetDeviceDescriptorSize(iClient, *((TDes8*) a1));
- else
- r = KErrArgument;
- break;
-
- case RDevUsbcClient::EControlGetConfigurationDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptor"));
- 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"));
- if (a1 != NULL)
- {
- r = iController->GetConfigurationDescriptorSize(iClient, *((TDes8*) a1));
- }
- else
- r = KErrArgument;
- break;
-
- case RDevUsbcClient::EControlSetConfigurationDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationDescriptor"));
- r = iController->SetConfigurationDescriptor(iClient, *((TDes8*) a1));
- break;
-
- case RDevUsbcClient::EControlGetInterfaceDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptor"));
- r = iController->GetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
- break;
-
- case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptorSize"));
- r = iController->GetInterfaceDescriptorSize(iClient, this, (TInt) a1, *(TDes8*) a2);
- break;
-
- case RDevUsbcClient::EControlSetInterfaceDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterfaceDescriptor"));
- r = iController->SetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
- break;
-
- case RDevUsbcClient::EControlGetEndpointDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptor"));
- 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"));
- 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"));
- 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"));
- 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"));
- if (a1 != NULL)
- r = iController->SetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
- else
- r = KErrArgument;
- break;
-
- case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetOtherSpeedConfigurationDescriptor"));
- 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"));
- r = iController->SetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
- break;
-
-
- case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptor"));
- r = iController->GetCSInterfaceDescriptorBlock(iClient, this, (TInt) a1, *((TDes8*) a2));
- break;
-
- case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptorSize"));
- r = iController->GetCSInterfaceDescriptorBlockSize(iClient, this, (TInt) a1, *(TDes8*) a2);
- break;
-
- case RDevUsbcClient::EControlGetCSEndpointDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptor"));
- 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"));
- 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"));
- 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"));
- r = iController->PowerUpUdc();
- break;
-
- case RDevUsbcClient::EControlSetDeviceControl:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl"));
- 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"));
- 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);
- if (iValidInterface && (iDeviceState == UsbShai::EUsbPeripheralStateConfigured))
- {
- r = KErrGeneral;
- }
- else
- {
- 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"));
- 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"));
- 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"));
- 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"));
- r = iController->GetStringDescriptorLangId(iClient, *((TDes8*) a1));
- break;
-
- case RDevUsbcClient::EControlSetStringDescriptorLangId:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptorLangId"));
- r = iController->SetStringDescriptorLangId(reinterpret_cast<TUint>(a1));
- break;
-
- case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetManufacturerStringDescriptor"));
- r = iController->GetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetManufacturerStringDescriptor"));
- r = iController->SetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlRemoveManufacturerStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveManufacturerStringDescriptor"));
- r = iController->RemoveManufacturerStringDescriptor();
- break;
-
- case RDevUsbcClient::EControlGetProductStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetProductStringDescriptor"));
- r = iController->GetProductStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlSetProductStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetProductStringDescriptor"));
- r = iController->SetProductStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlRemoveProductStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveProductStringDescriptor"));
- r = iController->RemoveProductStringDescriptor();
- break;
-
- case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetSerialNumberStringDescriptor"));
- r = iController->GetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetSerialNumberStringDescriptor"));
- r = iController->SetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlRemoveSerialNumberStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveSerialNumberStringDescriptor"));
- r = iController->RemoveSerialNumberStringDescriptor();
- break;
-
- case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationStringDescriptor"));
- r = iController->GetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationStringDescriptor"));
- r = iController->SetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
- break;
-
- case RDevUsbcClient::EControlRemoveConfigurationStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveConfigurationStringDescriptor"));
- r = iController->RemoveConfigurationStringDescriptor();
- break;
-
- case RDevUsbcClient::EControlGetStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptor"));
- r = iController->GetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
- break;
-
- case RDevUsbcClient::EControlSetStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptor"));
- r = iController->SetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
- break;
-
- case RDevUsbcClient::EControlRemoveStringDescriptor:
- __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveStringDescriptor"));
- r = iController->RemoveStringDescriptor((TUint8) (TInt) a1);
- 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;
-
- 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.]
- // Both IN and OUT buffers will be fully cached:
- const TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
- const TUint32 bandwidthPriority = aInfoBuf->iBandwidthPriority;
-
- // Supports ep0+5 endpoints
- TInt real_ep_numbers[6] = {-1, -1, -1, -1, -1, -1};
-
- // 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,
- ifc_info_buf().iTotalEndpointsUsed,
- ifc_info_buf().iEndpointData,
- &real_ep_numbers,
- ifc_info_buf().iFeatureWord);
-
- __KTRACE_OPT(KUSB, Kern::Printf("SetInterface controller returned %d", r));
- if (r != KErrNone)
- {
- __KTRACE_OPT(KPANIC, Kern::Printf("SetInterface failed reason=%d", r));
- return r;
- }
-
- // [The next variable has to be initialized here because of the goto's that follow.]
- TUsbcAlternateSettingList* alternateSettingListRec;
-
- // 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"));
- DestroyEp0();
- goto F1;
- }
- }
-
- alternateSettingListRec = new TUsbcAlternateSettingList;
- if (!alternateSettingListRec)
- {
- r = KErrNoMemory;
- goto F1;
- }
-
- __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::SetInterface num_endpoints=%d", num_endpoints));
-
- // other endpoints
- // calculate the total buffer size
- 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 F2;
- }
-
- TUsbcEndpoint* ep = new TUsbcEndpoint(this, iController, pEndpointData, i, bandwidthPriority);
- alternateSettingListRec->iEndpoint[i] = ep;
- if (!ep)
- {
- r = KErrNoMemory;
- goto F2;
- }
- if (ep->Construct() != KErrNone)
- {
- r = KErrNoMemory;
- goto F2;
- }
-
- __KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d rec=0x%08x ep==0x%08x",
- i, alternateSettingListRec, ep));
- }
-
- // buf size of each endpoint
- TInt bufSizes[KMaxEndpointsPerClient + 1];
- TInt epNum[KMaxEndpointsPerClient + 1];
-
- // init
- for( TInt i=0;i<KMaxEndpointsPerClient+1;i++ )
- {
- bufSizes[i] = -1;
- epNum[i] = i;
- }
-
- // Record the actual buf size of each endpoint
- for( TInt i=1;i<=num_endpoints;i++ )
- {
- bufSizes[i] = alternateSettingListRec->iEndpoint[i]->BufferSize();
- }
-
- __KTRACE_OPT(KUSB, Kern::Printf("Sort the endpoints:"));
-
- // sort the endpoint number by the bufsize decreasely
- for( TInt i=1;i<num_endpoints;i++ )
- {
- TInt epMaxBuf = i;
- for(TInt k=i+1;k<=num_endpoints;k++ )
- {
- if( bufSizes[epMaxBuf]<bufSizes[k])
- {
- epMaxBuf = k;
- }
- }
- TInt temp = bufSizes[i];
- bufSizes[i] = bufSizes[epMaxBuf];
- bufSizes[epMaxBuf] = temp;
-
- temp = epNum[i];
- epNum[i] = epNum[epMaxBuf];
- epNum[epMaxBuf] = temp;
-
- alternateSettingListRec->iEpNumDeOrderedByBufSize[i] = epNum[i];
-
- __KTRACE_OPT(KUSB, Kern::Printf(" %d:%d", epNum[i], bufSizes[i]));
- }
- alternateSettingListRec->iEpNumDeOrderedByBufSize[num_endpoints] = epNum[num_endpoints];
- __KTRACE_OPT(KUSB, Kern::Printf(" %d:%d", epNum[num_endpoints], bufSizes[num_endpoints]));
- __KTRACE_OPT(KUSB, Kern::Printf("\n"));
-
- // chain in this alternate setting
- alternateSettingListRec->iNext = iAlternateSettingList;
- iAlternateSettingList = alternateSettingListRec;
- alternateSettingListRec->iSetting = aInterfaceNumber;
- alternateSettingListRec->iNumberOfEndpoints = num_endpoints;
-
- // 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]);
- }
-
- r = SetupInterfaceMemory(iHwChunks, cacheAttribs );
- if( r==KErrNone )
- {
- __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;
- }
- else
- {
- __KTRACE_OPT(KUSB, Kern::Printf("Destroying all interfaces"));
- DestroyAllInterfaces();
- DestroyEp0();
- return r;
- }
-
- F2:
- delete alternateSettingListRec;
- //Fall through
-
- F1:
-#if _DEBUG
- TInt r1 = iController->ReleaseInterface(this, aInterfaceNumber);
- __KTRACE_OPT(KUSB, Kern::Printf("Release Interface controller returned %d", r1));
-#else
- (void) iController->ReleaseInterface(this, aInterfaceNumber);
-#endif
- return r;
- }
-
-// realloc the memory, and set the previous interfaces
-TInt DLddUsbcChannel::SetupInterfaceMemory(RArray<DPlatChunkHw*> &aHwChunks,
- TUint32 aCacheAttribs )
- {
- TUsbcAlternateSettingList* asRec = iAlternateSettingList;
-
- // if buffers has been changed
- TBool chunkChanged = EFalse;
- TInt numOfEp = asRec->iNumberOfEndpoints;
-
- // 1, collect all bufs' sizes for the current interface
- // to realloc all the chunks
- __KTRACE_OPT(KUSB, Kern::Printf("Collect all buffer sizes:"));
- RArray<TInt> bufSizes;
- for(TInt i=1;i<=numOfEp;i++)
- {
- TInt nextEp = asRec->iEpNumDeOrderedByBufSize[i];
- TInt epBufCount = asRec->iEndpoint[nextEp]->BufferNumber();
- __KTRACE_OPT(KUSB, Kern::Printf(" ep %d, buf count %d", nextEp, epBufCount ));
- for(TInt k=0;k<epBufCount;k++)
- {
- TInt epBufSize = asRec->iEndpoint[nextEp]->BufferSize();
- TInt r = bufSizes.Append(epBufSize);
- if(r!=KErrNone)
- {
- iController->DeRegisterClient(this);
- bufSizes.Close();
- return r;
- }
- __KTRACE_OPT(KUSB,Kern::Printf(" %d", epBufSize ));
- }
- __KTRACE_OPT(KUSB, Kern::Printf("\n"));
-
- }
-
- // 2, alloc the buffer decreasely, biggest-->smallest
- // 2.1 check the existing chunks
- TInt bufCount = bufSizes.Count();
- __KTRACE_OPT(KUSB, Kern::Printf(" ep buf number needed %d", bufCount ));
- __KTRACE_OPT(KUSB, Kern::Printf(" chunks available %d", aHwChunks.Count() ));
-
- TInt chunkInd = 0;
- while( (chunkInd<aHwChunks.Count())&& (chunkInd<bufCount))
- {
- TUint8* oldAddr = NULL;
- oldAddr = reinterpret_cast<TUint8*>(aHwChunks[chunkInd]->LinearAddress());
-
- DPlatChunkHw* chunk = ReAllocate(bufSizes[chunkInd], aHwChunks[chunkInd], aCacheAttribs);
- if (chunk == NULL)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("Failed to alloc chunks size %d!", bufSizes[chunkInd]));
- // lost all interfaces:
- // Tell Controller to release Interface and h/w resources associated with this
- iController->DeRegisterClient(this);
- bufSizes.Close();
- return KErrNoMemory;
- }
- else
- {
- // Parcel out the memory between endpoints
- TUint8* newAddr = reinterpret_cast<TUint8*>(chunk->LinearAddress());
- __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory alloc new chunk=0x%x, size=%d", newAddr,bufSizes[chunkInd]));
- // The check is important to avoid chunkChanged to be corrupted.
- // This code change is to fix the problem that one chunk is used by multiple interfaces.
- if(!chunkChanged)
- {
- chunkChanged = (newAddr != oldAddr);
- }
- aHwChunks[chunkInd] = chunk;
- }
- chunkInd++;
- }
-
- // 2.2 in case available chunks are not enough
- while( chunkInd<bufCount)
- {
- DPlatChunkHw* chunk = NULL;
- chunk = Allocate( bufSizes[chunkInd], aCacheAttribs);
- if (chunk == NULL)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("Failed to alloc chunk, size %d!", bufSizes[chunkInd]));
- // lost all interfaces:
- // Tell Controller to release Interface and h/w resources associated with this
- iController->DeRegisterClient(this);
- bufSizes.Close();
- return KErrNoMemory;
- }
- else
- {
- // Parcel out the memory between endpoints
- __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory alloc new chunk=0x%x, size=%d",
- reinterpret_cast<TUint8*>(chunk->LinearAddress()), bufSizes[chunkInd]));
- TInt r = aHwChunks.Append(chunk);
- if(r!=KErrNone)
- {
- ClosePhysicalChunk(chunk);
- iController->DeRegisterClient(this);
- bufSizes.Close();
- return r;
- }
- }
- chunkInd++;
- }
-
- // 3, Set the the bufs of the interfaces
-
- ReSetInterfaceMemory(asRec, aHwChunks);
-
- if(chunkChanged)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory readdressing."));
- 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 readdressing setting=%d", asRec->iSetting));
- ReSetInterfaceMemory(asRec, aHwChunks);
- asRec = asRec->iNext;
- }
- }
- return KErrNone;
- }
-
-TInt DLddUsbcChannel::SetupEp0()
- {
- __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 entry %x", this));
- TInt ep0Size = iController->Ep0PacketSize();
- TUsbcEndpointInfo ep0Info = TUsbcEndpointInfo(UsbShai::KUsbEpTypeControl, UsbShai::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 bufferNum = ep0->BufferNumber();
- TInt bufferSize = ep0->BufferSize();
- TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
-
- for(TInt i=0;i<bufferNum;i++)
- {
- DPlatChunkHw* chunk = Allocate(bufferSize, cacheAttribs );
- if(chunk==NULL)
- {
- return KErrNoMemory;
- }
- TInt r = iHwChunksEp0.Append(chunk);
- if(r!=KErrNone)
- {
- ClosePhysicalChunk(chunk);
- return r;
- }
- TUint8 * buf;
- buf = (TUint8*) chunk->LinearAddress();
- ep0->SetBufferAddr( i, buf);
- __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 60 buffer number %d", i));
- __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 60 buffer size %d", bufferSize));
- }
-
- ep0->SetRealEpNumber(0);
- return KErrNone;
- }
-
-// Set buffer address of the interface
-// Precondition: Enough chunks available.
-void DLddUsbcChannel::ReSetInterfaceMemory(TUsbcAlternateSettingList* aAlternateSettingListRec,
- RArray<DPlatChunkHw*> &aHwChunks)
- {
- TUsbcAlternateSettingList* asRec = aAlternateSettingListRec;
-
- // set all the interfaces
- TInt chunkInd = 0;
- TInt numOfEp = asRec->iNumberOfEndpoints;
-
- for (TInt i = 1; i <= numOfEp; i++)
- {
- TInt nextEp = asRec->iEpNumDeOrderedByBufSize[i];
- TInt epBufCount = asRec->iEndpoint[nextEp]->BufferNumber();
- for(TInt k=0;k<epBufCount;k++)
- {
- TUsbcEndpoint* ep = asRec->iEndpoint[nextEp];
- if (ep != NULL )
- {
- TUint8* pBuf = NULL;
- pBuf = reinterpret_cast<TUint8*>(aHwChunks[chunkInd]->LinearAddress());
- ep->SetBufferAddr( k, pBuf);
- __KTRACE_OPT(KUSB, Kern::Printf(" ep %d, buf %d, addr 0x%x", nextEp, k, pBuf ));
- chunkInd++;
- __ASSERT_DEBUG(chunkInd<=aHwChunks.Count(),
- Kern::Printf(" Error: available chunks %d, run out at epInd%d, bufInd%d",
- aHwChunks.Count(), i, k));
- __ASSERT_DEBUG(chunkInd<=aHwChunks.Count(),
- Kern::Fault("usbc.ldd", __LINE__));
- }
- }
- }
-
- }
-
-void DLddUsbcChannel::DestroyAllInterfaces()
- {
- // Removes all interfaces
- TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
- while (alternateSettingListRec)
- {
- iController->ReleaseInterface(this, alternateSettingListRec->iSetting);
- TUsbcAlternateSettingList* alternateSettingListRecNext = alternateSettingListRec->iNext;
- delete alternateSettingListRec;
- alternateSettingListRec = alternateSettingListRecNext;
- }
- iNumberOfEndpoints = 0;
- iAlternateSettingList = NULL;
-
- for(TInt i=0;i<iHwChunks.Count();i++)
- {
- ClosePhysicalChunk( iHwChunks[i]);
- }
- iHwChunks.Close();
-
- 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;
- }
- delete alternateSettingListRec;
- break;
- }
- alternateSettingListRecOld = alternateSettingListRec;
- alternateSettingListRec = alternateSettingListRecNext;
- }
-
- if (iAlternateSettingList == NULL)
- {
- // if no interfaces left destroy non-ep0 buffering
- for(TInt i=0;i<iHwChunks.Count();i++)
- {
- ClosePhysicalChunk( iHwChunks[i]);
- }
- iHwChunks.Close();
- }
- }
-
-
-void DLddUsbcChannel::DestroyEp0()
- {
- delete iEndpoint[0];
- iEndpoint[0] = NULL;
- for(TInt i=0;i<iHwChunksEp0.Count();i++)
- {
- ClosePhysicalChunk( iHwChunksEp0[i] );
- }
- iHwChunksEp0.Close();
- }
-
-
-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;
-
- dUsbc->iEndpointStatusChangeReq->Data() = endpointState;
- dUsbc->iRequestStatus[reqNo] = NULL;
- Kern::QueueRequestComplete(client,dUsbc->iEndpointStatusChangeReq,KErrNone);
- 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)) != UsbShai::EUsbPeripheralNoState);
- ++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())
- {
- dUsbc->iRequestStatus[reqNo]=NULL;
- Kern::QueueRequestComplete(dUsbc->iClient,dUsbc->iStatusChangeReq,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"));
- dUsbc->iOtgFeatureChangeReq->Data()=features;
- dUsbc->iRequestStatus[reqNo] = NULL;
- Kern::QueueRequestComplete(dUsbc->iClient,dUsbc->iOtgFeatureChangeReq,KErrNone);
- 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];
- }
- // Only after correct alternate setting has been chosen.
- UpdateEndpointSizes();
- }
- 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 == UsbShai::EUsbPeripheralStateSuspended)
- {
- __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 == UsbShai::EUsbPeripheralStateConfigured);
- TBool deconfigured = EFalse;
- TInt cancellationCode = KErrNone;
- if (aDeviceState == UsbShai::EUsbPeripheralStateSuspended)
- {
- __KTRACE_OPT(KUSB, Kern::Printf(" Suspending..."));
- iOldDeviceState = iDeviceState;
- // Put PSL into low power mode here
- }
- else
- {
- deconfigured = (iDeviceState == UsbShai::EUsbPeripheralStateConfigured &&
- aDeviceState != UsbShai::EUsbPeripheralStateConfigured);
- if (iDeviceState == UsbShai::EUsbPeripheralStateConfigured)
- {
- if (aDeviceState == UsbShai::EUsbPeripheralStateUndefined)
- cancellationCode = KErrUsbCableDetached;
- else if (aDeviceState == UsbShai::EUsbPeripheralStateAddress)
- cancellationCode = KErrUsbDeviceNotConfigured;
- else if (aDeviceState == UsbShai::EUsbPeripheralStateDefault)
- 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)
- {
- // Update size of Ep0.
- iEndpoint[0]->SetMaxPacketSize(iController->Ep0PacketSize());
- // First cancel transfers on all endpoints
- ResetInterface(KErrUsbInterfaceChange);
- // Select main interface & latch in new endpoint set
- SelectAlternateSetting(0);
- // Here we go
- StartEpReads();
- }
- }
-
- const TInt reqNo = (TInt) RDevUsbcClient::ERequestReEnumerate;
- if (renumerateState && iRequestStatus[reqNo])
- {
- // This lot must be done if we are reenumerated
- CompleteBufferRequest(iClient, reqNo, KErrNone);
- }
-
- return KErrNone;
- }
-
-
-void DLddUsbcChannel::UpdateEndpointSizes()
- {
- // 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,iClientAsynchNotify[aEndpoint]->iClientBuffer);
- if (completeNow)
- {
- aTUsbcEndpoint->SetClientReadPending(EFalse);
- CompleteBufferRequest(iClient, aEndpoint, err);
- }
- aTUsbcEndpoint->TryToStartRead(aReEntrant);
- return err;
- }
-
-
-void DLddUsbcChannel::DoRxCompleteNow(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint)
- {
- aTUsbcEndpoint->SetClientReadPending(EFalse);
- CompleteBufferRequest(iClient, aEndpoint, KErrCancel);
- }
-
-
-void DLddUsbcChannel::DoTxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TInt aError)
- {
- aTUsbcEndpoint->SetClientWritePending(EFalse);
- CompleteBufferRequest(iClient, 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"));
- iStatusChangeReq->Data()=deviceState;
- 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();
- iRequestStatus[KEpNotReq]=NULL;
- Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,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)
- {
- // Reset each endpoint except ep0
- for (TInt i = 1; i <= iNumberOfEndpoints; i++)
- {
- __KTRACE_OPT(KUSB, Kern::Printf("Cancelling transfer ep=%d", i));
- iEndpoint[i]->CancelTransfer(iClient,iClientAsynchNotify[i]->iClientBuffer); // Copies data userside
- iEndpoint[i]->AbortTransfer(); // kills any ldd->pil outstanding transfers
- iEndpoint[i]->iDmaBuffers->Flush();
- if (iRequestStatus[i] != NULL)
- CompleteBufferRequest(iClient, 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++)
- {
- if (iEndpoint[i])
- {
- // kills any LDD->PDD outstanding transfers
- iEndpoint[i]->AbortTransfer();
- }
- }
- }
- }
-
-
-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]));
-
- if (i == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
- {
-
- iDeviceStatusNeeded = EFalse;
- iStatusFifo->FlushQueue();
-
- if (iStatusChangePtr)
- {
- iStatusChangeReq->Data() = iController->GetDeviceStatus();
- iStatusChangePtr = NULL;
-
- if (iStatusChangeReq->IsReady())
- {
- iRequestStatus[i] = NULL;
- Kern::QueueRequestComplete(iClient, iStatusChangeReq,
- KErrDisconnected);
- }
- }
-
- }
- else if (i == RDevUsbcClient::ERequestEndpointStatusNotify)
- {
-
- 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;
- }
-
- iEndpointStatusChangeReq->Data() = epBitmap;
- iEndpointStatusChangePtr = NULL;
- }
-
- if (iEndpointStatusChangeReq->IsReady())
- {
- iRequestStatus[i] = NULL;
- Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,KErrDisconnected);
- }
-
- }
- else if (i == RDevUsbcClient::ERequestOtgFeaturesNotify)
- {
-
- if (iOtgFeatureChangePtr)
- {
- TUint8 features;
- iController->GetCurrentOtgFeatures(features);
- iOtgFeatureChangeReq->Data()=features;
- iOtgFeatureChangePtr = NULL;
- }
-
- if (iOtgFeatureChangeReq->IsReady())
- {
- iRequestStatus[i] = NULL;
- Kern::QueueRequestComplete(iClient, iOtgFeatureChangeReq,
- KErrDisconnected);
- }
-
- }
- else
- {
- CompleteBufferRequest(iClient, 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;
- }
-
- UsbShai::TTransferDirection transferDir = iRequestCallbackInfo->iTransferDir;
- TInt error = iRequestCallbackInfo->iError;
-
- switch (transferDir)
- {
-
- case UsbShai::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 UsbShai::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 == UsbShai::KUsbEpTypeBulk) && (lastPacketSize & (maxPacketSize - 1)))
- {
- completeNow = ETrue;
- }
- else if ((type != UsbShai::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, TClientBuffer *aTcb)
- {
- TBool completeNow;
- return CopyToClient(aClient, completeNow,aTcb);
- }
-
-
-TInt TUsbcEndpoint::CopyToClient(DThread* aClient, TBool& aCompleteNow, TClientBuffer *aTcb)
- {
- TInt err;
- const TInt length = iTransferInfo.iTransferSize;
- const TBool KReadData = EFalse;
- const TBool KReadUntilShort = ETrue;
-
- __KTRACE_OPT(KUSB, Kern::Printf("CopyToClient: length = %d", length));
-
- if (iTransferInfo.iTransferType == ETransferTypeReadPacket)
- {
- err = iDmaBuffers->RxCopyPacketToClient(aClient, aTcb, length);
- aCompleteNow = ETrue;
- }
- else if (iTransferInfo.iTransferType == ETransferTypeReadOneOrMore)
- {
- err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
- KReadData, aCompleteNow);
- aCompleteNow = ETrue;
- }
- else if (iTransferInfo.iTransferType == ETransferTypeReadUntilShort)
- {
- err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
- KReadUntilShort, aCompleteNow);
- }
- else
- {
- err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, 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 != UsbShai::KUsbEpDirOut &&
- iEndpointInfo.iDir != UsbShai::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 != UsbShai::KUsbEpDirIn &&
- iEndpointInfo.iDir != UsbShai::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;
- 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(), iLdd->GetClientBuffer(iEndpointNumber), length, iBytesTransferred);
- if (r != KErrNone)
- return r;
- 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, TClientBuffer *aTcb)
- {
- __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,aTcb);
- }
- }
- }
-
-
-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();
- }
- }
-
-
-TUsbcAlternateSettingList::TUsbcAlternateSettingList()
- : iNext(NULL),
- iNumberOfEndpoints(0),
- iSetting(0)
- {
- for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
- {
- iEpNumDeOrderedByBufSize[i] = -1;
- 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;
- }
-
-void TClientAsynchNotify::Reset()
-{
- iBufferRequest->Reset();
- iClientBuffer=NULL;
-}
-
-//---