--- /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 <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include <kernel/kpower.h>
+#include <platform.h>
+
+#include <d32usbc.h>
+
+#include <drivers/usbcshared.h>
+
+
+
+/** 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<TUint> *iStatusChangeReq;
+ TClientDataRequest<TUint> *iEndpointStatusChangeReq;
+ TClientDataRequest<TUint> *iOtgFeatureChangeReq;
+ TEndpointTransferInfo iTfrInfo;
+ };
+
+
+#include <drivers/usbc.inl>
+
+#endif // __USBC_H__