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