|
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/usbc.h |
|
15 // Kernel side definitions for the USB Device driver stack (PIL + LDD). |
|
16 // |
|
17 // |
|
18 |
|
19 /** |
|
20 @file usbc.h |
|
21 @internalTechnology |
|
22 */ |
|
23 |
|
24 #ifndef __USBC_H__ |
|
25 #define __USBC_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 <d32usbc.h> |
|
33 |
|
34 #include <drivers/usbcshared.h> |
|
35 |
|
36 |
|
37 |
|
38 /** LDD Major version, This should agree with the information in RDevUsbcClient::TVer. |
|
39 */ |
|
40 const TInt KUsbcMajorVersion = 0; |
|
41 |
|
42 /** LDD Minor version, This should agree with the information in RDevUsbcClient::TVer. |
|
43 */ |
|
44 const TInt KUsbcMinorVersion = 1; |
|
45 |
|
46 /** LDD Build version, This should agree with the information in RDevUsbcClient::TVer. |
|
47 */ |
|
48 const TInt KUsbcBuildVersion = KE32BuildVersionNumber; |
|
49 |
|
50 /** Must correspond to the max enum of TRequest + 1; |
|
51 currently this is ERequestOtgFeaturesNotify = 10. |
|
52 */ |
|
53 const TInt KUsbcMaxRequests = 11; |
|
54 |
|
55 // |
|
56 //########################### Logical Device Driver (LDD) ############################# |
|
57 // |
|
58 |
|
59 /** USB LDD factory class. |
|
60 */ |
|
61 class DUsbcLogDevice : public DLogicalDevice |
|
62 { |
|
63 public: |
|
64 DUsbcLogDevice(); |
|
65 virtual TInt Install(); |
|
66 virtual void GetCaps(TDes8& aDes) const; |
|
67 virtual TInt Create(DLogicalChannelBase*& aChannel); |
|
68 }; |
|
69 |
|
70 |
|
71 /** OUT buffering is a collection of flat buffers. Each is either fillable or drainable. |
|
72 When one buffer becomes full (notified by the PIL) it is marked as not-fillable and the next |
|
73 fillable buffer is used. When the buffer has finished draining it is marked as fillable. |
|
74 */ |
|
75 class TDmaBuf |
|
76 { |
|
77 public: |
|
78 TDmaBuf(); |
|
79 TDmaBuf(TUsbcEndpointInfo* aEndpointInfo, TInt aBandwidthPriority); |
|
80 ~TDmaBuf(); |
|
81 TInt Construct(TUsbcEndpointInfo* aEndpointInfo); |
|
82 TUint8* SetBufferBase(TUint8* aBase); |
|
83 TInt BufferTotalSize() const; |
|
84 TUint8* BufferBase() const; |
|
85 void SetMaxPacketSize(TInt aSize); |
|
86 void Flush(); |
|
87 // Rx (OUT) variants |
|
88 void RxSetActive(); |
|
89 void RxSetInActive(); |
|
90 TBool RxIsActive(); |
|
91 TBool IsReaderEmpty(); |
|
92 void ReadXferComplete(TInt aNoBytesRx, TInt aNoPacketsRx, TInt aErrorCode); |
|
93 TInt RxCopyDataToClient(DThread* aThread, TClientBuffer *aTcb, TInt aLength, TUint32& aDestOffset, |
|
94 TBool aRUS, TBool& aCompleteNow); |
|
95 TInt RxCopyPacketToClient(DThread* aThread,TClientBuffer *aTcb, TInt aLength); |
|
96 TInt RxGetNextXfer(TUint8*& aBufferAddr, TUsbcPacketArray*& aIndexArray, TUsbcPacketArray*& aSizeArray, |
|
97 TInt& aLength, TPhysAddr& aBufferPhys); |
|
98 TBool RxIsEnoughSpace(TInt aSize); |
|
99 inline TInt RxBytesAvailable() const; |
|
100 inline void IncrementBufferIndex(TInt& aIndex); |
|
101 inline TInt NoRxPackets() const; |
|
102 TInt SetDrainable(TInt aBufferNum); |
|
103 // Tx (IN) variants |
|
104 void TxSetActive(); |
|
105 void TxSetInActive(); |
|
106 TBool TxIsActive(); |
|
107 TInt TxStoreData(DThread* aThread,TClientBuffer *aTcb, TInt aTxLength, TUint32 aBufferOffset); |
|
108 TInt TxGetNextXfer(TUint8*& aBufferAddr, TInt& aTxLength, TPhysAddr& aBufferPhys); |
|
109 TBool ShortPacketExists(); |
|
110 |
|
111 #if defined(USBC_LDD_BUFFER_TRACE) |
|
112 TInt NoRxPacketsAlt() const; |
|
113 TInt NoRxBytesAlt() const; |
|
114 #endif |
|
115 |
|
116 private: |
|
117 TBool AdvancePacket(); |
|
118 inline TInt GetCurrentError(); |
|
119 TBool NextDrainableBuffer(); |
|
120 TBool NextFillableBuffer(); |
|
121 void FreeDrainedBuffers(); |
|
122 TInt PeekNextPacketSize(); |
|
123 TInt PeekNextDrainableBuffer(); |
|
124 void ModifyTotalRxBytesAvail(TInt aVal); |
|
125 void ModifyTotalRxPacketsAvail(TInt aVal); |
|
126 void AddToDrainQueue(TInt aBufferIndex); |
|
127 inline TInt CopyToUser(DThread* aThread, const TUint8* aSourceAddr, TInt aLength, |
|
128 TClientBuffer *aTcb, TUint32& aDestOffset); |
|
129 private: |
|
130 TInt iExtractOffset; // offset into current packet for data read |
|
131 TInt iMaxPacketSize; |
|
132 TInt iNumberofBuffers; |
|
133 TInt iBufSz; |
|
134 TBool iRxActive; |
|
135 TBool iTxActive; |
|
136 TInt iTotalRxBytesAvail; |
|
137 TInt iTotalRxPacketsAvail; |
|
138 // |
|
139 TUint8* iBufBasePtr; |
|
140 TUint8* iCurrentDrainingBuffer; |
|
141 TInt iCurrentDrainingBufferIndex; |
|
142 TInt iCurrentFillingBufferIndex; |
|
143 TUint iCurrentPacket; |
|
144 TUsbcPacketArray* iCurrentPacketIndexArray; |
|
145 TUsbcPacketArray* iCurrentPacketSizeArray; |
|
146 TUint8* iBuffers[KUsbcDmaBufNumMax]; |
|
147 TBool iDrainable[KUsbcDmaBufNumMax]; |
|
148 TUsbcPacketArray iPacketInfoStorage[KUsbcDmaBufNumMax * KUsbcDmaBufNumArrays * KUsbcDmaBufMaxPkts]; |
|
149 TUsbcPacketArray* iPacketIndex[KUsbcDmaBufNumMax]; |
|
150 TUsbcPacketArray* iPacketSize[KUsbcDmaBufNumMax]; |
|
151 TUint iNumberofBytesRx[KUsbcDmaBufNumMax]; |
|
152 TUint iNumberofPacketsRx[KUsbcDmaBufNumMax]; |
|
153 TInt iError[KUsbcDmaBufNumMax]; |
|
154 TPhysAddr iBufferPhys[KUsbcDmaBufNumMax]; |
|
155 TBool iCanBeFreed[KUsbcDmaBufNumMax]; |
|
156 TInt iDrainQueue[KUsbcDmaBufNumMax + 1]; |
|
157 TInt iDrainQueueIndex; |
|
158 TUint iEndpointType; |
|
159 |
|
160 #if defined(USBC_LDD_BUFFER_TRACE) |
|
161 TInt iFillingOrder; |
|
162 TInt iFillingOrderArray[KUsbcDmaBufNumMax]; |
|
163 TInt iDrainingOrder; |
|
164 TUint iNumberofBytesRxRemain[KUsbcDmaBufNumMax]; |
|
165 TUint iNumberofPacketsRxRemain[KUsbcDmaBufNumMax]; |
|
166 #endif |
|
167 }; |
|
168 |
|
169 |
|
170 class DLddUsbcChannel; |
|
171 |
|
172 /** Endpoint tracking for the LDD buffering etc. |
|
173 */ |
|
174 class TUsbcEndpoint |
|
175 { |
|
176 public: |
|
177 TUsbcEndpoint(); |
|
178 TUsbcEndpoint(DLddUsbcChannel* aLDD, DUsbClientController* aController, |
|
179 const TUsbcEndpointInfo* aEndpointInfo, TInt aEndpointNum, |
|
180 TInt aBandwidthPriority); |
|
181 ~TUsbcEndpoint(); |
|
182 TInt Construct(); |
|
183 TInt TryToStartRead(TBool aReEntrant); |
|
184 TInt TryToStartWrite(TEndpointTransferInfo* pTfr); |
|
185 TInt CopyToClient(DThread* aThread, TClientBuffer *aTcb); |
|
186 TInt CopyToClient(DThread* aClient, TBool& aCompleteNow, TClientBuffer *aTcb); |
|
187 TInt ContinueWrite(); |
|
188 void SetMaxPacketSize(TInt aSize); |
|
189 void CancelTransfer(DThread* aThread, TClientBuffer *aTcb); |
|
190 void AbortTransfer(); |
|
191 inline TUsbcEndpointInfo* EndpointInfo(); |
|
192 inline TInt RxBytesAvailable() const; |
|
193 inline TInt BufferTotalSize() const; |
|
194 inline TUint8* SetBufferBase(TUint8* aBase); |
|
195 inline void SetTransferInfo(TEndpointTransferInfo* aTransferInfo); |
|
196 inline void ResetTransferInfo(); |
|
197 inline void SetClientReadPending(TBool aVal); |
|
198 inline void SetClientWritePending(TBool aVal); |
|
199 inline TBool ClientWritePending(); |
|
200 inline TBool ClientReadPending(); |
|
201 inline void SetRealEpNumber(TInt aRealEpNumber); |
|
202 inline TInt RealEpNumber() const; |
|
203 |
|
204 public: |
|
205 TDmaBuf* iDmaBuffers; |
|
206 |
|
207 private: |
|
208 static void RequestCallback(TAny* aTUsbcEndpoint); |
|
209 void TxComplete(); |
|
210 TInt RxComplete(TBool aReEntrant); |
|
211 void RxCompleteNow(); |
|
212 TInt EndpointComplete(); |
|
213 |
|
214 private: |
|
215 DUsbClientController* iController; |
|
216 TUsbcEndpointInfo iEndpointInfo; |
|
217 TEndpointTransferInfo iTransferInfo; |
|
218 TBool iClientReadPending; |
|
219 TBool iClientWritePending; |
|
220 TInt iEndpointNumber; |
|
221 TInt iRealEpNumber; |
|
222 DLddUsbcChannel* iLdd; |
|
223 TInt iError; |
|
224 TUsbcRequestCallback* iRequestCallbackInfo; |
|
225 TUint32 iBytesTransferred; |
|
226 TInt iBandwidthPriority; |
|
227 }; |
|
228 |
|
229 |
|
230 /** Linked list of 'alternate setting' info for use by the LDD. |
|
231 */ |
|
232 class TUsbcAlternateSettingList |
|
233 { |
|
234 public: |
|
235 TUsbcAlternateSettingList(); |
|
236 ~TUsbcAlternateSettingList(); |
|
237 |
|
238 public: |
|
239 TUsbcAlternateSettingList* iNext; |
|
240 TInt iNumberOfEndpoints; |
|
241 TUint iSetting; |
|
242 TUsbcEndpoint* iEndpoint[KMaxEndpointsPerClient + 1]; |
|
243 }; |
|
244 |
|
245 |
|
246 struct TClientAsynchNotify |
|
247 { |
|
248 TClientBufferRequest *iBufferRequest; |
|
249 TClientBuffer *iClientBuffer; |
|
250 void Reset(); |
|
251 }; |
|
252 /** The channel class - the actual USB LDD. |
|
253 */ |
|
254 class DLddUsbcChannel : public DLogicalChannel |
|
255 { |
|
256 public: |
|
257 DLddUsbcChannel(); |
|
258 ~DLddUsbcChannel(); |
|
259 virtual TInt SendMsg(TMessageBase * aMsg); |
|
260 TInt PreSendRequest(TMessageBase * aMsg,TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); |
|
261 TInt SendControl(TMessageBase* aMsg); |
|
262 virtual void HandleMsg(TMessageBase* aMsg); |
|
263 virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); |
|
264 virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); |
|
265 TInt DoRxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TBool aReentrant); |
|
266 void DoRxCompleteNow(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint); |
|
267 void DoTxComplete(TUsbcEndpoint* aTUsbcEndpoint, TInt aEndpoint, TInt aError); |
|
268 inline DThread* Client() const {return iClient;} |
|
269 inline TBool ChannelClosing() const {return iChannelClosing;} |
|
270 inline TUint AlternateSetting() const {return iAlternateSetting;} |
|
271 TClientBuffer *GetClientBuffer(TInt aEndpoint); |
|
272 |
|
273 private: |
|
274 TInt DoCancel(TInt aReqNo); |
|
275 void DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); |
|
276 TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); |
|
277 TInt DoTransferAsyncReq(TInt aEndpointNum, TAny* a1, TAny* a2, TBool& aNeedsCompletion); |
|
278 TInt DoOtherAsyncReq(TInt aReqNo, TAny* a1, TAny* a2, TBool& aNeedsCompletion); |
|
279 TBool AlternateDeviceStateTestComplete(); |
|
280 TInt SetInterface(TInt aInterfaceNum, TUsbcIfcInfo* aUserInterfaceInfoBuf); |
|
281 void StartEpReads(); |
|
282 void DestroyAllInterfaces(); |
|
283 void DestroyInterface(TUint aInterface); |
|
284 void DestroyEp0(); |
|
285 inline TBool ValidEndpoint(TInt aEndpoint); |
|
286 TInt DoEmergencyComplete(); |
|
287 void ReadDes8(const TAny* aPtr, TDes8& aDes); |
|
288 TInt SetupEp0(); |
|
289 DPlatChunkHw* ReAllocate(TInt aBuffersize, DPlatChunkHw* aHwChunk, TUint32 aCacheAttribs); |
|
290 DPlatChunkHw* Allocate(TInt aBuffersize, TUint32 aCacheAttribs); |
|
291 void ClosePhysicalChunk(DPlatChunkHw* &aHwChunk); |
|
292 void CancelNotifyEndpointStatus(); |
|
293 void CancelNotifyOtgFeatures(); |
|
294 static void StatusChangeCallback(TAny* aDLddUsbcChannel); |
|
295 static void EndpointStatusChangeCallback(TAny* aDLddUsbcChannel); |
|
296 static void OtgFeatureChangeCallback(TAny* aDLddUsbcChannel); |
|
297 static void EmergencyCompleteDfc(TAny* aDLddUsbcChannel); |
|
298 void DeConfigure(TInt aErrorCode); |
|
299 TInt SelectAlternateSetting(TUint aAlternateSetting); |
|
300 TInt EpFromAlternateSetting(TUint aAlternateSetting, TInt aEndpoint); |
|
301 TInt ProcessAlternateSetting(TUint aAlternateSetting); |
|
302 TInt ProcessDeviceState(TUsbcDeviceState aDeviceState); |
|
303 void ResetInterface(TInt aErrorCode); |
|
304 void AbortInterface(); |
|
305 void RebaseInterfaceMemory(TUsbcAlternateSettingList* aAlternateSettingListRec, TUint8* aBase, |
|
306 TUint aDirection); |
|
307 void UpdateEndpointSizes(); |
|
308 DPlatChunkHw* SetupInterfaceMemory(TInt aBufferSize, DPlatChunkHw* aHwChunk, TUint aDirection, |
|
309 TUint32 aCacheAttribs); |
|
310 void PanicClientThread(TInt aReason); |
|
311 |
|
312 TInt PinMemory(TDesC8 *aDes, TVirtualPinObject *iPinObj); //Descriptor pinning helper. |
|
313 void CompleteBufferRequest(DThread* aThread, TInt aReqNo, TInt aReason); |
|
314 private: |
|
315 DUsbClientController* iController; |
|
316 DThread* iClient; |
|
317 TBool iValidInterface; |
|
318 TUsbcAlternateSettingList* iAlternateSettingList; |
|
319 TUsbcEndpoint* iEndpoint[KMaxEndpointsPerClient + 1]; // include ep0 |
|
320 TRequestStatus* iRequestStatus[KUsbcMaxRequests]; |
|
321 TClientAsynchNotify* iClientAsynchNotify[KUsbcMaxRequests]; |
|
322 TUsbcClientCallback iCompleteAllCallbackInfo; |
|
323 TAny* iStatusChangePtr; |
|
324 TUsbcStatusCallback iStatusCallbackInfo; |
|
325 TAny* iEndpointStatusChangePtr; |
|
326 TUsbcEndpointStatusCallback iEndpointStatusCallbackInfo; |
|
327 TAny* iOtgFeatureChangePtr; |
|
328 TUsbcOtgFeatureCallback iOtgFeatureCallbackInfo; |
|
329 TUint8* iBufferBaseEp0; |
|
330 TInt iBufferSizeEp0; |
|
331 TInt iNumberOfEndpoints; |
|
332 DPlatChunkHw* iHwChunkIN; |
|
333 DPlatChunkHw* iHwChunkOUT; |
|
334 DPlatChunkHw* iHwChunkEp0; |
|
335 TUsbcDeviceState iDeviceState; |
|
336 TUsbcDeviceState iOldDeviceState; |
|
337 TBool iOwnsDeviceControl; |
|
338 TUint iAlternateSetting; |
|
339 TBool iDeviceStatusNeeded; |
|
340 TUsbcDeviceStatusQueue* iStatusFifo; |
|
341 TBool iChannelClosing; |
|
342 TVirtualPinObject *iPinObj1; |
|
343 TVirtualPinObject *iPinObj2; |
|
344 TVirtualPinObject *iPinObj3; |
|
345 TClientDataRequest<TUint> *iStatusChangeReq; |
|
346 TClientDataRequest<TUint> *iEndpointStatusChangeReq; |
|
347 TClientDataRequest<TUint> *iOtgFeatureChangeReq; |
|
348 TEndpointTransferInfo iTfrInfo; |
|
349 }; |
|
350 |
|
351 |
|
352 #include <drivers/usbc.inl> |
|
353 |
|
354 #endif // __USBC_H__ |