First public contribution.
1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32/drivers/usbc/d_usbc.cpp
15 // LDD for USB Device driver stack:
16 // The channel object.
25 #include <drivers/usbc.h>
28 _LIT(KUsbLddName, "Usbc");
30 static const TInt KUsbRequestCallbackPriority = 2;
33 // Quick sanity check on endpoint properties
34 static TBool ValidateEndpoint(const TUsbcEndpointInfo* aEndpointInfo)
36 const TUint dir = aEndpointInfo->iDir;
37 const TInt size = aEndpointInfo->iSize;
41 switch (aEndpointInfo->iType)
43 case KUsbEpTypeControl:
44 if (dir != KUsbEpDirBidirect || size > 64)
47 case KUsbEpTypeIsochronous:
48 if ((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 1024)
52 if ((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 512)
55 case KUsbEpTypeInterrupt:
56 if ((dir != KUsbEpDirIn && dir != KUsbEpDirOut) || size > 1024)
66 /** Real entry point from the Kernel: return a new driver.
68 DECLARE_STANDARD_LDD()
70 return new DUsbcLogDevice;
74 /** Create a channel on the device.
78 TInt DUsbcLogDevice::Create(DLogicalChannelBase*& aChannel)
80 aChannel = new DLddUsbcChannel;
81 return aChannel ? KErrNone : KErrNoMemory;
85 DUsbcLogDevice::DUsbcLogDevice()
87 iParseMask = KDeviceAllowUnit;
88 iUnitsMask = 0xffffffff; // Leave units decision to the Controller
89 iVersion = TVersion(KUsbcMajorVersion, KUsbcMinorVersion, KUsbcBuildVersion);
93 TInt DUsbcLogDevice::Install()
95 // Only proceed if we have the Controller underneath us
96 if (!DUsbClientController::UsbcControllerPointer())
98 __KTRACE_OPT(KPANIC, Kern::Printf("LDD Install: USB Controller Not Present"));
101 return SetName(&KUsbLddName);
106 // Return the USB controller capabilities.
108 void DUsbcLogDevice::GetCaps(TDes8& aDes) const
110 TPckgBuf<TCapsDevUsbc> b;
111 b().version = iVersion;
112 Kern::InfoCopy(aDes, b);
119 DLddUsbcChannel::DLddUsbcChannel()
120 : iValidInterface(EFalse),
121 iAlternateSettingList(NULL),
122 iCompleteAllCallbackInfo(this, DLddUsbcChannel::EmergencyCompleteDfc, KUsbRequestCallbackPriority),
123 iStatusChangePtr(NULL),
124 iStatusCallbackInfo(this, DLddUsbcChannel::StatusChangeCallback, KUsbRequestCallbackPriority),
125 iEndpointStatusChangePtr(NULL),
126 iEndpointStatusCallbackInfo(this, DLddUsbcChannel::EndpointStatusChangeCallback,
127 KUsbRequestCallbackPriority),
128 iOtgFeatureChangePtr(NULL),
129 iOtgFeatureCallbackInfo(this, DLddUsbcChannel::OtgFeatureChangeCallback, KUsbRequestCallbackPriority),
130 iNumberOfEndpoints(0),
131 iDeviceState(EUsbcDeviceStateUndefined),
132 iOwnsDeviceControl(EFalse),
133 iAlternateSetting(0),
134 iDeviceStatusNeeded(EFalse),
135 iChannelClosing(EFalse)
137 __KTRACE_OPT(KUSB, Kern::Printf("*** DLddUsbcChannel::DLddUsbcChannel CTOR"));
138 iClient = &Kern::CurrentThread();
140 for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
144 for (TInt i = 1; i < KUsbcMaxRequests; i++)
146 iRequestStatus[i] = NULL;
151 DLddUsbcChannel::~DLddUsbcChannel()
153 __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::~DLddUsbcChannel()"));
156 iStatusCallbackInfo.Cancel();
157 iEndpointStatusCallbackInfo.Cancel();
158 iOtgFeatureCallbackInfo.Cancel();
159 iCompleteAllCallbackInfo.Cancel();
161 DestroyAllInterfaces();
162 if (iOwnsDeviceControl)
164 iController->ReleaseDeviceControl(this);
165 iOwnsDeviceControl = EFalse;
167 iController->DeRegisterClient(this);
170 Kern::DestroyClientRequest(iStatusChangeReq);
171 Kern::DestroyClientRequest(iEndpointStatusChangeReq);
172 Kern::DestroyClientRequest(iOtgFeatureChangeReq);
174 Kern::DestroyVirtualPinObject(iPinObj1);
175 Kern::DestroyVirtualPinObject(iPinObj2);
176 Kern::DestroyVirtualPinObject(iPinObj3);
178 for (TInt i = 0; i < KUsbcMaxRequests; i++)
180 Kern::DestroyClientBufferRequest(iClientAsynchNotify[i]->iBufferRequest);
181 delete iClientAsynchNotify[i];
184 Kern::SafeClose((DObject*&)iClient, NULL);
188 inline TBool DLddUsbcChannel::ValidEndpoint(TInt aEndpoint)
190 return (aEndpoint <= iNumberOfEndpoints && aEndpoint >= 0);
197 TInt DLddUsbcChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
199 __KTRACE_OPT(KUSB, Kern::Printf("LDD DoCreateL 1 Ver = %02d %02d %02d",
200 aVer.iMajor, aVer.iMinor, aVer.iBuild));
201 if (!Kern::CurrentThreadHasCapability(ECapabilityCommDD,
202 __PLATSEC_DIAGNOSTIC_STRING("Checked by USBC.LDD (USB Driver)")))
204 return KErrPermissionDenied;
207 iController = DUsbClientController::UsbcControllerPointer();
214 iStatusFifo = new TUsbcDeviceStatusQueue;
215 if (iStatusFifo == NULL)
220 if (!Kern::QueryVersionSupported(TVersion(KUsbcMajorVersion, KUsbcMinorVersion, KUsbcBuildVersion), aVer))
222 return KErrNotSupported;
225 // set up the correct DFC queue
226 SetDfcQ(iController->DfcQ(0)); // sets the channel's dfc queue
227 #ifdef DFC_REALTIME_STATE
228 iDfcQ.SetRealtimeState(ERealtimeStateOn);
230 iCompleteAllCallbackInfo.SetDfcQ(iDfcQ);
231 iStatusCallbackInfo.SetDfcQ(iDfcQ); // use the channel's dfcq for this dfc
232 iEndpointStatusCallbackInfo.SetDfcQ(iDfcQ); // use the channel's dfcq for this dfc
233 iOtgFeatureCallbackInfo.SetDfcQ(iDfcQ);
234 iMsgQ.Receive(); //start up the message q
235 TInt r = iController->RegisterClientCallback(iCompleteAllCallbackInfo);
238 r = iController->RegisterForStatusChange(iStatusCallbackInfo);
241 r = iController->RegisterForEndpointStatusChange(iEndpointStatusCallbackInfo);
244 r = iController->RegisterForOtgFeatureChange(iOtgFeatureCallbackInfo);
248 r = Kern::CreateClientDataRequest(iStatusChangeReq);
251 r = Kern::CreateClientDataRequest(iEndpointStatusChangeReq);
254 r = Kern::CreateClientDataRequest(iOtgFeatureChangeReq);
258 Kern::CreateVirtualPinObject(iPinObj1);
259 Kern::CreateVirtualPinObject(iPinObj2);
260 Kern::CreateVirtualPinObject(iPinObj3);
262 for (TInt i = 0; i < KUsbcMaxRequests; i++)
264 iClientAsynchNotify[i] = new TClientAsynchNotify;
265 if(iClientAsynchNotify[i] == NULL)
267 r = Kern::CreateClientBufferRequest(iClientAsynchNotify[i]->iBufferRequest,1,TClientBufferRequest::EPinVirtual);
270 delete iClientAsynchNotify[i];
271 iClientAsynchNotify[i]=NULL;
281 void DLddUsbcChannel::CompleteBufferRequest(DThread* aThread, TInt aReqNo, TInt aReason)
283 iRequestStatus[aReqNo]=NULL;
284 Kern::QueueBufferRequestComplete(aThread, iClientAsynchNotify[aReqNo]->iBufferRequest, aReason);
288 TClientBuffer * DLddUsbcChannel::GetClientBuffer(TInt aEndpoint)
290 return iClientAsynchNotify[aEndpoint]->iClientBuffer;
293 //Runs in client thread
294 TInt DLddUsbcChannel::SendMsg(TMessageBase * aMsg)
296 TThreadMessage& m=* (TThreadMessage*)aMsg;
303 r = DLogicalChannel::SendMsg(aMsg);
309 TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
310 r = PreSendRequest(aMsg,~id, pS, m.Ptr1(), m.Ptr2());
313 r = DLogicalChannel::SendMsg(aMsg);
319 r = SendControl(aMsg);
325 TInt DLddUsbcChannel::PreSendRequest(TMessageBase * aMsg,TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
328 if (aReqNo >= KUsbcMaxRequests)
330 Kern::RequestComplete(aStatus, KErrNotSupported);
331 return KErrNotSupported;
333 if (aReqNo > KUsbcMaxEpNumber)//DoOtherAsyncReq
337 case RDevUsbcClient::ERequestEndpointStatusNotify:
338 iEndpointStatusChangeReq->Reset();
339 iEndpointStatusChangeReq->SetStatus(aStatus);
340 iEndpointStatusChangeReq->SetDestPtr(a1);
342 case RDevUsbcClient::ERequestOtgFeaturesNotify:
343 iOtgFeatureChangeReq->Reset();
344 iOtgFeatureChangeReq->SetStatus(aStatus);
345 iOtgFeatureChangeReq->SetDestPtr(a1);
347 case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
348 iStatusChangeReq->Reset();
349 iStatusChangeReq->SetStatus(aStatus);
350 iStatusChangeReq->SetDestPtr(a1);
352 case RDevUsbcClient::ERequestReEnumerate://WE use bufferrequest to complete even tho we dont add any buffers
353 iClientAsynchNotify[aReqNo]->Reset();
354 r=iClientAsynchNotify[aReqNo]->iBufferRequest->StartSetup(aStatus);
357 iClientAsynchNotify[aReqNo]->iBufferRequest->EndSetup();
361 else //DoTransferAsyncReq
365 iClientAsynchNotify[aReqNo]->Reset();
366 r=iClientAsynchNotify[aReqNo]->iBufferRequest->StartSetup(aStatus);
369 kumemget(&iTfrInfo,a1,sizeof(TEndpointTransferInfo));
370 r=iClientAsynchNotify[aReqNo]->iBufferRequest->AddBuffer(iClientAsynchNotify[aReqNo]->iClientBuffer, iTfrInfo.iDes);
373 iClientAsynchNotify[aReqNo]->iBufferRequest->EndSetup();
374 TThreadMessage& m=*(TThreadMessage*)aMsg;
375 m.iArg[1] = (TAny*)&iTfrInfo; //Use Channel owned TransfereInfo structure
381 void DLddUsbcChannel::HandleMsg(TMessageBase* aMsg)
383 TThreadMessage& m = *(TThreadMessage*)aMsg;
385 if (id == (TInt) ECloseMsg)
387 iChannelClosing = ETrue;
388 m.Complete(KErrNone, EFalse);
391 else if (id == KMaxTInt)
394 TInt mask = m.Int0();
396 for(TInt reqNo = 0; reqNo < KUsbcMaxRequests; reqNo++)
398 TRequestStatus* pS = iRequestStatus[reqNo];
399 if ((mask & b) && (pS != NULL))
405 m.Complete(KErrNone, ETrue);
412 TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
413 DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
414 m.Complete(KErrNone, ETrue);
419 TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
420 m.Complete(r, ETrue);
426 // Overriding DObject virtual
428 TInt DLddUsbcChannel::RequestUserHandle(DThread* aThread, TOwnerType /*aType*/)
430 __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::RequestUserHandle"));
431 // The USB client LDD is not designed for a channel to be shared between
432 // threads. It saves a pointer to the current thread when it is opened, and
433 // uses this to complete any asynchronous requests.
434 // It is therefore not acceptable for the handle to be duplicated and used
435 // by another thread:
436 if (aThread == iClient)
442 return KErrAccessDenied;
448 // Asynchronous requests - overriding pure virtual
450 void DLddUsbcChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
452 // Check on request status
453 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest 0x%08x", aReqNo));
455 if (iRequestStatus[aReqNo] != NULL)
457 DestroyAllInterfaces();
458 PanicClientThread(ERequestAlreadyPending);
462 TBool needsCompletion;
463 iRequestStatus[aReqNo] = aStatus;
465 if (aReqNo > KUsbcMaxEpNumber)
467 r = DoOtherAsyncReq(aReqNo, a1, a2, needsCompletion);
472 case RDevUsbcClient::ERequestEndpointStatusNotify:
473 iRequestStatus[aReqNo]=NULL;
474 Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,r);
476 case RDevUsbcClient::ERequestOtgFeaturesNotify:
477 iRequestStatus[aReqNo]=NULL;
478 Kern::QueueRequestComplete(iClient,iOtgFeatureChangeReq,r);
480 case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
481 iRequestStatus[aReqNo]=NULL;
482 Kern::QueueRequestComplete(iClient,iStatusChangeReq,r);
484 case RDevUsbcClient::ERequestReEnumerate:
485 iRequestStatus[aReqNo]=NULL;
486 Kern::QueueBufferRequestComplete(iClient, iClientAsynchNotify[aReqNo]->iBufferRequest, r);
493 r = DoTransferAsyncReq(aReqNo, a1, a2, needsCompletion);
496 //Kern::RequestComplete(iClient, iRequestStatus[aReqNo], r);
497 CompleteBufferRequest(iClient, aReqNo, r);
505 TInt DLddUsbcChannel::DoOtherAsyncReq(TInt aReqNo, TAny* a1, TAny* a2, TBool& aNeedsCompletion)
507 // The general assumption is that none of these will complete now.
508 // However, those that make this function return something other than
509 // KErrNone will get completed by the calling function.
510 // So, 1) If you are returning KErrNone but really need to complete because
511 // completion criteria can be met (for example, sufficient data is
512 // available in the buffer) and then set aNeedsCompletion = ETrue.
513 // 2) Do NOT complete here AT ALL.
515 aNeedsCompletion = EFalse;
520 case RDevUsbcClient::ERequestAlternateDeviceStatusNotify:
522 __KTRACE_OPT(KUSB, Kern::Printf("EControlReqDeviceStatusNotify"));
525 iDeviceStatusNeeded = ETrue;
526 iStatusChangePtr = a1;
527 aNeedsCompletion = AlternateDeviceStateTestComplete();
533 case RDevUsbcClient::ERequestReEnumerate:
535 __KTRACE_OPT(KUSB, Kern::Printf("ERequestReEnumerate"));
536 // If successful, this will complete via the status notification.
537 r = iController->ReEnumerate();
540 case RDevUsbcClient::ERequestEndpointStatusNotify:
542 __KTRACE_OPT(KUSB, Kern::Printf("ERequestEndpointStatusNotify"));
545 iEndpointStatusChangePtr = a1;
551 case RDevUsbcClient::ERequestOtgFeaturesNotify:
553 __KTRACE_OPT(KUSB, Kern::Printf("ERequestOtgFeaturesNotify"));
556 iOtgFeatureChangePtr = a1;
563 r = KErrNotSupported;
566 aNeedsCompletion = aNeedsCompletion || (r != KErrNone);
572 TInt DLddUsbcChannel::DoTransferAsyncReq(TInt aEndpointNum, TAny* a1, TAny* a2, TBool& aNeedsCompletion)
574 // The general assumption is that none of these will complete now.
575 // however, those that are returning something other than KErrNone will get completed
576 // by the calling function.
577 // So, 1) if you are returning KErrNone but really need to complete because completion criteria can be met
578 // (for example, sufficient data is available in the buffer) and then set aNeedsCompletion=ETrue..
579 // 2) Do NOT complete here AT ALL.
581 aNeedsCompletion = EFalse;
583 TUsbcEndpoint* pEndpoint = NULL;
584 TUsbcEndpointInfo* pEndpointInfo = NULL;
585 TEndpointTransferInfo* pTfr = NULL;
587 if (aEndpointNum == 0)
590 if (!(iValidInterface || iOwnsDeviceControl))
592 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest rejected: not configured (Ep0)"));
593 r = KErrUsbInterfaceNotReady;
600 if (!(iValidInterface && (iDeviceState == EUsbcDeviceStateConfigured ||
601 iDeviceState == EUsbcDeviceStateSuspended))
604 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest rejected not configured (Ep %d)", aEndpointNum));
605 r = KErrUsbInterfaceNotReady;
610 if (!ValidEndpoint(aEndpointNum))
612 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Read: in error complete"));
613 r = KErrUsbEpNotInInterface;
622 pTfr = (TEndpointTransferInfo *)a1;
624 if (pTfr->iTransferSize < 0)
629 pEndpoint = iEndpoint[aEndpointNum];
632 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Read: in error complete"));
633 r = KErrUsbEpNotInInterface;
637 pEndpointInfo = pEndpoint->EndpointInfo();
638 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest %d", aEndpointNum));
640 switch (pTfr->iTransferType)
643 case ETransferTypeReadData:
644 case ETransferTypeReadPacket:
645 case ETransferTypeReadUntilShort:
646 case ETransferTypeReadOneOrMore:
648 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read"));
649 if (pEndpoint->iDmaBuffers->RxIsActive())
651 __KTRACE_OPT(KUSB, Kern::Printf("**** ReadReq ep%d RxActive", aEndpointNum));
655 __KTRACE_OPT(KUSB, Kern::Printf("**** ReadReq ep%d RxInActive", aEndpointNum));
658 if (pEndpointInfo->iDir != KUsbEpDirOut &&
659 pEndpointInfo->iDir != KUsbEpDirBidirect)
661 // Trying to do the wrong thing
662 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Read: in error complete"));
663 r = KErrUsbEpBadDirection;
666 // Set the length of data to zero now to catch all cases
667 TPtrC8 pZeroDesc(NULL, 0);
668 r=Kern::ThreadBufWrite(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer, pZeroDesc, 0, 0,iClient);
670 PanicClientThread(r);
671 pEndpoint->SetTransferInfo(pTfr);
672 if (pEndpoint->iDmaBuffers->IsReaderEmpty())
674 pEndpoint->SetClientReadPending(ETrue);
678 if (pTfr->iTransferType == ETransferTypeReadPacket)
680 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read packet: data available complete"));
681 r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
682 aNeedsCompletion = ETrue;
685 else if (pTfr->iTransferType == ETransferTypeReadData)
687 if (pTfr->iTransferSize <= pEndpoint->RxBytesAvailable())
689 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
690 r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
691 aNeedsCompletion = ETrue;
696 pEndpoint->SetClientReadPending(ETrue);
699 else if (pTfr->iTransferType == ETransferTypeReadOneOrMore)
701 if (pEndpoint->RxBytesAvailable() > 0)
703 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
704 r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
705 aNeedsCompletion = ETrue;
710 pEndpoint->SetClientReadPending(ETrue);
713 else if (pTfr->iTransferType == ETransferTypeReadUntilShort)
715 TInt nRx = pEndpoint->RxBytesAvailable();
716 TInt maxPacketSize = pEndpoint->EndpointInfo()->iSize;
717 if( (pTfr->iTransferSize <= nRx) ||
718 (nRx < maxPacketSize) ||
719 pEndpoint->iDmaBuffers->ShortPacketExists())
721 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read data: data available complete"));
722 r = pEndpoint->CopyToClient(iClient,iClientAsynchNotify[aEndpointNum]->iClientBuffer);
723 aNeedsCompletion = ETrue;
727 pEndpoint->SetClientReadPending(ETrue);
731 r = pEndpoint->TryToStartRead(EFalse);
734 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Read: couldn't start read"));
735 r = KErrNone; // Reader full isn't a userside error;
740 case ETransferTypeWrite:
742 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 1"));
743 if (pEndpointInfo->iDir != KUsbEpDirIn &&
744 pEndpointInfo->iDir != KUsbEpDirBidirect)
746 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Write: wrong direction complete"));
747 r = KErrUsbEpBadDirection;
750 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 2"));
753 TInt desLength=iClientAsynchNotify[aEndpointNum]->iClientBuffer->Length();
755 if (desLength < pTfr->iTransferSize)
757 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Write: user buffer too short"));
758 r = KErrUsbTransferSize;
762 __KTRACE_OPT(KUSB, Kern::Printf("DoRequest Write 3 length=%d maxlength=%d",
763 pTfr->iTransferSize, desLength));
764 // Zero length writes are acceptable
765 pEndpoint->SetClientWritePending(ETrue);
766 r = pEndpoint->TryToStartWrite(pTfr);
769 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoRequest Write: couldn't start write"));
770 pEndpoint->SetClientWritePending(EFalse);
776 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: DoTransferAsyncReq: pTfr->iTransferType = %d not supported",
777 pTfr->iTransferType));
778 r = KErrNotSupported;
782 aNeedsCompletion = aNeedsCompletion || (r != KErrNone);
788 // Cancel an outstanding request - overriding pure virtual
790 TInt DLddUsbcChannel::DoCancel(TInt aReqNo)
793 __KTRACE_OPT(KUSB, Kern::Printf("DoCancel: 0x%x", aReqNo));
794 if (aReqNo <= iNumberOfEndpoints)
796 __KTRACE_OPT(KUSB, Kern::Printf("DoCancel endpoint: 0x%x", aReqNo));
797 iEndpoint[aReqNo]->CancelTransfer(iClient,iClientAsynchNotify[aReqNo]->iClientBuffer);
799 else if (aReqNo == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
801 __KTRACE_OPT(KUSB, Kern::Printf("DoCancel: ERequestAlternateDeviceStatusNotify 0x%x", aReqNo));
802 iDeviceStatusNeeded = EFalse;
803 iStatusFifo->FlushQueue();
804 if (iStatusChangePtr)
806 iStatusChangeReq->Data()=iController->GetDeviceStatus();
807 iStatusChangePtr = NULL;
809 if (iStatusChangeReq->IsReady())
811 iRequestStatus[aReqNo] = NULL;
812 Kern::QueueRequestComplete(iClient, iStatusChangeReq, KErrCancel);
817 else if (aReqNo == RDevUsbcClient::ERequestReEnumerate)
819 __KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestReEnumerate: 0x%x", aReqNo));
821 else if (aReqNo == RDevUsbcClient::ERequestEndpointStatusNotify)
823 __KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestEndpointStatusNotify: 0x%x", aReqNo));
824 CancelNotifyEndpointStatus();
825 if (iEndpointStatusChangeReq->IsReady())
827 iRequestStatus[aReqNo] = NULL;
828 Kern::QueueRequestComplete(iClient, iEndpointStatusChangeReq, KErrCancel);
832 else if (aReqNo == RDevUsbcClient::ERequestOtgFeaturesNotify)
834 __KTRACE_OPT(KUSB, Kern::Printf("DoCancel ERequestOtgFeaturesNotify: 0x%x", aReqNo));
835 CancelNotifyOtgFeatures();
836 if (iOtgFeatureChangeReq->IsReady())
838 iRequestStatus[aReqNo] = NULL;
839 Kern::QueueRequestComplete(iClient, iOtgFeatureChangeReq, KErrCancel);
844 __KTRACE_OPT(KUSB, Kern::Printf("DoCancel Unknown! 0x%x", aReqNo));
850 CompleteBufferRequest(iClient, aReqNo, r);
855 void DLddUsbcChannel::CancelNotifyEndpointStatus()
857 if (iEndpointStatusChangePtr)
860 for (TInt i = 0; i <= iNumberOfEndpoints; i++)
862 TInt v = iController->GetEndpointStatus(this, iEndpoint[i]->RealEpNumber());
864 (v == EEndpointStateStalled) ? b = 1 : b = 0;
867 iEndpointStatusChangeReq->Data()=epBitmap;
868 iEndpointStatusChangePtr = NULL;
873 void DLddUsbcChannel::CancelNotifyOtgFeatures()
875 if (iOtgFeatureChangePtr)
878 iController->GetCurrentOtgFeatures(features);
879 iOtgFeatureChangeReq->Data()=features;
880 iOtgFeatureChangePtr = NULL;
884 TInt DLddUsbcChannel::PinMemory(TDesC8 *aDes, TVirtualPinObject *aPinObj)
889 const TUint8*p = Kern::KUDesInfo(*aDes, len,mlen);
890 r=Kern::PinVirtualMemory(aPinObj, (TLinAddr) p, len);
894 //Called in Client thread context
895 TInt DLddUsbcChannel::SendControl(TMessageBase* aMsg)
897 TThreadMessage& m=*(TThreadMessage*)aMsg;
898 const TInt fn=m.iValue;
899 TAny *const a1=m.Ptr0();
900 TAny *const a2=m.Ptr1();
902 TEndpointDescriptorInfo epi;
904 TCSDescriptorInfo desInfo;
910 case RDevUsbcClient::EControlDeviceStatus:
911 case RDevUsbcClient::EControlGetAlternateSetting:
912 m.iArg[0] = &kern_param; // update message to point to kernel-side buffer
915 case RDevUsbcClient::EControlQueryReceiveBuffer:
916 case RDevUsbcClient::EControlEndpointStatus:
917 m.iArg[1] = &kern_param; // update message to point to kernel-side buffer
920 case RDevUsbcClient::EControlEndpointCaps:
921 case RDevUsbcClient::EControlDeviceCaps:
922 case RDevUsbcClient::EControlGetDeviceDescriptor:
923 case RDevUsbcClient::EControlSetDeviceDescriptor:
924 case RDevUsbcClient::EControlGetDeviceDescriptorSize:
925 case RDevUsbcClient::EControlGetConfigurationDescriptor:
926 case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
927 case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
928 case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
929 case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
930 case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
931 case RDevUsbcClient::EControlGetStringDescriptorLangId:
932 case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
933 case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
934 case RDevUsbcClient::EControlGetProductStringDescriptor:
935 case RDevUsbcClient::EControlSetProductStringDescriptor:
936 case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
937 case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
938 case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
939 case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
940 case RDevUsbcClient::EControlSetOtgDescriptor:
941 case RDevUsbcClient::EControlGetOtgDescriptor:
942 case RDevUsbcClient::EControlGetOtgFeatures:
943 r=PinMemory((TDesC8 *) a1, iPinObj1);
946 PanicClientThread(r);
951 case RDevUsbcClient::EControlGetInterfaceDescriptor:
952 case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
953 case RDevUsbcClient::EControlSetInterfaceDescriptor:
954 case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
955 case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
956 case RDevUsbcClient::EControlGetStringDescriptor:
957 case RDevUsbcClient::EControlSetStringDescriptor:
958 r=PinMemory((TDesC8 *) a2, iPinObj1);
961 PanicClientThread(r);
966 case RDevUsbcClient::EControlGetEndpointDescriptor:
967 case RDevUsbcClient::EControlGetEndpointDescriptorSize:
968 case RDevUsbcClient::EControlSetEndpointDescriptor:
969 case RDevUsbcClient::EControlGetCSEndpointDescriptor:
970 case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
973 r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a1, sizeof(epi));
976 PanicClientThread(r);
979 kumemget(&epi, a1, sizeof(epi));
980 r=PinMemory((TDesC8 *) epi.iArg, iPinObj2);
983 Kern::UnpinVirtualMemory(iPinObj1);
984 PanicClientThread(r);
990 case RDevUsbcClient::EControlSetInterface:
993 r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a2, sizeof(ifc));
996 PanicClientThread(r);
999 kumemget(&ifc, a2, sizeof(ifc));
1000 r=PinMemory((TDesC8 *) ifc.iInterfaceData, iPinObj2);
1003 Kern::UnpinVirtualMemory(iPinObj1);
1004 PanicClientThread(r);
1010 case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
1011 case RDevUsbcClient::EControlSetCSEndpointDescriptor:
1014 r=Kern::PinVirtualMemory(iPinObj1, (TLinAddr)a1, sizeof(desInfo));
1017 PanicClientThread(r);
1020 kumemget(&desInfo, a1, sizeof(desInfo));
1021 r=PinMemory((TDesC8 *) desInfo.iArg, iPinObj2);
1024 Kern::UnpinVirtualMemory(iPinObj1);
1025 PanicClientThread(r);
1033 //Send Message and wait for synchronous complete
1034 r = DLogicalChannel::SendMsg(aMsg);
1040 case RDevUsbcClient::EControlDeviceStatus:
1041 case RDevUsbcClient::EControlGetAlternateSetting:
1042 umemput32(a1, &kern_param, sizeof(kern_param));
1045 case RDevUsbcClient::EControlQueryReceiveBuffer:
1046 case RDevUsbcClient::EControlEndpointStatus:
1047 umemput32(a2, &kern_param, sizeof(kern_param));
1050 case RDevUsbcClient::EControlDeviceCaps:
1051 case RDevUsbcClient::EControlEndpointCaps:
1052 case RDevUsbcClient::EControlGetDeviceDescriptor:
1053 case RDevUsbcClient::EControlSetDeviceDescriptor:
1054 case RDevUsbcClient::EControlGetDeviceDescriptorSize:
1055 case RDevUsbcClient::EControlGetConfigurationDescriptor:
1056 case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
1057 case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
1058 case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
1059 case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
1060 case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
1061 case RDevUsbcClient::EControlGetStringDescriptorLangId:
1062 case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
1063 case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
1064 case RDevUsbcClient::EControlGetProductStringDescriptor:
1065 case RDevUsbcClient::EControlSetProductStringDescriptor:
1066 case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
1067 case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
1068 case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
1069 case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
1070 case RDevUsbcClient::EControlSetOtgDescriptor:
1071 case RDevUsbcClient::EControlGetOtgDescriptor:
1072 case RDevUsbcClient::EControlGetOtgFeatures:
1075 Kern::UnpinVirtualMemory(iPinObj1);
1079 case RDevUsbcClient::EControlGetInterfaceDescriptor:
1080 case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
1081 case RDevUsbcClient::EControlSetInterfaceDescriptor:
1082 case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
1083 case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
1084 case RDevUsbcClient::EControlGetStringDescriptor:
1085 case RDevUsbcClient::EControlSetStringDescriptor:
1088 Kern::UnpinVirtualMemory(iPinObj1);
1092 case RDevUsbcClient::EControlGetEndpointDescriptor:
1093 case RDevUsbcClient::EControlGetEndpointDescriptorSize:
1094 case RDevUsbcClient::EControlSetEndpointDescriptor:
1095 case RDevUsbcClient::EControlGetCSEndpointDescriptor:
1096 case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
1097 case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
1098 case RDevUsbcClient::EControlSetCSEndpointDescriptor:
1101 Kern::UnpinVirtualMemory(iPinObj1);
1102 Kern::UnpinVirtualMemory(iPinObj2);
1106 case RDevUsbcClient::EControlSetInterface:
1109 Kern::UnpinVirtualMemory(iPinObj1);
1110 Kern::UnpinVirtualMemory(iPinObj2);
1119 TInt DLddUsbcChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
1121 __KTRACE_OPT(KUSB, Kern::Printf("DoControl: %d", aFunction));
1125 TUsbcEndpoint* pEndpoint;
1126 TPtrC8 pZeroDesc(NULL, 0);
1127 TEndpointDescriptorInfo epInfo;
1128 TUsbcIfcInfo ifcInfo;
1129 TCSDescriptorInfo desInfo;
1130 TUsbcEndpointResource epRes;
1131 TInt bandwidthPriority;
1135 case RDevUsbcClient::EControlEndpointZeroRequestError:
1136 __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroRequestError"));
1138 if (iOwnsDeviceControl || (iValidInterface && iDeviceState == EUsbcDeviceStateConfigured))
1140 iController->Ep0Stall(this);
1144 if (iDeviceState != EUsbcDeviceStateConfigured)
1145 r = KErrUsbDeviceNotConfigured;
1147 r = KErrUsbInterfaceNotReady;
1151 case RDevUsbcClient::EControlGetAlternateSetting:
1152 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetAlternateSetting"));
1153 if (iValidInterface && iDeviceState == EUsbcDeviceStateConfigured)
1155 r = iController->GetInterfaceNumber(this, *(TInt*)a1);
1159 if (iDeviceState != EUsbcDeviceStateConfigured)
1160 r = KErrUsbDeviceNotConfigured;
1162 r = KErrUsbInterfaceNotReady;
1166 case RDevUsbcClient::EControlDeviceStatus:
1167 __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceStatus"));
1168 *(TInt*)a1 = iController->GetDeviceStatus();
1171 case RDevUsbcClient::EControlEndpointStatus:
1172 __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointStatus"));
1173 if (iValidInterface && ValidEndpoint((TInt) a1))
1175 pEndpoint = iEndpoint[(TInt)a1];
1176 if (pEndpoint == NULL)
1177 r = KErrNotSupported;
1180 *(TInt*)a2 = iController->GetEndpointStatus(this, iEndpoint[(TInt)a1]->RealEpNumber());
1185 if (iDeviceState != EUsbcDeviceStateConfigured)
1186 r = KErrUsbDeviceNotConfigured;
1188 r = KErrUsbInterfaceNotReady;
1192 case RDevUsbcClient::EControlQueryReceiveBuffer:
1193 __KTRACE_OPT(KUSB, Kern::Printf("EControlQueryReceiveBuffer"));
1194 if (iValidInterface && ValidEndpoint((TInt) a1))
1196 pEndpoint=iEndpoint[(TInt) a1];
1197 if (pEndpoint == NULL)
1198 r = KErrNotSupported;
1199 else if (pEndpoint->EndpointInfo()->iDir != KUsbEpDirIn)
1201 __KTRACE_OPT(KUSB, Kern::Printf(" bytes = %d", pEndpoint->RxBytesAvailable()));
1202 *(TInt*)a2 = pEndpoint->RxBytesAvailable();
1207 if (iDeviceState != EUsbcDeviceStateConfigured)
1208 r = KErrUsbDeviceNotConfigured;
1210 r = KErrUsbInterfaceNotReady;
1214 case RDevUsbcClient::EControlEndpointCaps:
1215 __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointCaps"));
1216 r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
1218 PanicClientThread(r);
1219 iController->EndpointCaps(this, *((TDes8*) a1));
1222 case RDevUsbcClient::EControlDeviceCaps:
1223 __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceCaps"));
1224 r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
1226 PanicClientThread(r);
1227 iController->DeviceCaps(this, *((TDes8*) a1));
1230 case RDevUsbcClient::EControlSendEp0StatusPacket:
1231 __KTRACE_OPT(KUSB, Kern::Printf("EControlSendEp0StatusPacket"));
1232 iController->SendEp0StatusPacket(this);
1235 case RDevUsbcClient::EControlHaltEndpoint:
1236 __KTRACE_OPT(KUSB, Kern::Printf("EControlHaltEndpoint"));
1237 if (iValidInterface && ValidEndpoint((TInt) a1))
1239 r = iController->HaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
1243 if (iDeviceState != EUsbcDeviceStateConfigured)
1244 r = KErrUsbDeviceNotConfigured;
1246 r = KErrUsbInterfaceNotReady;
1250 case RDevUsbcClient::EControlClearHaltEndpoint:
1251 __KTRACE_OPT(KUSB, Kern::Printf("EControlClearHaltEndpoint"));
1252 if (iValidInterface && ValidEndpoint((TInt) a1))
1254 r = iController->ClearHaltEndpoint(this, iEndpoint[(TInt)a1]->RealEpNumber());
1258 if (iDeviceState != EUsbcDeviceStateConfigured)
1259 r = KErrUsbDeviceNotConfigured;
1261 r = KErrUsbInterfaceNotReady;
1265 case RDevUsbcClient::EControlDumpRegisters:
1266 __KTRACE_OPT(KUSB, Kern::Printf("EControlDumpRegisters"));
1267 iController->DumpRegisters();
1270 case RDevUsbcClient::EControlReleaseDeviceControl:
1271 __KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseDeviceControl"));
1272 iController->ReleaseDeviceControl(this);
1273 iOwnsDeviceControl = EFalse;
1276 case RDevUsbcClient::EControlEndpointZeroMaxPacketSizes:
1277 __KTRACE_OPT(KUSB, Kern::Printf("EControlEndpointZeroMaxPacketSizes"));
1278 r = iController->EndpointZeroMaxPacketSizes();
1281 case RDevUsbcClient::EControlSetEndpointZeroMaxPacketSize:
1282 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointZeroMaxPacketSize"));
1283 r = iController->SetEndpointZeroMaxPacketSize(reinterpret_cast<TInt>(a1));
1286 case RDevUsbcClient::EControlGetEndpointZeroMaxPacketSize:
1287 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointZeroMaxPacketSize"));
1288 r = iController->Ep0PacketSize();
1291 case RDevUsbcClient::EControlGetDeviceDescriptor:
1292 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptor"));
1293 r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
1295 PanicClientThread(r);
1296 r = iController->GetDeviceDescriptor(iClient, *((TDes8*) a1));
1299 case RDevUsbcClient::EControlSetDeviceDescriptor:
1300 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceDescriptor"));
1302 r = iController->SetDeviceDescriptor(iClient, *((TDes8*) a1));
1307 case RDevUsbcClient::EControlGetDeviceDescriptorSize:
1308 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceDescriptorSize"));
1310 r = iController->GetDeviceDescriptorSize(iClient, *((TDes8*) a1));
1315 case RDevUsbcClient::EControlGetConfigurationDescriptor:
1316 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptor"));
1317 r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
1319 PanicClientThread(r);
1320 r = iController->GetConfigurationDescriptor(iClient, *((TDes8*) a1));
1323 case RDevUsbcClient::EControlGetConfigurationDescriptorSize:
1324 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationDescriptorSize"));
1327 r = iController->GetConfigurationDescriptorSize(iClient, *((TDes8*) a1));
1333 case RDevUsbcClient::EControlSetConfigurationDescriptor:
1334 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationDescriptor"));
1335 r = iController->SetConfigurationDescriptor(iClient, *((TDes8*) a1));
1338 case RDevUsbcClient::EControlGetInterfaceDescriptor:
1339 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptor"));
1340 r = iController->GetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
1343 case RDevUsbcClient::EControlGetInterfaceDescriptorSize:
1344 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetInterfaceDescriptorSize"));
1345 r = iController->GetInterfaceDescriptorSize(iClient, this, (TInt) a1, *(TDes8*) a2);
1348 case RDevUsbcClient::EControlSetInterfaceDescriptor:
1349 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterfaceDescriptor"));
1350 r = iController->SetInterfaceDescriptor(iClient, this, (TInt) a1, *((TDes8*) a2));
1353 case RDevUsbcClient::EControlGetEndpointDescriptor:
1354 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptor"));
1355 r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
1357 PanicClientThread(r);
1358 ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
1359 r = iController->GetEndpointDescriptor(iClient, this, epInfo.iSetting,
1360 ep, *(TDes8*) epInfo.iArg);
1363 case RDevUsbcClient::EControlGetEndpointDescriptorSize:
1364 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetEndpointDescriptorSize"));
1365 r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
1367 PanicClientThread(r);
1368 ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
1369 r = iController->GetEndpointDescriptorSize(iClient, this, epInfo.iSetting,
1370 ep, *(TDes8*) epInfo.iArg);
1373 case RDevUsbcClient::EControlSetEndpointDescriptor:
1374 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetEndpointDescriptor"));
1375 r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
1377 PanicClientThread(r);
1378 ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
1379 r = iController->SetEndpointDescriptor(iClient, this, epInfo.iSetting,
1380 ep, *(TDes8*)epInfo.iArg);
1383 case RDevUsbcClient::EControlGetDeviceQualifierDescriptor:
1384 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetDeviceQualifierDescriptor"));
1385 r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0, 0, iClient);
1387 PanicClientThread(r);
1388 r = iController->GetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
1391 case RDevUsbcClient::EControlSetDeviceQualifierDescriptor:
1392 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceQualifierDescriptor"));
1394 r = iController->SetDeviceQualifierDescriptor(iClient, *((TDes8*) a1));
1399 case RDevUsbcClient::EControlGetOtherSpeedConfigurationDescriptor:
1400 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetOtherSpeedConfigurationDescriptor"));
1401 r = Kern::ThreadDesWrite(iClient, a1, pZeroDesc, 0 , 0, iClient);
1403 PanicClientThread(r);
1404 r = iController->GetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
1407 case RDevUsbcClient::EControlSetOtherSpeedConfigurationDescriptor:
1408 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetOtherSpeedConfigurationDescriptor"));
1409 r = iController->SetOtherSpeedConfigurationDescriptor(iClient, *((TDes8*) a1));
1413 case RDevUsbcClient::EControlGetCSInterfaceDescriptor:
1414 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptor"));
1415 r = iController->GetCSInterfaceDescriptorBlock(iClient, this, (TInt) a1, *((TDes8*) a2));
1418 case RDevUsbcClient::EControlGetCSInterfaceDescriptorSize:
1419 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSInterfaceDescriptorSize"));
1420 r = iController->GetCSInterfaceDescriptorBlockSize(iClient, this, (TInt) a1, *(TDes8*) a2);
1423 case RDevUsbcClient::EControlGetCSEndpointDescriptor:
1424 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptor"));
1425 r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
1427 PanicClientThread(r);
1428 ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
1429 r = iController->GetCSEndpointDescriptorBlock(iClient, this, epInfo.iSetting,
1430 ep, *(TDes8*) epInfo.iArg);
1433 case RDevUsbcClient::EControlGetCSEndpointDescriptorSize:
1434 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetCSEndpointDescriptorSize"));
1435 r = Kern::ThreadRawRead(iClient, a1, &epInfo, sizeof(epInfo));
1437 PanicClientThread(r);
1438 ep = EpFromAlternateSetting(epInfo.iSetting, epInfo.iEndpoint);
1439 r = iController->GetCSEndpointDescriptorBlockSize(iClient, this, epInfo.iSetting,
1440 ep, *(TDes8*) epInfo.iArg);
1443 case RDevUsbcClient::EControlSignalRemoteWakeup:
1444 __KTRACE_OPT(KUSB, Kern::Printf("EControlSignalRemoteWakeup"));
1445 r = iController->SignalRemoteWakeup();
1448 case RDevUsbcClient::EControlDeviceDisconnectFromHost:
1449 __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceDisconnectFromHost"));
1450 r = iController->UsbDisconnect();
1453 case RDevUsbcClient::EControlDeviceConnectToHost:
1454 __KTRACE_OPT(KUSB, Kern::Printf("EControlDeviceConnectToHost"));
1455 r = iController->UsbConnect();
1458 case RDevUsbcClient::EControlDevicePowerUpUdc:
1459 __KTRACE_OPT(KUSB, Kern::Printf("EControlDevicePowerUpUdc"));
1460 r = iController->PowerUpUdc();
1463 case RDevUsbcClient::EControlSetDeviceControl:
1464 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl"));
1465 r = iController->SetDeviceControl(this);
1468 iOwnsDeviceControl = ETrue;
1469 if (iEndpoint[0] == NULL)
1471 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetDeviceControl 11"));
1475 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: SetupEp0() failed"));
1476 iController->ReleaseDeviceControl(this);
1478 iOwnsDeviceControl = EFalse;
1480 iEndpoint[0]->TryToStartRead(EFalse);
1487 case RDevUsbcClient::EControlCurrentlyUsingHighSpeed:
1488 __KTRACE_OPT(KUSB, Kern::Printf("EControlCurrentlyUsingHighSpeed"));
1489 r = iController->CurrentlyUsingHighSpeed();
1492 case RDevUsbcClient::EControlSetInterface:
1493 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetInterface"));
1494 r = Kern::ThreadRawRead(iClient, a2, &ifcInfo, sizeof(ifcInfo));
1496 PanicClientThread(r);
1497 if (iValidInterface && (iDeviceState == EUsbcDeviceStateConfigured))
1503 bandwidthPriority = ifcInfo.iBandwidthPriority;
1504 if ((bandwidthPriority & 0xffffff00) ||
1505 ((bandwidthPriority & 0x0f) >= KUsbcDmaBufMaxPriorities) ||
1506 (((bandwidthPriority >> 4) & 0x0f) >= KUsbcDmaBufMaxPriorities))
1512 r = SetInterface((TInt) a1, &ifcInfo);
1518 case RDevUsbcClient::EControlReleaseInterface:
1519 __KTRACE_OPT(KUSB, Kern::Printf("EControlReleaseInterface"));
1520 r = iController->ReleaseInterface(this, (TInt) a1);
1523 DestroyInterface((TUint) a1);
1527 __KTRACE_OPT(KPANIC, Kern::Printf(" Error in PIL: LDD interface won't be released."));
1531 case RDevUsbcClient::EControlSetCSInterfaceDescriptor:
1532 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSInterfaceDescriptor"));
1533 r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
1535 PanicClientThread(r);
1536 r = iController->SetCSInterfaceDescriptorBlock(iClient, this, desInfo.iSetting,
1537 *reinterpret_cast<const TDes8*>(desInfo.iArg),
1541 case RDevUsbcClient::EControlSetCSEndpointDescriptor:
1542 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetCSEndpointDescriptor"));
1543 r = Kern::ThreadRawRead(iClient, a1, &desInfo, sizeof(desInfo));
1545 PanicClientThread(r);
1546 ep = EpFromAlternateSetting(desInfo.iSetting, desInfo.iEndpoint);
1547 r = iController->SetCSEndpointDescriptorBlock(iClient, this, desInfo.iSetting, ep,
1548 *reinterpret_cast<const TDes8*>(desInfo.iArg),
1552 case RDevUsbcClient::EControlGetStringDescriptorLangId:
1553 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptorLangId"));
1554 r = iController->GetStringDescriptorLangId(iClient, *((TDes8*) a1));
1557 case RDevUsbcClient::EControlSetStringDescriptorLangId:
1558 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptorLangId"));
1559 r = iController->SetStringDescriptorLangId(reinterpret_cast<TUint>(a1));
1562 case RDevUsbcClient::EControlGetManufacturerStringDescriptor:
1563 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetManufacturerStringDescriptor"));
1564 r = iController->GetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
1567 case RDevUsbcClient::EControlSetManufacturerStringDescriptor:
1568 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetManufacturerStringDescriptor"));
1569 r = iController->SetManufacturerStringDescriptor(iClient, *((TPtr8*) a1));
1572 case RDevUsbcClient::EControlRemoveManufacturerStringDescriptor:
1573 __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveManufacturerStringDescriptor"));
1574 r = iController->RemoveManufacturerStringDescriptor();
1577 case RDevUsbcClient::EControlGetProductStringDescriptor:
1578 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetProductStringDescriptor"));
1579 r = iController->GetProductStringDescriptor(iClient, *((TPtr8*) a1));
1582 case RDevUsbcClient::EControlSetProductStringDescriptor:
1583 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetProductStringDescriptor"));
1584 r = iController->SetProductStringDescriptor(iClient, *((TPtr8*) a1));
1587 case RDevUsbcClient::EControlRemoveProductStringDescriptor:
1588 __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveProductStringDescriptor"));
1589 r = iController->RemoveProductStringDescriptor();
1592 case RDevUsbcClient::EControlGetSerialNumberStringDescriptor:
1593 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetSerialNumberStringDescriptor"));
1594 r = iController->GetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
1597 case RDevUsbcClient::EControlSetSerialNumberStringDescriptor:
1598 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetSerialNumberStringDescriptor"));
1599 r = iController->SetSerialNumberStringDescriptor(iClient, *((TPtr8*) a1));
1602 case RDevUsbcClient::EControlRemoveSerialNumberStringDescriptor:
1603 __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveSerialNumberStringDescriptor"));
1604 r = iController->RemoveSerialNumberStringDescriptor();
1607 case RDevUsbcClient::EControlGetConfigurationStringDescriptor:
1608 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetConfigurationStringDescriptor"));
1609 r = iController->GetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
1612 case RDevUsbcClient::EControlSetConfigurationStringDescriptor:
1613 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetConfigurationStringDescriptor"));
1614 r = iController->SetConfigurationStringDescriptor(iClient, *((TPtr8*) a1));
1617 case RDevUsbcClient::EControlRemoveConfigurationStringDescriptor:
1618 __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveConfigurationStringDescriptor"));
1619 r = iController->RemoveConfigurationStringDescriptor();
1622 case RDevUsbcClient::EControlGetStringDescriptor:
1623 __KTRACE_OPT(KUSB, Kern::Printf("EControlGetStringDescriptor"));
1624 r = iController->GetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
1627 case RDevUsbcClient::EControlSetStringDescriptor:
1628 __KTRACE_OPT(KUSB, Kern::Printf("EControlSetStringDescriptor"));
1629 r = iController->SetStringDescriptor(iClient, (TUint8) (TInt) a1, *((TPtr8*) a2));
1632 case RDevUsbcClient::EControlRemoveStringDescriptor:
1633 __KTRACE_OPT(KUSB, Kern::Printf("EControlRemoveStringDescriptor"));
1634 r = iController->RemoveStringDescriptor((TUint8) (TInt) a1);
1637 case RDevUsbcClient::EControlAllocateEndpointResource:
1638 epRes = (TUsbcEndpointResource)((TInt) a2);
1639 if (!ValidEndpoint((TInt)a1))
1641 r = KErrUsbEpNotInInterface;
1645 r = iController->AllocateEndpointResource(this, iEndpoint[(TInt)a1]->RealEpNumber(), epRes);
1649 case RDevUsbcClient::EControlDeAllocateEndpointResource:
1650 epRes = (TUsbcEndpointResource)((TInt) a2);
1651 if (!ValidEndpoint((TInt)a1))
1653 r = KErrUsbEpNotInInterface;
1657 r = iController->DeAllocateEndpointResource(this, iEndpoint[(TInt)a1]->RealEpNumber(), epRes);
1661 case RDevUsbcClient::EControlQueryEndpointResourceUse:
1662 epRes = (TUsbcEndpointResource)((TInt) a2);
1663 if (!ValidEndpoint((TInt)a1))
1665 r = KErrUsbEpNotInInterface;
1669 r = iController->QueryEndpointResource(this, iEndpoint[(TInt)a1]->RealEpNumber(), epRes);
1673 case RDevUsbcClient::EControlSetOtgDescriptor:
1675 r = iController->SetOtgDescriptor(iClient, *((const TDesC8*)a1));
1679 case RDevUsbcClient::EControlGetOtgDescriptor:
1681 r = iController->GetOtgDescriptor(iClient, *((TDes8*)a1));
1685 case RDevUsbcClient::EControlGetOtgFeatures:
1687 r = iController->GetOtgFeatures(iClient, *((TDes8*)a1));
1692 __KTRACE_OPT(KUSB, Kern::Printf("Function code not supported"));
1693 r = KErrNotSupported;
1700 TInt DLddUsbcChannel::SetInterface(TInt aInterfaceNumber, TUsbcIfcInfo* aInfoBuf)
1702 TUsbcInterfaceInfoBuf ifc_info_buf;
1703 TUsbcInterfaceInfoBuf* const ifc_info_buf_ptr = aInfoBuf->iInterfaceData;
1704 const TInt srcLen = Kern::ThreadGetDesLength(iClient, ifc_info_buf_ptr);
1705 if (srcLen < ifc_info_buf.Length())
1707 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface can't copy"));
1708 PanicClientThread(EDesOverflow);
1711 TInt r = Kern::ThreadDesRead(iClient, ifc_info_buf_ptr, ifc_info_buf, 0, KChunkShiftBy0);
1714 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface Copy failed reason=%d", r));
1715 PanicClientThread(r);
1718 TUsbcEndpointInfo* pEndpointData = ifc_info_buf().iEndpointData;
1720 // If an alternate interface is being asked for then do nothing,
1721 // just pass it down to the Controller.
1722 const TInt num_endpoints = ifc_info_buf().iTotalEndpointsUsed;
1723 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface num_endpoints=%d", num_endpoints));
1725 // [The next 4 variables have to be initialized here because of the goto's that follow.]
1726 // Both IN and OUT buffers will be fully cached:
1727 const TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
1728 const TUint32 bandwidthPriority = aInfoBuf->iBandwidthPriority;
1730 // Supports ep0+5 endpoints
1731 TInt real_ep_numbers[6] = {-1, -1, -1, -1, -1, -1};
1733 // See if PIL will accept this interface
1734 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface Calling controller"));
1735 r = iController->SetInterface(this,
1738 ifc_info_buf().iClass,
1740 ifc_info_buf().iTotalEndpointsUsed,
1741 ifc_info_buf().iEndpointData,
1743 ifc_info_buf().iFeatureWord);
1745 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface controller returned %d", r));
1748 __KTRACE_OPT(KPANIC, Kern::Printf("SetInterface failed reason=%d", r));
1752 // [The next variable has to be initialized here because of the goto's that follow.]
1753 TUsbcAlternateSettingList* alternateSettingListRec;
1756 if (iEndpoint[0] == NULL)
1758 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface 11"));
1762 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: SetupEp0() failed"));
1768 alternateSettingListRec = new TUsbcAlternateSettingList;
1769 if (!alternateSettingListRec)
1775 __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::SetInterface num_endpoints=%d", num_endpoints));
1778 // calculate the total buffer size
1779 for (TInt i = 1; i <= num_endpoints; i++, pEndpointData++)
1781 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d", i));
1782 if (!ValidateEndpoint(pEndpointData))
1784 r = KErrUsbBadEndpoint;
1788 TUsbcEndpoint* ep = new TUsbcEndpoint(this, iController, pEndpointData, i, bandwidthPriority);
1789 alternateSettingListRec->iEndpoint[i] = ep;
1795 if (ep->Construct() != KErrNone)
1801 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface for ep=%d rec=0x%08x ep==0x%08x",
1802 i, alternateSettingListRec, ep));
1805 // buf size of each endpoint
1806 TInt bufSizes[KMaxEndpointsPerClient + 1];
1807 TInt epNum[KMaxEndpointsPerClient + 1];
1810 for( TInt i=0;i<KMaxEndpointsPerClient+1;i++ )
1816 // Record the actual buf size of each endpoint
1817 for( TInt i=1;i<=num_endpoints;i++ )
1819 bufSizes[i] = alternateSettingListRec->iEndpoint[i]->BufferSize();
1822 __KTRACE_OPT(KUSB, Kern::Printf("Sort the endpoints:"));
1824 // sort the endpoint number by the bufsize decreasely
1825 for( TInt i=1;i<num_endpoints;i++ )
1828 for(TInt k=i+1;k<=num_endpoints;k++ )
1830 if( bufSizes[epMaxBuf]<bufSizes[k])
1835 TInt temp = bufSizes[i];
1836 bufSizes[i] = bufSizes[epMaxBuf];
1837 bufSizes[epMaxBuf] = temp;
1840 epNum[i] = epNum[epMaxBuf];
1841 epNum[epMaxBuf] = temp;
1843 alternateSettingListRec->iEpNumDeOrderedByBufSize[i] = epNum[i];
1845 __KTRACE_OPT(KUSB, Kern::Printf(" %d:%d", epNum[i], bufSizes[i]));
1847 alternateSettingListRec->iEpNumDeOrderedByBufSize[num_endpoints] = epNum[num_endpoints];
1848 __KTRACE_OPT(KUSB, Kern::Printf(" %d:%d", epNum[num_endpoints], bufSizes[num_endpoints]));
1849 __KTRACE_OPT(KUSB, Kern::Printf("\n"));
1851 // chain in this alternate setting
1852 alternateSettingListRec->iNext = iAlternateSettingList;
1853 iAlternateSettingList = alternateSettingListRec;
1854 alternateSettingListRec->iSetting = aInterfaceNumber;
1855 alternateSettingListRec->iNumberOfEndpoints = num_endpoints;
1857 // Record the 'real' endpoint number used by the PDD in both the Ep and
1858 // the Req callback:
1859 for (TInt i = 1; i <= num_endpoints; i++)
1861 alternateSettingListRec->iEndpoint[i]->SetRealEpNumber(real_ep_numbers[i]);
1864 r = SetupInterfaceMemory(iHwChunks, cacheAttribs );
1867 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface ready to exit"));
1869 if (aInterfaceNumber == 0)
1871 // make sure we're ready to go with the main interface
1872 iValidInterface = ETrue;
1873 __KTRACE_OPT(KUSB, Kern::Printf("SetInterface SelectAlternateSetting"));
1874 SelectAlternateSetting(0);
1880 __KTRACE_OPT(KUSB, Kern::Printf("Destroying all interfaces"));
1881 DestroyAllInterfaces();
1887 delete alternateSettingListRec;
1892 TInt r1 = iController->ReleaseInterface(this, aInterfaceNumber);
1893 __KTRACE_OPT(KUSB, Kern::Printf("Release Interface controller returned %d", r1));
1895 (void) iController->ReleaseInterface(this, aInterfaceNumber);
1900 // realloc the memory, and set the previous interfaces
1901 TInt DLddUsbcChannel::SetupInterfaceMemory(RArray<DPlatChunkHw*> &aHwChunks,
1902 TUint32 aCacheAttribs )
1904 TUsbcAlternateSettingList* asRec = iAlternateSettingList;
1906 // if buffers has been changed
1907 TBool chunkChanged = EFalse;
1908 TInt numOfEp = asRec->iNumberOfEndpoints;
1910 // 1, collect all bufs' sizes for the current interface
1911 // to realloc all the chunks
1912 __KTRACE_OPT(KUSB, Kern::Printf("Collect all buffer sizes:"));
1913 RArray<TInt> bufSizes;
1914 for(TInt i=1;i<=numOfEp;i++)
1916 TInt nextEp = asRec->iEpNumDeOrderedByBufSize[i];
1917 TInt epBufCount = asRec->iEndpoint[nextEp]->BufferNumber();
1918 __KTRACE_OPT(KUSB, Kern::Printf(" ep %d, buf count %d", nextEp, epBufCount ));
1919 for(TInt k=0;k<epBufCount;k++)
1921 TInt epBufSize = asRec->iEndpoint[nextEp]->BufferSize();
1922 TInt r = bufSizes.Append(epBufSize);
1925 iController->DeRegisterClient(this);
1929 __KTRACE_OPT(KUSB,Kern::Printf(" %d", epBufSize ));
1931 __KTRACE_OPT(KUSB, Kern::Printf("\n"));
1935 // 2, alloc the buffer decreasely, biggest-->smallest
1936 // 2.1 check the existing chunks
1937 TInt bufCount = bufSizes.Count();
1938 __KTRACE_OPT(KUSB, Kern::Printf(" ep buf number needed %d", bufCount ));
1939 __KTRACE_OPT(KUSB, Kern::Printf(" chunks available %d", aHwChunks.Count() ));
1942 while( (chunkInd<aHwChunks.Count())&& (chunkInd<bufCount))
1944 TUint8* oldAddr = NULL;
1945 oldAddr = reinterpret_cast<TUint8*>(aHwChunks[chunkInd]->LinearAddress());
1947 DPlatChunkHw* chunk = ReAllocate(bufSizes[chunkInd], aHwChunks[chunkInd], aCacheAttribs);
1950 __KTRACE_OPT(KUSB, Kern::Printf("Failed to alloc chunks size %d!", bufSizes[chunkInd]));
1951 // lost all interfaces:
1952 // Tell Controller to release Interface and h/w resources associated with this
1953 iController->DeRegisterClient(this);
1955 return KErrNoMemory;
1959 // Parcel out the memory between endpoints
1960 TUint8* newAddr = reinterpret_cast<TUint8*>(chunk->LinearAddress());
1961 __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory alloc new chunk=0x%x, size=%d", newAddr,bufSizes[chunkInd]));
1962 chunkChanged = (newAddr != oldAddr);
1963 aHwChunks[chunkInd] = chunk;
1968 // 2.2 in case available chunks are not enough
1969 while( chunkInd<bufCount)
1971 DPlatChunkHw* chunk = NULL;
1972 chunk = Allocate( bufSizes[chunkInd], aCacheAttribs);
1975 __KTRACE_OPT(KUSB, Kern::Printf("Failed to alloc chunk, size %d!", bufSizes[chunkInd]));
1976 // lost all interfaces:
1977 // Tell Controller to release Interface and h/w resources associated with this
1978 iController->DeRegisterClient(this);
1980 return KErrNoMemory;
1984 // Parcel out the memory between endpoints
1985 __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory alloc new chunk=0x%x, size=%d",
1986 reinterpret_cast<TUint8*>(chunk->LinearAddress()), bufSizes[chunkInd]));
1987 TInt r = aHwChunks.Append(chunk);
1990 ClosePhysicalChunk(chunk);
1991 iController->DeRegisterClient(this);
1999 // 3, Set the the bufs of the interfaces
2001 ReSetInterfaceMemory(asRec, aHwChunks);
2005 __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory readdressing."));
2006 asRec = asRec->iNext;
2009 // Interfaces are not concurrent so they can all start at the same logical address
2010 __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory readdressing setting=%d", asRec->iSetting));
2011 ReSetInterfaceMemory(asRec, aHwChunks);
2012 asRec = asRec->iNext;
2018 TInt DLddUsbcChannel::SetupEp0()
2020 __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 entry %x", this));
2021 TInt ep0Size = iController->Ep0PacketSize();
2022 TUsbcEndpointInfo ep0Info = TUsbcEndpointInfo(KUsbEpTypeControl, KUsbEpDirBidirect, ep0Size);
2023 TUsbcEndpoint* ep0 = new TUsbcEndpoint(this, iController, &ep0Info, 0, 0);
2026 return KErrNoMemory;
2028 // In case we have to return early:
2030 TInt r = ep0->Construct();
2033 return KErrNoMemory;
2036 TInt bufferNum = ep0->BufferNumber();
2037 TInt bufferSize = ep0->BufferSize();
2038 TUint32 cacheAttribs = EMapAttrSupRw | EMapAttrCachedMax;
2040 for(TInt i=0;i<bufferNum;i++)
2042 DPlatChunkHw* chunk = Allocate(bufferSize, cacheAttribs );
2045 return KErrNoMemory;
2047 TInt r = iHwChunksEp0.Append(chunk);
2050 ClosePhysicalChunk(chunk);
2054 buf = (TUint8*) chunk->LinearAddress();
2055 ep0->SetBufferAddr( i, buf);
2056 __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 60 buffer number %d", i));
2057 __KTRACE_OPT(KUSB, Kern::Printf("SetupEp0 60 buffer size %d", bufferSize));
2060 ep0->SetRealEpNumber(0);
2064 // Set buffer address of the interface
2065 // Precondition: Enough chunks available.
2066 void DLddUsbcChannel::ReSetInterfaceMemory(TUsbcAlternateSettingList* aAlternateSettingListRec,
2067 RArray<DPlatChunkHw*> &aHwChunks)
2069 TUsbcAlternateSettingList* asRec = aAlternateSettingListRec;
2071 // set all the interfaces
2073 TInt numOfEp = asRec->iNumberOfEndpoints;
2075 for (TInt i = 1; i <= numOfEp; i++)
2077 TInt nextEp = asRec->iEpNumDeOrderedByBufSize[i];
2078 TInt epBufCount = asRec->iEndpoint[nextEp]->BufferNumber();
2079 for(TInt k=0;k<epBufCount;k++)
2081 TUsbcEndpoint* ep = asRec->iEndpoint[nextEp];
2084 TUint8* pBuf = NULL;
2085 pBuf = reinterpret_cast<TUint8*>(aHwChunks[chunkInd]->LinearAddress());
2086 ep->SetBufferAddr( k, pBuf);
2087 __KTRACE_OPT(KUSB, Kern::Printf(" ep %d, buf %d, addr 0x%x", nextEp, k, pBuf ));
2089 __ASSERT_DEBUG(chunkInd<=aHwChunks.Count(),
2090 Kern::Printf(" Error: available chunks %d, run out at epInd%d, bufInd%d",
2091 aHwChunks.Count(), i, k));
2092 __ASSERT_DEBUG(chunkInd<=aHwChunks.Count(),
2093 Kern::Fault("usbc.ldd", __LINE__));
2100 void DLddUsbcChannel::DestroyAllInterfaces()
2102 // Removes all interfaces
2103 TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
2104 while (alternateSettingListRec)
2106 iController->ReleaseInterface(this, alternateSettingListRec->iSetting);
2107 TUsbcAlternateSettingList* alternateSettingListRecNext = alternateSettingListRec->iNext;
2108 delete alternateSettingListRec;
2109 alternateSettingListRec = alternateSettingListRecNext;
2111 iNumberOfEndpoints = 0;
2112 iAlternateSettingList = NULL;
2114 for(TInt i=0;i<iHwChunks.Count();i++)
2116 ClosePhysicalChunk( iHwChunks[i]);
2120 iValidInterface = EFalse;
2124 void DLddUsbcChannel::DestroyInterface(TUint aInterfaceNumber)
2126 if (iAlternateSetting == aInterfaceNumber)
2128 ResetInterface(KErrUsbInterfaceNotReady);
2129 iValidInterface = EFalse;
2130 iNumberOfEndpoints = 0;
2131 for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
2133 iEndpoint[i] = NULL;
2136 TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
2137 TUsbcAlternateSettingList* alternateSettingListRecOld = NULL;
2138 while (alternateSettingListRec)
2140 TUsbcAlternateSettingList* alternateSettingListRecNext = alternateSettingListRec->iNext;
2141 if (alternateSettingListRec->iSetting == aInterfaceNumber)
2143 // This record is to be deleted
2144 if (alternateSettingListRecOld == NULL)
2146 // The record to be deleted is at the list head
2147 iAlternateSettingList = alternateSettingListRecNext;
2151 // The record to be deleted is NOT at the list head
2152 alternateSettingListRecOld->iNext = alternateSettingListRecNext;
2154 delete alternateSettingListRec;
2157 alternateSettingListRecOld = alternateSettingListRec;
2158 alternateSettingListRec = alternateSettingListRecNext;
2161 if (iAlternateSettingList == NULL)
2163 // if no interfaces left destroy non-ep0 buffering
2164 for(TInt i=0;i<iHwChunks.Count();i++)
2166 ClosePhysicalChunk( iHwChunks[i]);
2173 void DLddUsbcChannel::DestroyEp0()
2175 delete iEndpoint[0];
2176 iEndpoint[0] = NULL;
2177 for(TInt i=0;i<iHwChunksEp0.Count();i++)
2179 ClosePhysicalChunk( iHwChunksEp0[i] );
2181 iHwChunksEp0.Close();
2185 void DLddUsbcChannel::EndpointStatusChangeCallback(TAny* aDLddUsbcChannel)
2187 __KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback"));
2188 DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
2189 if (dUsbc->iChannelClosing)
2191 TUint endpointState = dUsbc->iEndpointStatusCallbackInfo.State();
2192 const TInt reqNo = (TInt) RDevUsbcClient::ERequestEndpointStatusNotify;
2193 if (dUsbc->iRequestStatus[reqNo])
2195 __KTRACE_OPT(KUSB, Kern::Printf("EndpointStatusChangeCallback Notify status"));
2196 DThread* client = dUsbc->iClient;
2198 dUsbc->iEndpointStatusChangeReq->Data() = endpointState;
2199 dUsbc->iRequestStatus[reqNo] = NULL;
2200 Kern::QueueRequestComplete(client,dUsbc->iEndpointStatusChangeReq,KErrNone);
2201 dUsbc->iEndpointStatusChangePtr = NULL;
2206 void DLddUsbcChannel::StatusChangeCallback(TAny* aDLddUsbcChannel)
2208 DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
2209 if (dUsbc->iChannelClosing)
2212 TUsbcDeviceState deviceState;
2215 (i < KUsbcDeviceStateRequests) && ((deviceState = dUsbc->iStatusCallbackInfo.State(i)) != EUsbcNoState);
2218 __KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallBack status=%d", deviceState));
2219 if (deviceState & KUsbAlternateSetting)
2221 dUsbc->ProcessAlternateSetting(deviceState);
2225 dUsbc->ProcessDeviceState(deviceState);
2227 // Only queue if userside is interested
2228 if (dUsbc->iDeviceStatusNeeded)
2230 dUsbc->iStatusFifo->AddStatusToQueue(deviceState);
2231 const TInt reqNo = (TInt) RDevUsbcClient::ERequestAlternateDeviceStatusNotify;
2232 if (dUsbc->AlternateDeviceStateTestComplete())
2234 dUsbc->iRequestStatus[reqNo]=NULL;
2235 Kern::QueueRequestComplete(dUsbc->iClient,dUsbc->iStatusChangeReq,KErrNone);
2239 // We don't want to be interrupted in the middle of this:
2240 const TInt irqs = NKern::DisableInterrupts(2);
2241 dUsbc->iStatusCallbackInfo.ResetState();
2242 NKern::RestoreInterrupts(irqs);
2246 void DLddUsbcChannel::OtgFeatureChangeCallback(TAny* aDLddUsbcChannel)
2248 __KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback"));
2249 DLddUsbcChannel* dUsbc = (DLddUsbcChannel*) aDLddUsbcChannel;
2250 if (dUsbc->iChannelClosing)
2254 // No return value check. Assume OTG always supported here
2255 dUsbc->iController->GetCurrentOtgFeatures(features);
2257 const TInt reqNo = (TInt) RDevUsbcClient::ERequestOtgFeaturesNotify;
2258 if (dUsbc->iRequestStatus[reqNo])
2260 __KTRACE_OPT(KUSB, Kern::Printf("OtgFeatureChangeCallback Notify status"));
2261 dUsbc->iOtgFeatureChangeReq->Data()=features;
2262 dUsbc->iRequestStatus[reqNo] = NULL;
2263 Kern::QueueRequestComplete(dUsbc->iClient,dUsbc->iOtgFeatureChangeReq,KErrNone);
2264 dUsbc->iOtgFeatureChangePtr = NULL;
2269 TInt DLddUsbcChannel::SelectAlternateSetting(TUint aAlternateSetting)
2271 TInt r = KErrGeneral; // error code doesn't go userside
2272 TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
2273 while (alternateSettingListRec)
2275 if (alternateSettingListRec->iSetting == aAlternateSetting)
2277 // found the correct interface, now latch in new endpoint set
2278 for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
2280 iEndpoint[i] = NULL;
2282 iNumberOfEndpoints = alternateSettingListRec->iNumberOfEndpoints;
2284 for (TInt i = 1; i <= KMaxEndpointsPerClient; i++)
2286 iEndpoint[i] = alternateSettingListRec->iEndpoint[i];
2288 // Only after correct alternate setting has been chosen.
2289 UpdateEndpointSizes();
2291 alternateSettingListRec = alternateSettingListRec->iNext;
2297 TInt DLddUsbcChannel::EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint)
2299 TUsbcAlternateSettingList* alternateSettingListRec = iAlternateSettingList;
2300 while (alternateSettingListRec)
2302 if (alternateSettingListRec->iSetting == aAlternateSetting)
2304 if ((aEndpoint <= alternateSettingListRec->iNumberOfEndpoints) &&
2307 return alternateSettingListRec->iEndpoint[aEndpoint]->RealEpNumber();
2311 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: aEndpoint %d wrong for aAlternateSetting %d",
2312 aEndpoint, aAlternateSetting));
2316 alternateSettingListRec = alternateSettingListRec->iNext;
2318 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: no aAlternateSetting %d found", aAlternateSetting));
2323 TInt DLddUsbcChannel::ProcessAlternateSetting(TUint aAlternateSetting)
2325 ResetInterface(KErrUsbInterfaceChange); // kill any outstanding transfers
2326 __KTRACE_OPT(KUSB, Kern::Printf("ProcessAlternateSetting 0x%08x", aAlternateSetting));
2327 TUint newSetting = aAlternateSetting&(~KUsbAlternateSetting);
2328 __KTRACE_OPT(KUSB, Kern::Printf("ProcessAlternateSetting selecting alternate setting 0x%08x", newSetting));
2329 TInt r = SelectAlternateSetting(newSetting);
2333 iAlternateSetting = newSetting;
2338 TInt DLddUsbcChannel::ProcessDeviceState(TUsbcDeviceState aDeviceState)
2340 __KTRACE_OPT(KUSB, Kern::Printf("ProcessDeviceState(%d -> %d)", iDeviceState, aDeviceState));
2341 if (iDeviceState == aDeviceState)
2343 __KTRACE_OPT(KUSB, Kern::Printf(" No state change => nothing to be done."));
2346 if (iDeviceState == EUsbcDeviceStateSuspended)
2348 __KTRACE_OPT(KUSB, Kern::Printf(" Coming out of Suspend: old state = %d", iOldDeviceState));
2349 iDeviceState = iOldDeviceState;
2350 if (iDeviceState == aDeviceState)
2352 __KTRACE_OPT(KUSB, Kern::Printf(" New state same as before Suspend => nothing to be done."));
2356 TBool renumerateState = (aDeviceState == EUsbcDeviceStateConfigured);
2357 TBool deconfigured = EFalse;
2358 TInt cancellationCode = KErrNone;
2359 if (aDeviceState == EUsbcDeviceStateSuspended)
2361 __KTRACE_OPT(KUSB, Kern::Printf(" Suspending..."));
2362 iOldDeviceState = iDeviceState;
2363 // Put PSL into low power mode here
2367 deconfigured = (iDeviceState == EUsbcDeviceStateConfigured &&
2368 aDeviceState != EUsbcDeviceStateConfigured);
2369 if (iDeviceState == EUsbcDeviceStateConfigured)
2371 if (aDeviceState == EUsbcDeviceStateUndefined)
2372 cancellationCode = KErrUsbCableDetached;
2373 else if (aDeviceState == EUsbcDeviceStateAddress)
2374 cancellationCode = KErrUsbDeviceNotConfigured;
2375 else if (aDeviceState == EUsbcDeviceStateDefault)
2376 cancellationCode = KErrUsbDeviceBusReset;
2378 cancellationCode = KErrUsbDeviceNotConfigured;
2381 __KTRACE_OPT(KUSB, Kern::Printf(" %d --> %d", iDeviceState, aDeviceState));
2382 iDeviceState = aDeviceState;
2383 if (iValidInterface || iOwnsDeviceControl)
2385 // This LDD may not own an interface. It could be some manager reenumerating
2386 // after its subordinate LDDs have setup their interfaces.
2389 DeConfigure(cancellationCode);
2391 else if (renumerateState)
2393 // Update size of Ep0.
2394 iEndpoint[0]->SetMaxPacketSize(iController->Ep0PacketSize());
2395 // First cancel transfers on all endpoints
2396 ResetInterface(KErrUsbInterfaceChange);
2397 // Select main interface & latch in new endpoint set
2398 SelectAlternateSetting(0);
2404 const TInt reqNo = (TInt) RDevUsbcClient::ERequestReEnumerate;
2405 if (renumerateState && iRequestStatus[reqNo])
2407 // This lot must be done if we are reenumerated
2408 CompleteBufferRequest(iClient, reqNo, KErrNone);
2415 void DLddUsbcChannel::UpdateEndpointSizes()
2417 // The regular ones.
2419 while ((++i <= KMaxEndpointsPerClient) && iEndpoint[i])
2421 const TInt size = iController->EndpointPacketSize(this, iEndpoint[i]->RealEpNumber());
2424 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Packet size < 0 for ep %d", i));
2427 iEndpoint[i]->SetMaxPacketSize(size);
2429 __ASSERT_DEBUG(i == iNumberOfEndpoints + 1,
2430 Kern::Printf(" Error: iNumberOfEndpoints wrong (%d)", iNumberOfEndpoints));
2434 DPlatChunkHw* DLddUsbcChannel::ReAllocate(TInt aBuffersize, DPlatChunkHw* aHwChunk, TUint32 aCacheAttribs)
2436 DPlatChunkHw* chunk = aHwChunk;
2437 if ((!chunk) || (chunk->iSize < aBuffersize))
2441 ClosePhysicalChunk(chunk);
2443 __KTRACE_OPT(KUSB, Kern::Printf("ReAllocate need to get new chunk"));
2444 chunk = Allocate(aBuffersize, aCacheAttribs);
2450 DPlatChunkHw* DLddUsbcChannel::Allocate(TInt aBuffersize, TUint32 aCacheAttribs)
2452 TUint32 physAddr = 0;
2453 TUint32 size = Kern::RoundToPageSize(aBuffersize);
2455 if (Epoc::AllocPhysicalRam(size, physAddr) != KErrNone)
2458 DPlatChunkHw* HwChunk;
2459 if (DPlatChunkHw::New(HwChunk, physAddr, aBuffersize, aCacheAttribs) != KErrNone)
2461 Epoc::FreePhysicalRam(physAddr, size);
2469 TInt DLddUsbcChannel::DoRxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TBool aReEntrant)
2472 TInt err = aTUsbcEndpoint->CopyToClient(iClient, completeNow,iClientAsynchNotify[aEndpoint]->iClientBuffer);
2475 aTUsbcEndpoint->SetClientReadPending(EFalse);
2476 CompleteBufferRequest(iClient, aEndpoint, err);
2478 aTUsbcEndpoint->TryToStartRead(aReEntrant);
2483 void DLddUsbcChannel::DoRxCompleteNow(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint)
2485 aTUsbcEndpoint->SetClientReadPending(EFalse);
2486 CompleteBufferRequest(iClient, aEndpoint, KErrCancel);
2490 void DLddUsbcChannel::DoTxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TInt aError)
2492 aTUsbcEndpoint->SetClientWritePending(EFalse);
2493 CompleteBufferRequest(iClient, aEndpoint, aError);
2497 TBool DLddUsbcChannel::AlternateDeviceStateTestComplete()
2499 TBool completeNow = EFalse;
2500 const TInt reqNo = (TInt) RDevUsbcClient::ERequestAlternateDeviceStatusNotify;
2501 if (iRequestStatus[reqNo])
2503 // User req is outstanding
2504 TUint32 deviceState;
2505 if (iStatusFifo->GetDeviceQueuedStatus(deviceState) == KErrNone)
2507 // Device state waiting to be sent userside
2508 completeNow = ETrue;
2509 __KTRACE_OPT(KUSB, Kern::Printf("StatusChangeCallback Notify status"));
2510 iStatusChangeReq->Data()=deviceState;
2511 iStatusChangePtr = NULL;
2518 void DLddUsbcChannel::EmergencyCompleteDfc(TAny* aDLddUsbcChannel)
2520 ((DLddUsbcChannel*) aDLddUsbcChannel)->DoEmergencyComplete();
2524 void DLddUsbcChannel::DeConfigure(TInt aErrorCode)
2526 __KTRACE_OPT(KUSB, Kern::Printf("DLddUsbcChannel::DeConfigure()"));
2527 // Called after deconfiguration. Cancels transfers on all endpoints.
2528 ResetInterface(aErrorCode);
2529 // Cancel the endpoint status notify request if it is outstanding.
2530 const TInt KEpNotReq = RDevUsbcClient::ERequestEndpointStatusNotify;
2531 if (iRequestStatus[KEpNotReq])
2533 CancelNotifyEndpointStatus();
2534 iRequestStatus[KEpNotReq]=NULL;
2535 Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,aErrorCode);
2537 // We have to reset the alternate setting number when the config goes away.
2538 SelectAlternateSetting(0);
2539 iAlternateSetting = 0;
2543 void DLddUsbcChannel::StartEpReads()
2545 // Queued after enumeration. Starts reads on all endpoints.
2546 // The endpoint itself decides if it can do a read
2548 for (i = 0; i <= iNumberOfEndpoints; i++)
2550 // The endpoint itself will decide if it can read
2551 iEndpoint[i]->TryToStartRead(EFalse);
2556 void DLddUsbcChannel::ResetInterface(TInt aErrorCode)
2558 // Called after change in alternate setting. Cancels transfers on all endpoints
2559 if (iValidInterface || iOwnsDeviceControl)
2561 // Reset each endpoint except ep0
2562 for (TInt i = 1; i <= iNumberOfEndpoints; i++)
2564 __KTRACE_OPT(KUSB, Kern::Printf("Cancelling transfer ep=%d", i));
2565 iEndpoint[i]->CancelTransfer(iClient,iClientAsynchNotify[i]->iClientBuffer); // Copies data userside
2566 iEndpoint[i]->AbortTransfer(); // kills any ldd->pil outstanding transfers
2567 iEndpoint[i]->iDmaBuffers->Flush();
2568 if (iRequestStatus[i] != NULL)
2569 CompleteBufferRequest(iClient, i, aErrorCode);
2570 iEndpoint[i]->SetClientWritePending(EFalse);
2571 iEndpoint[i]->SetClientReadPending(EFalse);
2577 void DLddUsbcChannel::AbortInterface()
2579 // Called after when channel is closing
2580 if (iValidInterface || iOwnsDeviceControl)
2582 for (TInt i = 0; i <= iNumberOfEndpoints; i++)
2586 // kills any LDD->PDD outstanding transfers
2587 iEndpoint[i]->AbortTransfer();
2594 void DLddUsbcChannel::ClosePhysicalChunk(DPlatChunkHw*& aHwChunk)
2598 const TPhysAddr addr = aHwChunk->PhysicalAddress();
2599 const TInt size = aHwChunk->iSize;
2600 aHwChunk->Close(NULL);
2601 Epoc::FreePhysicalRam(addr, size);
2607 TInt DLddUsbcChannel::DoEmergencyComplete()
2609 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::DoEmergencyComplete"));
2610 // cancel any pending DFCs
2611 // complete all client requests
2612 for (TInt i = 0; i < KUsbcMaxRequests; i++)
2614 if (iRequestStatus[i])
2616 __KTRACE_OPT(KUSB, Kern::Printf("Complete request 0x%x", iRequestStatus[i]));
2618 if (i == RDevUsbcClient::ERequestAlternateDeviceStatusNotify)
2621 iDeviceStatusNeeded = EFalse;
2622 iStatusFifo->FlushQueue();
2624 if (iStatusChangePtr)
2626 iStatusChangeReq->Data() = iController->GetDeviceStatus();
2627 iStatusChangePtr = NULL;
2629 if (iStatusChangeReq->IsReady())
2631 iRequestStatus[i] = NULL;
2632 Kern::QueueRequestComplete(iClient, iStatusChangeReq,
2638 else if (i == RDevUsbcClient::ERequestEndpointStatusNotify)
2641 if (iEndpointStatusChangePtr)
2644 for (TInt i = 0; i <= iNumberOfEndpoints; i++)
2646 TInt v = iController->GetEndpointStatus(this, iEndpoint[i]->RealEpNumber());
2648 (v == EEndpointStateStalled) ? b = 1 : b = 0;
2652 iEndpointStatusChangeReq->Data() = epBitmap;
2653 iEndpointStatusChangePtr = NULL;
2656 if (iEndpointStatusChangeReq->IsReady())
2658 iRequestStatus[i] = NULL;
2659 Kern::QueueRequestComplete(iClient,iEndpointStatusChangeReq,KErrDisconnected);
2663 else if (i == RDevUsbcClient::ERequestOtgFeaturesNotify)
2666 if (iOtgFeatureChangePtr)
2669 iController->GetCurrentOtgFeatures(features);
2670 iOtgFeatureChangeReq->Data()=features;
2671 iOtgFeatureChangePtr = NULL;
2674 if (iOtgFeatureChangeReq->IsReady())
2676 iRequestStatus[i] = NULL;
2677 Kern::QueueRequestComplete(iClient, iOtgFeatureChangeReq,
2684 CompleteBufferRequest(iClient, i, KErrDisconnected);
2690 iStatusCallbackInfo.Cancel();
2691 iEndpointStatusCallbackInfo.Cancel();
2692 iOtgFeatureCallbackInfo.Cancel();
2697 void DLddUsbcChannel::PanicClientThread(TInt aReason)
2699 Kern::ThreadKill(iClient, EExitPanic, aReason, KUsbLDDKillCat);
2703 // ===============Endpoint====================
2706 TUsbcEndpoint::TUsbcEndpoint(DLddUsbcChannel* aLDD, DUsbClientController* aController,
2707 const TUsbcEndpointInfo* aEndpointInfo, TInt aEndpointNum,
2708 TInt aBandwidthPriority)
2709 : iController(aController),
2710 iEndpointInfo(aEndpointInfo->iType, aEndpointInfo->iDir, aEndpointInfo->iSize),
2711 iClientReadPending(EFalse),
2712 iClientWritePending(EFalse),
2713 iEndpointNumber(aEndpointNum),
2717 iRequestCallbackInfo(NULL),
2718 iBytesTransferred(0),
2719 iBandwidthPriority(aBandwidthPriority)
2721 ResetTransferInfo();
2722 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::TUsbcEndpoint 2"));
2726 TInt TUsbcEndpoint::Construct()
2728 iDmaBuffers = new TDmaBuf(&iEndpointInfo, iBandwidthPriority);
2729 if (iDmaBuffers == NULL)
2731 return KErrNoMemory;
2733 const TInt r = iDmaBuffers->Construct(&iEndpointInfo);
2738 iRequestCallbackInfo = new TUsbcRequestCallback(iLdd,
2740 TUsbcEndpoint::RequestCallback,
2743 KUsbRequestCallbackPriority);
2744 if (iRequestCallbackInfo == NULL)
2746 return KErrNoMemory;
2752 TUsbcEndpoint::~TUsbcEndpoint()
2754 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::~TUsbcEndpoint(%d)", iEndpointNumber));
2756 delete iRequestCallbackInfo;
2761 void TUsbcEndpoint::RequestCallback(TAny* aTUsbcEndpoint)
2763 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::RequestCallback"));
2764 ((TUsbcEndpoint*) aTUsbcEndpoint)->EndpointComplete();
2768 void TUsbcEndpoint::SetMaxPacketSize(TInt aSize)
2770 iEndpointInfo.iSize = aSize;
2771 iDmaBuffers->SetMaxPacketSize(aSize);
2775 TInt TUsbcEndpoint::EndpointComplete()
2777 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete ep=%d %d",
2778 iEndpointNumber, iRequestCallbackInfo->iEndpointNum));
2780 if (iLdd->ChannelClosing())
2782 __KTRACE_OPT(KUSB, Kern::Printf("We're going home -> completions no longer accepted"));
2786 TTransferDirection transferDir = iRequestCallbackInfo->iTransferDir;
2787 TInt error = iRequestCallbackInfo->iError;
2789 switch (transferDir)
2792 case EControllerWrite:
2794 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete Write 2"));
2795 if (!iDmaBuffers->TxIsActive())
2797 __KTRACE_OPT(KUSB, Kern::Printf(" TX completion but !iDmaBuffers->TxIsActive()"));
2801 iDmaBuffers->TxSetInActive();
2802 TBool completeNow = EFalse;
2803 iBytesTransferred += iRequestCallbackInfo->iTxBytes;
2804 if (iClientWritePending)
2806 //Complete Outstanding Write if necessary
2808 if (iError != KErrNone)
2810 completeNow = ETrue;
2811 if (iError == KErrPrematureEnd) // Previous write could not be completed
2816 if (iBytesTransferred == (TUint32) iTransferInfo.iTransferSize)
2818 completeNow = ETrue;
2822 iError = ContinueWrite();
2823 if (iError != KErrNone)
2824 completeNow = ETrue;
2830 ResetTransferInfo();
2831 if (iEndpointNumber == 0)
2833 iDmaBuffers->Flush();
2834 TryToStartRead(EFalse);
2841 case EControllerRead:
2843 // The first packet always contains the total #of bytes
2844 const TInt byteCount = iRequestCallbackInfo->iPacketSize[0];
2845 const TInt packetCount = iRequestCallbackInfo->iRxPackets;
2846 iDmaBuffers->ReadXferComplete(byteCount, packetCount, error);
2848 // We queue the dfc if we can complete the read, i.e. if we are reading a packet,
2849 // or if we have enough data to satisfy a read data request.
2850 if (iClientReadPending)
2852 //Complete outstanding read
2853 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcEndpoint::EndpointComplete Read 3 (bytes "
2854 "available=%d)", iDmaBuffers->RxBytesAvailable()));
2855 TInt bytesReqd = iTransferInfo.iTransferSize - iBytesTransferred;
2856 TBool completeNow = EFalse;
2858 if (iTransferInfo.iTransferType == ETransferTypeReadPacket ||
2859 iTransferInfo.iTransferType == ETransferTypeReadOneOrMore)
2861 // Always complete on a packet read
2862 completeNow = ETrue;
2864 else if (iTransferInfo.iTransferType == ETransferTypeReadData)
2866 // Complete only if enough data is present
2867 if (iDmaBuffers->RxBytesAvailable() >= bytesReqd)
2868 completeNow = ETrue;
2870 else if (iTransferInfo.iTransferType == ETransferTypeReadUntilShort)
2872 // Complete if enough data is present or if a short packet has been delivered
2873 const TInt maxPacketSize = iEndpointInfo.iSize;
2874 const TInt lastPacketSize = iRequestCallbackInfo->iPacketSize[packetCount - 1];
2875 if (lastPacketSize < maxPacketSize)
2876 completeNow = ETrue;
2877 else if (iDmaBuffers->RxBytesAvailable() >= bytesReqd)
2878 completeNow = ETrue;
2881 const TUint type = iEndpointInfo.iType;
2882 if ((type == KUsbEpTypeBulk) && (lastPacketSize & (maxPacketSize - 1)))
2884 completeNow = ETrue;
2886 else if ((type != KUsbEpTypeBulk) &&
2887 (lastPacketSize > maxPacketSize) &&
2888 (lastPacketSize % maxPacketSize))
2890 completeNow = ETrue;
2898 iClientReadPending = EFalse;
2901 iDmaBuffers->RxSetInActive();
2902 if (error != KErrNone)
2906 if (TryToStartRead(EFalse) != KErrNone)
2908 // if (iEndpointNumber != 0)
2909 // Kern::Printf("EndpointComplete couldn't start read on ep=%d", iEndpointNumber);
2915 // shouldn't get here
2923 void TUsbcEndpoint::TxComplete()
2925 iLdd->DoTxComplete(this, iEndpointNumber, iError);
2929 TInt TUsbcEndpoint::RxComplete(TBool aReEntrant)
2931 return iLdd->DoRxComplete(this, iEndpointNumber, aReEntrant);
2935 void TUsbcEndpoint::RxCompleteNow()
2937 iLdd->DoRxCompleteNow(this, iEndpointNumber);
2941 TInt TUsbcEndpoint::CopyToClient(DThread* aClient, TClientBuffer *aTcb)
2944 return CopyToClient(aClient, completeNow,aTcb);
2948 TInt TUsbcEndpoint::CopyToClient(DThread* aClient, TBool& aCompleteNow, TClientBuffer *aTcb)
2951 const TInt length = iTransferInfo.iTransferSize;
2952 const TBool KReadData = EFalse;
2953 const TBool KReadUntilShort = ETrue;
2955 __KTRACE_OPT(KUSB, Kern::Printf("CopyToClient: length = %d", length));
2957 if (iTransferInfo.iTransferType == ETransferTypeReadPacket)
2959 err = iDmaBuffers->RxCopyPacketToClient(aClient, aTcb, length);
2960 aCompleteNow = ETrue;
2962 else if (iTransferInfo.iTransferType == ETransferTypeReadOneOrMore)
2964 err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
2965 KReadData, aCompleteNow);
2966 aCompleteNow = ETrue;
2968 else if (iTransferInfo.iTransferType == ETransferTypeReadUntilShort)
2970 err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
2971 KReadUntilShort, aCompleteNow);
2975 err = iDmaBuffers->RxCopyDataToClient(aClient, aTcb, length, iBytesTransferred,
2976 KReadData, aCompleteNow);
2981 ResetTransferInfo();
2982 SetClientReadPending(EFalse);
2989 TInt TUsbcEndpoint::TryToStartRead(TBool aReEntrant)
2991 __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead 1 ep=%d", iEndpointNumber));
2993 if (iEndpointInfo.iDir != KUsbEpDirOut &&
2994 iEndpointInfo.iDir != KUsbEpDirBidirect)
2996 // Verify ep direction
2997 __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead wrong direction ep=%d", iEndpointNumber));
2998 return KErrUsbEpBadDirection;
3001 if (iEndpointNumber == 0)
3003 // Can't issue an Ep0 read if reader or writer is active
3004 if (iDmaBuffers->TxIsActive())
3006 __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead ep0 Tx already active FATAL"));
3007 return KErrUsbEpNotReady;
3009 if (iDmaBuffers->RxIsActive())
3011 __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead ep0 Rx already active non-FATAL"));
3015 if (!(iDmaBuffers->RxIsActive()))
3019 TUsbcPacketArray* indexArray;
3020 TUsbcPacketArray* sizeArray;
3022 r = iDmaBuffers->RxGetNextXfer(bufferAddr, indexArray, sizeArray, length, physAddr);
3025 iDmaBuffers->RxSetActive();
3026 iRequestCallbackInfo->SetRxBufferInfo(bufferAddr, physAddr, indexArray, sizeArray, length);
3028 __KTRACE_OPT(KUSB, Kern::Printf("TryToStartRead 2 bufferAddr=0x%08x", bufferAddr));
3030 r = iController->SetupReadBuffer(*iRequestCallbackInfo);
3033 iDmaBuffers->RxSetInActive();
3034 __KTRACE_OPT(KPANIC, Kern::Printf(" Error: TryToStartRead controller rejects read"));
3039 if (iClientReadPending)
3041 // Deadlock, try to resolve it by draining buffer into descriptor
3048 // we are stuck, better complete userside otherwise the userside request will hang
3058 TInt TUsbcEndpoint::TryToStartWrite(TEndpointTransferInfo* pTfr)
3060 __KTRACE_OPT(KUSB, Kern::Printf("TryToStartWrite 1 ep=%d", iEndpointNumber));
3061 if (iEndpointInfo.iDir != KUsbEpDirIn &&
3062 iEndpointInfo.iDir != KUsbEpDirBidirect)
3064 // Verify ep direction
3065 return KErrUsbEpBadDirection;
3067 if (iEndpointNumber == 0)
3069 // Can't issue an Ep0 write if unread data is available or writer is active
3070 if (iDmaBuffers->TxIsActive() || !iDmaBuffers->IsReaderEmpty())
3072 return KErrUsbEpNotReady;
3074 if (iDmaBuffers->RxIsActive())
3076 // if a reader is active then cancel the read
3077 iDmaBuffers->RxSetInActive();
3078 iController->CancelReadBuffer(iLdd, iRealEpNumber);
3081 SetTransferInfo(pTfr);
3087 TInt TUsbcEndpoint::ContinueWrite()
3089 __KTRACE_OPT(KUSB, Kern::Printf("ContinueWrite 2"));
3093 TInt r = iDmaBuffers->TxGetNextXfer(bufferAddr, bufferLength, physAddr);
3094 if (r != KErrNone) // probably already active
3096 __KTRACE_OPT(KUSB, Kern::Printf("ContinueWrite 3"));
3097 iDmaBuffers->TxSetActive();
3098 TBool zlpReqd = EFalse;
3099 TUint32 transferSize = iTransferInfo.iTransferSize;
3100 TInt length = Min(transferSize - iBytesTransferred, (TUint32) bufferLength);
3101 if (iBytesTransferred+length>=transferSize)
3103 // only send a zlp if this is the last buffer of the transfer
3104 zlpReqd = iTransferInfo.iZlpReqd;
3106 r = iDmaBuffers->TxStoreData(iLdd->Client(), iLdd->GetClientBuffer(iEndpointNumber), length, iBytesTransferred);
3109 iDmaBuffers->TxSetActive();
3110 iRequestCallbackInfo->SetTxBufferInfo(bufferAddr, physAddr, length);
3111 iRequestCallbackInfo->iZlpReqd = zlpReqd;
3113 for (TInt i = 0; i < iRequestCallbackInfo->iLength; i++)
3115 __KTRACE_OPT(KUSB, Kern::Printf("Buffer[%d] = 0x%02x", i, iRequestCallbackInfo->iBufferStart[i]));
3118 r = iController->SetupWriteBuffer(*iRequestCallbackInfo);
3123 void TUsbcEndpoint::CancelTransfer(DThread* aThread, TClientBuffer *aTcb)
3125 __KTRACE_OPT(KUSB, Kern::Printf("CancelTransfer"));
3126 if (iDmaBuffers != NULL)
3128 if (iClientWritePending)
3130 __KTRACE_OPT(KUSB, Kern::Printf(" (iClientWritePending)"));
3131 iClientWritePending = EFalse;
3132 iController->CancelWriteBuffer(iLdd, iRealEpNumber);
3133 iDmaBuffers->TxSetInActive();
3135 if (iClientReadPending)
3137 __KTRACE_OPT(KUSB, Kern::Printf(" (iClientReadPending)"));
3138 iClientReadPending = EFalse;
3139 CopyToClient(aThread,aTcb);
3145 void TUsbcEndpoint::AbortTransfer()
3147 __KTRACE_OPT(KUSB, Kern::Printf("Abort Transfer"));
3148 if (iDmaBuffers != NULL)
3150 if (iDmaBuffers->TxIsActive())
3152 __KTRACE_OPT(KUSB, Kern::Printf(" (iClientWritePending)"));
3153 iController->CancelWriteBuffer(iLdd, iRealEpNumber);
3154 iDmaBuffers->TxSetInActive();
3156 if (iDmaBuffers->RxIsActive())
3158 __KTRACE_OPT(KUSB, Kern::Printf(" (iClientReadPending)"));
3159 iController->CancelReadBuffer(iLdd, iRealEpNumber);
3160 iDmaBuffers->RxSetInActive();
3162 iRequestCallbackInfo->iDfc.Cancel();
3167 TUsbcAlternateSettingList::TUsbcAlternateSettingList()
3169 iNumberOfEndpoints(0),
3172 for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
3174 iEpNumDeOrderedByBufSize[i] = -1;
3175 iEndpoint[i] = NULL;
3180 TUsbcAlternateSettingList::~TUsbcAlternateSettingList()
3182 __KTRACE_OPT(KUSB, Kern::Printf("TUsbcAlternateSettingList::~TUsbcAlternateSettingList()"));
3183 for (TInt i = 0; i <= KMaxEndpointsPerClient; i++)
3185 delete iEndpoint[i];
3190 TUsbcDeviceStatusQueue::TUsbcDeviceStatusQueue()
3196 void TUsbcDeviceStatusQueue::FlushQueue()
3198 for (TInt i = 0; i < KUsbDeviceStatusQueueDepth; i++)
3200 iDeviceStatusQueue[i] = KUsbDeviceStatusNull;
3202 iStatusQueueHead = 0;
3206 void TUsbcDeviceStatusQueue::AddStatusToQueue(TUint32 aDeviceStatus)
3208 // Only add a new status if it is not a duplicate of the one at the head of the queue
3209 if (!(iStatusQueueHead != 0 &&
3210 iDeviceStatusQueue[iStatusQueueHead - 1] == aDeviceStatus))
3212 if (iStatusQueueHead == KUsbDeviceStatusQueueDepth)
3214 // Discard item at tail of queue
3216 GetDeviceQueuedStatus(status);
3218 iDeviceStatusQueue[iStatusQueueHead] = aDeviceStatus;
3224 TInt TUsbcDeviceStatusQueue::GetDeviceQueuedStatus(TUint32& aDeviceStatus)
3227 if (iStatusQueueHead <= 0)
3230 aDeviceStatus = KUsbDeviceStatusNull;
3234 aDeviceStatus = iDeviceStatusQueue[0];
3235 for(TInt i = 1; i < KUsbDeviceStatusQueueDepth; i++)
3237 TUint32 s = iDeviceStatusQueue[i];
3238 iDeviceStatusQueue[i - 1] = s;
3241 iDeviceStatusQueue[KUsbDeviceStatusQueueDepth - 1] = KUsbDeviceStatusNull;
3246 void TClientAsynchNotify::Reset()
3248 iBufferRequest->Reset();