diff -r 000000000000 -r a41df078684a kernel/eka/include/drivers/usbc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/include/drivers/usbc.h Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,354 @@ +// 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/include/drivers/usbc.h +// Kernel side definitions for the USB Device driver stack (PIL + LDD). +// +// + +/** + @file usbc.h + @internalTechnology +*/ + +#ifndef __USBC_H__ +#define __USBC_H__ + +#include +#include +#include +#include + +#include + +#include + + + +/** LDD Major version, This should agree with the information in RDevUsbcClient::TVer. +*/ +const TInt KUsbcMajorVersion = 0; + +/** LDD Minor version, This should agree with the information in RDevUsbcClient::TVer. +*/ +const TInt KUsbcMinorVersion = 1; + +/** LDD Build version, This should agree with the information in RDevUsbcClient::TVer. +*/ +const TInt KUsbcBuildVersion = KE32BuildVersionNumber; + +/** Must correspond to the max enum of TRequest + 1; + currently this is ERequestOtgFeaturesNotify = 10. +*/ +const TInt KUsbcMaxRequests = 11; + +// +//########################### Logical Device Driver (LDD) ############################# +// + +/** USB LDD factory class. +*/ +class DUsbcLogDevice : public DLogicalDevice + { +public: + DUsbcLogDevice(); + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + + +/** OUT buffering is a collection of flat buffers. Each is either fillable or drainable. + When one buffer becomes full (notified by the PIL) it is marked as not-fillable and the next + fillable buffer is used. When the buffer has finished draining it is marked as fillable. +*/ +class TDmaBuf + { +public: + TDmaBuf(); + TDmaBuf(TUsbcEndpointInfo* aEndpointInfo, TInt aBandwidthPriority); + ~TDmaBuf(); + TInt Construct(TUsbcEndpointInfo* aEndpointInfo); + TUint8* SetBufferBase(TUint8* aBase); + TInt BufferTotalSize() const; + TUint8* BufferBase() const; + void SetMaxPacketSize(TInt aSize); + void Flush(); + // Rx (OUT) variants + void RxSetActive(); + void RxSetInActive(); + TBool RxIsActive(); + TBool IsReaderEmpty(); + void ReadXferComplete(TInt aNoBytesRx, TInt aNoPacketsRx, TInt aErrorCode); + TInt RxCopyDataToClient(DThread* aThread, TClientBuffer *aTcb, TInt aLength, TUint32& aDestOffset, + TBool aRUS, TBool& aCompleteNow); + TInt RxCopyPacketToClient(DThread* aThread,TClientBuffer *aTcb, TInt aLength); + TInt RxGetNextXfer(TUint8*& aBufferAddr, TUsbcPacketArray*& aIndexArray, TUsbcPacketArray*& aSizeArray, + TInt& aLength, TPhysAddr& aBufferPhys); + TBool RxIsEnoughSpace(TInt aSize); + inline TInt RxBytesAvailable() const; + inline void IncrementBufferIndex(TInt& aIndex); + inline TInt NoRxPackets() const; + TInt SetDrainable(TInt aBufferNum); + // Tx (IN) variants + void TxSetActive(); + void TxSetInActive(); + TBool TxIsActive(); + TInt TxStoreData(DThread* aThread,TClientBuffer *aTcb, TInt aTxLength, TUint32 aBufferOffset); + TInt TxGetNextXfer(TUint8*& aBufferAddr, TInt& aTxLength, TPhysAddr& aBufferPhys); + TBool ShortPacketExists(); + +#if defined(USBC_LDD_BUFFER_TRACE) + TInt NoRxPacketsAlt() const; + TInt NoRxBytesAlt() const; +#endif + +private: + TBool AdvancePacket(); + inline TInt GetCurrentError(); + TBool NextDrainableBuffer(); + TBool NextFillableBuffer(); + void FreeDrainedBuffers(); + TInt PeekNextPacketSize(); + TInt PeekNextDrainableBuffer(); + void ModifyTotalRxBytesAvail(TInt aVal); + void ModifyTotalRxPacketsAvail(TInt aVal); + void AddToDrainQueue(TInt aBufferIndex); + inline TInt CopyToUser(DThread* aThread, const TUint8* aSourceAddr, TInt aLength, + TClientBuffer *aTcb, TUint32& aDestOffset); +private: + TInt iExtractOffset; // offset into current packet for data read + TInt iMaxPacketSize; + TInt iNumberofBuffers; + TInt iBufSz; + TBool iRxActive; + TBool iTxActive; + TInt iTotalRxBytesAvail; + TInt iTotalRxPacketsAvail; + // + TUint8* iBufBasePtr; + TUint8* iCurrentDrainingBuffer; + TInt iCurrentDrainingBufferIndex; + TInt iCurrentFillingBufferIndex; + TUint iCurrentPacket; + TUsbcPacketArray* iCurrentPacketIndexArray; + TUsbcPacketArray* iCurrentPacketSizeArray; + TUint8* iBuffers[KUsbcDmaBufNumMax]; + TBool iDrainable[KUsbcDmaBufNumMax]; + TUsbcPacketArray iPacketInfoStorage[KUsbcDmaBufNumMax * KUsbcDmaBufNumArrays * KUsbcDmaBufMaxPkts]; + TUsbcPacketArray* iPacketIndex[KUsbcDmaBufNumMax]; + TUsbcPacketArray* iPacketSize[KUsbcDmaBufNumMax]; + TUint iNumberofBytesRx[KUsbcDmaBufNumMax]; + TUint iNumberofPacketsRx[KUsbcDmaBufNumMax]; + TInt iError[KUsbcDmaBufNumMax]; + TPhysAddr iBufferPhys[KUsbcDmaBufNumMax]; + TBool iCanBeFreed[KUsbcDmaBufNumMax]; + TInt iDrainQueue[KUsbcDmaBufNumMax + 1]; + TInt iDrainQueueIndex; + TUint iEndpointType; + +#if defined(USBC_LDD_BUFFER_TRACE) + TInt iFillingOrder; + TInt iFillingOrderArray[KUsbcDmaBufNumMax]; + TInt iDrainingOrder; + TUint iNumberofBytesRxRemain[KUsbcDmaBufNumMax]; + TUint iNumberofPacketsRxRemain[KUsbcDmaBufNumMax]; +#endif + }; + + +class DLddUsbcChannel; + +/** Endpoint tracking for the LDD buffering etc. +*/ +class TUsbcEndpoint + { +public: + TUsbcEndpoint(); + TUsbcEndpoint(DLddUsbcChannel* aLDD, DUsbClientController* aController, + const TUsbcEndpointInfo* aEndpointInfo, TInt aEndpointNum, + TInt aBandwidthPriority); + ~TUsbcEndpoint(); + TInt Construct(); + TInt TryToStartRead(TBool aReEntrant); + TInt TryToStartWrite(TEndpointTransferInfo* pTfr); + TInt CopyToClient(DThread* aThread, TClientBuffer *aTcb); + TInt CopyToClient(DThread* aClient, TBool& aCompleteNow, TClientBuffer *aTcb); + TInt ContinueWrite(); + void SetMaxPacketSize(TInt aSize); + void CancelTransfer(DThread* aThread, TClientBuffer *aTcb); + void AbortTransfer(); + inline TUsbcEndpointInfo* EndpointInfo(); + inline TInt RxBytesAvailable() const; + inline TInt BufferTotalSize() const; + inline TUint8* SetBufferBase(TUint8* aBase); + inline void SetTransferInfo(TEndpointTransferInfo* aTransferInfo); + inline void ResetTransferInfo(); + inline void SetClientReadPending(TBool aVal); + inline void SetClientWritePending(TBool aVal); + inline TBool ClientWritePending(); + inline TBool ClientReadPending(); + inline void SetRealEpNumber(TInt aRealEpNumber); + inline TInt RealEpNumber() const; + +public: + TDmaBuf* iDmaBuffers; + +private: + static void RequestCallback(TAny* aTUsbcEndpoint); + void TxComplete(); + TInt RxComplete(TBool aReEntrant); + void RxCompleteNow(); + TInt EndpointComplete(); + +private: + DUsbClientController* iController; + TUsbcEndpointInfo iEndpointInfo; + TEndpointTransferInfo iTransferInfo; + TBool iClientReadPending; + TBool iClientWritePending; + TInt iEndpointNumber; + TInt iRealEpNumber; + DLddUsbcChannel* iLdd; + TInt iError; + TUsbcRequestCallback* iRequestCallbackInfo; + TUint32 iBytesTransferred; + TInt iBandwidthPriority; + }; + + +/** Linked list of 'alternate setting' info for use by the LDD. +*/ +class TUsbcAlternateSettingList + { +public: + TUsbcAlternateSettingList(); + ~TUsbcAlternateSettingList(); + +public: + TUsbcAlternateSettingList* iNext; + TInt iNumberOfEndpoints; + TUint iSetting; + TUsbcEndpoint* iEndpoint[KMaxEndpointsPerClient + 1]; + }; + + +struct TClientAsynchNotify + { + TClientBufferRequest *iBufferRequest; + TClientBuffer *iClientBuffer; + void Reset(); + }; +/** The channel class - the actual USB LDD. +*/ +class DLddUsbcChannel : public DLogicalChannel + { +public: + DLddUsbcChannel(); + ~DLddUsbcChannel(); + virtual TInt SendMsg(TMessageBase * aMsg); + TInt PreSendRequest(TMessageBase * aMsg,TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); + TInt SendControl(TMessageBase* aMsg); + virtual void HandleMsg(TMessageBase* aMsg); + virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); + TInt DoRxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TBool aReentrant); + void DoRxCompleteNow(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint); + void DoTxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TInt aError); + inline DThread* Client() const {return iClient;} + inline TBool ChannelClosing() const {return iChannelClosing;} + inline TUint AlternateSetting() const {return iAlternateSetting;} + TClientBuffer *GetClientBuffer(TInt aEndpoint); + +private: + TInt DoCancel(TInt aReqNo); + void DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); + TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); + TInt DoTransferAsyncReq(TInt aEndpointNum, TAny* a1, TAny* a2, TBool& aNeedsCompletion); + TInt DoOtherAsyncReq(TInt aReqNo, TAny* a1, TAny* a2, TBool& aNeedsCompletion); + TBool AlternateDeviceStateTestComplete(); + TInt SetInterface(TInt aInterfaceNum, TUsbcIfcInfo* aUserInterfaceInfoBuf); + void StartEpReads(); + void DestroyAllInterfaces(); + void DestroyInterface(TUint aInterface); + void DestroyEp0(); + inline TBool ValidEndpoint(TInt aEndpoint); + TInt DoEmergencyComplete(); + void ReadDes8(const TAny* aPtr, TDes8& aDes); + TInt SetupEp0(); + DPlatChunkHw* ReAllocate(TInt aBuffersize, DPlatChunkHw* aHwChunk, TUint32 aCacheAttribs); + DPlatChunkHw* Allocate(TInt aBuffersize, TUint32 aCacheAttribs); + void ClosePhysicalChunk(DPlatChunkHw* &aHwChunk); + void CancelNotifyEndpointStatus(); + void CancelNotifyOtgFeatures(); + static void StatusChangeCallback(TAny* aDLddUsbcChannel); + static void EndpointStatusChangeCallback(TAny* aDLddUsbcChannel); + static void OtgFeatureChangeCallback(TAny* aDLddUsbcChannel); + static void EmergencyCompleteDfc(TAny* aDLddUsbcChannel); + void DeConfigure(TInt aErrorCode); + TInt SelectAlternateSetting(TUint aAlternateSetting); + TInt EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint); + TInt ProcessAlternateSetting(TUint aAlternateSetting); + TInt ProcessDeviceState(TUsbcDeviceState aDeviceState); + void ResetInterface(TInt aErrorCode); + void AbortInterface(); + void RebaseInterfaceMemory(TUsbcAlternateSettingList* aAlternateSettingListRec, TUint8* aBase, + TUint aDirection); + void UpdateEndpointSizes(); + DPlatChunkHw* SetupInterfaceMemory(TInt aBufferSize, DPlatChunkHw* aHwChunk, TUint aDirection, + TUint32 aCacheAttribs); + void PanicClientThread(TInt aReason); + + TInt PinMemory(TDesC8 *aDes, TVirtualPinObject *iPinObj); //Descriptor pinning helper. + void CompleteBufferRequest(DThread* aThread, TInt aReqNo, TInt aReason); +private: + DUsbClientController* iController; + DThread* iClient; + TBool iValidInterface; + TUsbcAlternateSettingList* iAlternateSettingList; + TUsbcEndpoint* iEndpoint[KMaxEndpointsPerClient + 1]; // include ep0 + TRequestStatus* iRequestStatus[KUsbcMaxRequests]; + TClientAsynchNotify* iClientAsynchNotify[KUsbcMaxRequests]; + TUsbcClientCallback iCompleteAllCallbackInfo; + TAny* iStatusChangePtr; + TUsbcStatusCallback iStatusCallbackInfo; + TAny* iEndpointStatusChangePtr; + TUsbcEndpointStatusCallback iEndpointStatusCallbackInfo; + TAny* iOtgFeatureChangePtr; + TUsbcOtgFeatureCallback iOtgFeatureCallbackInfo; + TUint8* iBufferBaseEp0; + TInt iBufferSizeEp0; + TInt iNumberOfEndpoints; + DPlatChunkHw* iHwChunkIN; + DPlatChunkHw* iHwChunkOUT; + DPlatChunkHw* iHwChunkEp0; + TUsbcDeviceState iDeviceState; + TUsbcDeviceState iOldDeviceState; + TBool iOwnsDeviceControl; + TUint iAlternateSetting; + TBool iDeviceStatusNeeded; + TUsbcDeviceStatusQueue* iStatusFifo; + TBool iChannelClosing; + TVirtualPinObject *iPinObj1; + TVirtualPinObject *iPinObj2; + TVirtualPinObject *iPinObj3; + TClientDataRequest *iStatusChangeReq; + TClientDataRequest *iEndpointStatusChangeReq; + TClientDataRequest *iOtgFeatureChangeReq; + TEndpointTransferInfo iTfrInfo; + }; + + +#include + +#endif // __USBC_H__