1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/dma_v2.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1135 @@
1.4 +// Copyright (c) 2002-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 "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 +// include/drivers/dma_v2.h
1.18 +// DMA Framework - Client API v2 definition.
1.19 +//
1.20 +// NB: DMA clients should never include this file directly, but only ever the
1.21 +// generic header file <drivers/dma.h>.
1.22 +//
1.23 +
1.24 +#ifndef __DMA_H__
1.25 +#error "dma_v2.h must'n be included directly - use <drivers/dma.h> instead"
1.26 +#endif // #ifndef __DMA_H__
1.27 +
1.28 +#ifndef __DMA_V2_H__
1.29 +#define __DMA_V2_H__
1.30 +
1.31 +
1.32 +#include <kernel/kernel.h>
1.33 +#include <drivers/dmadefs.h>
1.34 +
1.35 +
1.36 +//////////////////////////////////////////////////////////////////////////////
1.37 +// Debug Support - KDmaPanicCat is defined in each source file
1.38 +
1.39 +#define __DMA_ASSERTD(e) __ASSERT_DEBUG(e, Kern::Fault(KDmaPanicCat, __LINE__))
1.40 +#define __DMA_ASSERTA(e) __ASSERT_ALWAYS(e, Kern::Fault(KDmaPanicCat, __LINE__))
1.41 +#ifdef _DEBUG
1.42 +#define __DMA_CANT_HAPPEN() Kern::Fault(KDmaPanicCat, __LINE__)
1.43 +#define __DMA_DECLARE_INVARIANT public: void Invariant();
1.44 +#define __DMA_INVARIANT() Invariant()
1.45 +#else
1.46 +#define __DMA_CANT_HAPPEN()
1.47 +#define __DMA_DECLARE_INVARIANT
1.48 +#define __DMA_INVARIANT()
1.49 +#endif
1.50 +
1.51 +
1.52 +//////////////////////////////////////////////////////////////////////////////
1.53 +// INTERFACE EXPOSED TO DEVICE-DRIVERS
1.54 +//////////////////////////////////////////////////////////////////////////////
1.55 +
1.56 +//////////////////////////////////////////////////////////////////////////////
1.57 +
1.58 +/** Bitmasks used for configuring a DMA request.
1.59 +
1.60 + In general, specify KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest)
1.61 + if the source (resp. destination) is a memory buffer and clear
1.62 + KDmaMemSrc|KDmaIncSrc (resp. KDmaMemDest|KDmaIncDest) if the source
1.63 + (resp. destination) is a peripheral.
1.64 +
1.65 + If the location is given as a physical address (rather than a linear one)
1.66 + then also specify KDmaPhysAddrSrc and/or KDmaPhysAddrDest.
1.67 +
1.68 + The EKA1 "Fill Mode" can be implemented by omitting KDmaIncSrc.
1.69 +
1.70 + Some peripherals may require a post-increment address mode.
1.71 +
1.72 + @see DDmaRequest::Fragment
1.73 + @publishedPartner
1.74 + @released
1.75 +*/
1.76 +enum TDmaRequestFlags
1.77 + {
1.78 + // Note: This enum is only required for backwards compatibility with the
1.79 + // old DMA framework, it can be removed once this is no longer needed.
1.80 +
1.81 + /** Source is address of memory buffer */
1.82 + KDmaMemSrc = 0x01,
1.83 + /** Destination is address of memory buffer */
1.84 + KDmaMemDest = 0x02,
1.85 + /** Source address must be post-incremented during transfer */
1.86 + KDmaIncSrc = 0x04,
1.87 + /** Destination address must be post-incremented during transfer */
1.88 + KDmaIncDest = 0x08,
1.89 + /** Source address is a physical address (as opposed to a linear one) */
1.90 + KDmaPhysAddrSrc = 0x10,
1.91 + /** Destination address is a physical address (as opposed to a linear one) */
1.92 + KDmaPhysAddrDest = 0x20,
1.93 + /** Request a different max transfer size (for instance for test purposes) */
1.94 + KDmaAltTransferLen = 0x40
1.95 + };
1.96 +
1.97 +
1.98 +/** Each hardware or pseudo descriptor is associated with a header. Headers
1.99 + are needed because hardware descriptors can not easily be extended to store
1.100 + additional information.
1.101 +
1.102 + @publishedPartner
1.103 + @released
1.104 +*/
1.105 +struct SDmaDesHdr
1.106 + {
1.107 + SDmaDesHdr* iNext;
1.108 + };
1.109 +
1.110 +/** Pointer to signature of the new extended callback function.
1.111 +
1.112 + TUint - bitmask of one or more TDmaCallbackType values
1.113 + TDmaResult - just that
1.114 + TAny* - was provided by client in DDmaRequest constructor
1.115 + SDmaDesHdr* - points to header (and thus descriptor) which caused a
1.116 + 'descriptor completed' or 'descriptor paused' event.
1.117 + */
1.118 +typedef void (*TDmaCallback)(TUint, TDmaResult, TAny*, SDmaDesHdr*);
1.119 +
1.120 +class TDmaChannel;
1.121 +
1.122 +/** A DMA request is a list of fragments small enough to be transferred in one go
1.123 + by the DMAC.
1.124 +
1.125 + In general, fragmentation is done in the framework by calling Fragment() but
1.126 + clients with special needs can allocate a blank descriptor list with
1.127 + ExpandDesList() and customise it to fit their needs.
1.128 +
1.129 + Clients should not set attributes directly, but should use the various functions
1.130 + instead.
1.131 +
1.132 + This class has not been designed to be called from several concurrent threads.
1.133 + Multithreaded clients must implement their own locking scheme (via DMutex).
1.134 +
1.135 + Mutexes are used internally to protect data structures accessed both by the
1.136 + client thread and the DFC thread. Therefore no fast mutex can be held when
1.137 + calling a request function.
1.138 +
1.139 + @publishedPartner
1.140 + @released
1.141 + */
1.142 +class DDmaRequest : public DBase
1.143 + {
1.144 + friend class TDmaChannel;
1.145 +
1.146 +public:
1.147 + /** The outcome of the transfer
1.148 +
1.149 + @deprecated
1.150 + @see TDmaResult
1.151 + */
1.152 + enum TResult {EBadResult=0, EOk, EError};
1.153 + /** The signature of the completion/failure callback function
1.154 +
1.155 + @deprecated
1.156 + @see TDmaCallback
1.157 + */
1.158 + typedef void (*TCallback)(TResult, TAny*);
1.159 +
1.160 +public:
1.161 + /** Constructor.
1.162 +
1.163 + Create a new transfer request.
1.164 +
1.165 + @param aChannel The channel this request is bound to.
1.166 + @param aCb Callback function called on transfer completion or failure
1.167 + (in channel DFC context). Can be NULL.
1.168 + @param aCbArg Argument passed to callback function.
1.169 + @param aMaxTransferSize Maximum fragment size. If not specified, defaults to the maximum size
1.170 + supported by the DMA controller for the type of transfer that is later scheduled.
1.171 +
1.172 + @deprecated
1.173 + */
1.174 + IMPORT_C DDmaRequest(TDmaChannel& aChannel, TCallback aCb=NULL, TAny* aCbArg=NULL,
1.175 + TInt aMaxTransferSize=0);
1.176 +
1.177 +
1.178 + /** Constructor.
1.179 +
1.180 + Create a new transfer request.
1.181 +
1.182 + @param aChannel The channel this request is bound to.
1.183 + @param aDmaCb Callback function called on transfer completion or
1.184 + failure (in channel DFC or ISR context). Can be NULL.
1.185 + @param aCbArg Argument passed to callback function.
1.186 + @param aMaxTransferSize Maximum fragment size. If not specified,
1.187 + defaults to the maximum size supported by the DMA controller for the
1.188 + type of transfer that is later scheduled.
1.189 + */
1.190 + IMPORT_C DDmaRequest(TDmaChannel& aChannel, TDmaCallback aDmaCb, TAny* aCbArg=NULL,
1.191 + TUint aMaxTransferSize=0);
1.192 +
1.193 +
1.194 + /** Destructor.
1.195 +
1.196 + Assume the request is not being transferred or pending.
1.197 + */
1.198 + IMPORT_C ~DDmaRequest();
1.199 +
1.200 +
1.201 + /** Split request into a list of fragments small enough to be fed to the
1.202 + DMAC.
1.203 +
1.204 + The size of each fragment is smaller than or equal to the maximum
1.205 + transfer size supported by the DMAC. If the source and/or destination
1.206 + is memory, each fragment points to memory which is physically
1.207 + contiguous.
1.208 +
1.209 + The kind of transfer to perform is specified via a set of flags used by
1.210 + a PIL and a magic cookie passed to the PSL. If the source
1.211 + (resp. destination) is a peripheral, aSrc (resp. aDest) is treated as a
1.212 + magic cookie by the PIL and passed straight to the PSL.
1.213 +
1.214 + The request can be uninitialised or may have been fragmented
1.215 + previously. The previous configuration if any is lost whether or not
1.216 + the function succeeds.
1.217 +
1.218 + @param aSrc Source memory buffer linear address or peripheral magic
1.219 + cookie.
1.220 + @param aDest Destination memory buffer linear address or peripheral
1.221 + magic cookie.
1.222 + @param aCount Number of bytes to transfer.
1.223 + @param aFlags Bitmask characterising the transfer.
1.224 + @param aPslInfo Hardware-specific information passed to PSL.
1.225 +
1.226 + @return KErrNone if success. KErrArgument if aFlags and/or aPslInfo are
1.227 + invalid when finding the maximum transfer size. May also fail if
1.228 + running out of descriptors.
1.229 +
1.230 + @pre The request is not being transferred or pending.
1.231 + @pre The various parameters must be valid. The PIL or PSL will fault the
1.232 + kernel if not.
1.233 +
1.234 + @see TDmaRequestFlags
1.235 +
1.236 + @deprecated
1.237 + */
1.238 + IMPORT_C TInt Fragment(TUint32 aSrc, TUint32 aDest, TInt aCount, TUint aFlags, TUint32 aPslInfo);
1.239 +
1.240 +
1.241 + /** New version of the DMA request fragment function, to be used with the
1.242 + TDmaTransferArgs structure.
1.243 + */
1.244 + IMPORT_C TInt Fragment(const TDmaTransferArgs& aTransferArgs);
1.245 +
1.246 +
1.247 + /** Transfer asynchronously this request.
1.248 +
1.249 + If this request's channel is idle, the request is transferred
1.250 + immediately. Otherwise, it is queued and transferred later.
1.251 +
1.252 + The client is responsible for ensuring cache consistency before and/or
1.253 + after the transfer if necessary.
1.254 +
1.255 + @return KErrNone if success, KErrGeneral otherwise.
1.256 + */
1.257 + IMPORT_C TInt Queue();
1.258 +
1.259 +
1.260 + /** Append new descriptor(s) to existing list.
1.261 +
1.262 + Clients needing to build a custom descriptor list should call this
1.263 + function to allocate the list and access the resulting list through
1.264 + iFirstHdr and iLastHdr.
1.265 +
1.266 + Clients should not change the value of iFirstHdr, iLastHdr and the
1.267 + iNext field of the descriptor headers to ensure descriptors can be
1.268 + deallocated. Clients are free to change hardware descriptors, including
1.269 + chaining, in whatever way suit them.
1.270 +
1.271 + Assume the request is not being transferred or pending.
1.272 +
1.273 + @param aCount Number of descriptors to append.
1.274 +
1.275 + @return KErrNone or standard error code.
1.276 + */
1.277 + IMPORT_C TInt ExpandDesList(TInt aCount=1);
1.278 +
1.279 +
1.280 + /** Append new descriptor(s) to existing list. This function variant
1.281 + operates on the source port descriptor chain.
1.282 +
1.283 + Works like ExpandDesList except that it uses the iSrcFirstHdr and
1.284 + iSrcLastHdr fields.
1.285 +
1.286 + @see ExpandDesList
1.287 +
1.288 + This function can only be used if SDmacCaps::iAsymHwDescriptors is
1.289 + true, otherwise it will just return KErrGeneral.
1.290 +
1.291 + @param aCount Number of descriptors to append.
1.292 +
1.293 + @return KErrNone or standard error code.
1.294 + */
1.295 + IMPORT_C TInt ExpandSrcDesList(TInt aCount=1);
1.296 +
1.297 +
1.298 + /** Append new descriptor(s) to existing list. This function variant
1.299 + operates on the destination port descriptor chain.
1.300 +
1.301 + Works like ExpandDesList except that it uses the iDstFirstHdr and
1.302 + iDstLastHdr fields.
1.303 +
1.304 + @see ExpandDesList
1.305 +
1.306 + This function can only be used if SDmacCaps::iAsymHwDescriptors is
1.307 + true, otherwise it will just return KErrGeneral.
1.308 +
1.309 + @param aCount Number of descriptors to append.
1.310 +
1.311 + @return KErrNone or standard error code.
1.312 + */
1.313 + IMPORT_C TInt ExpandDstDesList(TInt aCount=1);
1.314 +
1.315 +
1.316 + /** Free resources associated with this request.
1.317 +
1.318 + Assume the request is not being transferred or pending.
1.319 + */
1.320 + IMPORT_C void FreeDesList();
1.321 +
1.322 +
1.323 + /** Free resources associated with this request. This function variant
1.324 + operates on the source port descriptor chain.
1.325 +
1.326 + @see FreeDesList
1.327 +
1.328 + This function can only be used if SDmacCaps::iAsymHwDescriptors is
1.329 + true, otherwise it will do nothing.
1.330 + */
1.331 + IMPORT_C void FreeSrcDesList();
1.332 +
1.333 +
1.334 + /** Free resources associated with this request. This function variant
1.335 + operates on the destination port descriptor chain.
1.336 +
1.337 + @see FreeDesList
1.338 +
1.339 + This function can only be used if SDmacCaps::iAsymHwDescriptors is
1.340 + true, otherwise it will do nothing.
1.341 + */
1.342 + IMPORT_C void FreeDstDesList();
1.343 +
1.344 +
1.345 + /** Enables the functionality for counting the transferred source
1.346 + elements.
1.347 +
1.348 + This function can be called at any time, but the enabled/disabled
1.349 + status is checked by the framework only at two points in time.
1.350 +
1.351 + The first one is after a request has been queued, and if it is enabled
1.352 + then the counting will commence as soon as the transfer starts.
1.353 +
1.354 + The second point is when Resume() is called for a paused transfer, and
1.355 + in this case the following applies. If counting was enabled when the
1.356 + transfer was paused and it is now disabled then the counting is stopped
1.357 + at that point and the count value frozen. If counting was disabled when
1.358 + the transfer was paused and it is now enabled then the counting will
1.359 + commence when the transfer resumes. (The starting value will depend on
1.360 + the argument of the enable function.) Otherwise nothing will change,
1.361 + i.e. counting will either continue normally (enabled/enabled) or
1.362 + neither stop nor continue (disabled/disabled).
1.363 +
1.364 + Once a status has been set, it remains valid for the entire duration of
1.365 + the transfer (and beyond, if it is not changed again).
1.366 +
1.367 + @param aResetElementCount If ETrue (the default) then the count
1.368 + variable will be reset to zero, otherwise it will retain its current
1.369 + value.
1.370 +
1.371 + @see Queue()
1.372 + @see TotalNumSrcElementsTransferred()
1.373 + */
1.374 + IMPORT_C void EnableSrcElementCounting(TBool aResetElementCount=ETrue);
1.375 +
1.376 +
1.377 + /** Enables the functionality for counting the transferred destination
1.378 + elements.
1.379 +
1.380 + This function can be called at any time, but the enabled/disabled
1.381 + status is checked by the framework only at two points in time.
1.382 +
1.383 + The first one is after a request has been queued, and if it is enabled
1.384 + then the counting will commence as soon as the transfer starts.
1.385 +
1.386 + The second point is when Resume() is called for a paused transfer, and
1.387 + in this case the following applies. If counting was enabled when the
1.388 + transfer was paused and it is now disabled then the counting is stopped
1.389 + at that point and the count value frozen. If counting was disabled when
1.390 + the transfer was paused and it is now enabled then the counting will
1.391 + commence when the transfer resumes. (The starting value will depend on
1.392 + the argument of the enable function.) Otherwise nothing will change,
1.393 + i.e. counting will either continue normally (enabled/enabled) or
1.394 + neither stop nor continue (disabled/disabled).
1.395 +
1.396 + Once a status has been set, it remains valid for the entire duration of
1.397 + the transfer (and beyond, if it is not changed again).
1.398 +
1.399 + @param aResetElementCount If ETrue (the default) then the count
1.400 + variable will be reset to zero, otherwise it will retain its current
1.401 + value.
1.402 +
1.403 + @see Queue()
1.404 + @see TotalNumDstElementsTransferred()
1.405 + */
1.406 + IMPORT_C void EnableDstElementCounting(TBool aResetElementCount=ETrue);
1.407 +
1.408 +
1.409 + /** Disables the functionality for counting the transferred source
1.410 + elements.
1.411 +
1.412 + This function can be called at any time, but the enabled/disabled
1.413 + status is checked by the framework only at two points in time.
1.414 +
1.415 + The first one is after a request has been queued, and if it is enabled
1.416 + then the counting will commence as soon as the transfer starts.
1.417 +
1.418 + The second point is when Resume() is called for a paused transfer, and
1.419 + in this case the following applies. If counting was enabled when the
1.420 + transfer was paused and it is now disabled then the counting is stopped
1.421 + at that point and the count value frozen. If counting was disabled when
1.422 + the transfer was paused and it is now enabled then the counting will
1.423 + commence when the transfer resumes. (The starting value will depend on
1.424 + the argument of the enable function.) Otherwise nothing will change,
1.425 + i.e. counting will either continue normally (enabled/enabled) or
1.426 + neither stop nor continue (disabled/disabled).
1.427 +
1.428 + Once a status has been set, it remains valid for the entire duration of
1.429 + the transfer (and beyond, if it is not changed again).
1.430 +
1.431 + @see Queue()
1.432 + @see TotalNumSrcElementsTransferred()
1.433 + */
1.434 + IMPORT_C void DisableSrcElementCounting();
1.435 +
1.436 +
1.437 + /** Disables the functionality for counting the transferred destination
1.438 + elements.
1.439 +
1.440 + This function can be called at any time, but the enabled/disabled
1.441 + status is checked by the framework only at two points in time.
1.442 +
1.443 + The first one is after a request has been queued, and if it is enabled
1.444 + then the counting will commence as soon as the transfer starts.
1.445 +
1.446 + The second point is when Resume() is called for a paused transfer, and
1.447 + in this case the following applies. If counting was enabled when the
1.448 + transfer was paused and it is now disabled then the counting is stopped
1.449 + at that point and the count value frozen. If counting was disabled when
1.450 + the transfer was paused and it is now enabled then the counting will
1.451 + commence when the transfer resumes. (The starting value will depend on
1.452 + the argument of the enable function.) Otherwise nothing will change,
1.453 + i.e. counting will either continue normally (enabled/enabled) or
1.454 + neither stop nor continue (disabled/disabled).
1.455 +
1.456 + Once a status has been set, it remains valid for the entire duration of
1.457 + the transfer (and beyond, if it is not changed again).
1.458 +
1.459 + @see Queue()
1.460 + @see TotalNumDstElementsTransferred()
1.461 + */
1.462 + IMPORT_C void DisableDstElementCounting();
1.463 +
1.464 +
1.465 + /** Returns the number of elements that have been transferred by this
1.466 + transfer request at the source port.
1.467 +
1.468 + To use this method, the counting functionality has to be explicitly
1.469 + enabled, either before the transfer request is queued or while it is
1.470 + paused.
1.471 +
1.472 + @see EnableSrcElementCounting()
1.473 + @see DisableSrcElementCounting()
1.474 +
1.475 + This function should only be called after the transfer has finished
1.476 + (completed with or without error, or because it was cancelled) or while
1.477 + it is paused. Otherwise it may just return 0.
1.478 +
1.479 + @return The number of elements that have been transferred by this
1.480 + transfer request at the source port.
1.481 + */
1.482 + IMPORT_C TUint32 TotalNumSrcElementsTransferred();
1.483 +
1.484 +
1.485 + /** Returns the number of elements that have been transferred by this
1.486 + transfer request at the destination port.
1.487 +
1.488 + To use this method, the counting functionality has to be explicitly
1.489 + enabled, either before the transfer request is queued or while it is
1.490 + paused.
1.491 +
1.492 + @see EnableDstElementCounting()
1.493 + @see DisableDstElementCounting()
1.494 +
1.495 + This function should only be called after the transfer has finished
1.496 + (completed with or without error, or because it was cancelled) or while
1.497 + it is paused. Otherwise it may just return 0.
1.498 +
1.499 + @return The number of elements that have been transferred by this
1.500 + transfer request at the destination port.
1.501 + */
1.502 + IMPORT_C TUint32 TotalNumDstElementsTransferred();
1.503 +
1.504 +
1.505 + /** Returns the number of fragments that this transfer request has been
1.506 + split into.
1.507 +
1.508 + This number will only be different from 0 once Fragment() has been
1.509 + called or after descriptors have been manually allocated by the client
1.510 + using ExpandDesList().
1.511 +
1.512 + If SDmacCaps::iAsymHwDescriptors is true then this function will always
1.513 + return 0, and SrcFragmentCount() / DstFragmentCount() should be used
1.514 + instead.
1.515 +
1.516 + @return The number of fragments (descriptors / pseudo descriptors) that
1.517 + this transfer request has been split into.
1.518 + */
1.519 + IMPORT_C TInt FragmentCount();
1.520 +
1.521 + /** Returns the number of source port fragments that this transfer request
1.522 + has been split into.
1.523 +
1.524 + This number will only be different from 0 once Fragment() has been
1.525 + called or after descriptors have been manually allocated by the client
1.526 + using ExpandSrcDesList().
1.527 +
1.528 + This function can only be used if SDmacCaps::iAsymHwDescriptors is
1.529 + true, otherwise it will always return 0.
1.530 +
1.531 + @return The number of source port fragments (descriptors) that this
1.532 + transfer request has been split into.
1.533 + */
1.534 + IMPORT_C TInt SrcFragmentCount();
1.535 +
1.536 +
1.537 + /** Returns the number of destination port fragments that this transfer
1.538 + request has been split into.
1.539 +
1.540 + This number will only be different from 0 once Fragment() has been
1.541 + called or after descriptors have been manually allocated by the client
1.542 + using ExpandDstDesList().
1.543 +
1.544 + This function can only be used if SDmacCaps::iAsymHwDescriptors is
1.545 + true, otherwise it will always return 0.
1.546 +
1.547 + @return The number of destination port fragments (descriptors) that
1.548 + this transfer request has been split into.
1.549 + */
1.550 + IMPORT_C TInt DstFragmentCount();
1.551 +
1.552 +private:
1.553 + inline void OnDeque();
1.554 + TUint GetTransferCount(const TDmaTransferArgs& aTransferArgs);
1.555 + TInt Frag(TDmaTransferArgs& aTransferArgs);
1.556 + TInt FragSym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
1.557 + TInt FragAsym(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
1.558 + TInt FragAsymSrc(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
1.559 + TInt FragAsymDst(TDmaTransferArgs& aTransferArgs, TUint aCount, TUint aMaxTransferLen);
1.560 + TInt ExpandDesList(TInt aCount, TInt& aDesCount, SDmaDesHdr*& aFirstHdr,
1.561 + SDmaDesHdr*& aLastHdr);
1.562 + void FreeDesList(TInt& aDesCount, SDmaDesHdr*& aFirstHdr, SDmaDesHdr*& aLastHdr);
1.563 + TInt FragmentCount(const SDmaDesHdr* aHdr);
1.564 +
1.565 +public:
1.566 + // WARNING: The following attributes are accessed both in client and DFC
1.567 + // context and so accesses must be protected with the channel lock.
1.568 + TDmaChannel& iChannel; /**< The channel this request is bound to */
1.569 + TCallback iCb; /**< Called on completion/failure (can be NULL) */
1.570 + TAny* iCbArg; /**< Callback argument */
1.571 + TDmaCallback iDmaCb; // the new-style callback function
1.572 + TAny* iDmaCbArg; // the new-style callback arg
1.573 + TBool iIsrCb; // client wants callback in ISR context
1.574 + TInt iDesCount; /**< The number of fragments in list */
1.575 + SDmaDesHdr* iFirstHdr; /**< The first fragment in the list (or NULL) */
1.576 + SDmaDesHdr* iLastHdr; /**< The last fragment in the list (or NULL) */
1.577 + TInt iSrcDesCount; /**< The number of fragments in list */
1.578 + SDmaDesHdr* iSrcFirstHdr; /**< The first fragment in the list (or NULL) */
1.579 + SDmaDesHdr* iSrcLastHdr; /**< The last fragment in the list (or NULL) */
1.580 + TInt iDstDesCount; /**< The number of fragments in list */
1.581 + SDmaDesHdr* iDstFirstHdr; /**< The first fragment in the list (or NULL) */
1.582 + SDmaDesHdr* iDstLastHdr; /**< The last fragment in the list (or NULL) */
1.583 + SDblQueLink iLink; /**< The link on channel queue of pending requests */
1.584 + TBool iQueued; /**< Indicates whether request is pending or being transferred */
1.585 + TUint iMaxTransferSize; /**< Defaults to DMA controller max. transfer size */
1.586 +
1.587 + TUint32 iTotalNumSrcElementsTransferred;
1.588 + TUint32 iTotalNumDstElementsTransferred;
1.589 +
1.590 + __DMA_DECLARE_INVARIANT
1.591 + };
1.592 +
1.593 +
1.594 +//////////////////////////////////////////////////////////////////////////////
1.595 +
1.596 +class TDmac;
1.597 +class DmaChannelMgr;
1.598 +class TDmaCancelInfo;
1.599 +
1.600 +/** DMA channel base class.
1.601 +
1.602 + Standard derived classes are provided for this channel (see
1.603 + TDmaSbChannel, TDmaDbChannel, TDmaSgChannel, and TDmaAsymSgChannel).
1.604 + The base-port implementor will only need to write their own derived
1.605 + class if one of the standard classes is unsuitable.
1.606 +
1.607 + This class has not been designed to be called from several concurrent
1.608 + client threads. Multithreaded clients must implement their own locking
1.609 + scheme (via DMutex).
1.610 +
1.611 + Mutexes are used internally to protect data structures accessed both by the
1.612 + client thread and the DFC one. Therefore no fast mutex can be held when
1.613 + calling a channel function.
1.614 +
1.615 + @publishedPartner
1.616 + @released
1.617 + */
1.618 +class TDmaChannel
1.619 + {
1.620 + friend class DDmaRequest;
1.621 + friend class TDmac;
1.622 + friend class DmaChannelMgr;
1.623 +public:
1.624 +
1.625 + /** Information passed by client when opening a channel */
1.626 + struct SCreateInfo
1.627 + {
1.628 + /** Default constructor. Initializes all fields with meaningful default
1.629 + values.
1.630 +
1.631 + Must be inline (for now) because exporting it would break existing
1.632 + custom DMA libs as their clients would need the export which would
1.633 + be missing from the custom .def files.
1.634 + */
1.635 + SCreateInfo() : iPriority(KDmaPriorityNone), iDynChannel(EFalse) {};
1.636 +
1.637 + /** Identifier used by PSL to select channel to open */
1.638 + TUint32 iCookie;
1.639 + /** Number of descriptors this channel can use.
1.640 +
1.641 + This number is not used in the upgraded version of the DMA
1.642 + framework and is kept there only for source compatibility. If the
1.643 + client is certain that it will only ever use that version, then the
1.644 + value passed here doesn't matter - the framework will ignore it.
1.645 +
1.646 + @deprecated
1.647 + */
1.648 + TInt iDesCount;
1.649 + /** DFC queue used to service DMA interrupts.
1.650 +
1.651 + The DFC thread priority must be higher than any client thread
1.652 + priority to avoid a situation where a transfer completes while
1.653 + being cancelled and another transfer is started before the DFC
1.654 + thread gets a chance to run. This would lead to a stray DFC.
1.655 + */
1.656 + TDfcQue* iDfcQ;
1.657 + /** DFC priority */
1.658 + TUint8 iDfcPriority;
1.659 + /** Used by PSL to configure a channel priority (if possible).
1.660 +
1.661 + The default is KDmaPriorityNone (the don't care value).
1.662 +
1.663 + @see TDmaPriority
1.664 + */
1.665 + TUint iPriority;
1.666 + /** Request a dynamic DMA channel.
1.667 +
1.668 + If this is set to ETrue then the Open call is for a 'dynamic' as
1.669 + opposed to a static and solely owned DMA channel. A number of
1.670 + properties of the opened TDmaChannel object will be different in
1.671 + that case.
1.672 +
1.673 + The default value is EFalse.
1.674 + */
1.675 + TBool iDynChannel;
1.676 + };
1.677 +
1.678 +public:
1.679 + /** Opens the DMA channel.
1.680 +
1.681 + Channel selection is done by the hardware-specific layer using a cookie
1.682 + passed in via aInfo.
1.683 +
1.684 + The client should not delete the returned pointer as the framework owns
1.685 + channel objects. However, the client should explicitly close the
1.686 + channel when finished with it.
1.687 +
1.688 + @param aInfo Information passed by caller to select and configure
1.689 + channel.
1.690 +
1.691 + @param aChannel Points to open channel on successful return. NULL
1.692 + otherwise.
1.693 +
1.694 + @return KErrNone or standard error code.
1.695 + */
1.696 + IMPORT_C static TInt Open(const SCreateInfo& aInfo, TDmaChannel*& aChannel);
1.697 +
1.698 +
1.699 + /** Closes a previously opened DMA channel.
1.700 +
1.701 + Assumes the channel is idle and all requests have been deleted.
1.702 +
1.703 + The call will cause the resources associated with this channel to be
1.704 + released, and the pointer/reference to it mustn't therefore be accessed
1.705 + any longer after the function has returned. The channel pointer should
1.706 + be set to NULL by the client.
1.707 + */
1.708 + IMPORT_C void Close();
1.709 +
1.710 +
1.711 + /** Logically links this channel to the one specified as an argument, or,
1.712 + if the argument is NULL, unlinks this channel.
1.713 +
1.714 + The effect of channel linking is that once a transfer on this channel
1.715 + has finished, instead of causing the associated client callback to be
1.716 + called, 'aChannel' will be enabled by hardware and a preconfigured
1.717 + transfer on that channel will start.
1.718 +
1.719 + Note that conceptually 'linking' here always refers to the end of a
1.720 + channel transfer, not the beginning, i.e. a channel can only be linked
1.721 + once and always to a successor, never twice or to a predecessor. (This
1.722 + does not preclude the possibility that two channels are linked in a
1.723 + circular fashion.)
1.724 +
1.725 + This function can only be used if the DMAC supports logical channel
1.726 + linking.
1.727 +
1.728 + @see SDmacCaps::iChannelLinking
1.729 +
1.730 + @param aChannel Points to the channel this one should be linked to, or
1.731 + NULL if this channel is to be unlinked from any other one.
1.732 +
1.733 + @return KErrNone if the channel has been linked or unlinked
1.734 + successfully, KErrCompletion if this channel was already linked to
1.735 + aChannel or already unlinked, KErrNotSupported if the DMAC doesn't
1.736 + support channel linking, KErrArgument if this channel was already
1.737 + linked to a different channel, KErrGeneral if a general error occurred
1.738 + preventing a successful outcome.
1.739 + */
1.740 + IMPORT_C TInt LinkToChannel(TDmaChannel* aChannel);
1.741 +
1.742 + /** Pauses an active transfer on this channel.
1.743 +
1.744 + A paused channel transfer can be resumed by calling Resume() or it can
1.745 + be stopped altogether by calling CancelAll().
1.746 +
1.747 + @see TDmaChannel::Resume()
1.748 +
1.749 + Function can only be used if the DMAC supports this functionality.
1.750 +
1.751 + @see SDmacCaps::iChannelPauseAndResume
1.752 +
1.753 + @return KErrNone if a transfer has been paused successfully,
1.754 + KErrCompletion if a transfer was already paused, KErrNotSupported if
1.755 + the DMAC doesn't support channel transfer pausing/resuming, KErrGeneral
1.756 + if a general error occurred preventing a successful outcome.
1.757 + */
1.758 + IMPORT_C TInt Pause();
1.759 +
1.760 +
1.761 + /** Resumes a transfer on this channel that is paused.
1.762 +
1.763 + Resume() can be called to resume channel operation when the transfer is
1.764 + paused as a result of a previous call to Pause() or because the DMAC
1.765 + has encountered a Pause bit in a H/W descriptor.
1.766 +
1.767 + @see TDmaChannel::Pause()
1.768 + @see TDmaCallbackType::EDmaCallbackLinkedListPaused
1.769 +
1.770 + Function can only be used if the DMAC supports this functionality.
1.771 +
1.772 + @see SDmacCaps::iChannelPauseAndResume
1.773 +
1.774 + @return KErrNone if a paused transfer has been resumed successfully,
1.775 + KErrCompletion if there was no paused transfer, KErrNotSupported if the
1.776 + DMAC doesn't support channel transfer pausing/resuming, KErrGeneral if
1.777 + a general error occurred preventing a successful outcome.
1.778 + */
1.779 + IMPORT_C TInt Resume();
1.780 +
1.781 +
1.782 + /** Cancels the current request and all the pending ones.
1.783 + */
1.784 + IMPORT_C void CancelAll();
1.785 +
1.786 +
1.787 + /** Returns the channel's maximum transfer length based on the passed
1.788 + arguments.
1.789 +
1.790 + @param aSrcFlags Bitmask characterising transfer source
1.791 + @see TDmaTransferArgs::iSrcConfig::iFlags
1.792 +
1.793 + @param aDstFlags Bitmask characterising transfer destination
1.794 + @see TDmaTransferArgs::iDstConfig::iFlags
1.795 +
1.796 + @param aPslInfo Cookie passed to the PSL
1.797 + @see TDmaTransferArgs::iPslRequestInfo
1.798 +
1.799 + @return 0 if transfer length is not limited, the maximum transfer
1.800 + length in bytes otherwise.
1.801 + */
1.802 + IMPORT_C TUint MaxTransferLength(TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo);
1.803 +
1.804 +
1.805 + /** Retrieves from the PSL the address / memory alignment mask based on the
1.806 + parameters passed. Some DMA controllers impose alignment constraints on
1.807 + the base address of memory buffers. This mask is AND'ed against memory
1.808 + addresses computed during fragmentation.
1.809 +
1.810 + This function needs to be called separately for source and destination.
1.811 +
1.812 + @param aTargetFlags Bitmask characterising transfer source or
1.813 + destination
1.814 + @see TDmaTransferArgs::iSrcConfig::iFlags
1.815 + @see TDmaTransferArgs::iDstConfig::iFlags
1.816 +
1.817 + @param aElementSize Element size used for the transfer. Can be zero if
1.818 + not known or 'don't care'.
1.819 +
1.820 + @param aPslInfo Cookie passed to the PSL
1.821 + @see TDmaTransferArgs::iPslRequestInfo
1.822 +
1.823 + @return A value representing the alignment mask (e.g. 3 if buffer must
1.824 + be 4-byte aligned)
1.825 + */
1.826 + IMPORT_C TUint AddressAlignMask(TUint aTargetFlags, TUint aElementSize,
1.827 + TUint32 aPslInfo);
1.828 +
1.829 +
1.830 + /** Returns a reference to a structure containing the capabilities and
1.831 + features of the DMA controller associated with this channel.
1.832 +
1.833 + @return A reference to a structure containing the capabilities and
1.834 + features of the DMA controller associated with this channel.
1.835 + */
1.836 + IMPORT_C const SDmacCaps& DmacCaps();
1.837 +
1.838 +
1.839 + /** Sets up once more the transfer request that has just completed, after
1.840 + optionally having adjusted the transfer parameters as specified.
1.841 +
1.842 + This function is meant to be called exclusively from a client-supplied
1.843 + callback that is executed in ISR context, and only in response to a
1.844 + transfer completion notification.
1.845 +
1.846 + If this call returns to the caller with KErrNone then the framework's
1.847 + ISR handler will subsequently not queue the channel DFC for this
1.848 + completed request.
1.849 +
1.850 + The parameters specify which changes the framework should apply to the
1.851 + descriptors of the transfer request before rescheduling it. Arguments
1.852 + for which no change is required should be passed as their default
1.853 + values. The parameters correspond to those in the TDmaTransferArgs
1.854 + struct as follows.
1.855 +
1.856 + @param aSrcAddr @see TDmaTransferArgs::iSrcConfig::iAddr
1.857 + @param aDstAddr @see TDmaTransferArgs::iDstConfig::iAddr
1.858 + @param aTransferCount @see TDmaTransferArgs::iTransferCount
1.859 + @param aPslRequestInfo @see TDmaTransferArgs::iPslRequestInfo
1.860 + @param aIsrCb If set to ETrue (the default) then the callback of the
1.861 + rescheduled request will again be called in ISR context
1.862 +
1.863 + Since Epoc::LinearToPhysical() cannot be called in ISR context the
1.864 + addresses passed into this function must be physical ones, i.e.
1.865 + TDmaTransferFlags::KDmaPhysAddr is implied.
1.866 +
1.867 + If an address refers to a memory target then
1.868 + TDmaTransferFlags::KDmaMemIsContiguous is implied as well as no
1.869 + fragmentation is possible at this point.
1.870 +
1.871 + @pre Must only be called from a 'transfer complete' client callback in
1.872 + ISR context.
1.873 +
1.874 + @post Framework won't queue the channel DFC for the completed request
1.875 + in success case.
1.876 +
1.877 + @see DDmaRequest::DDmaRequest(TDmaChannel&, TDmaCallback, TAny*, TUint)
1.878 + @see TDmaCallbackType::EDmaCallbackRequestCompletion
1.879 + @see TDmaPILFlags::KDmaRequestCallbackFromIsr
1.880 +
1.881 + @return KErrGeneral if there was an error, KErrNone otherwise.
1.882 + */
1.883 + IMPORT_C TInt IsrRedoRequest(TUint32 aSrcAddr=KPhysAddrInvalid,
1.884 + TUint32 aDstAddr=KPhysAddrInvalid,
1.885 + TUint aTransferCount=0,
1.886 + TUint32 aPslRequestInfo=0,
1.887 + TBool aIsrCb=ETrue);
1.888 +
1.889 +
1.890 + /** Tests whether the channel is currently opened.
1.891 +
1.892 + @return ETrue if channel is currently opened, EFalse otherwise.
1.893 +
1.894 + NB: This API should not be used any longer.
1.895 +
1.896 + After calling TDmaChannel::Open() successfully the channel is
1.897 + guaranteed to be open. Therefore there seems no good reason for this
1.898 + API to exist.
1.899 +
1.900 + @deprecated
1.901 + */
1.902 + inline TBool IsOpened() const;
1.903 +
1.904 +
1.905 + /** Tests whether the channel's request queue is currently empty.
1.906 +
1.907 + @return ETrue if request queue is currently empty, EFalse otherwise.
1.908 + */
1.909 + inline TBool IsQueueEmpty() const;
1.910 +
1.911 +
1.912 + /** Returns a PSL-specific value which uniquely identifies this channel -
1.913 + it is used for debug tracing by the PIL.
1.914 +
1.915 + @return PSL-specific value which uniquely identifies this channel.
1.916 + */
1.917 + inline TUint32 PslId() const;
1.918 +
1.919 +
1.920 + /** Called by a test harness to force an error when the next fragment is
1.921 + transferred.
1.922 +
1.923 + @param aFragmentCount The number of consecutive fragments to fail
1.924 + */
1.925 + IMPORT_C TInt FailNext(TInt aFragmentCount);
1.926 +
1.927 +
1.928 + /** Called by a test harness to force the DMA controller to miss one or
1.929 + more interrupts.
1.930 +
1.931 + @param aInterruptCount The number of consecutive interrupts to miss
1.932 + */
1.933 + IMPORT_C TInt MissNextInterrupts(TInt aInterruptCount);
1.934 +
1.935 +
1.936 + /** Function allowing platform-specific layer to extend channel API with
1.937 + new channel-specific operations.
1.938 +
1.939 + @param aCmd Command identifier. Negative values are reserved for use by
1.940 + Nokia.
1.941 + @param aArg PSL-specific argument
1.942 +
1.943 + @return KErrNotSupported if aCmd is not supported. PSL-specific value
1.944 + otherwise.
1.945 + */
1.946 + IMPORT_C TInt Extension(TInt aCmd, TAny* aArg);
1.947 +
1.948 +
1.949 + /** This is a function that allows the Platform Specific Layer (PSL) to
1.950 + extend the DMA API with new channel-independent operations.
1.951 +
1.952 + @param aCmd Command identifier. Negative values are reserved for
1.953 + Symbian use.
1.954 + @param aArg PSL-specific.
1.955 +
1.956 + @return KErrNotSupported if aCmd is not supported; a PSL specific value
1.957 + otherwise.
1.958 + */
1.959 + IMPORT_C TInt StaticExtension(TInt aCmd, TAny* aArg);
1.960 +
1.961 +
1.962 + /** @deprecated
1.963 + @see DmacCaps()
1.964 + */
1.965 + inline const TDmac* Controller() const;
1.966 +
1.967 + /** @deprecated
1.968 + @see MaxTransferLength()
1.969 + */
1.970 + inline TInt MaxTransferSize(TUint aFlags, TUint32 aPslInfo);
1.971 +
1.972 + /** @deprecated
1.973 + @see AddressAlignMask()
1.974 + */
1.975 + inline TUint MemAlignMask(TUint aFlags, TUint32 aPslInfo);
1.976 +
1.977 +protected:
1.978 + // Interface with state machines
1.979 + TDmaChannel();
1.980 +
1.981 + /** Called by the PIL when adding a new request to the channel's queue.
1.982 + The implementation should update the channel's state as appropriate
1.983 + and begin transfer of aReq if possible.
1.984 +
1.985 + @param aReq The request which has been added to the queue
1.986 + */
1.987 + virtual void DoQueue(const DDmaRequest& aReq);
1.988 +
1.989 + /** Called by the PIL in response to a CancelAll call. It should update
1.990 + the channel state appropriately.
1.991 + */
1.992 + virtual void DoCancelAll() = 0;
1.993 +
1.994 + /** This is called by the PIL when a DDmaRequest is removed from the
1.995 + channel's queue. In general the implementation simply needs to unlink
1.996 + the hardware descriptor corresponding to aHdr from the next.
1.997 +
1.998 + Since the PIL links the hardware descriptor chains of adjacent queued
1.999 + requests (for speed) it is necessary to break the chain when a request
1.1000 + is completed so that the request may be requeued by the client without
1.1001 + having called DDmaRequest::Fragment again.
1.1002 +
1.1003 + @param aHdr The header for a descriptor, which must be unlinked
1.1004 + from its next descriptor (if there is one)
1.1005 + */
1.1006 + virtual void DoUnlink(SDmaDesHdr& aHdr);
1.1007 +
1.1008 + /** Called by the PIL whenever a transfer associated with aCurReq is
1.1009 + done. The implementation must advance the channel's state and
1.1010 + may transfer the next header if necessary (the provided
1.1011 + scatter-gather channel does not do this). It must also report
1.1012 + back which header was associated with the last transfer to
1.1013 + complete.
1.1014 +
1.1015 + @param aCurReq The current request.
1.1016 + @param aCompletedHdr Must be set by the implementation to the header
1.1017 + of the last transfer to complete.
1.1018 + */
1.1019 + virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr);
1.1020 +
1.1021 + /** Called by the PIL whenever a transfer associated with aCurReq is
1.1022 + done. The implementation must advance the channel's state and
1.1023 + may start the transfer for the next headers if necessary (the
1.1024 + provided scatter-gather channels do not do this). If one
1.1025 + header has a successor but the other is the last in the chain it
1.1026 + is an error.
1.1027 +
1.1028 + @note Must be implemented by PSL if channel uses asymmetric hardware
1.1029 + descriptors and is not derived from TDmaAsymSgChannel.
1.1030 +
1.1031 + @param aCurReq The current request.
1.1032 +
1.1033 + @param aSrcCompletedHdr Must be set by the implementation to
1.1034 + the header of the last source descriptor to complete.
1.1035 +
1.1036 + @param aDstCompletedHdr Must be set by the implementation to
1.1037 + the header of the last destination descriptor to complete.
1.1038 + */
1.1039 + virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
1.1040 + SDmaDesHdr*& aDstCompletedHdr);
1.1041 +
1.1042 + virtual ~TDmaChannel();
1.1043 +
1.1044 +private:
1.1045 + static void Dfc(TAny*);
1.1046 + void DoDfc();
1.1047 + inline void Wait();
1.1048 + inline void Signal();
1.1049 + inline void Flash();
1.1050 + void ResetStateMachine();
1.1051 +
1.1052 +protected:
1.1053 + TDmac* iController; // DMAC this channel belongs to (NULL when closed)
1.1054 + const SDmacCaps* iDmacCaps; // what is supported by DMAC on this channel
1.1055 + TUint32 iPslId; // unique identifier provided by PSL
1.1056 + TBool iDynChannel; // this is a dynamically allocated channel
1.1057 + TUint iPriority; // hardware priority of this channel
1.1058 + DMutex* iMutex; // for data accessed in both client & DFC context
1.1059 + SDmaDesHdr* iCurHdr; // fragment being transferred or NULL
1.1060 + SDmaDesHdr** iNullPtr; // Pointer to NULL pointer following last fragment
1.1061 + TDfc iDfc; // transfer completion/failure DFC
1.1062 + TInt iMaxDesCount; // maximum number of allocable descriptors
1.1063 + TInt iAvailDesCount; // available number of descriptors
1.1064 + volatile TUint32 iIsrDfc; // Interface between ISR and DFC:
1.1065 + enum {KErrorFlagMask = 0x80000000}; // bit 31 - error flag
1.1066 + enum {KCancelFlagMask = 0x40000000}; // bit 30 - cancel flag
1.1067 + enum {KDfcCountMask = 0x3FFFFFFF}; // bits 0-29 - number of queued DFCs
1.1068 + SDblQue iReqQ; // being/about to be transferred request queue
1.1069 + TInt iReqCount; // number of requests attached to this channel
1.1070 +private:
1.1071 + TDmaCancelInfo* iCancelInfo; // ...
1.1072 + TBool iRedoRequest; // client ISR callback wants a redo of request
1.1073 + TBool iIsrCbRequest; // request on queue using ISR callback
1.1074 +
1.1075 + __DMA_DECLARE_INVARIANT
1.1076 + };
1.1077 +
1.1078 +
1.1079 +//////////////////////////////////////////////////////////////////////////////
1.1080 +// INTERFACE WITH TEST HARNESS
1.1081 +//////////////////////////////////////////////////////////////////////////////
1.1082 +
1.1083 +/** Set of information used by test harness.
1.1084 +
1.1085 + @publishedPartner
1.1086 + @released
1.1087 +*/
1.1088 +struct TDmaTestInfo
1.1089 + {
1.1090 + /** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/
1.1091 + TUint iMaxTransferSize;
1.1092 + /** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */
1.1093 + TUint iMemAlignMask;
1.1094 + /** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer*/
1.1095 + TUint32 iMemMemPslInfo;
1.1096 + /** Number of test single-buffer channels */
1.1097 + TInt iMaxSbChannels;
1.1098 + /** Pointer to array containing single-buffer test channel ids */
1.1099 + TUint32* iSbChannels;
1.1100 + /** Number of test double-buffer channels */
1.1101 + TInt iMaxDbChannels;
1.1102 + /** Pointer to array containing double-buffer test channel ids */
1.1103 + TUint32* iDbChannels;
1.1104 + /** Number of test scatter-gather channels */
1.1105 + TInt iMaxSgChannels;
1.1106 + /** Pointer to array containing scatter-gather test channel ids */
1.1107 + TUint32* iSgChannels;
1.1108 + };
1.1109 +
1.1110 +
1.1111 +/** Provides access to test information structure stored in the PSL.
1.1112 +
1.1113 + Must be implemented by the PSL.
1.1114 +
1.1115 + @publishedPartner
1.1116 + @released
1.1117 +*/
1.1118 +IMPORT_C const TDmaTestInfo& DmaTestInfo();
1.1119 +
1.1120 +/** Provides access to test information structure stored in the PSL.
1.1121 +
1.1122 + Must be implemented by the PSL.
1.1123 +
1.1124 + @publishedPartner
1.1125 + @released
1.1126 +*/
1.1127 +IMPORT_C const TDmaV2TestInfo& DmaTestInfoV2();
1.1128 +
1.1129 +
1.1130 +
1.1131 +//////////////////////////////////////////////////////////////////////////////
1.1132 +
1.1133 +
1.1134 +#include <drivers/dma_compat.inl>
1.1135 +#include <drivers/dma_v2.inl>
1.1136 +
1.1137 +
1.1138 +#endif // #ifndef __DMA_V2_H__