1 // Copyright (c) 2002-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 "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 // include/drivers/dma_v2.h |
|
15 // DMA Framework - Client API v2 definition. |
|
16 // |
|
17 // NB: DMA clients should never include this file directly, but only ever the |
|
18 // generic header file <drivers/dma.h>. |
|
19 // |
|
20 |
|
21 #ifndef __DMA_H__ |
|
22 #error "dma_v2.h must'n be included directly - use <drivers/dma.h> instead" |
|
23 #endif // #ifndef __DMA_H__ |
|
24 |
|
25 #ifndef __DMA_V2_H__ |
|
26 #define __DMA_V2_H__ |
|
27 |
|
28 |
|
29 #include <kernel/kernel.h> |
|
30 #include <drivers/dmadefs.h> |
|
31 |
|
32 |
|
33 ////////////////////////////////////////////////////////////////////////////// |
|
34 // Debug Support - KDmaPanicCat is defined in each source file |
|
35 |
|
36 #define __DMA_ASSERTD(e) __ASSERT_DEBUG(e, Kern::Fault(KDmaPanicCat, __LINE__)) |
|
37 #define __DMA_ASSERTA(e) __ASSERT_ALWAYS(e, Kern::Fault(KDmaPanicCat, __LINE__)) |
|
38 #ifdef _DEBUG |
|
39 #define __DMA_CANT_HAPPEN() Kern::Fault(KDmaPanicCat, __LINE__) |
|
40 #define __DMA_DECLARE_INVARIANT public: void Invariant(); |
|
41 #define __DMA_INVARIANT() Invariant() |
|
42 #else |
|
43 #define __DMA_CANT_HAPPEN() |
|
44 #define __DMA_DECLARE_INVARIANT |
|
45 #define __DMA_INVARIANT() |
|
46 #endif |
|
47 |
|
48 |
|
49 ////////////////////////////////////////////////////////////////////////////// |
|
50 // INTERFACE EXPOSED TO DEVICE-DRIVERS |
|
51 ////////////////////////////////////////////////////////////////////////////// |
|
52 |
|
53 ////////////////////////////////////////////////////////////////////////////// |
|
54 |
|
55 /** Bitmasks used for configuring a DMA request. |
|
56 |
|
57 In general, specify KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest) |
|
58 if the source (resp. destination) is a memory buffer and clear |
|
59 KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest) if the source |
|
60 (resp. destination) is a peripheral. |
|
61 |
|
62 If the location is given as a physical address (rather than a linear one) |
|
63 then also specify KDmaPhysAddrSrc and/or KDmaPhysAddrDest. |
|
64 |
|
65 The EKA1 "Fill Mode" can be implemented by omitting KDmaIncSrc. |
|
66 |
|
67 Some peripherals may require a post-increment address mode. |
|
68 |
|
69 @see DDmaRequest::Fragment |
|
70 @publishedPartner |
|
71 @released |
|
72 */ |
|
73 enum TDmaRequestFlags |
|
74 { |
|
75 // Note: This enum is only required for backwards compatibility with the |
|
76 // old DMA framework, it can be removed once this is no longer needed. |
|
77 |
|
78 /** Source is address of memory buffer */ |
|
79 KDmaMemSrc = 0x01, |
|
80 /** Destination is address of memory buffer */ |
|
81 KDmaMemDest = 0x02, |
|
82 /** Source address must be post-incremented during transfer */ |
|
83 KDmaIncSrc = 0x04, |
|
84 /** Destination address must be post-incremented during transfer */ |
|
85 KDmaIncDest = 0x08, |
|
86 /** Source address is a physical address (as opposed to a linear one) */ |
|
87 KDmaPhysAddrSrc = 0x10, |
|
88 /** Destination address is a physical address (as opposed to a linear one) */ |
|
89 KDmaPhysAddrDest = 0x20, |
|
90 /** Request a different max transfer size (for instance for test purposes) */ |
|
91 KDmaAltTransferLen = 0x40 |
|
92 }; |
|
93 |
|
94 |
|
95 /** Each hardware or pseudo descriptor is associated with a header. Headers |
|
96 are needed because hardware descriptors can not easily be extended to store |
|
97 additional information. |
|
98 |
|
99 @publishedPartner |
|
100 @released |
|
101 */ |
|
102 struct SDmaDesHdr |
|
103 { |
|
104 SDmaDesHdr* iNext; |
|
105 }; |
|
106 |
|
107 /** Pointer to signature of the new extended callback function. |
|
108 |
|
109 TUint - bitmask of one or more TDmaCallbackType values |
|
110 TDmaResult - just that |
|
111 TAny* - was provided by client in DDmaRequest constructor |
|
112 SDmaDesHdr* - points to header (and thus descriptor) which caused a |
|
113 'descriptor completed' or 'descriptor paused' event. |
|
114 */ |
|
115 typedef void (*TDmaCallback)(TUint, TDmaResult, TAny*, SDmaDesHdr*); |
|
116 |
|
117 class TDmaChannel; |
|
118 |
|
119 /** A DMA request is a list of fragments small enough to be transferred in one go |
|
120 by the DMAC. |
|
121 |
|
122 In general, fragmentation is done in the framework by calling Fragment() but |
|
123 clients with special needs can allocate a blank descriptor list with |
|
124 ExpandDesList() and customise it to fit their needs. |
|
125 |
|
126 Clients should not set attributes directly, but should use the various functions |
|
127 instead. |
|
128 |
|
129 This class has not been designed to be called from several concurrent threads. |
|
130 Multithreaded clients must implement their own locking scheme (via DMutex). |
|
131 |
|
132 Mutexes are used internally to protect data structures accessed both by the |
|
133 client thread and the DFC thread. Therefore no fast mutex can be held when |
|
134 calling a request function. |
|
135 |
|
136 @publishedPartner |
|
137 @released |
|
138 */ |
|
139 class DDmaRequest : public DBase |
|
140 { |
|
141 friend class TDmaChannel; |
|
142 |
|
143 public: |
|
144 /** The outcome of the transfer |
|
145 |
|
146 @deprecated |
|
147 @see TDmaResult |
|
148 */ |
|
149 enum TResult {EBadResult=0, EOk, EError}; |
|
150 /** The signature of the completion/failure callback function |
|
151 |
|
152 @deprecated |
|
153 @see TDmaCallback |
|
154 */ |
|
155 typedef void (*TCallback)(TResult, TAny*); |
|
156 |
|
157 public: |
|
158 /** Constructor. |
|
159 |
|
160 Create a new transfer request. |
|
161 |
|
162 @param aChannel The channel this request is bound to. |
|
163 @param aCb Callback function called on transfer completion or failure |
|
164 (in channel DFC context). Can be NULL. |
|
165 @param aCbArg Argument passed to callback function. |
|
166 @param aMaxTransferSize Maximum fragment size. If not specified, defaults to the maximum size |
|
167 supported by the DMA controller for the type of transfer that is later scheduled. |
|
168 |
|
169 @deprecated |
|
170 */ |
|
171 IMPORT_C DDmaRequest(TDmaChannel& aChannel, TCallback aCb=NULL, TAny* aCbArg=NULL, |
|
172 TInt aMaxTransferSize=0); |
|
173 |
|
174 |
|
175 /** Constructor. |
|
176 |
|
177 Create a new transfer request. |
|
178 |
|
179 @param aChannel The channel this request is bound to. |
|
180 @param aDmaCb Callback function called on transfer completion or |
|
181 failure (in channel DFC or ISR context). Can be NULL. |
|
182 @param aCbArg Argument passed to callback function. |
|
183 @param aMaxTransferSize Maximum fragment size. If not specified, |
|
184 defaults to the maximum size supported by the DMA controller for the |
|
185 type of transfer that is later scheduled. |
|
186 */ |
|
187 IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb, TAny* aCbArg=NULL, |
|
188 TUint aMaxTransferSize=0); |
|
189 |
|
190 |
|
191 /** Destructor. |
|
192 |
|
193 Assume the request is not being transferred or pending. |
|
194 */ |
|
195 IMPORT_C ~DDmaRequest(); |
|
196 |
|
197 |
|
198 /** Split request into a list of fragments small enough to be fed to the |
|
199 DMAC. |
|
200 |
|
201 The size of each fragment is smaller than or equal to the maximum |
|
202 transfer size supported by the DMAC. If the source and/or destination |
|
203 is memory, each fragment points to memory which is physically |
|
204 contiguous. |
|
205 |
|
206 The kind of transfer to perform is specified via a set of flags used by |
|
207 a PIL and a magic cookie passed to the PSL. If the source |
|
208 (resp. destination) is a peripheral, aSrc (resp. aDest) is treated as a |
|
209 magic cookie by the PIL and passed straight to the PSL. |
|
210 |
|
211 The request can be uninitialised or may have been fragmented |
|
212 previously. The previous configuration if any is lost whether or not |
|
213 the function succeeds. |
|
214 |
|
215 @param aSrc Source memory buffer linear address or peripheral magic |
|
216 cookie. |
|
217 @param aDest Destination memory buffer linear address or peripheral |
|
218 magic cookie. |
|
219 @param aCount Number of bytes to transfer. |
|
220 @param aFlags Bitmask characterising the transfer. |
|
221 @param aPslInfo Hardware-specific information passed to PSL. |
|
222 |
|
223 @return KErrNone if success. KErrArgument if aFlags and/or aPslInfo are |
|
224 invalid when finding the maximum transfer size. May also fail if |
|
225 running out of descriptors. |
|
226 |
|
227 @pre The request is not being transferred or pending. |
|
228 @pre The various parameters must be valid. The PIL or PSL will fault the |
|
229 kernel if not. |
|
230 |
|
231 @see TDmaRequestFlags |
|
232 |
|
233 @deprecated |
|
234 */ |
|
235 IMPORT_C TInt Fragment(TUint32 aSrc, TUint32 aDest, TInt aCount, TUint aFlags, TUint32 aPslInfo); |
|
236 |
|
237 |
|
238 /** New version of the DMA request fragment function, to be used with the |
|
239 TDmaTransferArgs structure. |
|
240 */ |
|
241 IMPORT_C TInt Fragment(const TDmaTransferArgs& aTransferArgs); |
|
242 |
|
243 |
|
244 /** Transfer asynchronously this request. |
|
245 |
|
246 If this request's channel is idle, the request is transferred |
|
247 immediately. Otherwise, it is queued and transferred later. |
|
248 |
|
249 The client is responsible for ensuring cache consistency before and/or |
|
250 after the transfer if necessary. |
|
251 |
|
252 @return KErrNone if success, KErrGeneral otherwise. |
|
253 */ |
|
254 IMPORT_C TInt Queue(); |
|
255 |
|
256 |
|
257 /** Append new descriptor(s) to existing list. |
|
258 |
|
259 Clients needing to build a custom descriptor list should call this |
|
260 function to allocate the list and access the resulting list through |
|
261 iFirstHdr and iLastHdr. |
|
262 |
|
263 Clients should not change the value of iFirstHdr, iLastHdr and the |
|
264 iNext field of the descriptor headers to ensure descriptors can be |
|
265 deallocated. Clients are free to change hardware descriptors, including |
|
266 chaining, in whatever way suit them. |
|
267 |
|
268 Assume the request is not being transferred or pending. |
|
269 |
|
270 @param aCount Number of descriptors to append. |
|
271 |
|
272 @return KErrNone or standard error code. |
|
273 */ |
|
274 IMPORT_C TInt ExpandDesList(TInt aCount=1); |
|
275 |
|
276 |
|
277 /** Append new descriptor(s) to existing list. This function variant |
|
278 operates on the source port descriptor chain. |
|
279 |
|
280 Works like ExpandDesList except that it uses the iSrcFirstHdr and |
|
281 iSrcLastHdr fields. |
|
282 |
|
283 @see ExpandDesList |
|
284 |
|
285 This function can only be used if SDmacCaps::iAsymHwDescriptors is |
|
286 true, otherwise it will just return KErrGeneral. |
|
287 |
|
288 @param aCount Number of descriptors to append. |
|
289 |
|
290 @return KErrNone or standard error code. |
|
291 */ |
|
292 IMPORT_C TInt ExpandSrcDesList(TInt aCount=1); |
|
293 |
|
294 |
|
295 /** Append new descriptor(s) to existing list. This function variant |
|
296 operates on the destination port descriptor chain. |
|
297 |
|
298 Works like ExpandDesList except that it uses the iDstFirstHdr and |
|
299 iDstLastHdr fields. |
|
300 |
|
301 @see ExpandDesList |
|
302 |
|
303 This function can only be used if SDmacCaps::iAsymHwDescriptors is |
|
304 true, otherwise it will just return KErrGeneral. |
|
305 |
|
306 @param aCount Number of descriptors to append. |
|
307 |
|
308 @return KErrNone or standard error code. |
|
309 */ |
|
310 IMPORT_C TInt ExpandDstDesList(TInt aCount=1); |
|
311 |
|
312 |
|
313 /** Free resources associated with this request. |
|
314 |
|
315 Assume the request is not being transferred or pending. |
|
316 */ |
|
317 IMPORT_C void FreeDesList(); |
|
318 |
|
319 |
|
320 /** Free resources associated with this request. This function variant |
|
321 operates on the source port descriptor chain. |
|
322 |
|
323 @see FreeDesList |
|
324 |
|
325 This function can only be used if SDmacCaps::iAsymHwDescriptors is |
|
326 true, otherwise it will do nothing. |
|
327 */ |
|
328 IMPORT_C void FreeSrcDesList(); |
|
329 |
|
330 |
|
331 /** Free resources associated with this request. This function variant |
|
332 operates on the destination port descriptor chain. |
|
333 |
|
334 @see FreeDesList |
|
335 |
|
336 This function can only be used if SDmacCaps::iAsymHwDescriptors is |
|
337 true, otherwise it will do nothing. |
|
338 */ |
|
339 IMPORT_C void FreeDstDesList(); |
|
340 |
|
341 |
|
342 /** Enables the functionality for counting the transferred source |
|
343 elements. |
|
344 |
|
345 This function can be called at any time, but the enabled/disabled |
|
346 status is checked by the framework only at two points in time. |
|
347 |
|
348 The first one is after a request has been queued, and if it is enabled |
|
349 then the counting will commence as soon as the transfer starts. |
|
350 |
|
351 The second point is when Resume() is called for a paused transfer, and |
|
352 in this case the following applies. If counting was enabled when the |
|
353 transfer was paused and it is now disabled then the counting is stopped |
|
354 at that point and the count value frozen. If counting was disabled when |
|
355 the transfer was paused and it is now enabled then the counting will |
|
356 commence when the transfer resumes. (The starting value will depend on |
|
357 the argument of the enable function.) Otherwise nothing will change, |
|
358 i.e. counting will either continue normally (enabled/enabled) or |
|
359 neither stop nor continue (disabled/disabled). |
|
360 |
|
361 Once a status has been set, it remains valid for the entire duration of |
|
362 the transfer (and beyond, if it is not changed again). |
|
363 |
|
364 @param aResetElementCount If ETrue (the default) then the count |
|
365 variable will be reset to zero, otherwise it will retain its current |
|
366 value. |
|
367 |
|
368 @see Queue() |
|
369 @see TotalNumSrcElementsTransferred() |
|
370 */ |
|
371 IMPORT_C void EnableSrcElementCounting(TBool aResetElementCount=ETrue); |
|
372 |
|
373 |
|
374 /** Enables the functionality for counting the transferred destination |
|
375 elements. |
|
376 |
|
377 This function can be called at any time, but the enabled/disabled |
|
378 status is checked by the framework only at two points in time. |
|
379 |
|
380 The first one is after a request has been queued, and if it is enabled |
|
381 then the counting will commence as soon as the transfer starts. |
|
382 |
|
383 The second point is when Resume() is called for a paused transfer, and |
|
384 in this case the following applies. If counting was enabled when the |
|
385 transfer was paused and it is now disabled then the counting is stopped |
|
386 at that point and the count value frozen. If counting was disabled when |
|
387 the transfer was paused and it is now enabled then the counting will |
|
388 commence when the transfer resumes. (The starting value will depend on |
|
389 the argument of the enable function.) Otherwise nothing will change, |
|
390 i.e. counting will either continue normally (enabled/enabled) or |
|
391 neither stop nor continue (disabled/disabled). |
|
392 |
|
393 Once a status has been set, it remains valid for the entire duration of |
|
394 the transfer (and beyond, if it is not changed again). |
|
395 |
|
396 @param aResetElementCount If ETrue (the default) then the count |
|
397 variable will be reset to zero, otherwise it will retain its current |
|
398 value. |
|
399 |
|
400 @see Queue() |
|
401 @see TotalNumDstElementsTransferred() |
|
402 */ |
|
403 IMPORT_C void EnableDstElementCounting(TBool aResetElementCount=ETrue); |
|
404 |
|
405 |
|
406 /** Disables the functionality for counting the transferred source |
|
407 elements. |
|
408 |
|
409 This function can be called at any time, but the enabled/disabled |
|
410 status is checked by the framework only at two points in time. |
|
411 |
|
412 The first one is after a request has been queued, and if it is enabled |
|
413 then the counting will commence as soon as the transfer starts. |
|
414 |
|
415 The second point is when Resume() is called for a paused transfer, and |
|
416 in this case the following applies. If counting was enabled when the |
|
417 transfer was paused and it is now disabled then the counting is stopped |
|
418 at that point and the count value frozen. If counting was disabled when |
|
419 the transfer was paused and it is now enabled then the counting will |
|
420 commence when the transfer resumes. (The starting value will depend on |
|
421 the argument of the enable function.) Otherwise nothing will change, |
|
422 i.e. counting will either continue normally (enabled/enabled) or |
|
423 neither stop nor continue (disabled/disabled). |
|
424 |
|
425 Once a status has been set, it remains valid for the entire duration of |
|
426 the transfer (and beyond, if it is not changed again). |
|
427 |
|
428 @see Queue() |
|
429 @see TotalNumSrcElementsTransferred() |
|
430 */ |
|
431 IMPORT_C void DisableSrcElementCounting(); |
|
432 |
|
433 |
|
434 /** Disables the functionality for counting the transferred destination |
|
435 elements. |
|
436 |
|
437 This function can be called at any time, but the enabled/disabled |
|
438 status is checked by the framework only at two points in time. |
|
439 |
|
440 The first one is after a request has been queued, and if it is enabled |
|
441 then the counting will commence as soon as the transfer starts. |
|
442 |
|
443 The second point is when Resume() is called for a paused transfer, and |
|
444 in this case the following applies. If counting was enabled when the |
|
445 transfer was paused and it is now disabled then the counting is stopped |
|
446 at that point and the count value frozen. If counting was disabled when |
|
447 the transfer was paused and it is now enabled then the counting will |
|
448 commence when the transfer resumes. (The starting value will depend on |
|
449 the argument of the enable function.) Otherwise nothing will change, |
|
450 i.e. counting will either continue normally (enabled/enabled) or |
|
451 neither stop nor continue (disabled/disabled). |
|
452 |
|
453 Once a status has been set, it remains valid for the entire duration of |
|
454 the transfer (and beyond, if it is not changed again). |
|
455 |
|
456 @see Queue() |
|
457 @see TotalNumDstElementsTransferred() |
|
458 */ |
|
459 IMPORT_C void DisableDstElementCounting(); |
|
460 |
|
461 |
|
462 /** Returns the number of elements that have been transferred by this |
|
463 transfer request at the source port. |
|
464 |
|
465 To use this method, the counting functionality has to be explicitly |
|
466 enabled, either before the transfer request is queued or while it is |
|
467 paused. |
|
468 |
|
469 @see EnableSrcElementCounting() |
|
470 @see DisableSrcElementCounting() |
|
471 |
|
472 This function should only be called after the transfer has finished |
|
473 (completed with or without error, or because it was cancelled) or while |
|
474 it is paused. Otherwise it may just return 0. |
|
475 |
|
476 @return The number of elements that have been transferred by this |
|
477 transfer request at the source port. |
|
478 */ |
|
479 IMPORT_C TUint32 TotalNumSrcElementsTransferred(); |
|
480 |
|
481 |
|
482 /** Returns the number of elements that have been transferred by this |
|
483 transfer request at the destination port. |
|
484 |
|
485 To use this method, the counting functionality has to be explicitly |
|
486 enabled, either before the transfer request is queued or while it is |
|
487 paused. |
|
488 |
|
489 @see EnableDstElementCounting() |
|
490 @see DisableDstElementCounting() |
|
491 |
|
492 This function should only be called after the transfer has finished |
|
493 (completed with or without error, or because it was cancelled) or while |
|
494 it is paused. Otherwise it may just return 0. |
|
495 |
|
496 @return The number of elements that have been transferred by this |
|
497 transfer request at the destination port. |
|
498 */ |
|
499 IMPORT_C TUint32 TotalNumDstElementsTransferred(); |
|
500 |
|
501 |
|
502 /** Returns the number of fragments that this transfer request has been |
|
503 split into. |
|
504 |
|
505 This number will only be different from 0 once Fragment() has been |
|
506 called or after descriptors have been manually allocated by the client |
|
507 using ExpandDesList(). |
|
508 |
|
509 If SDmacCaps::iAsymHwDescriptors is true then this function will always |
|
510 return 0, and SrcFragmentCount() / DstFragmentCount() should be used |
|
511 instead. |
|
512 |
|
513 @return The number of fragments (descriptors / pseudo descriptors) that |
|
514 this transfer request has been split into. |
|
515 */ |
|
516 IMPORT_C TInt FragmentCount(); |
|
517 |
|
518 /** Returns the number of source port fragments that this transfer request |
|
519 has been split into. |
|
520 |
|
521 This number will only be different from 0 once Fragment() has been |
|
522 called or after descriptors have been manually allocated by the client |
|
523 using ExpandSrcDesList(). |
|
524 |
|
525 This function can only be used if SDmacCaps::iAsymHwDescriptors is |
|
526 true, otherwise it will always return 0. |
|
527 |
|
528 @return The number of source port fragments (descriptors) that this |
|
529 transfer request has been split into. |
|
530 */ |
|
531 IMPORT_C TInt SrcFragmentCount(); |
|
532 |
|
533 |
|
534 /** Returns the number of destination port fragments that this transfer |
|
535 request has been split into. |
|
536 |
|
537 This number will only be different from 0 once Fragment() has been |
|
538 called or after descriptors have been manually allocated by the client |
|
539 using ExpandDstDesList(). |
|
540 |
|
541 This function can only be used if SDmacCaps::iAsymHwDescriptors is |
|
542 true, otherwise it will always return 0. |
|
543 |
|
544 @return The number of destination port fragments (descriptors) that |
|
545 this transfer request has been split into. |
|
546 */ |
|
547 IMPORT_C TInt DstFragmentCount(); |
|
548 |
|
549 private: |
|
550 inline void OnDeque(); |
|
551 TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs); |
|
552 TInt Frag(TDmaTransferArgs& aTransferArgs); |
|
553 TInt FragSym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen); |
|
554 TInt FragAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen); |
|
555 TInt FragAsymSrc(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen); |
|
556 TInt FragAsymDst(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen); |
|
557 TInt ExpandDesList(TInt aCount, TInt& aDesCount, SDmaDesHdr*& aFirstHdr, |
|
558 SDmaDesHdr*& aLastHdr); |
|
559 void FreeDesList(TInt& aDesCount, SDmaDesHdr*& aFirstHdr, SDmaDesHdr*& aLastHdr); |
|
560 TInt FragmentCount(const SDmaDesHdr* aHdr); |
|
561 |
|
562 public: |
|
563 // WARNING: The following attributes are accessed both in client and DFC |
|
564 // context and so accesses must be protected with the channel lock. |
|
565 TDmaChannel& iChannel; /**< The channel this request is bound to */ |
|
566 TCallback iCb; /**< Called on completion/failure (can be NULL) */ |
|
567 TAny* iCbArg; /**< Callback argument */ |
|
568 TDmaCallback iDmaCb; // the new-style callback function |
|
569 TAny* iDmaCbArg; // the new-style callback arg |
|
570 TBool iIsrCb; // client wants callback in ISR context |
|
571 TInt iDesCount; /**< The number of fragments in list */ |
|
572 SDmaDesHdr* iFirstHdr; /**< The first fragment in the list (or NULL) */ |
|
573 SDmaDesHdr* iLastHdr; /**< The last fragment in the list (or NULL) */ |
|
574 TInt iSrcDesCount; /**< The number of fragments in list */ |
|
575 SDmaDesHdr* iSrcFirstHdr; /**< The first fragment in the list (or NULL) */ |
|
576 SDmaDesHdr* iSrcLastHdr; /**< The last fragment in the list (or NULL) */ |
|
577 TInt iDstDesCount; /**< The number of fragments in list */ |
|
578 SDmaDesHdr* iDstFirstHdr; /**< The first fragment in the list (or NULL) */ |
|
579 SDmaDesHdr* iDstLastHdr; /**< The last fragment in the list (or NULL) */ |
|
580 SDblQueLink iLink; /**< The link on channel queue of pending requests */ |
|
581 TBool iQueued; /**< Indicates whether request is pending or being transferred */ |
|
582 TUint iMaxTransferSize; /**< Defaults to DMA controller max. transfer size */ |
|
583 |
|
584 TUint32 iTotalNumSrcElementsTransferred; |
|
585 TUint32 iTotalNumDstElementsTransferred; |
|
586 |
|
587 __DMA_DECLARE_INVARIANT |
|
588 }; |
|
589 |
|
590 |
|
591 ////////////////////////////////////////////////////////////////////////////// |
|
592 |
|
593 class TDmac; |
|
594 class DmaChannelMgr; |
|
595 class TDmaCancelInfo; |
|
596 |
|
597 /** DMA channel base class. |
|
598 |
|
599 Standard derived classes are provided for this channel (see |
|
600 TDmaSbChannel, TDmaDbChannel, TDmaSgChannel, and TDmaAsymSgChannel). |
|
601 The base-port implementor will only need to write their own derived |
|
602 class if one of the standard classes is unsuitable. |
|
603 |
|
604 This class has not been designed to be called from several concurrent |
|
605 client threads. Multithreaded clients must implement their own locking |
|
606 scheme (via DMutex). |
|
607 |
|
608 Mutexes are used internally to protect data structures accessed both by the |
|
609 client thread and the DFC one. Therefore no fast mutex can be held when |
|
610 calling a channel function. |
|
611 |
|
612 @publishedPartner |
|
613 @released |
|
614 */ |
|
615 class TDmaChannel |
|
616 { |
|
617 friend class DDmaRequest; |
|
618 friend class TDmac; |
|
619 friend class DmaChannelMgr; |
|
620 public: |
|
621 |
|
622 /** Information passed by client when opening a channel */ |
|
623 struct SCreateInfo |
|
624 { |
|
625 /** Default constructor. Initializes all fields with meaningful default |
|
626 values. |
|
627 |
|
628 Must be inline (for now) because exporting it would break existing |
|
629 custom DMA libs as their clients would need the export which would |
|
630 be missing from the custom .def files. |
|
631 */ |
|
632 SCreateInfo() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {}; |
|
633 |
|
634 /** Identifier used by PSL to select channel to open */ |
|
635 TUint32 iCookie; |
|
636 /** Number of descriptors this channel can use. |
|
637 |
|
638 This number is not used in the upgraded version of the DMA |
|
639 framework and is kept there only for source compatibility. If the |
|
640 client is certain that it will only ever use that version, then the |
|
641 value passed here doesn't matter - the framework will ignore it. |
|
642 |
|
643 @deprecated |
|
644 */ |
|
645 TInt iDesCount; |
|
646 /** DFC queue used to service DMA interrupts. |
|
647 |
|
648 The DFC thread priority must be higher than any client thread |
|
649 priority to avoid a situation where a transfer completes while |
|
650 being cancelled and another transfer is started before the DFC |
|
651 thread gets a chance to run. This would lead to a stray DFC. |
|
652 */ |
|
653 TDfcQue* iDfcQ; |
|
654 /** DFC priority */ |
|
655 TUint8 iDfcPriority; |
|
656 /** Used by PSL to configure a channel priority (if possible). |
|
657 |
|
658 The default is KDmaPriorityNone (the don't care value). |
|
659 |
|
660 @see TDmaPriority |
|
661 */ |
|
662 TUint iPriority; |
|
663 /** Request a dynamic DMA channel. |
|
664 |
|
665 If this is set to ETrue then the Open call is for a 'dynamic' as |
|
666 opposed to a static and solely owned DMA channel. A number of |
|
667 properties of the opened TDmaChannel object will be different in |
|
668 that case. |
|
669 |
|
670 The default value is EFalse. |
|
671 */ |
|
672 TBool iDynChannel; |
|
673 }; |
|
674 |
|
675 public: |
|
676 /** Opens the DMA channel. |
|
677 |
|
678 Channel selection is done by the hardware-specific layer using a cookie |
|
679 passed in via aInfo. |
|
680 |
|
681 The client should not delete the returned pointer as the framework owns |
|
682 channel objects. However, the client should explicitly close the |
|
683 channel when finished with it. |
|
684 |
|
685 @param aInfo Information passed by caller to select and configure |
|
686 channel. |
|
687 |
|
688 @param aChannel Points to open channel on successful return. NULL |
|
689 otherwise. |
|
690 |
|
691 @return KErrNone or standard error code. |
|
692 */ |
|
693 IMPORT_C static TInt Open(const SCreateInfo& aInfo, TDmaChannel*& aChannel); |
|
694 |
|
695 |
|
696 /** Closes a previously opened DMA channel. |
|
697 |
|
698 Assumes the channel is idle and all requests have been deleted. |
|
699 |
|
700 The call will cause the resources associated with this channel to be |
|
701 released, and the pointer/reference to it mustn't therefore be accessed |
|
702 any longer after the function has returned. The channel pointer should |
|
703 be set to NULL by the client. |
|
704 */ |
|
705 IMPORT_C void Close(); |
|
706 |
|
707 |
|
708 /** Logically links this channel to the one specified as an argument, or, |
|
709 if the argument is NULL, unlinks this channel. |
|
710 |
|
711 The effect of channel linking is that once a transfer on this channel |
|
712 has finished, instead of causing the associated client callback to be |
|
713 called, 'aChannel' will be enabled by hardware and a preconfigured |
|
714 transfer on that channel will start. |
|
715 |
|
716 Note that conceptually 'linking' here always refers to the end of a |
|
717 channel transfer, not the beginning, i.e. a channel can only be linked |
|
718 once and always to a successor, never twice or to a predecessor. (This |
|
719 does not preclude the possibility that two channels are linked in a |
|
720 circular fashion.) |
|
721 |
|
722 This function can only be used if the DMAC supports logical channel |
|
723 linking. |
|
724 |
|
725 @see SDmacCaps::iChannelLinking |
|
726 |
|
727 @param aChannel Points to the channel this one should be linked to, or |
|
728 NULL if this channel is to be unlinked from any other one. |
|
729 |
|
730 @return KErrNone if the channel has been linked or unlinked |
|
731 successfully, KErrCompletion if this channel was already linked to |
|
732 aChannel or already unlinked, KErrNotSupported if the DMAC doesn't |
|
733 support channel linking, KErrArgument if this channel was already |
|
734 linked to a different channel, KErrGeneral if a general error occurred |
|
735 preventing a successful outcome. |
|
736 */ |
|
737 IMPORT_C TInt LinkToChannel(TDmaChannel* aChannel); |
|
738 |
|
739 /** Pauses an active transfer on this channel. |
|
740 |
|
741 A paused channel transfer can be resumed by calling Resume() or it can |
|
742 be stopped altogether by calling CancelAll(). |
|
743 |
|
744 @see TDmaChannel::Resume() |
|
745 |
|
746 Function can only be used if the DMAC supports this functionality. |
|
747 |
|
748 @see SDmacCaps::iChannelPauseAndResume |
|
749 |
|
750 @return KErrNone if a transfer has been paused successfully, |
|
751 KErrCompletion if a transfer was already paused, KErrNotSupported if |
|
752 the DMAC doesn't support channel transfer pausing/resuming, KErrGeneral |
|
753 if a general error occurred preventing a successful outcome. |
|
754 */ |
|
755 IMPORT_C TInt Pause(); |
|
756 |
|
757 |
|
758 /** Resumes a transfer on this channel that is paused. |
|
759 |
|
760 Resume() can be called to resume channel operation when the transfer is |
|
761 paused as a result of a previous call to Pause() or because the DMAC |
|
762 has encountered a Pause bit in a H/W descriptor. |
|
763 |
|
764 @see TDmaChannel::Pause() |
|
765 @see TDmaCallbackType::EDmaCallbackLinkedListPaused |
|
766 |
|
767 Function can only be used if the DMAC supports this functionality. |
|
768 |
|
769 @see SDmacCaps::iChannelPauseAndResume |
|
770 |
|
771 @return KErrNone if a paused transfer has been resumed successfully, |
|
772 KErrCompletion if there was no paused transfer, KErrNotSupported if the |
|
773 DMAC doesn't support channel transfer pausing/resuming, KErrGeneral if |
|
774 a general error occurred preventing a successful outcome. |
|
775 */ |
|
776 IMPORT_C TInt Resume(); |
|
777 |
|
778 |
|
779 /** Cancels the current request and all the pending ones. |
|
780 */ |
|
781 IMPORT_C void CancelAll(); |
|
782 |
|
783 |
|
784 /** Returns the channel's maximum transfer length based on the passed |
|
785 arguments. |
|
786 |
|
787 @param aSrcFlags Bitmask characterising transfer source |
|
788 @see TDmaTransferArgs::iSrcConfig::iFlags |
|
789 |
|
790 @param aDstFlags Bitmask characterising transfer destination |
|
791 @see TDmaTransferArgs::iDstConfig::iFlags |
|
792 |
|
793 @param aPslInfo Cookie passed to the PSL |
|
794 @see TDmaTransferArgs::iPslRequestInfo |
|
795 |
|
796 @return 0 if transfer length is not limited, the maximum transfer |
|
797 length in bytes otherwise. |
|
798 */ |
|
799 IMPORT_C TUint MaxTransferLength(TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo); |
|
800 |
|
801 |
|
802 /** Retrieves from the PSL the address / memory alignment mask based on the |
|
803 parameters passed. Some DMA controllers impose alignment constraints on |
|
804 the base address of memory buffers. This mask is AND'ed against memory |
|
805 addresses computed during fragmentation. |
|
806 |
|
807 This function needs to be called separately for source and destination. |
|
808 |
|
809 @param aTargetFlags Bitmask characterising transfer source or |
|
810 destination |
|
811 @see TDmaTransferArgs::iSrcConfig::iFlags |
|
812 @see TDmaTransferArgs::iDstConfig::iFlags |
|
813 |
|
814 @param aElementSize Element size used for the transfer. Can be zero if |
|
815 not known or 'don't care'. |
|
816 |
|
817 @param aPslInfo Cookie passed to the PSL |
|
818 @see TDmaTransferArgs::iPslRequestInfo |
|
819 |
|
820 @return A value representing the alignment mask (e.g. 3 if buffer must |
|
821 be 4-byte aligned) |
|
822 */ |
|
823 IMPORT_C TUint AddressAlignMask(TUint aTargetFlags, TUint aElementSize, |
|
824 TUint32 aPslInfo); |
|
825 |
|
826 |
|
827 /** Returns a reference to a structure containing the capabilities and |
|
828 features of the DMA controller associated with this channel. |
|
829 |
|
830 @return A reference to a structure containing the capabilities and |
|
831 features of the DMA controller associated with this channel. |
|
832 */ |
|
833 IMPORT_C const SDmacCaps& DmacCaps(); |
|
834 |
|
835 |
|
836 /** Sets up once more the transfer request that has just completed, after |
|
837 optionally having adjusted the transfer parameters as specified. |
|
838 |
|
839 This function is meant to be called exclusively from a client-supplied |
|
840 callback that is executed in ISR context, and only in response to a |
|
841 transfer completion notification. |
|
842 |
|
843 If this call returns to the caller with KErrNone then the framework's |
|
844 ISR handler will subsequently not queue the channel DFC for this |
|
845 completed request. |
|
846 |
|
847 The parameters specify which changes the framework should apply to the |
|
848 descriptors of the transfer request before rescheduling it. Arguments |
|
849 for which no change is required should be passed as their default |
|
850 values. The parameters correspond to those in the TDmaTransferArgs |
|
851 struct as follows. |
|
852 |
|
853 @param aSrcAddr @see TDmaTransferArgs::iSrcConfig::iAddr |
|
854 @param aDstAddr @see TDmaTransferArgs::iDstConfig::iAddr |
|
855 @param aTransferCount @see TDmaTransferArgs::iTransferCount |
|
856 @param aPslRequestInfo @see TDmaTransferArgs::iPslRequestInfo |
|
857 @param aIsrCb If set to ETrue (the default) then the callback of the |
|
858 rescheduled request will again be called in ISR context |
|
859 |
|
860 Since Epoc::LinearToPhysical() cannot be called in ISR context the |
|
861 addresses passed into this function must be physical ones, i.e. |
|
862 TDmaTransferFlags::KDmaPhysAddr is implied. |
|
863 |
|
864 If an address refers to a memory target then |
|
865 TDmaTransferFlags::KDmaMemIsContiguous is implied as well as no |
|
866 fragmentation is possible at this point. |
|
867 |
|
868 @pre Must only be called from a 'transfer complete' client callback in |
|
869 ISR context. |
|
870 |
|
871 @post Framework won't queue the channel DFC for the completed request |
|
872 in success case. |
|
873 |
|
874 @see DDmaRequest::DDmaRequest(TDmaChannel&, TDmaCallback, TAny*, TUint) |
|
875 @see TDmaCallbackType::EDmaCallbackRequestCompletion |
|
876 @see TDmaPILFlags::KDmaRequestCallbackFromIsr |
|
877 |
|
878 @return KErrGeneral if there was an error, KErrNone otherwise. |
|
879 */ |
|
880 IMPORT_C TInt IsrRedoRequest(TUint32 aSrcAddr=KPhysAddrInvalid, |
|
881 TUint32 aDstAddr=KPhysAddrInvalid, |
|
882 TUint aTransferCount=0, |
|
883 TUint32 aPslRequestInfo=0, |
|
884 TBool aIsrCb=ETrue); |
|
885 |
|
886 |
|
887 /** Tests whether the channel is currently opened. |
|
888 |
|
889 @return ETrue if channel is currently opened, EFalse otherwise. |
|
890 |
|
891 NB: This API should not be used any longer. |
|
892 |
|
893 After calling TDmaChannel::Open() successfully the channel is |
|
894 guaranteed to be open. Therefore there seems no good reason for this |
|
895 API to exist. |
|
896 |
|
897 @deprecated |
|
898 */ |
|
899 inline TBool IsOpened() const; |
|
900 |
|
901 |
|
902 /** Tests whether the channel's request queue is currently empty. |
|
903 |
|
904 @return ETrue if request queue is currently empty, EFalse otherwise. |
|
905 */ |
|
906 inline TBool IsQueueEmpty() const; |
|
907 |
|
908 |
|
909 /** Returns a PSL-specific value which uniquely identifies this channel - |
|
910 it is used for debug tracing by the PIL. |
|
911 |
|
912 @return PSL-specific value which uniquely identifies this channel. |
|
913 */ |
|
914 inline TUint32 PslId() const; |
|
915 |
|
916 |
|
917 /** Called by a test harness to force an error when the next fragment is |
|
918 transferred. |
|
919 |
|
920 @param aFragmentCount The number of consecutive fragments to fail |
|
921 */ |
|
922 IMPORT_C TInt FailNext(TInt aFragmentCount); |
|
923 |
|
924 |
|
925 /** Called by a test harness to force the DMA controller to miss one or |
|
926 more interrupts. |
|
927 |
|
928 @param aInterruptCount The number of consecutive interrupts to miss |
|
929 */ |
|
930 IMPORT_C TInt MissNextInterrupts(TInt aInterruptCount); |
|
931 |
|
932 |
|
933 /** Function allowing platform-specific layer to extend channel API with |
|
934 new channel-specific operations. |
|
935 |
|
936 @param aCmd Command identifier. Negative values are reserved for use by |
|
937 Nokia. |
|
938 @param aArg PSL-specific argument |
|
939 |
|
940 @return KErrNotSupported if aCmd is not supported. PSL-specific value |
|
941 otherwise. |
|
942 */ |
|
943 IMPORT_C TInt Extension(TInt aCmd, TAny* aArg); |
|
944 |
|
945 |
|
946 /** This is a function that allows the Platform Specific Layer (PSL) to |
|
947 extend the DMA API with new channel-independent operations. |
|
948 |
|
949 @param aCmd Command identifier. Negative values are reserved for |
|
950 Symbian use. |
|
951 @param aArg PSL-specific. |
|
952 |
|
953 @return KErrNotSupported if aCmd is not supported; a PSL specific value |
|
954 otherwise. |
|
955 */ |
|
956 IMPORT_C TInt StaticExtension(TInt aCmd, TAny* aArg); |
|
957 |
|
958 |
|
959 /** @deprecated |
|
960 @see DmacCaps() |
|
961 */ |
|
962 inline const TDmac* Controller() const; |
|
963 |
|
964 /** @deprecated |
|
965 @see MaxTransferLength() |
|
966 */ |
|
967 inline TInt MaxTransferSize(TUint aFlags, TUint32 aPslInfo); |
|
968 |
|
969 /** @deprecated |
|
970 @see AddressAlignMask() |
|
971 */ |
|
972 inline TUint MemAlignMask(TUint aFlags, TUint32 aPslInfo); |
|
973 |
|
974 protected: |
|
975 // Interface with state machines |
|
976 TDmaChannel(); |
|
977 |
|
978 /** Called by the PIL when adding a new request to the channel's queue. |
|
979 The implementation should update the channel's state as appropriate |
|
980 and begin transfer of aReq if possible. |
|
981 |
|
982 @param aReq The request which has been added to the queue |
|
983 */ |
|
984 virtual void DoQueue(const DDmaRequest& aReq); |
|
985 |
|
986 /** Called by the PIL in response to a CancelAll call. It should update |
|
987 the channel state appropriately. |
|
988 */ |
|
989 virtual void DoCancelAll() = 0; |
|
990 |
|
991 /** This is called by the PIL when a DDmaRequest is removed from the |
|
992 channel's queue. In general the implementation simply needs to unlink |
|
993 the hardware descriptor corresponding to aHdr from the next. |
|
994 |
|
995 Since the PIL links the hardware descriptor chains of adjacent queued |
|
996 requests (for speed) it is necessary to break the chain when a request |
|
997 is completed so that the request may be requeued by the client without |
|
998 having called DDmaRequest::Fragment again. |
|
999 |
|
1000 @param aHdr The header for a descriptor, which must be unlinked |
|
1001 from its next descriptor (if there is one) |
|
1002 */ |
|
1003 virtual void DoUnlink(SDmaDesHdr& aHdr); |
|
1004 |
|
1005 /** Called by the PIL whenever a transfer associated with aCurReq is |
|
1006 done. The implementation must advance the channel's state and |
|
1007 may transfer the next header if necessary (the provided |
|
1008 scatter-gather channel does not do this). It must also report |
|
1009 back which header was associated with the last transfer to |
|
1010 complete. |
|
1011 |
|
1012 @param aCurReq The current request. |
|
1013 @param aCompletedHdr Must be set by the implementation to the header |
|
1014 of the last transfer to complete. |
|
1015 */ |
|
1016 virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr); |
|
1017 |
|
1018 /** Called by the PIL whenever a transfer associated with aCurReq is |
|
1019 done. The implementation must advance the channel's state and |
|
1020 may start the transfer for the next headers if necessary (the |
|
1021 provided scatter-gather channels do not do this). If one |
|
1022 header has a successor but the other is the last in the chain it |
|
1023 is an error. |
|
1024 |
|
1025 @note Must be implemented by PSL if channel uses asymmetric hardware |
|
1026 descriptors and is not derived from TDmaAsymSgChannel. |
|
1027 |
|
1028 @param aCurReq The current request. |
|
1029 |
|
1030 @param aSrcCompletedHdr Must be set by the implementation to |
|
1031 the header of the last source descriptor to complete. |
|
1032 |
|
1033 @param aDstCompletedHdr Must be set by the implementation to |
|
1034 the header of the last destination descriptor to complete. |
|
1035 */ |
|
1036 virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr, |
|
1037 SDmaDesHdr*& aDstCompletedHdr); |
|
1038 |
|
1039 virtual ~TDmaChannel(); |
|
1040 |
|
1041 private: |
|
1042 static void Dfc(TAny*); |
|
1043 void DoDfc(); |
|
1044 inline void Wait(); |
|
1045 inline void Signal(); |
|
1046 inline void Flash(); |
|
1047 void ResetStateMachine(); |
|
1048 |
|
1049 protected: |
|
1050 TDmac* iController; // DMAC this channel belongs to (NULL when closed) |
|
1051 const SDmacCaps* iDmacCaps; // what is supported by DMAC on this channel |
|
1052 TUint32 iPslId; // unique identifier provided by PSL |
|
1053 TBool iDynChannel; // this is a dynamically allocated channel |
|
1054 TUint iPriority; // hardware priority of this channel |
|
1055 DMutex* iMutex; // for data accessed in both client & DFC context |
|
1056 SDmaDesHdr* iCurHdr; // fragment being transferred or NULL |
|
1057 SDmaDesHdr** iNullPtr; // Pointer to NULL pointer following last fragment |
|
1058 TDfc iDfc; // transfer completion/failure DFC |
|
1059 TInt iMaxDesCount; // maximum number of allocable descriptors |
|
1060 TInt iAvailDesCount; // available number of descriptors |
|
1061 volatile TUint32 iIsrDfc; // Interface between ISR and DFC: |
|
1062 enum {KErrorFlagMask = 0x80000000}; // bit 31 - error flag |
|
1063 enum {KCancelFlagMask = 0x40000000}; // bit 30 - cancel flag |
|
1064 enum {KDfcCountMask = 0x3FFFFFFF}; // bits 0-29 - number of queued DFCs |
|
1065 SDblQue iReqQ; // being/about to be transferred request queue |
|
1066 TInt iReqCount; // number of requests attached to this channel |
|
1067 private: |
|
1068 TDmaCancelInfo* iCancelInfo; // ... |
|
1069 TBool iRedoRequest; // client ISR callback wants a redo of request |
|
1070 TBool iIsrCbRequest; // request on queue using ISR callback |
|
1071 |
|
1072 __DMA_DECLARE_INVARIANT |
|
1073 }; |
|
1074 |
|
1075 |
|
1076 ////////////////////////////////////////////////////////////////////////////// |
|
1077 // INTERFACE WITH TEST HARNESS |
|
1078 ////////////////////////////////////////////////////////////////////////////// |
|
1079 |
|
1080 /** Set of information used by test harness. |
|
1081 |
|
1082 @publishedPartner |
|
1083 @released |
|
1084 */ |
|
1085 struct TDmaTestInfo |
|
1086 { |
|
1087 /** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/ |
|
1088 TUint iMaxTransferSize; |
|
1089 /** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */ |
|
1090 TUint iMemAlignMask; |
|
1091 /** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer*/ |
|
1092 TUint32 iMemMemPslInfo; |
|
1093 /** Number of test single-buffer channels */ |
|
1094 TInt iMaxSbChannels; |
|
1095 /** Pointer to array containing single-buffer test channel ids */ |
|
1096 TUint32* iSbChannels; |
|
1097 /** Number of test double-buffer channels */ |
|
1098 TInt iMaxDbChannels; |
|
1099 /** Pointer to array containing double-buffer test channel ids */ |
|
1100 TUint32* iDbChannels; |
|
1101 /** Number of test scatter-gather channels */ |
|
1102 TInt iMaxSgChannels; |
|
1103 /** Pointer to array containing scatter-gather test channel ids */ |
|
1104 TUint32* iSgChannels; |
|
1105 }; |
|
1106 |
|
1107 |
|
1108 /** Provides access to test information structure stored in the PSL. |
|
1109 |
|
1110 Must be implemented by the PSL. |
|
1111 |
|
1112 @publishedPartner |
|
1113 @released |
|
1114 */ |
|
1115 IMPORT_C const TDmaTestInfo& DmaTestInfo(); |
|
1116 |
|
1117 /** Provides access to test information structure stored in the PSL. |
|
1118 |
|
1119 Must be implemented by the PSL. |
|
1120 |
|
1121 @publishedPartner |
|
1122 @released |
|
1123 */ |
|
1124 IMPORT_C const TDmaV2TestInfo& DmaTestInfoV2(); |
|
1125 |
|
1126 |
|
1127 |
|
1128 ////////////////////////////////////////////////////////////////////////////// |
|
1129 |
|
1130 |
|
1131 #include <drivers/dma_compat.inl> |
|
1132 #include <drivers/dma_v2.inl> |
|
1133 |
|
1134 |
|
1135 #endif // #ifndef __DMA_V2_H__ |
|