|
1 // Copyright (c) 2002-2010 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 "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 // e32test\dmav2\d_dma2.h |
|
15 // User-side API for LDD used to test DMAv2 framework. |
|
16 // |
|
17 // |
|
18 |
|
19 #ifndef __D_DMA2_H__ |
|
20 #define __D_DMA2_H__ |
|
21 |
|
22 #include <e32cmn.h> |
|
23 #include <drivers/dmadefs.h> |
|
24 |
|
25 |
|
26 #define ARRAY_LENGTH(ARRAY) sizeof(ARRAY)/sizeof(ARRAY[0]) |
|
27 |
|
28 #ifdef __KERNEL_MODE__ |
|
29 #include <nkern.h> |
|
30 #include <kernel.h> |
|
31 #define TEST_FAULT FAULT(); |
|
32 #define PRINT(N) Kern::Printf("%s = 0x%08x (%d)", #N, (N), (N)) |
|
33 #define PRINTF(X) Kern::Printf X ; |
|
34 #else |
|
35 #include <e32std.h> |
|
36 #include <e32debug.h> |
|
37 #define TEST_FAULT {RDebug::Printf("Assertion failure in %s, %d", __FILE__, __LINE__); User::Invariant();} |
|
38 #define PRINT(N) RDebug::Printf("%s = 0x%08x (%d)", #N, (N), (N)) |
|
39 #define PRINTF(X) RDebug::Printf X ; |
|
40 #endif |
|
41 |
|
42 #define TEST_ASSERT(C) if(!(C)) {TEST_FAULT;} |
|
43 |
|
44 const TUint KPhysAddrInvalidUser=0xFFFFFFFFu; // KPhysAddrInvalid is not defined on the user side |
|
45 #ifdef __KERNEL_MODE__ |
|
46 //if this fails then KPhysAddrInvalidUser must be updated to match |
|
47 //KPhysAddrInvalid |
|
48 __ASSERT_COMPILE(KPhysAddrInvalidUser == KPhysAddrInvalid); |
|
49 #else |
|
50 const TUint KPhysAddrInvalid = KPhysAddrInvalidUser; |
|
51 #endif |
|
52 |
|
53 #ifdef __KERNEL_MODE__ |
|
54 //Function to format the output. |
|
55 inline void DmaAppendFormat(TDes8& aBuf, const char* aFmt, ...) |
|
56 { |
|
57 if(!(&aBuf)) |
|
58 return; |
|
59 VA_LIST list; |
|
60 VA_START(list,aFmt); |
|
61 Kern::AppendFormat(aBuf,aFmt,list); |
|
62 } |
|
63 #endif |
|
64 |
|
65 _LIT(KTestDmaLddNameSim, "TestDmaV2Sim"); |
|
66 _LIT(KTestDmaLddNameHw, "TestDmaV2"); |
|
67 #ifdef __DMASIM__ |
|
68 const TPtrC KTestDmaLddName = KTestDmaLddNameSim(); |
|
69 #else |
|
70 const TPtrC KTestDmaLddName = KTestDmaLddNameHw(); |
|
71 #endif |
|
72 |
|
73 inline TVersion TestDmaLddVersion() { return TVersion(1, 0, 1); } |
|
74 |
|
75 TInt Log2(TInt aNum); |
|
76 |
|
77 /** |
|
78 Indicates the number of each type of call back received |
|
79 and their context |
|
80 |
|
81 @note It does not indicate the context of each callback, only |
|
82 the final one |
|
83 */ |
|
84 const TInt KNumberOfCallbacks = 12; |
|
85 |
|
86 class TCallbackRecord |
|
87 { |
|
88 public: |
|
89 enum TCbContext |
|
90 { EInvalid, EThread, EIsr }; |
|
91 |
|
92 TCallbackRecord( |
|
93 TCbContext aContext = EThread, |
|
94 TInt aReq = 0, |
|
95 TInt aReqSrc = 0, |
|
96 TInt aReqDst = 0, |
|
97 |
|
98 TInt aDes = 0, |
|
99 TInt aDesSrc = 0, |
|
100 TInt aDesDst = 0, |
|
101 |
|
102 TInt aFrame = 0, |
|
103 TInt aFrameSrc = 0, |
|
104 TInt aFrameDst = 0, |
|
105 |
|
106 TInt aPause = 0, |
|
107 TInt aPauseSrc = 0, |
|
108 TInt aPauseDst = 0, |
|
109 TDmaResult aResult = EDmaResultOK |
|
110 ); |
|
111 |
|
112 static TCallbackRecord Empty(); |
|
113 |
|
114 void Reset(); |
|
115 |
|
116 /** |
|
117 Allows 2 callback records to be compared |
|
118 */ |
|
119 TBool operator == (const TCallbackRecord aOther) const; |
|
120 void Print() const; |
|
121 |
|
122 /** |
|
123 Get the number of callbacks for callback aCbType |
|
124 */ |
|
125 TInt GetCount(TDmaCallbackType aCbType) const; |
|
126 |
|
127 void SetCount(TDmaCallbackType aCbType, TInt aCount); |
|
128 |
|
129 /** |
|
130 Set the result (expected or actual) from |
|
131 TDmaChannel::IsrRedoRequest |
|
132 */ |
|
133 inline TCallbackRecord& IsrRedoResult(TInt aResult) {iIsrRedoRequestResult = aResult; return *this;} |
|
134 |
|
135 /** |
|
136 Reports the context in which the callback occurred. |
|
137 */ |
|
138 inline TCbContext GetContext() |
|
139 {return iContext;} |
|
140 |
|
141 /** |
|
142 Updates data based on callback mask aCallbackMask |
|
143 @param aCallbackMask Bitmask of callback events @see TDmaCallbackType |
|
144 @oaram aResult The result reported by the current callback |
|
145 */ |
|
146 void ProcessCallback(TUint aCallbackMask, TDmaResult aResultaContext); |
|
147 |
|
148 static void SelfTest(); |
|
149 |
|
150 // The below methods are setters, which may be chained together |
|
151 // ie. The Named Parameter Idiom |
|
152 // @see http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.18 |
|
153 TCallbackRecord& Context(TCbContext aContext) {iContext = aContext; return *this;} |
|
154 |
|
155 private: |
|
156 TInt BitToIndex(TDmaCallbackType aCbType) const; |
|
157 |
|
158 TCbContext CurrentContext() const; |
|
159 |
|
160 TInt iCallbackLog[KNumberOfCallbacks]; |
|
161 |
|
162 TDmaResult iResult; |
|
163 TCbContext iContext; |
|
164 /** Result of the most recent redo request call */ |
|
165 TInt iIsrRedoRequestResult; |
|
166 }; |
|
167 |
|
168 /** |
|
169 Extends SDmacCaps to contain the DMA PIL |
|
170 version being used |
|
171 */ |
|
172 struct TDmacTestCaps : public SDmacCaps |
|
173 { |
|
174 TDmacTestCaps(); |
|
175 TDmacTestCaps(const SDmacCaps& aDmacCaps, TInt aVersion = 2); |
|
176 |
|
177 TInt iPILVersion; |
|
178 }; |
|
179 |
|
180 |
|
181 /** SCreateInfo for opening DMA - Reused for testing */ |
|
182 struct SCreateInfoTest |
|
183 { |
|
184 /** Default constructor. Initializes all fields with meaningful default |
|
185 values. |
|
186 |
|
187 Must be inline (for now) because exporting it would break existing |
|
188 custom DMA libs as their clients would need the export which would |
|
189 be missing from the custom .def files. |
|
190 */ |
|
191 SCreateInfoTest() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {}; |
|
192 |
|
193 /** Identifier used by PSL to select channel to open */ |
|
194 TUint32 iCookie; |
|
195 /** Number of descriptors this channel can use. |
|
196 |
|
197 This number is not used in the upgraded version of the DMA |
|
198 framework and is kept there only for source compatibility. If the |
|
199 client is certain that it will only ever use that version, then the |
|
200 value passed here doesn't matter - the framework will ignore it. |
|
201 |
|
202 @deprecated |
|
203 */ |
|
204 TInt iDesCount; |
|
205 /** DFC queue used to service DMA interrupts. |
|
206 |
|
207 The DFC thread priority must be higher than any client thread |
|
208 priority to avoid a situation where a transfer completes while |
|
209 being cancelled and another transfer is started before the DFC |
|
210 thread gets a chance to run. This would lead to a stray DFC. |
|
211 */ |
|
212 //TDfcQue* iDfcQ; |
|
213 |
|
214 TAny* iDfcQ; |
|
215 |
|
216 /** DFC priority */ |
|
217 TUint8 iDfcPriority; |
|
218 /** Used by PSL to configure a channel priority (if possible). |
|
219 |
|
220 The default is KDmaPriorityNone (the don't care value). |
|
221 |
|
222 @see TDmaPriority |
|
223 */ |
|
224 TUint iPriority; |
|
225 /** Request a dynamic DMA channel. |
|
226 |
|
227 If this is set to ETrue then the Open call is for a 'dynamic' as |
|
228 opposed to a static and solely owned DMA channel. A number of |
|
229 properties of the opened TDmaChannel object will be different in |
|
230 that case. |
|
231 |
|
232 The default value is EFalse. |
|
233 */ |
|
234 TBool iDynChannel; |
|
235 }; |
|
236 |
|
237 |
|
238 class TDmaChannel; |
|
239 |
|
240 struct TAddrRange |
|
241 { |
|
242 TAddrRange(TUint aStart, TUint aLength); |
|
243 inline TUint End() const {return (iStart + iLength -1);} |
|
244 inline TUint Start() const {return iStart;} |
|
245 |
|
246 inline TBool Contains(TUint aValue) const {return Rng(iStart, aValue, End());} |
|
247 TBool Contains(TAddrRange aRange) const; |
|
248 |
|
249 TBool Overlaps(const TAddrRange& aRange) const; |
|
250 TBool IsFilled(TUint8 aValue) const; |
|
251 |
|
252 static void SelfTest(); |
|
253 |
|
254 private: |
|
255 TUint iStart; |
|
256 TUint iLength; |
|
257 }; |
|
258 |
|
259 |
|
260 struct TAddressParms |
|
261 { |
|
262 TAddressParms(TUint32 aSrcAddr=0, TUint32 aDstAddr=0, TUint aTransferCount=0) |
|
263 :iSrcAddr(aSrcAddr), iDstAddr(aDstAddr), iTransferCount(aTransferCount) |
|
264 {} |
|
265 |
|
266 TAddressParms(const TDmaTransferArgs& aArgs) |
|
267 :iSrcAddr(aArgs.iSrcConfig.iAddr), |
|
268 iDstAddr(aArgs.iDstConfig.iAddr), |
|
269 iTransferCount(aArgs.iTransferCount) |
|
270 {} |
|
271 |
|
272 /** |
|
273 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. |
|
274 the default values used for IsrRedoRequest) then substitute the values from |
|
275 aTransferArgs. |
|
276 */ |
|
277 void Substitute(const TDmaTransferArgs& aTransferArgs); |
|
278 |
|
279 /** |
|
280 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. |
|
281 the default values used for IsrRedoRequest) then substitute the values from |
|
282 aTransferArgs. |
|
283 */ |
|
284 void Substitute(const TAddressParms& aTransferArgs); |
|
285 |
|
286 /** |
|
287 When received by the test driver, src and dst |
|
288 addresses will be offsets from the dma test session's |
|
289 chunk base. They must be converted to absolute, *physical* addresses |
|
290 */ |
|
291 void Fixup(TLinAddr aChunkBase); |
|
292 |
|
293 /** |
|
294 Check that both the src and destination lie within the area |
|
295 defined by aStart and aSize |
|
296 */ |
|
297 TBool CheckRange(TLinAddr aStart, TUint aSize); |
|
298 |
|
299 TAddrRange SourceRange() const; |
|
300 TAddrRange DestRange() const; |
|
301 |
|
302 TBool Overlaps(const TAddrRange aRange) const; |
|
303 TBool Overlaps(const TAddressParms aParm) const; |
|
304 |
|
305 TBool operator==(const TAddressParms& aOther) const; |
|
306 |
|
307 |
|
308 /** |
|
309 Produce a printable representation |
|
310 */ |
|
311 void AppendString(TDes& aBuf) const |
|
312 { |
|
313 _LIT(KOutput, "TAddressParms: src=0x%08x (%d) dst=0x%08x (%d) count=0x%08x (%d)\0"); |
|
314 #ifdef __KERNEL_MODE__ |
|
315 DmaAppendFormat(aBuf, (const char*)KOutput().Ptr(), iSrcAddr, iSrcAddr, iDstAddr, iDstAddr, iTransferCount, iTransferCount); |
|
316 #else |
|
317 aBuf.AppendFormat(KOutput, iSrcAddr, iSrcAddr, iDstAddr, iDstAddr, iTransferCount, iTransferCount); |
|
318 #endif |
|
319 } |
|
320 |
|
321 void MakePhysical(); |
|
322 |
|
323 static void SelfTest(); |
|
324 |
|
325 TUint32 iSrcAddr; |
|
326 TUint32 iDstAddr; |
|
327 TUint iTransferCount; |
|
328 }; |
|
329 |
|
330 // These functions can be used for accessing TDmaTransferArgs in |
|
331 // terms of TAddressParms. (TAddressParms would be a natural base |
|
332 // class for TDmaTransferArgs but changing the production code |
|
333 // is undesirable) |
|
334 TAddressParms GetAddrParms(const TDmaTransferArgs&); |
|
335 void SetAddrParms(TDmaTransferArgs&, const TAddressParms&); |
|
336 |
|
337 /** |
|
338 This struct holds the arguments which can be used with TDmaChannel::IsrRedoRequest |
|
339 */ |
|
340 struct TIsrRequeArgs : public TAddressParms |
|
341 { |
|
342 TIsrRequeArgs(TUint32 aSrcAddr=KPhysAddrInvalidUser, TUint32 aDstAddr=KPhysAddrInvalidUser, |
|
343 TUint aTransferCount=0, TUint32 aPslRequestInfo=0, |
|
344 TBool aIsrCb=ETrue) |
|
345 : TAddressParms(aSrcAddr, aDstAddr, aTransferCount), iPslRequestInfo(aPslRequestInfo), iIsrCb(aIsrCb) |
|
346 {} |
|
347 |
|
348 |
|
349 TInt Call(TDmaChannel& aChannel); |
|
350 |
|
351 TBool CheckRange(TLinAddr aStart, TUint aSize) const; |
|
352 |
|
353 TUint32 iPslRequestInfo; |
|
354 TBool iIsrCb; |
|
355 }; |
|
356 class CISrRequeTest; |
|
357 /** |
|
358 A collection of TIsrRequeArgs |
|
359 */ |
|
360 struct TIsrRequeArgsSet |
|
361 { |
|
362 friend class CIsrRequeTest; |
|
363 TIsrRequeArgsSet(TIsrRequeArgs* aRequeueArgs=NULL, TInt aCount =0) |
|
364 :iCount(aCount), iIndex(0) |
|
365 { |
|
366 TEST_ASSERT(iCount <= MaxCount); |
|
367 for(TInt i=0; i<iCount; i++) |
|
368 { |
|
369 iRequeArgs[i] = aRequeueArgs[i]; |
|
370 } |
|
371 |
|
372 } |
|
373 |
|
374 TBool IsEmpty() const |
|
375 {return iCount == 0;} |
|
376 |
|
377 TIsrRequeArgs GetArgs(); |
|
378 |
|
379 /** |
|
380 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. |
|
381 the default values used for IsrRedoRequest) then substitute the appropriate |
|
382 value from the previous argument struct. aTransferArgs is used to |
|
383 substitute values for the initial argument struct. |
|
384 */ |
|
385 void Substitute(const TDmaTransferArgs& aTransferArgs); |
|
386 void Fixup(TLinAddr aChunkBase); |
|
387 TBool CheckRange(TLinAddr aAddr, TUint aSize) const; |
|
388 |
|
389 /** |
|
390 Check that all re-queue parameters will remain within the region defined |
|
391 by aAddr and aSize. This overload assumes that the requeue parameters have |
|
392 not been substituted hence the data in aInitialParms is required. |
|
393 |
|
394 @param aInitialParms The original transfer that the re-queues in this set are based on |
|
395 */ |
|
396 TBool CheckRange(TLinAddr aAddr, TUint aSize, const TDmaTransferArgs& aInitialParms) const; |
|
397 |
|
398 static void SelfTest(); |
|
399 private: |
|
400 enum {MaxCount=6}; |
|
401 TInt iCount; |
|
402 TInt iIndex; |
|
403 TIsrRequeArgs iRequeArgs[MaxCount]; |
|
404 }; |
|
405 |
|
406 class DDmaTestSession; |
|
407 class RDmaSession : public RBusLogicalChannel |
|
408 { |
|
409 friend class DDmaTestSession; |
|
410 public: |
|
411 #ifndef __KERNEL_MODE__ |
|
412 TInt ChannelIsQueueEmpty(TUint aDriverCookie,TBool& aQueueEmpty) |
|
413 { |
|
414 return DoControl(EIsQueueEmpty, reinterpret_cast<TAny*>(aDriverCookie), &aQueueEmpty); |
|
415 } |
|
416 |
|
417 TInt ChannelIsOpened(TUint aDriverCookie,TBool &aChannelOpen) |
|
418 { |
|
419 return DoControl(EIsOpened, reinterpret_cast<TAny*>(aDriverCookie), &aChannelOpen); |
|
420 } |
|
421 |
|
422 TInt ChannelCancelAll(TUint aDriverCookie) |
|
423 { |
|
424 return DoControl(ECancelAllChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
|
425 } |
|
426 |
|
427 TInt ChannelOpen(TUint aPslCookie, TUint& aDriverCookie) |
|
428 { |
|
429 return DoControl(EOpenChannel, reinterpret_cast<TAny*>(aPslCookie), &aDriverCookie); |
|
430 } |
|
431 |
|
432 TInt ChannelOpen(TUint& aDriverCookie, SCreateInfoTest& aInfo) |
|
433 { |
|
434 TPckg<SCreateInfoTest> package(aInfo); |
|
435 return DoControl(EOpenChannelExposed,&aDriverCookie, &package); |
|
436 } |
|
437 |
|
438 TInt ChannelClose(TUint aDriverCookie) |
|
439 { |
|
440 return DoControl(ECloseChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
|
441 } |
|
442 |
|
443 TInt ChannelPause(TUint aDriverCookie) |
|
444 { |
|
445 return DoControl(EPauseChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
|
446 } |
|
447 |
|
448 TInt ChannelResume(TUint aDriverCookie) |
|
449 { |
|
450 return DoControl(EResumeChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
|
451 } |
|
452 |
|
453 TInt ChannelLinking(TUint aDriverCookie) |
|
454 { |
|
455 return DoControl(ELinkChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
|
456 } |
|
457 |
|
458 TInt ChannelUnLinking(TUint aDriverCookie) |
|
459 { |
|
460 return DoControl(EUnlinkChannel, reinterpret_cast<TAny*>(aDriverCookie)); |
|
461 } |
|
462 |
|
463 TInt ChannelCaps(TUint aDriverCookie, SDmacCaps& aChannelCaps) |
|
464 { |
|
465 TDmacTestCaps caps; |
|
466 TInt r = ChannelCaps(aDriverCookie, caps); |
|
467 aChannelCaps = caps; |
|
468 return r; |
|
469 } |
|
470 |
|
471 TInt ChannelCaps(TUint aDriverCookie, TDmacTestCaps& aChannelCaps) |
|
472 { |
|
473 TPckg<TDmacTestCaps> package(aChannelCaps); |
|
474 return DoControl(EChannelCaps, reinterpret_cast<TAny*>(aDriverCookie), &package); |
|
475 } |
|
476 |
|
477 TInt Open() |
|
478 { |
|
479 TInt r = KErrNone; |
|
480 r = DoCreate(KTestDmaLddNameHw,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread); |
|
481 RDebug::Printf("RDmaSession::Open returned %d", r); |
|
482 return r; |
|
483 } |
|
484 |
|
485 TInt OpenSim() |
|
486 { |
|
487 return DoCreate(KTestDmaLddNameSim,TestDmaLddVersion(), 0, NULL, NULL, EOwnerThread); |
|
488 } |
|
489 |
|
490 TInt RequestCreateOld(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0) |
|
491 { |
|
492 return DoRequestCreate(aChannelCookie, EFalse, aMaxTransferSize, aRequestCookie); |
|
493 } |
|
494 |
|
495 |
|
496 TInt RequestCreate(TUint aChannelCookie, TUint& aRequestCookie, TUint aMaxTransferSize=0) |
|
497 { |
|
498 return DoRequestCreate(aChannelCookie, ETrue, aMaxTransferSize, aRequestCookie); |
|
499 } |
|
500 |
|
501 TInt RequestDestroy(TUint aRequestCookie) |
|
502 { |
|
503 return DoControl(ERequestClose, reinterpret_cast<TAny*>(aRequestCookie)); |
|
504 } |
|
505 |
|
506 TInt RequestFragmentCount(TUint aRequestCookie) |
|
507 { |
|
508 return DoControl(EFragmentCount, reinterpret_cast<TAny*>(aRequestCookie)); |
|
509 } |
|
510 |
|
511 TInt RequestEnableDstElementCounting(TUint aRequestCookie) |
|
512 { |
|
513 return DoControl(EEnableDstElementCounting, reinterpret_cast<TAny*>(aRequestCookie)); |
|
514 } |
|
515 |
|
516 TInt RequestEnableSrcElementCounting(TUint aRequestCookie) |
|
517 { |
|
518 return DoControl(EEnableSrcElementCounting, reinterpret_cast<TAny*>(aRequestCookie)); |
|
519 } |
|
520 |
|
521 TInt RequestDisableDstElementCounting(TUint aRequestCookie) |
|
522 { |
|
523 return DoControl(EDisableDstElementCounting, reinterpret_cast<TAny*>(aRequestCookie)); |
|
524 } |
|
525 |
|
526 TInt RequestDisableSrcElementCounting(TUint aRequestCookie) |
|
527 { |
|
528 return DoControl(EDisableSrcElementCounting, reinterpret_cast<TAny*>(aRequestCookie)); |
|
529 } |
|
530 |
|
531 TInt RequestTotalNumDstElementsTransferred(TUint aRequestCookie) |
|
532 { |
|
533 return DoControl(ETotalNumDstElementsTransferred, reinterpret_cast<TAny*>(aRequestCookie)); |
|
534 } |
|
535 |
|
536 TInt RequestTotalNumSrcElementsTransferred(TUint aRequestCookie) |
|
537 { |
|
538 return DoControl(ETotalNumSrcElementsTransferred, reinterpret_cast<TAny*>(aRequestCookie)); |
|
539 } |
|
540 |
|
541 /** |
|
542 Will fragment a DMA request using the legacy API |
|
543 */ |
|
544 TInt FragmentRequestOld(TUint aRequestCookie, const TDmaTransferArgs& aTransferArgs, TUint64* aDurationMicroSecs=NULL) |
|
545 { |
|
546 const TFragmentArgs args(aRequestCookie, aTransferArgs, aDurationMicroSecs); |
|
547 TPckgC<TFragmentArgs> package(args); |
|
548 return DoControl(EFragmentLegacy, &package); |
|
549 } |
|
550 |
|
551 /** |
|
552 Will fragment a DMA request using the new API |
|
553 */ |
|
554 TInt FragmentRequest(TUint aRequestCookie, const TDmaTransferArgs& aTransferArgs, TUint64* aDurationMicroSecs=NULL) |
|
555 { |
|
556 const TFragmentArgs args(aRequestCookie, aTransferArgs, aDurationMicroSecs); |
|
557 TPckgC<TFragmentArgs> package(args); |
|
558 return DoControl(EFragment, &package); |
|
559 } |
|
560 |
|
561 TInt QueueRequest(TUint aRequestCookie, TRequestStatus& aStatus, TCallbackRecord* aRecord = NULL, TUint64* aDurationMicroSecs=NULL) |
|
562 { |
|
563 //These dummy values can accept the writeback from the driver |
|
564 //if the client does not want them. |
|
565 //(TClientDataRequest can not be programmed with a NULL to |
|
566 //indicate that an argument is unwanted) |
|
567 TCallbackRecord dummyRec; |
|
568 TUint64 dummyTime=0; |
|
569 |
|
570 aStatus = KRequestPending; |
|
571 |
|
572 TQueueArgs args(aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime); |
|
573 TPckgC<TQueueArgs> package(args); |
|
574 return DoControl(EQueueRequest, &package); |
|
575 } |
|
576 |
|
577 /** |
|
578 Synchronous version of QueueRequest |
|
579 */ |
|
580 TInt QueueRequest(TUint aRequestCookie, TCallbackRecord* aRecord = NULL, TUint64* aDurationMicroSecs=NULL) |
|
581 { |
|
582 TRequestStatus status; |
|
583 TInt r = QueueRequest(aRequestCookie, status, aRecord, aDurationMicroSecs); |
|
584 User::WaitForRequest(status); |
|
585 return r; |
|
586 } |
|
587 |
|
588 /** |
|
589 Queue a previously fragmented request. |
|
590 Additional request parameters are included in iRequeueArgs, these will be |
|
591 transferred from ISR context callback using the TDmaChannel::IsrRedoRequest function |
|
592 |
|
593 @pre Isr callback for completion must have been requested at request fragmentation time |
|
594 */ |
|
595 TInt QueueRequestWithRequeue(TUint aRequestCookie, TIsrRequeArgs* aRequeueArgs, TInt aCount, TRequestStatus& aStatus, TCallbackRecord* aRecord = NULL, TUint64* aDurationMicroSecs=NULL) |
|
596 { |
|
597 //These dummy values can accept the writeback from the driver |
|
598 //if the client does not want them. |
|
599 //(TClientDataRequest can not be programmed with a NULL to |
|
600 //indicate that an argument is unwanted) |
|
601 TCallbackRecord dummyRec; |
|
602 TUint64 dummyTime=0; |
|
603 |
|
604 aStatus = KRequestPending; |
|
605 |
|
606 TQueueArgsWithReque args(aRequeueArgs, aCount, aRequestCookie, &aStatus, aRecord ? aRecord : &dummyRec, aDurationMicroSecs ? aDurationMicroSecs : &dummyTime); |
|
607 TPckgC<TQueueArgsWithReque> package(args); |
|
608 return DoControl(EQueueRequestWithReque, &package); |
|
609 } |
|
610 |
|
611 /** |
|
612 Synchronous version of QueueRequestWithRequeue |
|
613 */ |
|
614 TInt QueueRequestWithRequeue(TUint aRequestCookie, TIsrRequeArgs* aRequeueArgs, TInt aCount, TCallbackRecord* aRecord = NULL, TUint64* aDurationMicroSecs=NULL) |
|
615 { |
|
616 TRequestStatus status; |
|
617 TInt r = QueueRequestWithRequeue(aRequestCookie, aRequeueArgs, aCount, status, aRecord, aDurationMicroSecs); |
|
618 User::WaitForRequest(status); |
|
619 return r; |
|
620 } |
|
621 |
|
622 TInt OpenSharedChunk(RChunk& aChunk) |
|
623 { |
|
624 TUint chunkHandle = DoControl(EOpenSharedChunk); |
|
625 return aChunk.SetReturnedHandle(chunkHandle); |
|
626 } |
|
627 |
|
628 TInt GetTestInfo(TDmaV2TestInfo& aInfo) |
|
629 { |
|
630 TPckg<TDmaV2TestInfo> package(aInfo); |
|
631 return DoControl(EGetTestInfo, &package); |
|
632 } |
|
633 |
|
634 static void SelfTest(TBool aSimulatedDmac); |
|
635 |
|
636 static void ApiTest(); |
|
637 #endif // __KERNEL_MODE__ |
|
638 |
|
639 private: |
|
640 |
|
641 TInt DoRequestCreate(TUint aChannelCookie, TBool aNewStyle, TUint aMaxTransferSize, TUint& aRequestCookie) |
|
642 { |
|
643 TRequestCreateArgs args(aChannelCookie, aNewStyle, aMaxTransferSize); |
|
644 TPckgC<TRequestCreateArgs> package(args); |
|
645 return DoControl(ERequestOpen, &package, &aRequestCookie); |
|
646 } |
|
647 |
|
648 struct TRequestCreateArgs |
|
649 { |
|
650 TRequestCreateArgs(TUint aChannelCookie, TBool aNewStyle, TUint aMaxFragmentSize) |
|
651 :iChannelCookie(aChannelCookie), iNewStyle(aNewStyle), iMaxFragmentSize(aMaxFragmentSize) |
|
652 {} |
|
653 |
|
654 TUint iChannelCookie; |
|
655 TBool iNewStyle; |
|
656 TUint iMaxFragmentSize; |
|
657 }; |
|
658 |
|
659 struct TFragmentArgs |
|
660 { |
|
661 TFragmentArgs() |
|
662 :iRequestCookie(0), iTransferArgs(), iDurationMicroSecs(NULL) |
|
663 {} |
|
664 TFragmentArgs(TUint aRequestCookie, const TDmaTransferArgs& aTransferArgs, TUint64* aDurationMicroSecs = NULL) |
|
665 :iRequestCookie(aRequestCookie), iTransferArgs(aTransferArgs), iDurationMicroSecs(aDurationMicroSecs) |
|
666 {} |
|
667 |
|
668 const TUint iRequestCookie; |
|
669 const TDmaTransferArgs iTransferArgs; |
|
670 TUint64* const iDurationMicroSecs; |
|
671 }; |
|
672 |
|
673 struct TQueueArgs |
|
674 { |
|
675 TQueueArgs(TUint aRequestCookie=0, TRequestStatus* aStatus=NULL, TCallbackRecord* aCallbackRecord=NULL, TUint64* aDurationMicroSecs=NULL) |
|
676 :iRequestCookie(aRequestCookie), iStatus(aStatus), iCallbackRecord(aCallbackRecord), iDurationMicroSecs(aDurationMicroSecs) |
|
677 {} |
|
678 TUint iRequestCookie; |
|
679 TRequestStatus* iStatus; |
|
680 TCallbackRecord* iCallbackRecord; |
|
681 TUint64* iDurationMicroSecs; |
|
682 }; |
|
683 |
|
684 /** |
|
685 This struct is used for queing and including a set of transfers |
|
686 to be setup from ISR context callback |
|
687 */ |
|
688 struct TQueueArgsWithReque : public TQueueArgs |
|
689 { |
|
690 TQueueArgsWithReque(TIsrRequeArgs* aRequeueArgs=NULL, TInt aCount=0, |
|
691 TUint aRequestCookie=0, TRequestStatus* aStatus=NULL, TCallbackRecord* aCallbackRecord=NULL, TUint64* aDurationMicroSecs=NULL) |
|
692 :TQueueArgs(aRequestCookie, aStatus, aCallbackRecord, aDurationMicroSecs), iRequeSet(aRequeueArgs, aCount) |
|
693 { |
|
694 } |
|
695 |
|
696 TIsrRequeArgsSet iRequeSet; |
|
697 }; |
|
698 |
|
699 enum TControl |
|
700 { |
|
701 EOpenChannel, |
|
702 EOpenChannelExposed, |
|
703 ECloseChannel, |
|
704 EPauseChannel, |
|
705 EResumeChannel, |
|
706 EChannelCaps, |
|
707 ERequestOpen, |
|
708 ERequestClose, |
|
709 EOpenSharedChunk, |
|
710 EFragmentLegacy, |
|
711 EFragment, |
|
712 EFragmentCount, |
|
713 EQueueRequest, |
|
714 EGetTestInfo, |
|
715 EIsQueueEmpty, |
|
716 EIsOpened, |
|
717 EIsrRedoRequest, |
|
718 ECancelAllChannel, |
|
719 EQueueRequestWithReque, |
|
720 ELinkChannel, |
|
721 EUnlinkChannel, |
|
722 EEnableDstElementCounting, |
|
723 EEnableSrcElementCounting, |
|
724 EDisableDstElementCounting, |
|
725 EDisableSrcElementCounting, |
|
726 ETotalNumDstElementsTransferred, |
|
727 ETotalNumSrcElementsTransferred, |
|
728 }; |
|
729 }; |
|
730 #endif // __D_DMA2_H__ |