1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/usbcsc.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,499 @@
1.4 +// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\include\drivers\usbcsc.h
1.18 +// Kernel side definitions for the USB Device driver stack (PIL + LDD).
1.19 +//
1.20 +//
1.21 +
1.22 +/**
1.23 + @file usbcsc.h
1.24 + @internalTechnology
1.25 +*/
1.26 +
1.27 +#ifndef __USBCSC_H__
1.28 +#define __USBCSC_H__
1.29 +
1.30 +#include <kernel/kernel.h>
1.31 +#include <kernel/kern_priv.h>
1.32 +#include <kernel/kpower.h>
1.33 +#include <platform.h>
1.34 +
1.35 +#include <d32usbcsc.h>
1.36 +
1.37 +#include <drivers/usbcshared.h>
1.38 +
1.39 +/** LDD Major version, This should agree with the information in RDevUsbcClient::TVer.
1.40 +*/
1.41 +const TInt KUsbcScMajorVersion = 0;
1.42 +
1.43 +/** LDD Minor version, This should agree with the information in RDevUsbcClient::TVer.
1.44 +*/
1.45 +const TInt KUsbcScMinorVersion = 1;
1.46 +
1.47 +/** LDD Build version, This should agree with the information in RDevUsbcClient::TVer.
1.48 +*/
1.49 +const TInt KUsbcScBuildVersion = KE32BuildVersionNumber;
1.50 +
1.51 +/** Must correspond to the max enum of TRequest + 1;
1.52 + currently this is ERequestOtgFeaturesNotify = 10.
1.53 +*/
1.54 +const TInt KUsbcScMaxRequests = 11;
1.55 +
1.56 +// Request queue sizes need to be power of 2.
1.57 +
1.58 +/** The number of requests that can be queued on any IN endpoint */
1.59 +const TInt KUsbcScInRequests = 4;
1.60 +/** The number of requests that can be queued on any OUT endpoint */
1.61 +const TInt KUsbcScOutRequests = 2;
1.62 +
1.63 +/** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an IN endpoint */
1.64 +const TInt KUsbcScIn = 0;
1.65 +/** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an OUT endpoint */
1.66 +const TInt KUsbcScOut = 1;
1.67 +
1.68 +
1.69 +/** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an Bidirectional endpoint
1.70 +currently operating as an IN endpoint */
1.71 +const TInt KUsbcScBiIn = 2;
1.72 +/** In TUsbcScBuffer.iDirection, this indicates that the endpoint is an Bidirectional endpoint
1.73 +currently operating as an OUT endpoint */
1.74 +const TInt KUsbcScBiOut = 3;
1.75 +
1.76 +/** The number of directions supported for endpoints, other then EP0. Currently 2, IN and OUT. */
1.77 +const TInt KUsbcScDirections = 2;
1.78 +
1.79 +/** In TUsbcScBuffer::iDirection, this indicates that the endpoint direction is Unknown. */
1.80 +const TInt KUsbcScUnknown = 4;
1.81 +
1.82 +const TInt KPageSize = 0x1000;
1.83 +
1.84 +/** The default buffer size requested for a endpoint, if the user app does not specify a size.*/
1.85 +const TInt KUsbcScDefaultBufferSize = 0x10000; // 64k
1.86 +
1.87 +/** The size of the unmapped region of memory between endpoint buffers.
1.88 +This serves as a guard region, making memory over/under runs more obviose.*/
1.89 +const TInt KGuardSize = KPageSize;
1.90 +
1.91 +/** The size put aside for the chunk header structre.*/
1.92 +const TInt KHeaderSize = KPageSize;
1.93 +
1.94 +/** For buffers of size >= KUsbScBigBuffIs, The smallest unit of continiouse memory that will be used.
1.95 +No read will be set up smaller then this, to avoid overly fragmenting the data.
1.96 +*/
1.97 +const TInt KUsbSc_BigBuff_MinimumRamRun = KPageSize;
1.98 +
1.99 +/** For buffers of size < KUsbScBigBuffIs, The smallest unit of continiouse memory that will be used.
1.100 +No read will be set up smaller then this, to avoid overly fragmenting the data.*/
1.101 +const TInt KUsbSc_SmallBuff_MinimumRamRun = 1024;
1.102 +
1.103 +/** The size a buffer request has to be to switch to using KUsbSc_BigBuff_MinimumRamRun.
1.104 +If the requested buffer is smaller, then the smallest memory allocated to a buffer is KPageSize*/
1.105 +const TInt KUsbScBigBuffIs = KPageSize*6;
1.106 +
1.107 +
1.108 +
1.109 +// EP0 is mapped manually, unlike the other endpoints.
1.110 +
1.111 +/** The position, within the chunk, that the EP0 IN buffer appears*/
1.112 +const TInt KUsbScEP0InBufPos = 0x800;
1.113 +/** The position, within the chunk, that the EP0 IN buffer ends*/
1.114 +const TInt KUsbScEP0InBufEnd = KUsbScEP0InBufPos + 0x400;
1.115 +
1.116 +// Its better for Out to go 2nd, so gaurd page after it.
1.117 +/** The position, within the chunk, that the EP0 OUT buffer appears*/
1.118 +const TInt KUsbScEP0OutBufPos = 0xc00;
1.119 +/** The position, within the chunk, that the EP0 OUT buffer ends*/
1.120 +const TInt KUsbScEP0OutBufEnd = KUsbScEP0OutBufPos + 0x400;
1.121 +
1.122 +/** The number of the entry within the chunk BufferRecord table, for the OUT ep0 buffer.*/
1.123 +const TInt KUsbcScEp0OutBuff = 0;
1.124 +/** The number of the entry within the chunk BufferRecord table, for the IN ep0 buffer.*/
1.125 +const TInt KUsbcScEp0InBuff = 1;
1.126 +
1.127 +
1.128 +//
1.129 +//########################### Logical Device Driver (LDD) #############################
1.130 +//
1.131 +
1.132 +/** USB LDD factory class.
1.133 +*/
1.134 +class DUsbcScLogDevice : public DLogicalDevice
1.135 + {
1.136 +public:
1.137 + DUsbcScLogDevice();
1.138 + virtual TInt Install();
1.139 + virtual void GetCaps(TDes8& aDes) const;
1.140 + virtual TInt Create(DLogicalChannelBase*& aChannel);
1.141 + };
1.142 +
1.143 +
1.144 +class DLddUsbcScChannel;
1.145 +class TUsbcScBuffer;
1.146 +/** Endpoint tracking for the LDD buffering etc.
1.147 +*/
1.148 +class TUsbcScEndpoint
1.149 + {
1.150 +public:
1.151 + TUsbcScEndpoint(DLddUsbcScChannel* aLDD, DUsbClientController* aController,
1.152 + const TUsbcScEndpointInfo* aEndpointInfo, TInt aEndpointNum
1.153 + );
1.154 + ~TUsbcScEndpoint();
1.155 + TInt Construct();
1.156 + void CancelTransfer(DThread* aThread);
1.157 + void AbortTransfer();
1.158 + inline TUsbcScEndpointInfo* EndpointInfo();
1.159 + inline TInt RxBytesAvailable() const;
1.160 + inline void ResetTransferInfo();
1.161 + inline void SetClientReadPending(TBool aVal);
1.162 + inline void SetClientWritePending(TBool aVal);
1.163 + inline TBool ClientWritePending();
1.164 + inline TBool ClientReadPending();
1.165 + inline void SetRealEpNumber(TInt aRealEpNumber);
1.166 + inline TInt RealEpNumber() const;
1.167 + inline TInt EpNumber() const;
1.168 + inline void StartBuffer();
1.169 + inline void SetBuffer(TUsbcScBuffer* aBuffer);
1.170 + inline TUsbcScBuffer* GetBuffer();
1.171 +
1.172 +
1.173 +private:
1.174 + static void RequestCallback(TAny* aTUsbcScEndpoint);
1.175 + void TxComplete();
1.176 + TInt RxComplete(TBool aReEntrant);
1.177 + void RxCompleteNow();
1.178 +
1.179 +
1.180 +
1.181 +public:
1.182 + TUsbcRequestCallback* iRequestCallbackInfo;
1.183 +
1.184 +private:
1.185 + DUsbClientController* iController;
1.186 + TUsbcScEndpointInfo iEndpointInfo;
1.187 + TBool iClientReadPending;
1.188 + TBool iClientWritePending;
1.189 + TInt iEndpointNumber;
1.190 + TInt iRealEpNumber;
1.191 + DLddUsbcScChannel* iLdd;
1.192 + TInt iError;
1.193 + TUint32 iBytesTransferred;
1.194 + TInt iBandwidthPriority;
1.195 + TUsbcScBuffer* iBuffer;
1.196 +
1.197 + };
1.198 +
1.199 +
1.200 +/** Linked list of 'alternate setting' info for use by the LDD.
1.201 +*/
1.202 +class TUsbcScAlternateSetting
1.203 + {
1.204 +public:
1.205 + TUsbcScAlternateSetting();
1.206 + ~TUsbcScAlternateSetting();
1.207 +
1.208 +public:
1.209 + TUsbcScAlternateSetting* iNext;
1.210 + TUsbcScAlternateSetting* iPrevious;
1.211 + TInt iNumberOfEndpoints;
1.212 + TUint iSetting;
1.213 + TUsbcScEndpoint* iEndpoint[KMaxEndpointsPerClient + 1];
1.214 + };
1.215 +
1.216 +class TUsbcScAlternateSettingList
1.217 + {
1.218 +public:
1.219 + TUsbcScAlternateSettingList();
1.220 + ~TUsbcScAlternateSettingList();
1.221 +
1.222 +public:
1.223 + TUsbcScAlternateSetting* iHead;
1.224 + TUsbcScAlternateSetting* iTail;
1.225 + };
1.226 +
1.227 +class TUsbcScChunkInfo
1.228 + {
1.229 +public:
1.230 + TUsbcScChunkInfo(DLogicalDevice* aLdd);
1.231 + TInt CreateChunk(TInt aTotalSize);
1.232 + void Close();
1.233 + TInt ChunkAlloc(TInt aOffset, TInt aSize);
1.234 + void ChunkCleanup();
1.235 + TInt GetPhysical(TInt aOffset, TPhysAddr* aPhysical);
1.236 + static TInt New(TUsbcScChunkInfo*& aChunk, TInt aSize, DLogicalDevice* aLdd);
1.237 +private:
1.238 + TUint* iPhysicalMap;
1.239 +public:
1.240 + DChunk* iChunk;
1.241 + TDfc iCleanup;
1.242 +
1.243 + TInt8 iPageNtz; // Number of trailing zeros for a page. (Eg 4k page has 12 t.z.)
1.244 + TInt iAllocatedSize;
1.245 + TInt8* iChunkMem;
1.246 + TUint32 iChunkMapAttr;
1.247 + DLogicalDevice* iLdd;
1.248 + };
1.249 +
1.250 +
1.251 +// Used to represent a matrix of endpoints with a column of sizes.
1.252 +// Used by TRealizeInfo
1.253 +
1.254 +class TEndpointSortBufs
1.255 + {
1.256 + public:
1.257 + TUsbcScEndpoint** iEp;
1.258 + TInt* iSizes;
1.259 + TInt iEps;
1.260 + };
1.261 +
1.262 +// This is used to calculate the layout of the shared chunk
1.263 +// based on a list of alternative settings / endpoints provided.
1.264 +
1.265 +class TRealizeInfo
1.266 + {
1.267 + public:
1.268 + void Init(TUsbcScAlternateSettingList* aAlternateSettingList);
1.269 + TInt CopyAndSortEndpoints();
1.270 + void CalcBuffSizes();
1.271 + void Free();
1.272 +
1.273 + void LayoutChunkHeader(TUsbcScChunkInfo* aChunkInfo);
1.274 + public:
1.275 + TInt iMaxEndpoints;
1.276 + TInt iTotalSize;
1.277 + TInt iTotalBuffers;
1.278 + TInt iAltSettings;
1.279 + TEndpointSortBufs iBufs[KUsbcScDirections];
1.280 + TUsbcScAlternateSettingList* iAlternateSettingList;
1.281 +
1.282 + // Chunk layout info.
1.283 + TUsbcScChunkBuffersHeader* iChunkStuct;
1.284 + TUsbcScChunkAltSettingHeader* iAltSettingsTbl;
1.285 + };
1.286 +
1.287 +
1.288 +
1.289 +/** The channel class - the actual USB LDD.
1.290 +*/
1.291 +class DLddUsbcScChannel : public DLogicalChannel
1.292 + {
1.293 +public:
1.294 + DLddUsbcScChannel();
1.295 + ~DLddUsbcScChannel();
1.296 + virtual void HandleMsg(TMessageBase* aMsg);
1.297 + virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
1.298 + virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
1.299 + inline DThread* Client() const {return iClient;}
1.300 + inline TBool ChannelClosing() const {return iChannelClosing;}
1.301 + inline TUint AlternateSetting() const {return iAlternateSetting;}
1.302 +
1.303 + static void RequestCallbackEp0(TAny* aTUsbcScChannel);
1.304 +
1.305 +private:
1.306 +
1.307 + TInt DoCancel(TInt aReqNo, TUint aMask, TUint a1);
1.308 + TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2);
1.309 + TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
1.310 + TInt DoReadDataNotify(TRequestStatus* aStatus, TInt aBufferNum, TInt aLength);
1.311 + void StartDataRead(TInt aBufferNum);
1.312 + TInt DoWriteData(TRequestStatus* aStatus,TInt aBufferNum, TUint aStart, TUint aLength, TUint aFlags);
1.313 + TBool AlternateDeviceStateTestComplete();
1.314 + TInt SetInterface(TInt aInterfaceNum, TUsbcScIfcInfo* aUserInterfaceInfoBuf);
1.315 + void StartEpReads();
1.316 + void DestroyAllInterfaces();
1.317 + void DestroyInterface(TUint aInterface);
1.318 + void DestroyEp0();
1.319 + inline TBool ValidEndpoint(TInt aEndpoint);
1.320 + TInt GetRealEpForEpResource(TInt aEndpoint, TInt& aRealEp);
1.321 + inline TBool Configured();
1.322 + TInt DoEmergencyComplete();
1.323 + void ReadDes8(const TAny* aPtr, TDes8& aDes);
1.324 + TInt SetupEp0();
1.325 + void CancelNotifyEndpointStatus();
1.326 + void CancelNotifyOtgFeatures();
1.327 + static void StatusChangeCallback(TAny* aDLddUsbcChannel);
1.328 + static void EndpointStatusChangeCallback(TAny* aDLddUsbcChannel);
1.329 + static void OtgFeatureChangeCallback(TAny* aDLddUsbcChannel);
1.330 + static void EmergencyCompleteDfc(TAny* aDLddUsbcChannel);
1.331 + void DeConfigure(TInt aErrorCode);
1.332 + TInt SelectAlternateSetting(TUint aAlternateSetting);
1.333 + TInt EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint);
1.334 + TInt ProcessAlternateSetting(TUint aAlternateSetting);
1.335 + TInt32 StartNextInAlternateSetting();
1.336 + TInt ProcessDeviceState(TUsbcDeviceState aDeviceState);
1.337 + void ResetInterface(TInt aErrorCode);
1.338 + void PanicClientThread(TInt aReason);
1.339 +
1.340 + TInt RealizeInterface(void);
1.341 +
1.342 +private:
1.343 + DUsbClientController* iController;
1.344 + DThread* iClient;
1.345 + TBool iValidInterface;
1.346 +
1.347 + TUsbcScAlternateSettingList* iAlternateSettingList;
1.348 + TUsbcScEndpoint** iEndpoint; // Pointer to the current endpoint set.
1.349 +
1.350 + static const TInt KUsbcMaxRequests = RDevUsbcScClient::ERequestMaxRequests;
1.351 + TRequestStatus* iRequestStatus[KUsbcMaxRequests];
1.352 + TUsbcClientCallback iCompleteAllCallbackInfo;
1.353 + TAny* iStatusChangePtr;
1.354 + TUsbcStatusCallback iStatusCallbackInfo;
1.355 + TAny* iEndpointStatusChangePtr;
1.356 + TUsbcEndpointStatusCallback iEndpointStatusCallbackInfo;
1.357 + TAny* iOtgFeatureChangePtr;
1.358 + TUsbcOtgFeatureCallback iOtgFeatureCallbackInfo;
1.359 + TUint8* iBufferBaseEp0;
1.360 + TInt iBufferSizeEp0;
1.361 + TInt iNumberOfEndpoints;
1.362 + TUsbcDeviceState iDeviceState;
1.363 + TUsbcDeviceState iOldDeviceState;
1.364 + TBool iOwnsDeviceControl;
1.365 + TUint16 iAlternateSetting;
1.366 + TUint16 iAsSeq;
1.367 +
1.368 + TUsbcDeviceStatusQueue* iStatusFifo;
1.369 + TBool iUserKnowsAltSetting;
1.370 + TBool iDeviceStatusNeeded;
1.371 + TBool iChannelClosing;
1.372 + TBool iRealizeCalled;
1.373 +
1.374 + TUsbcScChunkInfo* iChunkInfo;
1.375 + TInt iNumBuffers;
1.376 + TUsbcScBuffer *iBuffers;
1.377 +
1.378 + TUsbcScEndpoint* iEp0Endpoint;
1.379 + TInt iEP0InBuff;
1.380 + TInt iEP0OutBuff;
1.381 +
1.382 + friend class TUsbcScBuffer;
1.383 + friend void TUsbcScEndpoint::AbortTransfer();
1.384 + };
1.385 +
1.386 +/**
1.387 +This class is used by TUsbcScStatusList to form a queue of status requests.
1.388 +These requests are on a buffer basis, so that all buffers can have at least two requests
1.389 +pending, at the same time. (i.e. buffer 1 could have two requests outstanding, as well as 2 on buffer 2.)
1.390 +*/
1.391 +
1.392 +class TUsbcScStatusElement
1.393 +{
1.394 +public:
1.395 + TRequestStatus* iStatus;
1.396 + TInt iLength;
1.397 + TUint iStart;
1.398 + TUint iFlags;
1.399 +};
1.400 +
1.401 +enum TUsbcScStatusState
1.402 +{
1.403 + ENotRunning,
1.404 + EInProgress,
1.405 + EReadingAhead,
1.406 + EFramgementInProgress
1.407 +};
1.408 +
1.409 +class TUsbcScStatusList
1.410 +{
1.411 +public:
1.412 + TInt Construct(TInt aSize, DThread* aThread);
1.413 + void Destroy();
1.414 +
1.415 + TUsbcScStatusElement* Next();
1.416 + void Pop();
1.417 + TInt Add(TRequestStatus* aStatus, TInt aLength, TUint aStart, TUint aFlags);
1.418 + void CancelQueued(TInt aErrorCode=KErrCancel);
1.419 + TInt Complete(TInt aError);
1.420 + void Complete();
1.421 +public:
1.422 + TUsbcScStatusState iState;
1.423 +
1.424 +private:
1.425 + DThread* iClient;
1.426 + TInt iHead; // The element at the head of the queue, ie, the earliest added, and next to be removed.
1.427 + TInt iLength; // Length of queue, ie number of elements within
1.428 + TInt iSize; // size of array, ie, max # of requests at a time.
1.429 + TUsbcScStatusElement* iElements;
1.430 +
1.431 +};
1.432 +
1.433 +
1.434 +
1.435 +/**
1.436 +This class holds the kernel's copy of all the details related to a shared endpoint buffer,
1.437 +and provides methods for the LDD to manipulate it.
1.438 +*/
1.439 +class TUsbcScBuffer
1.440 +{
1.441 +public:
1.442 + static const TInt8 KNoEpAssigned=0;
1.443 + static const TInt8 KEpIsEnding=1;
1.444 + static const TInt8 KEpIsStarting=2;
1.445 +
1.446 +public:
1.447 + TInt Construct(TInt aDirection, DLddUsbcScChannel* aLdd, TInt aBufferOffset, TInt aBufferEndOffset, TInt aMinReadSize, TInt aMaxPacketSize, TInt aMaxReadSize);
1.448 + void CreateChunkBufferHeader();
1.449 + void StartEndpoint(TUsbcRequestCallback* iRequestInfo, TUint iFlags);
1.450 +
1.451 + void Destroy();
1.452 +
1.453 + TInt StartDataRead();
1.454 + void CompleteRead(TBool aStartNextRead=ETrue);
1.455 + void PopStall();
1.456 + void StartDataWrite();
1.457 + void CompleteWrite();
1.458 + void Cancel(TInt aErrorCode);
1.459 +
1.460 + void UpdateBufferList(TInt aByteCount,TUint aFlags, TBool aStartNextRead=ETrue);
1.461 + void Ep0CancelLddRead();
1.462 + void SendEp0StatusPacket(TInt aState);
1.463 +
1.464 +public:
1.465 +
1.466 + TInt8 iDirection;
1.467 + TInt8 iMode;
1.468 + TInt8 iNeedsPacket;
1.469 + TInt8 iReserved;
1.470 + DLddUsbcScChannel* iLdd;
1.471 + TLinAddr iChunkAddr;
1.472 + SUsbcScBufferHeader* iBufferStart;
1.473 + TUint iBufferEnd; // One word on from the last word in the buffer.
1.474 + TUint iAlignMask;
1.475 + TUsbcScStatusList iStatusList;
1.476 + TUsbcRequestCallback* iCallback;
1.477 + union
1.478 + {
1.479 + TInt iHead; // Out endpoints only;
1.480 + TUint iSent; // In endpoints only
1.481 + };
1.482 + TUsbcScChunkInfo* iChunkInfo;
1.483 + TInt iMinReadSize;
1.484 + TInt iMaxReadSize;
1.485 + TInt iMaxPacketSize; // 0 indicates unconfiured.
1.486 + TInt iFirstPacket;
1.487 + TInt iStalled;
1.488 +
1.489 + // needed for backwards compatibility
1.490 + TUsbcPacketArray iIndexArray[KUsbcDmaBufNumMax]; // Has 2 elements
1.491 + TUsbcPacketArray iSizeArray[KUsbcDmaBufNumMax]; // Has 2 elements
1.492 +#ifdef _DEBUG
1.493 + TUint iSequence;
1.494 +#endif
1.495 +
1.496 +};
1.497 +
1.498 +
1.499 +
1.500 +#include <drivers/usbcsc.inl>
1.501 +
1.502 +#endif // __USBCSC_H__