Adaptation/GUID-0D2F811C-81C3-526F-8EA4-98E50261BF4B.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-0D2F811C-81C3-526F-8EA4-98E50261BF4B" xml:lang="en"><title>DMA
       
    13 Framework Technology</title><shortdesc>Describes the classes that the DMA Framework provides to transfer
       
    14 data using DMA. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <p>The following diagram shows the general relationship between the various
       
    16 classes and structs that form the DMA Framework. The individual items are
       
    17 described in more detail below. </p>
       
    18 <fig id="GUID-C6B032F0-7E05-5E29-8024-B713C42A2434">
       
    19 <image href="GUID-D43AB2F5-32AE-540C-80D8-DE8B2072F1E6_d0e10612_href.png" placement="inline"/>
       
    20 </fig>
       
    21 <section id="GUID-D9855D5F-3D4D-5A65-A1BB-B7CB94E60316"><title>The DMA Software
       
    22 Controller</title> <p>This is the <xref href="GUID-25398075-927B-36E4-B953-16785EC4086C.dita"><apiname>TDmac</apiname></xref> object. It has
       
    23 two purposes: </p> <ul>
       
    24 <li id="GUID-E4C8A5C5-192B-5E3E-A2F1-D884BF7FE641"><p>It defines the main
       
    25 interface between the platform independent and platform specific layers. </p> </li>
       
    26 <li id="GUID-98888CE1-5AA6-5D91-A5C5-E60F1200465A"><p>it is a container for
       
    27 channels, descriptors and descriptor headers </p> </li>
       
    28 </ul> </section>
       
    29 <section id="GUID-37DF82BE-5F8E-5497-90E8-C48F44C2A7F1"><title>The Channel
       
    30 Manager</title> <p>The channel manager is a <xref href="GUID-176B8E0D-0422-341B-A134-7C85432E1303.dita"><apiname>DmaChannelMgr</apiname></xref> object. </p> <p> <codeph> DmaChannelMgr</codeph> is
       
    31 a static class defined by the platform independent layer but implemented in
       
    32 the platform specific layer. The functionality is used by the platform independent
       
    33 layer. It contains: </p> <ul>
       
    34 <li id="GUID-B5626DA4-1465-5469-BE3D-36F31996C75A"><p>a function to open a
       
    35 DMA channel: <xref href="GUID-176B8E0D-0422-341B-A134-7C85432E1303.dita#GUID-176B8E0D-0422-341B-A134-7C85432E1303/GUID-934F46B3-1DF9-3870-87EE-A8E2DEF82810"><apiname>DmaChannelMgr::Open()</apiname></xref>  </p> </li>
       
    36 <li id="GUID-67C7DE2F-196E-5919-BA80-99898DF6837D"><p>a function that is called
       
    37 when a channel is closed: <xref href="GUID-176B8E0D-0422-341B-A134-7C85432E1303.dita#GUID-176B8E0D-0422-341B-A134-7C85432E1303/GUID-909D795A-7303-3A76-9C8E-3B07A97DD716"><apiname>DmaChannelMgr::Close()</apiname></xref>  </p> </li>
       
    38 <li id="GUID-F044E05A-A307-51B0-BDD5-8A29A950BE5F"><p>a function that can
       
    39 be used to extend the framework with platform specific functionality on a
       
    40 channel independent basis: <xref href="GUID-176B8E0D-0422-341B-A134-7C85432E1303.dita#GUID-176B8E0D-0422-341B-A134-7C85432E1303/GUID-C733B302-4269-3391-8ADE-617CFF198B56"><apiname>DmaChannelMgr::StaticExtension()</apiname></xref>  </p> </li>
       
    41 </ul> </section>
       
    42 <section id="GUID-34B8E965-9C5C-533E-BFE6-EB9B486A81BB"><title>Descriptors</title> <p>DMA
       
    43 controllers operating in scatter/gather mode are configured via a linked list
       
    44 of small data structures describing the data to be transferred. These data
       
    45 structures are called descriptors. (Note that the use of the term descriptor
       
    46 in the context of DMA should not be confused with the same term widely used
       
    47 in Symbian platform to refer to the family of <xref href="GUID-52D07F46-2162-380C-A775-C3BB335C42F5.dita"><apiname>TDesC</apiname></xref> derived
       
    48 classes). </p> <p>The Symbian platform DMA Framework always uses descriptor
       
    49 data structures to store transfer-configuration-information, even if the underlying
       
    50 DMA controller does not support scatter/gather mode. </p> <p>The following
       
    51 example illustrates the idea: assume that a device driver needs to transfer
       
    52 two disjoint blocks of memory, A and B, into another block C. Block A starts
       
    53 at address 1000 and is 300 bytes long. Block B starts at address 2000 and
       
    54 is 700 bytes long. The destination buffer C starts at address 5000 and is
       
    55 1000 bytes long. Assume that the DMA descriptors are allocated in a pool starting
       
    56 at address 600. The following diagram shows the scatter/gather list that the
       
    57 device driver might create: </p> <fig id="GUID-966DC875-FA9E-59E5-A1CA-842F4A82592D">
       
    58 <image href="GUID-EA0C5715-7CE8-5415-A915-D5701E3C957A_d0e10709_href.png" placement="inline"/>
       
    59 </fig> <p>If the DMA controller supports the scatter/gather arrangement, then
       
    60 the framework uses a structure that will be specific to the hardware. This
       
    61 structure is defined in the platform specific layer. </p> <p>If the DMA controller
       
    62 does not support scatter/gather, then the framework uses the generic structure <xref href="GUID-D7934AD9-38F6-325A-A734-F867D886D7C2.dita"><apiname>SDmaPseudoDes</apiname></xref> containing
       
    63 the following information: </p> <ul>
       
    64 <li id="GUID-D5EA7DC2-FC49-5FF3-95FE-6E5426D25BFF"><p>a set of generic flags
       
    65 that characterise the transfer. For example, is the source of the data memory
       
    66 or a peripheral; is the destination memory or peripheral; what addressing
       
    67 mode is to be used? </p> </li>
       
    68 <li id="GUID-4D54D3E6-0252-5F15-9966-E7F09A10020E"><p>the source and destination
       
    69 location. This is in the form of the base virtual address for a memory buffer,
       
    70 and a 32-bit value (or cookie) for peripherals. The meaning of the 32-bit
       
    71 value is interpreted by the platform specific layer. </p> </li>
       
    72 <li id="GUID-416CB113-5973-50AD-9FF3-F3AF78B47D0C"><p>The number of bytes
       
    73 to be transferred. </p> </li>
       
    74 <li id="GUID-D76CE2CE-5005-5C2F-B17D-F882D6BD7EB8"><p>A word that only has
       
    75 meaning for the platform specific layer, and passed by the client at request
       
    76 fragmentation time. </p> </li>
       
    77 </ul> </section>
       
    78 <section id="GUID-BC1C248D-170D-51AE-B2E5-61FFEC779D61"><title>Descriptor
       
    79 headers</title> <p>These are objects of type <xref href="GUID-710B3501-FF22-307D-AC88-D142E9A07CB8.dita"><apiname>SDmaDesHdr</apiname></xref>. </p> <p>A
       
    80 descriptor header allows additional information about a descriptor to be stored.
       
    81 The header is a separate object from the descriptor because it is difficult
       
    82 to embed additional data in a structure whose layout may be hardware-imposed. </p> <p>Descriptors
       
    83 and descriptor headers are stored in two parallel arrays allocated at boot-time,
       
    84 and each descriptor is always associated with the header of same index, so
       
    85 that there is always a one-to-one relationship between the header and the
       
    86 descriptor. </p> <fig id="GUID-A635E3EA-883C-5857-8690-E0AE6F43CAC4">
       
    87 <image href="GUID-99F7E70F-2733-57B2-94F5-A0C0FF9219FE_d0e10765_href.png" placement="inline"/>
       
    88 </fig> <p>In the current design, the only information in the descriptor header
       
    89 is a pointer, <codeph>SDmaDesHdr::iNext</codeph>, that is used to chain headers
       
    90 together on various lists. So, although the pool of headers is allocated as
       
    91 an array, they are almost always accessed by following the chain of pointers
       
    92 linking one header to the next. </p> <p>Descriptors are <i>always</i> accessed
       
    93 through their associated header. </p> <p>The platform independent layer never
       
    94 directly accesses hardware-specific descriptors. It just passes descriptor
       
    95 headers to the platform specific layer. However, the platform independent
       
    96 layer does directly manipulate the generic descriptors, <xref href="GUID-D7934AD9-38F6-325A-A734-F867D886D7C2.dita"><apiname>SDmaPseudoDes</apiname></xref>. </p> </section>
       
    97 <section id="GUID-F4685621-1FAA-544C-B4C0-B4DD566B856F"><title>Transfer Requests</title> <p>A
       
    98 transfer request is the way in which a device driver sets up and initiates
       
    99 a DMA transfer, and is represented by a <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita"><apiname>DDmaRequest</apiname></xref> object. </p> <p>A
       
   100 transfer request has a number of characteristics: </p> <ul>
       
   101 <li id="GUID-D5B73919-B6C8-54F9-8C1E-87467E32EAA0"><p>it is always associated
       
   102 with exactly one channel. </p> </li>
       
   103 <li id="GUID-FE3326FA-B0CF-50A2-BD4D-72F868226EFB"><p>it stores a client-provided
       
   104 callback function, which is invoked when the whole request completes, whether
       
   105 successfully or not. </p> </li>
       
   106 <li id="GUID-627B7D15-0119-5D72-A517-84832D90C3D1"><p>it can be in one of
       
   107 four states: </p> <ul>
       
   108 <li id="GUID-1D600F30-F06C-58FB-B258-8167164FE1FC"><p>not configured </p> </li>
       
   109 <li id="GUID-194A4B9A-12E6-50B6-816A-73717CD100F9"><p>idle </p> </li>
       
   110 <li id="GUID-0B7A0249-9F5D-5D5D-AB3C-4DDE8AFC58E6"><p>being transferred </p> </li>
       
   111 <li id="GUID-AF57DDF1-406D-55D4-A001-F62921165189"><p>pending; this state
       
   112 only occurs in streaming mode. </p> </li>
       
   113 </ul> </li>
       
   114 </ul> <p>Internally, a transfer request is represented as a singly linked
       
   115 list of descriptor headers. Each header in the list is associated with a descriptor
       
   116 that specifies how to transfer one fragment of the whole request. Transfer
       
   117 requests have pointers to the first and last headers in the list. </p> <p>When
       
   118 the request is idle, the header list ends with a NULL pointer. This is not
       
   119 always true when the request is queued (i.e. when the request is being transferred
       
   120 or is still pending). The following diagram shows an idle request with three
       
   121 fragments. </p> <fig id="GUID-0A5594BD-05E4-5A97-A3F7-459E3F8638A2">
       
   122 <image href="GUID-CF252B09-335E-5831-94A6-0B16B64C5030_d0e10851_href.png" placement="inline"/>
       
   123 </fig> <p>Splitting a request into fragments is useful because: </p> <ul>
       
   124 <li id="GUID-BEA0F4C5-4308-54E9-82AB-91570ACC9ADC"><p>it insulates device
       
   125 drivers from the maximum transfer size supported by the underlying DMA controller. </p> </li>
       
   126 <li id="GUID-A768A76B-DD9E-5A25-92D3-23A69299C096"><p>the source and destination
       
   127 DMA buffers may not be physically contiguous and thus require fragmenting. </p> </li>
       
   128 </ul> <p>Both of these situations can be handled by using the generic fragmentation
       
   129 algorithm <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita#GUID-780F4D53-5546-3B69-B328-0226C70EBDE2/GUID-B14B0478-80D6-3F5E-88B6-1676411D9CF2"><apiname>DDmaRequest::Fragment()</apiname></xref>. </p> <p>Some device
       
   130 drivers may have to create custom descriptors lists. For example, the USB
       
   131 section of the PXA250 manual describes how to build custom lists where a descriptor
       
   132 containing data transfer information is followed by another one poking an
       
   133 I/O port to issue a command to the USB controller. </p> <p>To cover that case, <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita"><apiname>DDmaRequest</apiname></xref> provides
       
   134 the <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita#GUID-780F4D53-5546-3B69-B328-0226C70EBDE2/GUID-AAB7C209-7D30-3282-B084-D80E12BB5152"><apiname>DDmaRequest::ExpandDesList()</apiname></xref> member function to allocate
       
   135 a list of headers associated with blank descriptors whose content is then
       
   136 set by device drivers. Blank descriptors thus created can be accessed in the
       
   137 following way (this example was taken and simplified from the PXA250 USB controller
       
   138 driver): </p> <codeblock id="GUID-EFA935A1-0D7E-5153-9071-2D0C58E8E920" xml:space="preserve">TDmaChannel* channel;
       
   139 TDmaChannel::SCreateInfo info;
       
   140 info.x = y;
       
   141 if (TDmaChannel::Open(info, channel) != KErrNone)
       
   142     ... return;
       
   143 DDmaRequest* req = new DDmaRequest(*channel);
       
   144 if (!req)
       
   145     ... return;
       
   146 const TDmac* dmac = req-&gt;iChannel.Controller();
       
   147 if (req-&gt;ExpandDesList(2) != KErrNone)
       
   148     ... return;
       
   149 TDmaDesc* desc1 = static_cast&lt;TDmaDesc*&gt;(dmac-&gt;HdrToHwDes(*req-&gt;iFirstHdr));
       
   150 TDmaDesc* desc2 = static_cast&lt;TDmaDesc*&gt;(dmac-&gt;HdrToHwDes(*req-&gt;iFirstHdr-&gt;iNext));
       
   151 desc1-&gt;iSrcAddr  = ...;
       
   152 desc1-&gt;iDestAddr = ...;
       
   153 desc1-&gt;iDescAddr = ...;
       
   154 desc1-&gt;iCmd      = ...;
       
   155 desc2...
       
   156 ...
       
   157 </codeblock> </section>
       
   158 <section id="GUID-4BF7605E-55D4-5B3A-BCD7-1F976765D738"><title>Channels</title> <p>A
       
   159 channel is a <xref href="GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37.dita"><apiname>TDmaChannel</apiname></xref> object, and there is one of these
       
   160 for each hardware DMA channel. </p> <p>A channel can be in one of 4 states: </p> <ul>
       
   161 <li id="GUID-09581FA5-D01A-502A-9841-52ABDF0BB16E"><p>closed </p> </li>
       
   162 <li id="GUID-D03F51BA-1493-5B23-B029-4FF5FCC4DE5E"><p>open and idle </p> </li>
       
   163 <li id="GUID-606FA290-FB8D-5CBE-88C2-BCD03062EE25"><p>open and transferring
       
   164 data </p> </li>
       
   165 <li id="GUID-2E845C88-292D-54B9-9F99-AAC3775768E4"><p>suspended following
       
   166 an error. </p> </li>
       
   167 </ul> <p>On opening a channel, the client device driver specifies: </p> <ul>
       
   168 <li id="GUID-6F373D39-4078-5C76-BF5E-69294297D8CE"><p>A 32-bit value (cookie)
       
   169 that is used by the platform specific layer to select which channel is to
       
   170 be opened </p> </li>
       
   171 <li id="GUID-71E4D026-4BA5-592B-BB3E-5F5354640E50"><p>The number of descriptors
       
   172 that must be reserved for this channel. </p> </li>
       
   173 <li id="GUID-4C34A82A-AF7E-5683-986B-A65EA6C8F5B2"><p>A DFC to be used by
       
   174 the framework to service DMA interrupts. </p> </li>
       
   175 </ul> <p>A channel maintains a queue of transfer requests. If the channel
       
   176 is being used for one-shot transfers, the queue will always contain an idle
       
   177 or a transferring request. In streaming mode, the queue may contain several
       
   178 requests, the first one being transferred and the remaining ones pending.
       
   179 When a request is completely transferred, it is removed from the queue. The
       
   180 first request is always the one being transferred. </p> <p>A transferring
       
   181 channel has a pointer to the header associated with the descriptor being transferred.
       
   182 The headers of all queued requests are linked together on one linked list. </p> <p>The
       
   183 following diagram shows a DMA channel with a three-fragment request being
       
   184 transferred and a two-fragment one pending. The fragment currently being transferred
       
   185 is the second one of the first request. </p> <fig id="GUID-36E11A64-4626-53F9-925C-3DC323DEA895">
       
   186 <image href="GUID-86C21C9B-9F08-579F-84E9-CBE46F756373_d0e10964_href.png" placement="inline"/>
       
   187 </fig> <p>The <xref href="GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37.dita"><apiname>TDmaChannel</apiname></xref> class contains the code and data
       
   188 that is common to all of the channel types. The code and data for the specific
       
   189 channel types: single buffer, double buffer, and scatter/gather channels,
       
   190 are implemented in the derived classes: <xref href="GUID-A8B4AD1B-770C-363E-A0DE-C78A9786CBDC.dita"><apiname>TDmaSbChannel</apiname></xref>, <xref href="GUID-FD76AF08-6250-3054-8A06-16343E385B23.dita"><apiname>TDmaDbChannel</apiname></xref>,
       
   191 and <xref href="GUID-2D4CFBB1-8D64-3CF5-B6F0-B24D16D5BAD4.dita"><apiname>TDmaSgChannel</apiname></xref> respectively. </p> <p><b>TDmaSbChannel
       
   192 State Machine</b> </p> <p>For reference purposes, the following diagram shows
       
   193 the state machine that <xref href="GUID-A8B4AD1B-770C-363E-A0DE-C78A9786CBDC.dita"><apiname>TDmaSbChannel</apiname></xref> implements to deal
       
   194 with a single buffer channel. </p> <fig id="GUID-82A8742D-CE5E-5EA2-A19E-6DCA30D9AE61">
       
   195 <image href="GUID-85332468-292D-589B-891B-0E7ACBADC7BA_d0e11000_href.png" placement="inline"/>
       
   196 </fig> <p><b>TDmaDbChannel
       
   197 State Machine</b> </p> <p>For reference purposes, the following diagram shows
       
   198 the state machine that <xref href="GUID-FD76AF08-6250-3054-8A06-16343E385B23.dita"><apiname>TDmaDbChannel</apiname></xref> implements to deal
       
   199 with a double buffer channel. </p> <fig id="GUID-1CF4D292-310C-5D75-9E3B-2DB65217FEEA">
       
   200 <image href="GUID-91958EA5-9444-5895-B4B8-F2C670B81CD7_d0e11017_href.png" placement="inline"/>
       
   201 </fig> <p><b>TDmaSgChannel
       
   202 State Machine</b> </p> <p>For reference purposes, the following diagram shows
       
   203 the state machine that <xref href="GUID-2D4CFBB1-8D64-3CF5-B6F0-B24D16D5BAD4.dita"><apiname>TDmaSgChannel</apiname></xref> implements to deal
       
   204 with a scatter/gather channel. </p> <fig id="GUID-1206C662-9856-57A1-A0C5-FDF74F2A3BD3">
       
   205 <image href="GUID-09EE01E2-BF5E-5302-BA25-46C440ADECF5_d0e11034_href.png" placement="inline"/>
       
   206 </fig> </section>
       
   207 <section id="GUID-2F8979D3-A4DC-5919-B027-F8C17739A05D"><title>Streaming and
       
   208 Scatter/Gather DMA Controllers</title> <p>When a transfer request is queued
       
   209 onto a channel that is already transferring data, the header descriptor for
       
   210 the new list of descriptors is appended to the header of the previous request
       
   211 on the queue. If the underlying DMA controller supports hardware descriptors,
       
   212 they must also be linked together. </p> <p>The following diagram shows how
       
   213 headers and descriptors for a new request are appended to the existing ones
       
   214 for a DMA controller. The dashed arrows represent the new links. </p> <fig id="GUID-7E06E92E-C8D1-53FF-AF03-5B1A3EBC1EA5">
       
   215 <image href="GUID-28F3F720-A2E0-59C9-8BB4-B6124CFC6C89_d0e11050_href.png" placement="inline"/>
       
   216 </fig> <p> <i>Note that hardware descriptors are linked together using physical
       
   217 addresses, not virtual ones.</i>  </p> <p>Linking hardware descriptors together
       
   218 is implemented in the platform specific layer. There are two issues to consider: </p> <ul>
       
   219 <li id="GUID-4236DD82-FFAD-56D3-B46F-9D2198E0349A"><p>The channel may go idle
       
   220 before the linking is complete, which means that the data for the new request
       
   221 would not be transferred. </p> </li>
       
   222 <li id="GUID-48AAA44F-1EEF-5899-9D62-587AA0EC8303"><p>If the channel is transferring
       
   223 the last descriptor in the list, then updating the “next” field in the descriptor
       
   224 will have no effect because the content of the descriptor will already have
       
   225 been loaded in the controller registers. Again the channel would go idle without
       
   226 transferring the data associated with the new request. </p> </li>
       
   227 </ul> <p>The solutions available when porting the DMA Framework are: </p> <ul>
       
   228 <li id="GUID-DC8EBCE6-E355-5D93-A265-0D591F06841C"><p>If the DMA controller
       
   229 has hardware support for appending descriptors while transferring data, then
       
   230 there is no problem. </p> </li>
       
   231 <li id="GUID-77DE96E7-9D9A-543F-8CD9-A36055F38E7A"><p>If the peripheral attached
       
   232 to the channel can withstand a short disruption in the transfer flow, then
       
   233 the channel can be suspended while the appending takes place. This should
       
   234 be done with interrupts disabled to minimise disruption. </p> </li>
       
   235 <li id="GUID-962DAD2E-2684-5F51-8F80-A1E3C86BC8F7"><p>The alternative technique
       
   236 is to append the new list with interrupts disabled and set a flag. When the
       
   237 next interrupt occurs, if the flag is set and the channel idle, then the interrupt
       
   238 service routine must restart the transfer. </p> </li>
       
   239 </ul> <p>See <xref href="GUID-0D2F811C-81C3-526F-8EA4-98E50261BF4B.dita#GUID-0D2F811C-81C3-526F-8EA4-98E50261BF4B/GUID-4BF7605E-55D4-5B3A-BCD7-1F976765D738">Channels</xref>. </p> </section>
       
   240 <section id="GUID-106BBBE0-C18B-5321-96AE-F1A65FAB4FF7"><title>Interrupt Service
       
   241 Routine (ISR) and DFC Issues</title> <p>The platform specific layer must notify
       
   242 the platform independent layer when the following events occur: </p> <ul>
       
   243 <li id="GUID-13589C1E-5146-5044-9587-092C4347D4EC"><p>when an error occurs. </p> </li>
       
   244 <li id="GUID-47C15152-8C06-5864-9292-4EF6A9A458E6"><p>when each fragment completes,
       
   245 for single-buffer and double-buffer controllers. </p> </li>
       
   246 <li id="GUID-BCDD4ECD-4396-5F2C-9A3A-B0C3B20DCC90"><p>when the last fragment
       
   247 of a request completes, for scatter/gather controllers. </p> </li>
       
   248 </ul> <p>The ISR, as implemented in the platform specific layer, must: </p> <ul>
       
   249 <li id="GUID-037B8F96-3C27-5D2F-8E70-35C66C601D63"><p>determine which channel
       
   250 the interrupt is for. If the DMA controller uses dedicated interrupt lines
       
   251 per channel, the ASSP/variant interrupt dispatcher will do this. See <xref href="GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita">Interrupt Dispatcher Tutorial</xref>. </p> </li>
       
   252 <li id="GUID-58A2D3AE-BF42-56E6-9EB1-B77DC9B2B934"><p>determine whether the
       
   253 interrupt was asserted following a successful transfer completion or a failure.
       
   254 If the DMA controller uses different interrupt lines for completion and failure,
       
   255 the ASSP/variant interrupt dispatcher will do this. </p> </li>
       
   256 <li id="GUID-F9D50FBF-171A-5D26-851E-3FDDB4AE38BB"><p>Call <xref href="GUID-25398075-927B-36E4-B953-16785EC4086C.dita#GUID-25398075-927B-36E4-B953-16785EC4086C/GUID-187EBCEB-4488-3606-BB71-8813111D8AF4"><apiname>TDmac::HandleIsr()</apiname></xref> in
       
   257 the platform specific layer. This function queues the DFC associated with
       
   258 the relevant channel. It takes care of the case where several interrupts occur
       
   259 before the DFC gets a chance to run. </p> </li>
       
   260 </ul> <p>The DFC updates the state of the channel and, for single and double
       
   261 buffer DMA controllers, configures the next fragment to transfer, if any.
       
   262 When all fragments making up a request have been transferred, the DFC calls
       
   263 the client-supplied callback associated with the completed request. The callback
       
   264 is also called if an error occurs during transfer. </p> </section>
       
   265 <section id="GUID-2CB7E268-0535-5AD0-8B08-3FEDBA39016D"><title>Locking Strategy</title> <p>For
       
   266 a given device driver, <xref href="GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37.dita"><apiname>TDmaChannel</apiname></xref> and <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita"><apiname>DDmaRequest</apiname></xref> instances
       
   267 can be accessed concurrently from the device driver thread and from a DFC
       
   268 queue thread. To avoid race conditions, each <xref href="GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37.dita"><apiname>TDmaChannel</apiname></xref> instance
       
   269 has a fast mutex, the protected data member <codeph>TDmaChannel::iLock</codeph>.
       
   270 This lock is acquired when queuing a new request, cancelling requests and
       
   271 executing the DFC. </p> <p> <xref href="GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37.dita"><apiname>TDmaChannel</apiname></xref> and <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita"><apiname>DDmaRequest</apiname></xref> instances
       
   272 are not protected against concurrent access from several client threads because
       
   273 this is assumed to be an exceptional case. A device driver with such need
       
   274 would have to implement its own locking scheme around calls to <xref href="GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37.dita"><apiname>TDmaChannel</apiname></xref> and <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita"><apiname>DDmaRequest</apiname></xref> member
       
   275 functions. </p> <p>Each <xref href="GUID-25398075-927B-36E4-B953-16785EC4086C.dita"><apiname>TDmac</apiname></xref> instance includes a fast
       
   276 mutex, the private member <codeph>TDmac::iLock</codeph> to protect descriptor
       
   277 reservation and allocation, because several device drivers may try to reserve
       
   278 or allocate descriptors concurrently. </p> <p>The <xref href="GUID-176B8E0D-0422-341B-A134-7C85432E1303.dita"><apiname>DmaChannelMgr</apiname></xref> static
       
   279 class includes a fast mutex which is used to protect channel opening as several
       
   280 device drivers may compete for the same channel. This lock is also used at
       
   281 channel closing time. </p> </section>
       
   282 </conbody></concept>