kernel/eka/include/drivers/usbcsc.h
changeset 0 a41df078684a
child 189 a5496987b1da
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\include\drivers\usbcsc.h
       
    15 // Kernel side definitions for the USB Device driver stack (PIL + LDD).
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file usbcsc.h
       
    21  @internalTechnology
       
    22 */
       
    23 
       
    24 #ifndef __USBCSC_H__
       
    25 #define __USBCSC_H__
       
    26 
       
    27 #include <kernel/kernel.h>
       
    28 #include <kernel/kern_priv.h>
       
    29 #include <kernel/kpower.h>
       
    30 #include <platform.h>
       
    31 
       
    32 #include <d32usbcsc.h>
       
    33 
       
    34 #include <drivers/usbcshared.h>
       
    35 
       
    36 /** LDD Major version, This should agree with the information in RDevUsbcClient::TVer.
       
    37 */
       
    38 const TInt KUsbcScMajorVersion = 0;
       
    39 
       
    40 /** LDD Minor version, This should agree with the information in RDevUsbcClient::TVer.
       
    41 */
       
    42 const TInt KUsbcScMinorVersion = 1;
       
    43 
       
    44 /** LDD Build version, This should agree with the information in RDevUsbcClient::TVer.
       
    45 */
       
    46 const TInt KUsbcScBuildVersion = KE32BuildVersionNumber;
       
    47 
       
    48 /** Must correspond to the max enum of TRequest + 1;
       
    49 	currently this is ERequestOtgFeaturesNotify = 10.
       
    50 */
       
    51 const TInt KUsbcScMaxRequests = 11;
       
    52 
       
    53 // Request queue sizes need to be power of 2.
       
    54 
       
    55 /** The number of requests that can be queued on any IN endpoint */
       
    56 const TInt KUsbcScInRequests = 4;
       
    57 /** The number of requests that can be queued on any OUT endpoint */
       
    58 const TInt KUsbcScOutRequests = 2;
       
    59 
       
    60 /** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an IN endpoint */
       
    61 const TInt KUsbcScIn =  0;
       
    62 /** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an OUT endpoint */
       
    63 const TInt KUsbcScOut = 1;
       
    64 
       
    65 
       
    66 /** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an Bidirectional endpoint
       
    67 currently operating as an IN endpoint */
       
    68 const TInt KUsbcScBiIn = 2;
       
    69 /** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an Bidirectional endpoint
       
    70 currently operating as an OUT endpoint */
       
    71 const TInt KUsbcScBiOut = 3;
       
    72 
       
    73 /** The number of directions supported for endpoints, other then EP0.  Currently 2, IN and OUT. */
       
    74 const TInt KUsbcScDirections = 2;
       
    75 
       
    76 /** In TUsbcScBuffer::iDirection, this indicates that the endpoint direction is Unknown. */
       
    77 const TInt KUsbcScUnknown = 4;
       
    78 
       
    79 const TInt KPageSize = 0x1000;
       
    80 
       
    81 /** The default buffer size requested for a endpoint, if the user app does not specify a size.*/
       
    82 const TInt KUsbcScDefaultBufferSize = 0x10000; // 64k
       
    83 
       
    84 /** The size of the unmapped region of memory between endpoint buffers.
       
    85 This serves as a guard region, making memory over/under runs more obviose.*/
       
    86 const TInt KGuardSize = KPageSize;
       
    87 
       
    88 /** The size put aside for the chunk header structre.*/
       
    89 const TInt KHeaderSize = KPageSize;
       
    90 
       
    91 /** For buffers of size >= KUsbScBigBuffIs, The smallest unit of continiouse memory that will be used.
       
    92 No read will be set up smaller then this, to avoid overly fragmenting the data.
       
    93 */
       
    94 const TInt KUsbSc_BigBuff_MinimumRamRun = KPageSize;
       
    95 
       
    96 /** For buffers of size < KUsbScBigBuffIs, The smallest unit of continiouse memory that will be used.
       
    97 No read will be set up smaller then this, to avoid overly fragmenting the data.*/
       
    98 const TInt KUsbSc_SmallBuff_MinimumRamRun = 1024;
       
    99 
       
   100 /** The size a buffer request has to be to switch to using KUsbSc_BigBuff_MinimumRamRun.
       
   101 If the requested buffer is smaller, then the smallest memory allocated to a buffer is KPageSize*/
       
   102 const TInt KUsbScBigBuffIs = KPageSize*6;
       
   103 
       
   104 
       
   105 
       
   106 // EP0 is mapped manually, unlike the other endpoints.
       
   107 
       
   108 /** The position, within the chunk, that the EP0 IN buffer appears*/
       
   109 const TInt KUsbScEP0InBufPos = 0x800;
       
   110 /** The position, within the chunk, that the EP0 IN buffer ends*/
       
   111 const TInt KUsbScEP0InBufEnd = KUsbScEP0InBufPos + 0x400;
       
   112 
       
   113 // Its better for Out to go 2nd, so gaurd page after it.
       
   114 /** The position, within the chunk, that the EP0 OUT buffer appears*/
       
   115 const TInt KUsbScEP0OutBufPos = 0xc00;
       
   116 /** The position, within the chunk, that the EP0 OUT buffer ends*/
       
   117 const TInt KUsbScEP0OutBufEnd = KUsbScEP0OutBufPos + 0x400;
       
   118 
       
   119 /** The number of the entry within the chunk BufferRecord table, for the OUT ep0 buffer.*/
       
   120 const TInt KUsbcScEp0OutBuff = 0;
       
   121 /** The number of the entry within the chunk BufferRecord table, for the IN ep0 buffer.*/
       
   122 const TInt KUsbcScEp0InBuff = 1;
       
   123 
       
   124 
       
   125 //
       
   126 //########################### Logical Device Driver (LDD) #############################
       
   127 //
       
   128 
       
   129 /** USB LDD factory class.
       
   130 */
       
   131 class DUsbcScLogDevice : public DLogicalDevice
       
   132 	{
       
   133 public:
       
   134 	DUsbcScLogDevice();
       
   135 	virtual TInt Install();
       
   136 	virtual void GetCaps(TDes8& aDes) const;
       
   137 	virtual TInt Create(DLogicalChannelBase*& aChannel);
       
   138 	};
       
   139 
       
   140 
       
   141 class DLddUsbcScChannel;
       
   142 class TUsbcScBuffer;
       
   143 /** Endpoint tracking for the LDD buffering etc.
       
   144 */
       
   145 class TUsbcScEndpoint
       
   146 	{
       
   147 public:
       
   148 	TUsbcScEndpoint(DLddUsbcScChannel* aLDD, DUsbClientController* aController,
       
   149 				  const TUsbcScEndpointInfo* aEndpointInfo, TInt aEndpointNum
       
   150 				  );
       
   151 	~TUsbcScEndpoint();
       
   152 	TInt Construct();
       
   153 	void CancelTransfer(DThread* aThread);
       
   154 	void AbortTransfer();
       
   155 	inline TUsbcScEndpointInfo* EndpointInfo();
       
   156 	inline TInt RxBytesAvailable() const;
       
   157 	inline void ResetTransferInfo();
       
   158 	inline void SetClientReadPending(TBool aVal);
       
   159 	inline void SetClientWritePending(TBool aVal);
       
   160 	inline TBool ClientWritePending();
       
   161 	inline TBool ClientReadPending();
       
   162 	inline void SetRealEpNumber(TInt aRealEpNumber);
       
   163 	inline TInt RealEpNumber() const;
       
   164 	inline TInt EpNumber() const;
       
   165 	inline void StartBuffer();
       
   166 	inline void SetBuffer(TUsbcScBuffer* aBuffer);
       
   167 	inline TUsbcScBuffer* GetBuffer();
       
   168 
       
   169 
       
   170 private:
       
   171 	static void RequestCallback(TAny* aTUsbcScEndpoint);
       
   172 	void TxComplete();
       
   173 	TInt RxComplete(TBool aReEntrant);
       
   174 	void RxCompleteNow();
       
   175 
       
   176 
       
   177 
       
   178 public:
       
   179 	TUsbcRequestCallback* iRequestCallbackInfo;
       
   180 
       
   181 private:
       
   182 	DUsbClientController* iController;
       
   183 	TUsbcScEndpointInfo iEndpointInfo;
       
   184 	TBool iClientReadPending;
       
   185 	TBool iClientWritePending;
       
   186 	TInt iEndpointNumber;
       
   187 	TInt iRealEpNumber;
       
   188 	DLddUsbcScChannel* iLdd;
       
   189 	TInt iError;
       
   190 	TUint32 iBytesTransferred;
       
   191 	TInt iBandwidthPriority;
       
   192 	TUsbcScBuffer* iBuffer;
       
   193 
       
   194 	};
       
   195 
       
   196 
       
   197 /** Linked list of 'alternate setting' info for use by the LDD.
       
   198 */
       
   199 class TUsbcScAlternateSetting
       
   200 	{
       
   201 public:
       
   202 	TUsbcScAlternateSetting();
       
   203 	~TUsbcScAlternateSetting();
       
   204 
       
   205 public:
       
   206 	TUsbcScAlternateSetting* iNext;
       
   207 	TUsbcScAlternateSetting* iPrevious;
       
   208 	TInt iNumberOfEndpoints;
       
   209 	TUint iSetting;
       
   210 	TUsbcScEndpoint* iEndpoint[KMaxEndpointsPerClient + 1];
       
   211 	};
       
   212 
       
   213 class TUsbcScAlternateSettingList
       
   214 	{
       
   215 public:
       
   216 	TUsbcScAlternateSettingList();
       
   217 	~TUsbcScAlternateSettingList();
       
   218 
       
   219 public:
       
   220 	TUsbcScAlternateSetting* iHead;
       
   221 	TUsbcScAlternateSetting* iTail;
       
   222 	};
       
   223 
       
   224 class TUsbcScChunkInfo
       
   225 	{
       
   226 public:
       
   227 	TUsbcScChunkInfo(DLogicalDevice* aLdd);
       
   228 	TInt CreateChunk(TInt aTotalSize);
       
   229 	void Close();
       
   230 	TInt ChunkAlloc(TInt aOffset, TInt aSize);
       
   231 	void ChunkCleanup();
       
   232 	TInt GetPhysical(TInt aOffset, TPhysAddr* aPhysical);
       
   233 	static TInt New(TUsbcScChunkInfo*& aChunk, TInt aSize, DLogicalDevice* aLdd);
       
   234 private:
       
   235 	TUint* iPhysicalMap;
       
   236 public:
       
   237 	DChunk* iChunk;
       
   238 	TDfc iCleanup;
       
   239 
       
   240 	TInt8 iPageNtz; // Number of trailing zeros for a page. (Eg 4k page has 12 t.z.)
       
   241 	TInt iAllocatedSize;
       
   242 	TInt8* iChunkMem;
       
   243 	TUint32 iChunkMapAttr;
       
   244 	DLogicalDevice* iLdd;
       
   245 	};
       
   246 
       
   247 
       
   248 // Used to represent a matrix of endpoints with a column of sizes.
       
   249 // Used by TRealizeInfo
       
   250 
       
   251 class TEndpointSortBufs
       
   252 	{
       
   253 	public:
       
   254 		TUsbcScEndpoint** iEp;
       
   255 		TInt* iSizes;
       
   256 		TInt iEps;
       
   257 	};
       
   258 
       
   259 // This is used to calculate the layout of the shared chunk
       
   260 // based on a list of alternative settings / endpoints provided.
       
   261  
       
   262 class TRealizeInfo
       
   263 	{
       
   264 	public:
       
   265 		void Init(TUsbcScAlternateSettingList* aAlternateSettingList);
       
   266 		TInt CopyAndSortEndpoints();
       
   267 		void CalcBuffSizes();
       
   268 		void Free();
       
   269 
       
   270 		void LayoutChunkHeader(TUsbcScChunkInfo* aChunkInfo);
       
   271 	public:
       
   272 		TInt iMaxEndpoints;
       
   273 		TInt iTotalSize;
       
   274 		TInt iTotalBuffers;
       
   275 		TInt iAltSettings;
       
   276 		TEndpointSortBufs iBufs[KUsbcScDirections];
       
   277 		TUsbcScAlternateSettingList* iAlternateSettingList;
       
   278 
       
   279 		// Chunk layout info.
       
   280 		TUsbcScChunkBuffersHeader* iChunkStuct;
       
   281 		TUsbcScChunkAltSettingHeader* iAltSettingsTbl;
       
   282 	};
       
   283 
       
   284 
       
   285 
       
   286 /** The channel class - the actual USB LDD.
       
   287 */
       
   288 class DLddUsbcScChannel : public DLogicalChannel
       
   289 	{
       
   290 public:
       
   291 	DLddUsbcScChannel();
       
   292 	~DLddUsbcScChannel();
       
   293 	virtual void HandleMsg(TMessageBase* aMsg);
       
   294 	virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
       
   295 	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
       
   296 	inline DThread* Client() const {return iClient;}
       
   297 	inline TBool ChannelClosing() const {return iChannelClosing;}
       
   298 	inline TUint AlternateSetting() const {return iAlternateSetting;}
       
   299 	
       
   300 	static void RequestCallbackEp0(TAny* aTUsbcScChannel);
       
   301 
       
   302 private:
       
   303 
       
   304 	TInt DoCancel(TInt aReqNo, TUint aMask, TUint a1);
       
   305 	TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2);
       
   306 	TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
       
   307 	TInt DoReadDataNotify(TRequestStatus* aStatus, TInt aBufferNum, TInt aLength);
       
   308 	void StartDataRead(TInt aBufferNum);
       
   309 	TInt DoWriteData(TRequestStatus* aStatus,TInt aBufferNum, TUint aStart, TUint aLength, TUint aFlags);
       
   310 	TBool AlternateDeviceStateTestComplete();
       
   311 	TInt SetInterface(TInt aInterfaceNum, TUsbcScIfcInfo* aUserInterfaceInfoBuf);
       
   312 	void StartEpReads();
       
   313 	void DestroyAllInterfaces();
       
   314 	void DestroyInterface(TUint aInterface);
       
   315 	void DestroyEp0();
       
   316 	inline TBool ValidEndpoint(TInt aEndpoint);
       
   317 	TInt GetRealEpForEpResource(TInt aEndpoint, TInt& aRealEp);
       
   318 	inline TBool Configured();
       
   319 	TInt DoEmergencyComplete();
       
   320 	void ReadDes8(const TAny* aPtr, TDes8& aDes);
       
   321 	TInt SetupEp0();
       
   322 	void CancelNotifyEndpointStatus();
       
   323 	void CancelNotifyOtgFeatures();
       
   324 	static void StatusChangeCallback(TAny* aDLddUsbcChannel);
       
   325 	static void EndpointStatusChangeCallback(TAny* aDLddUsbcChannel);
       
   326 	static void OtgFeatureChangeCallback(TAny* aDLddUsbcChannel);
       
   327 	static void EmergencyCompleteDfc(TAny* aDLddUsbcChannel);
       
   328 	void DeConfigure(TInt aErrorCode);
       
   329 	TInt SelectAlternateSetting(TUint aAlternateSetting);
       
   330 	TInt EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint);
       
   331 	TInt ProcessAlternateSetting(TUint aAlternateSetting);
       
   332 	TInt32 StartNextInAlternateSetting();
       
   333 	TInt ProcessDeviceState(TUsbcDeviceState aDeviceState);
       
   334 	void ResetInterface(TInt aErrorCode);
       
   335 	void PanicClientThread(TInt aReason);
       
   336 
       
   337 	TInt RealizeInterface(void);
       
   338 
       
   339 private:
       
   340 	DUsbClientController* iController;
       
   341 	DThread* iClient;
       
   342 	TBool iValidInterface;
       
   343 	
       
   344 	TUsbcScAlternateSettingList* iAlternateSettingList;
       
   345 	TUsbcScEndpoint** iEndpoint;  // Pointer to the current endpoint set.
       
   346 
       
   347 	static const TInt KUsbcMaxRequests = RDevUsbcScClient::ERequestMaxRequests;
       
   348 	TRequestStatus* iRequestStatus[KUsbcMaxRequests];
       
   349 	TUsbcClientCallback iCompleteAllCallbackInfo;
       
   350 	TAny* iStatusChangePtr;
       
   351 	TUsbcStatusCallback iStatusCallbackInfo;
       
   352 	TAny* iEndpointStatusChangePtr;
       
   353 	TUsbcEndpointStatusCallback iEndpointStatusCallbackInfo;
       
   354 	TAny* iOtgFeatureChangePtr;
       
   355 	TUsbcOtgFeatureCallback iOtgFeatureCallbackInfo;
       
   356 	TUint8* iBufferBaseEp0;
       
   357 	TInt iBufferSizeEp0;
       
   358 	TInt iNumberOfEndpoints;
       
   359 	TUsbcDeviceState iDeviceState;
       
   360 	TUsbcDeviceState iOldDeviceState;
       
   361 	TBool iOwnsDeviceControl;
       
   362 	TUint16 iAlternateSetting;
       
   363 	TUint16 iAsSeq;
       
   364 
       
   365 	TUsbcDeviceStatusQueue* iStatusFifo;
       
   366 	TBool iUserKnowsAltSetting;
       
   367 	TBool iDeviceStatusNeeded;
       
   368 	TBool iChannelClosing;
       
   369 	TBool iRealizeCalled;
       
   370 
       
   371 	TUsbcScChunkInfo* iChunkInfo;
       
   372 	TInt iNumBuffers;
       
   373 	TUsbcScBuffer *iBuffers;
       
   374 
       
   375 	TUsbcScEndpoint* iEp0Endpoint;
       
   376 	TInt iEP0InBuff;
       
   377 	TInt iEP0OutBuff;
       
   378 
       
   379 	friend class TUsbcScBuffer;
       
   380 	friend void TUsbcScEndpoint::AbortTransfer();
       
   381 	};
       
   382 
       
   383 /**
       
   384 This class is used by TUsbcScStatusList to form a queue of status requests.
       
   385 These requests are on a buffer basis, so that all buffers can have at least two requests
       
   386 pending, at the same time. (i.e. buffer 1 could have two requests outstanding, as well as 2 on buffer 2.)
       
   387 */
       
   388 
       
   389 class TUsbcScStatusElement
       
   390 {
       
   391 public:
       
   392 	TRequestStatus* iStatus;
       
   393 	TInt iLength;
       
   394 	TUint iStart;
       
   395 	TUint iFlags;	
       
   396 };
       
   397 
       
   398 enum TUsbcScStatusState
       
   399 {
       
   400 	ENotRunning,
       
   401 	EInProgress,
       
   402 	EReadingAhead,
       
   403 	EFramgementInProgress
       
   404 };
       
   405 
       
   406 class TUsbcScStatusList
       
   407 {
       
   408 public:
       
   409 	TInt Construct(TInt aSize, DThread* aThread);
       
   410 	void Destroy();
       
   411 
       
   412 	TUsbcScStatusElement* Next();
       
   413 	void Pop();
       
   414 	TInt Add(TRequestStatus* aStatus, TInt aLength, TUint aStart, TUint aFlags);
       
   415 	void CancelQueued(TInt aErrorCode=KErrCancel);
       
   416 	TInt Complete(TInt aError);
       
   417 	void Complete();
       
   418 public:
       
   419 	TUsbcScStatusState iState;
       
   420 
       
   421 private:
       
   422 	DThread* iClient;
       
   423 	TInt iHead;   // The element at the head of the queue, ie, the earliest added, and next to be removed.
       
   424 	TInt iLength; // Length of queue, ie number of elements within
       
   425 	TInt iSize;   // size of array, ie, max # of requests at a time.
       
   426 	TUsbcScStatusElement* iElements;
       
   427 
       
   428 };
       
   429 
       
   430 
       
   431 
       
   432 /**
       
   433 This class holds the kernel's copy of all the details related to a shared endpoint buffer,
       
   434 and provides methods for the LDD to manipulate it.
       
   435 */
       
   436 class TUsbcScBuffer
       
   437 {
       
   438 public:
       
   439 	static const TInt8 KNoEpAssigned=0;
       
   440 	static const TInt8 KEpIsEnding=1;
       
   441 	static const TInt8 KEpIsStarting=2;
       
   442 
       
   443 public:
       
   444 	TInt Construct(TInt aDirection, DLddUsbcScChannel* aLdd, TInt aBufferOffset, TInt aBufferEndOffset, TInt aMinReadSize, TInt aMaxPacketSize, TInt aMaxReadSize);
       
   445 	void CreateChunkBufferHeader();
       
   446 	void StartEndpoint(TUsbcRequestCallback* iRequestInfo, TUint iFlags);
       
   447 
       
   448 	void Destroy();
       
   449 
       
   450 	TInt StartDataRead();
       
   451 	void CompleteRead(TBool aStartNextRead=ETrue);
       
   452 	void PopStall();
       
   453 	void StartDataWrite();
       
   454 	void CompleteWrite();
       
   455 	void Cancel(TInt aErrorCode);
       
   456 
       
   457 	void UpdateBufferList(TInt aByteCount,TUint aFlags, TBool aStartNextRead=ETrue);
       
   458 	void Ep0CancelLddRead();
       
   459 	void SendEp0StatusPacket(TInt aState);
       
   460 
       
   461 public:
       
   462 	
       
   463 	TInt8 iDirection;
       
   464 	TInt8 iMode;
       
   465 	TInt8 iNeedsPacket;
       
   466 	TInt8 iReserved;
       
   467 	DLddUsbcScChannel* iLdd;
       
   468 	TLinAddr iChunkAddr;
       
   469 	SUsbcScBufferHeader* iBufferStart;
       
   470 	TUint iBufferEnd; // One word on from the last word in the buffer.
       
   471 	TUint iAlignMask;
       
   472 	TUsbcScStatusList iStatusList;
       
   473 	TUsbcRequestCallback* iCallback;
       
   474 	union 
       
   475 	{
       
   476 		TInt iHead; // Out endpoints only;
       
   477 		TUint iSent; // In endpoints only
       
   478 	};
       
   479 	TUsbcScChunkInfo* iChunkInfo;
       
   480 	TInt iMinReadSize;
       
   481 	TInt iMaxReadSize;
       
   482 	TInt iMaxPacketSize;  // 0 indicates unconfiured.
       
   483 	TInt iFirstPacket;
       
   484 	TInt iStalled;
       
   485 
       
   486 	// needed for backwards compatibility
       
   487 	TUsbcPacketArray iIndexArray[KUsbcDmaBufNumMax]; // Has 2 elements
       
   488 	TUsbcPacketArray iSizeArray[KUsbcDmaBufNumMax];  // Has 2 elements
       
   489 #ifdef _DEBUG
       
   490 	TUint iSequence;
       
   491 #endif
       
   492 
       
   493 };
       
   494 
       
   495 
       
   496 
       
   497 #include <drivers/usbcsc.inl>
       
   498 
       
   499 #endif	// __USBCSC_H__