€•QŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ1/translations/zh_CN/driver-api/dmaengine/provider”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ1/translations/zh_TW/driver-api/dmaengine/provider”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ1/translations/it_IT/driver-api/dmaengine/provider”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ1/translations/ja_JP/driver-api/dmaengine/provider”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ1/translations/ko_KR/driver-api/dmaengine/provider”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ1/translations/pt_BR/driver-api/dmaengine/provider”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ1/translations/sp_SP/driver-api/dmaengine/provider”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ"DMAengine controller documentation”h]”hŒ"DMAengine controller documentation”…”�”}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒK/var/lib/git/docbuild/linux/Documentation/driver-api/dmaengine/provider.rst”h´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒHardware Introduction”h]”hŒHardware Introduction”…”�”}”(hhÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhËh²hh³hÊh´KubhŒ paragraph”“”)�”}”(hŒQMost of the Slave DMA controllers have the same general principles of operations.”h]”hŒQMost of the Slave DMA controllers have the same general principles of operations.”…”�”}”(hhÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhhËh²hubhÝ)�”}”(hŒhThey have a given number of channels to use for the DMA transfers, and a given number of requests lines.”h]”hŒhThey have a given number of channels to use for the DMA transfers, and a given number of requests lines.”…”�”}”(hhìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K hhËh²hubhÝ)�”}”(hŒÖRequests and channels are pretty much orthogonal. Channels can be used to serve several to any requests. To simplify, channels are the entities that will be doing the copy, and requests what endpoints are involved.”h]”hŒÖRequests and channels are pretty much orthogonal. Channels can be used to serve several to any requests. To simplify, channels are the entities that will be doing the copy, and requests what endpoints are involved.”…”�”}”(hhúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhhËh²hubhÝ)�”}”(hŒëThe request lines actually correspond to physical lines going from the DMA-eligible devices to the controller itself. Whenever the device will want to start a transfer, it will assert a DMA request (DRQ) by asserting that request line.”h]”hŒëThe request lines actually correspond to physical lines going from the DMA-eligible devices to the controller itself. Whenever the device will want to start a transfer, it will assert a DMA request (DRQ) by asserting that request line.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhhËh²hubhÝ)�”}”(hŒÜA very simple DMA controller would only take into account a single parameter: the transfer size. At each clock cycle, it would transfer a byte of data from one buffer to another, until the transfer size has been reached.”h]”hŒÜA very simple DMA controller would only take into account a single parameter: the transfer size. At each clock cycle, it would transfer a byte of data from one buffer to another, until the transfer size has been reached.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhhËh²hubhÝ)�”}”(hXÿThat wouldn't work well in the real world, since slave devices might require a specific number of bits to be transferred in a single cycle. For example, we may want to transfer as much data as the physical bus allows to maximize performances when doing a simple memory copy operation, but our audio device could have a narrower FIFO that requires data to be written exactly 16 or 24 bits at a time. This is why most if not all of the DMA controllers can adjust this, using a parameter called the transfer width.”h]”hXThat wouldn’t work well in the real world, since slave devices might require a specific number of bits to be transferred in a single cycle. For example, we may want to transfer as much data as the physical bus allows to maximize performances when doing a simple memory copy operation, but our audio device could have a narrower FIFO that requires data to be written exactly 16 or 24 bits at a time. This is why most if not all of the DMA controllers can adjust this, using a parameter called the transfer width.”…”�”}”(hj$h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhhËh²hubhÝ)�”}”(hXÁMoreover, some DMA controllers, whenever the RAM is used as a source or destination, can group the reads or writes in memory into a buffer, so instead of having a lot of small memory accesses, which is not really efficient, you'll get several bigger transfers. This is done using a parameter called the burst size, that defines how many single reads/writes it's allowed to do without the controller splitting the transfer into smaller sub-transfers.”h]”hXÅMoreover, some DMA controllers, whenever the RAM is used as a source or destination, can group the reads or writes in memory into a buffer, so instead of having a lot of small memory accesses, which is not really efficient, you’ll get several bigger transfers. This is done using a parameter called the burst size, that defines how many single reads/writes it’s allowed to do without the controller splitting the transfer into smaller sub-transfers.”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K&hhËh²hubhÝ)�”}”(hXOur theoretical DMA controller would then only be able to do transfers that involve a single contiguous block of data. However, some of the transfers we usually have are not, and want to copy data from non-contiguous buffers to a contiguous buffer, which is called scatter-gather.”h]”hXOur theoretical DMA controller would then only be able to do transfers that involve a single contiguous block of data. However, some of the transfers we usually have are not, and want to copy data from non-contiguous buffers to a contiguous buffer, which is called scatter-gather.”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K.hhËh²hubhÝ)�”}”(hX:DMAEngine, at least for mem2dev transfers, require support for scatter-gather. So we're left with two cases here: either we have a quite simple DMA controller that doesn't support it, and we'll have to implement it in software, or we have a more advanced DMA controller, that implements in hardware scatter-gather.”h]”hX@DMAEngine, at least for mem2dev transfers, require support for scatter-gather. So we’re left with two cases here: either we have a quite simple DMA controller that doesn’t support it, and we’ll have to implement it in software, or we have a more advanced DMA controller, that implements in hardware scatter-gather.”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K4hhËh²hubhÝ)�”}”(hŒÂThe latter are usually programmed using a collection of chunks to transfer, and whenever the transfer is started, the controller will go over that collection, doing whatever we programmed there.”h]”hŒÂThe latter are usually programmed using a collection of chunks to transfer, and whenever the transfer is started, the controller will go over that collection, doing whatever we programmed there.”…”�”}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K:hhËh²hubhÝ)�”}”(hX;This collection is usually either a table or a linked list. You will then push either the address of the table and its number of elements, or the first item of the list to one channel of the DMA controller, and whenever a DRQ will be asserted, it will go through the collection to know where to fetch the data from.”h]”hX;This collection is usually either a table or a linked list. You will then push either the address of the table and its number of elements, or the first item of the list to one channel of the DMA controller, and whenever a DRQ will be asserted, it will go through the collection to know where to fetch the data from.”…”�”}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K>hhËh²hubhÝ)�”}”(hXEither way, the format of this collection is completely dependent on your hardware. Each DMA controller will require a different structure, but all of them will require, for every chunk, at least the source and destination addresses, whether it should increment these addresses or not and the three parameters we saw earlier: the burst size, the transfer width and the transfer size.”h]”hXEither way, the format of this collection is completely dependent on your hardware. Each DMA controller will require a different structure, but all of them will require, for every chunk, at least the source and destination addresses, whether it should increment these addresses or not and the three parameters we saw earlier: the burst size, the transfer width and the transfer size.”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KDhhËh²hubhÝ)�”}”(hŒ¯The one last thing is that usually, slave devices won't issue DRQ by default, and you have to enable this in your slave device driver first whenever you're willing to use DMA.”h]”hŒ³The one last thing is that usually, slave devices won’t issue DRQ by default, and you have to enable this in your slave device driver first whenever you’re willing to use DMA.”…”�”}”(hj†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KKhhËh²hubhÝ)�”}”(hŒÿThese were just the general memory-to-memory (also called mem2mem) or memory-to-device (mem2dev) kind of transfers. Most devices often support other kind of transfers or memory operations that dmaengine support and will be detailed later in this document.”h]”hŒÿThese were just the general memory-to-memory (also called mem2mem) or memory-to-device (mem2dev) kind of transfers. Most devices often support other kind of transfers or memory operations that dmaengine support and will be detailed later in this document.”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KOhhËh²hubeh}”(h]”Œhardware-introduction”ah ]”h"]”Œhardware introduction”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒDMA Support in Linux”h]”hŒDMA Support in Linux”…”�”}”(hj­h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjªh²hh³hÊh´KUubhÝ)�”}”(hŒÀHistorically, DMA controller drivers have been implemented using the async TX API, to offload operations such as memory copy, XOR, cryptography, etc., basically any memory to memory operation.”h]”hŒÀHistorically, DMA controller drivers have been implemented using the async TX API, to offload operations such as memory copy, XOR, cryptography, etc., basically any memory to memory operation.”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KWhjªh²hubhÝ)�”}”(hX)Over time, the need for memory to device transfers arose, and dmaengine was extended. Nowadays, the async TX API is written as a layer on top of dmaengine, and acts as a client. Still, dmaengine accommodates that API in some cases, and made some design choices to ensure that it stayed compatible.”h]”hX)Over time, the need for memory to device transfers arose, and dmaengine was extended. Nowadays, the async TX API is written as a layer on top of dmaengine, and acts as a client. Still, dmaengine accommodates that API in some cases, and made some design choices to ensure that it stayed compatible.”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K[hjªh²hubhÝ)�”}”(hŒFor more information on the Async TX API, please look the relevant documentation file in Documentation/crypto/async-tx-api.rst.”h]”hŒFor more information on the Async TX API, please look the relevant documentation file in Documentation/crypto/async-tx-api.rst.”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kahjªh²hubeh}”(h]”Œdma-support-in-linux”ah ]”h"]”Œdma support in linux”ah$]”h&]”uh1hµhh·h²hh³hÊh´KUubh¶)�”}”(hhh]”(h»)�”}”(hŒDMAEngine APIs”h]”hŒDMAEngine APIs”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjíh²hh³hÊh´Keubh¶)�”}”(hhh]”(h»)�”}”(hŒ$``struct dma_device`` Initialization”h]”(hŒliteral”“”)�”}”(hŒ``struct dma_device``”h]”hŒstruct dma_device”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ Initialization”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hºhjþh²hh³hÊh´KhubhÝ)�”}”(hŒÁJust like any other kernel framework, the whole DMAEngine registration relies on the driver filling a structure and registering against the framework. In our case, that structure is dma_device.”h]”hŒÁJust like any other kernel framework, the whole DMAEngine registration relies on the driver filling a structure and registering against the framework. In our case, that structure is dma_device.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kjhjþh²hubhÝ)�”}”(hŒ²The first thing you need to do in your driver is to allocate this structure. Any of the usual memory allocators will do, but you'll also need to initialize a few fields in there:”h]”hŒ´The first thing you need to do in your driver is to allocate this structure. Any of the usual memory allocators will do, but you’ll also need to initialize a few fields in there:”…”�”}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Knhjþh²hubhŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒY``channels``: should be initialized as a list using the INIT_LIST_HEAD macro for example ”h]”hÝ)�”}”(hŒX``channels``: should be initialized as a list using the INIT_LIST_HEAD macro for example”h]”(j)�”}”(hŒ ``channels``”h]”hŒchannels”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjFubhŒL: should be initialized as a list using the INIT_LIST_HEAD macro for example”…”�”}”(hjFh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KrhjBubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³hÊh´NubjA)�”}”(hŒU``src_addr_widths``: should contain a bitmask of the supported source transfer width ”h]”hÝ)�”}”(hŒT``src_addr_widths``: should contain a bitmask of the supported source transfer width”h]”(j)�”}”(hŒ``src_addr_widths``”h]”hŒsrc_addr_widths”…”�”}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjlubhŒA: should contain a bitmask of the supported source transfer width”…”�”}”(hjlh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kuhjhubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³hÊh´NubjA)�”}”(hŒZ``dst_addr_widths``: should contain a bitmask of the supported destination transfer width ”h]”hÝ)�”}”(hŒY``dst_addr_widths``: should contain a bitmask of the supported destination transfer width”h]”(j)�”}”(hŒ``dst_addr_widths``”h]”hŒdst_addr_widths”…”�”}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj’ubhŒF: should contain a bitmask of the supported destination transfer width”…”�”}”(hj’h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KxhjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³hÊh´NubjA)�”}”(hŒn``directions``: should contain a bitmask of the supported slave directions (i.e. excluding mem2mem transfers) ”h]”hÝ)�”}”(hŒm``directions``: should contain a bitmask of the supported slave directions (i.e. excluding mem2mem transfers)”h]”(j)�”}”(hŒ``directions``”h]”hŒ directions”…”�”}”(hj¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¸ubhŒ_: should contain a bitmask of the supported slave directions (i.e. excluding mem2mem transfers)”…”�”}”(hj¸h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K{hj´ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³hÊh´NubjA)�”}”(hX¨``residue_granularity``: granularity of the transfer residue reported to dma_set_residue. This can be either: - Descriptor: your device doesn't support any kind of residue reporting. The framework will only know that a particular transaction descriptor is done. - Segment: your device is able to report which chunks have been transferred - Burst: your device is able to report which burst have been transferred ”h]”(hÝ)�”}”(hŒm``residue_granularity``: granularity of the transfer residue reported to dma_set_residue. This can be either:”h]”(j)�”}”(hŒ``residue_granularity``”h]”hŒresidue_granularity”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÞubhŒV: granularity of the transfer residue reported to dma_set_residue. This can be either:”…”�”}”(hjÞh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhjÚubj<)�”}”(hhh]”(jA)�”}”(hŒ–Descriptor: your device doesn't support any kind of residue reporting. The framework will only know that a particular transaction descriptor is done. ”h]”hÝ)�”}”(hŒ•Descriptor: your device doesn't support any kind of residue reporting. The framework will only know that a particular transaction descriptor is done.”h]”hŒ—Descriptor: your device doesn’t support any kind of residue reporting. The framework will only know that a particular transaction descriptor is done.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kƒhjýubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjúubjA)�”}”(hŒJSegment: your device is able to report which chunks have been transferred ”h]”hÝ)�”}”(hŒISegment: your device is able to report which chunks have been transferred”h]”hŒISegment: your device is able to report which chunks have been transferred”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kˆhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjúubjA)�”}”(hŒGBurst: your device is able to report which burst have been transferred ”h]”hÝ)�”}”(hŒFBurst: your device is able to report which burst have been transferred”h]”hŒFBurst: your device is able to report which burst have been transferred”…”�”}”(hj1h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K‹hj-ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjúubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j;h³hÊh´KƒhjÚubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³Nh´NubjA)�”}”(hŒf``dev``: should hold the pointer to the ``struct device`` associated to your current driver instance. ”h]”hÝ)�”}”(hŒe``dev``: should hold the pointer to the ``struct device`` associated to your current driver instance.”h]”(j)�”}”(hŒ``dev``”h]”hŒdev”…”�”}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjWubhŒ!: should hold the pointer to the ”…”�”}”(hjWh²hh³Nh´Nubj)�”}”(hŒ``struct device``”h]”hŒ struct device”…”�”}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjWubhŒ, associated to your current driver instance.”…”�”}”(hjWh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KŽhjSubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj=h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´Krhjþh²hubeh}”(h]”Œ struct-dma-device-initialization”ah ]”h"]”Œ struct dma_device initialization”ah$]”h&]”uh1hµhjíh²hh³hÊh´Khubh¶)�”}”(hhh]”(h»)�”}”(hŒSupported transaction types”h]”hŒSupported transaction types”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj™h²hh³hÊh´K’ubhÝ)�”}”(hŒ\The next thing you need is to set which transaction types your device (and driver) supports.”h]”hŒ\The next thing you need is to set which transaction types your device (and driver) supports.”…”�”}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K”hj™h²hubhÝ)�”}”(hŒþOur ``dma_device structure`` has a field called cap_mask that holds the various types of transaction supported, and you need to modify this mask using the dma_cap_set function, with various flags depending on transaction types you support as an argument.”h]”(hŒOur ”…”�”}”(hj¸h²hh³Nh´Nubj)�”}”(hŒ``dma_device structure``”h]”hŒdma_device structure”…”�”}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj¸ubhŒâ has a field called cap_mask that holds the various types of transaction supported, and you need to modify this mask using the dma_cap_set function, with various flags depending on transaction types you support as an argument.”…”�”}”(hj¸h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K—hj™h²hubhÝ)�”}”(hŒiAll those capabilities are defined in the ``dma_transaction_type enum``, in ``include/linux/dmaengine.h``”h]”(hŒ*All those capabilities are defined in the ”…”�”}”(hjØh²hh³Nh´Nubj)�”}”(hŒ``dma_transaction_type enum``”h]”hŒdma_transaction_type enum”…”�”}”(hjàh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjØubhŒ, in ”…”�”}”(hjØh²hh³Nh´Nubj)�”}”(hŒ``include/linux/dmaengine.h``”h]”hŒinclude/linux/dmaengine.h”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjØubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kœhj™h²hubhÝ)�”}”(hŒ#Currently, the types available are:”h]”hŒ#Currently, the types available are:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KŸhj™h²hubj<)�”}”(hhh]”(jA)�”}”(hX;DMA_MEMCPY - The device is able to do memory to memory copies - No matter what the overall size of the combined chunks for source and destination is, only as many bytes as the smallest of the two will be transmitted. That means the number and size of the scatter-gather buffers in both lists need not be the same, and that the operation functionally is equivalent to a ``strncpy`` where the ``count`` argument equals the smallest total size of the two scatter-gather list buffers. - It's usually used for copying pixel data between host memory and memory-mapped GPU device memory, such as found on modern PCI video graphics cards. The most immediate example is the OpenGL API function ``glReadPixels()``, which might require a verbatim copy of a huge framebuffer from local device memory onto host memory. ”h]”(hÝ)�”}”(hŒ DMA_MEMCPY”h]”hŒ DMA_MEMCPY”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K¡hjubj<)�”}”(hhh]”(jA)�”}”(hŒ1The device is able to do memory to memory copies ”h]”hÝ)�”}”(hŒ0The device is able to do memory to memory copies”h]”hŒ0The device is able to do memory to memory copies”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K£hj,ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj)ubjA)�”}”(hX¡No matter what the overall size of the combined chunks for source and destination is, only as many bytes as the smallest of the two will be transmitted. That means the number and size of the scatter-gather buffers in both lists need not be the same, and that the operation functionally is equivalent to a ``strncpy`` where the ``count`` argument equals the smallest total size of the two scatter-gather list buffers. ”h]”hÝ)�”}”(hX No matter what the overall size of the combined chunks for source and destination is, only as many bytes as the smallest of the two will be transmitted. That means the number and size of the scatter-gather buffers in both lists need not be the same, and that the operation functionally is equivalent to a ``strncpy`` where the ``count`` argument equals the smallest total size of the two scatter-gather list buffers.”h]”(hX1No matter what the overall size of the combined chunks for source and destination is, only as many bytes as the smallest of the two will be transmitted. That means the number and size of the scatter-gather buffers in both lists need not be the same, and that the operation functionally is equivalent to a ”…”�”}”(hjHh²hh³Nh´Nubj)�”}”(hŒ ``strncpy``”h]”hŒstrncpy”…”�”}”(hjPh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjHubhŒ where the ”…”�”}”(hjHh²hh³Nh´Nubj)�”}”(hŒ ``count``”h]”hŒcount”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjHubhŒP argument equals the smallest total size of the two scatter-gather list buffers.”…”�”}”(hjHh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K¥hjDubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj)ubjA)�”}”(hXCIt's usually used for copying pixel data between host memory and memory-mapped GPU device memory, such as found on modern PCI video graphics cards. The most immediate example is the OpenGL API function ``glReadPixels()``, which might require a verbatim copy of a huge framebuffer from local device memory onto host memory. ”h]”hÝ)�”}”(hXBIt's usually used for copying pixel data between host memory and memory-mapped GPU device memory, such as found on modern PCI video graphics cards. The most immediate example is the OpenGL API function ``glReadPixels()``, which might require a verbatim copy of a huge framebuffer from local device memory onto host memory.”h]”(hŒÌIt’s usually used for copying pixel data between host memory and memory-mapped GPU device memory, such as found on modern PCI video graphics cards. The most immediate example is the OpenGL API function ”…”�”}”(hj„h²hh³Nh´Nubj)�”}”(hŒ``glReadPixels()``”h]”hŒglReadPixels()”…”�”}”(hjŒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj„ubhŒf, which might require a verbatim copy of a huge framebuffer from local device memory onto host memory.”…”�”}”(hj„h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K¬hj€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj)ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´K£hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjh²hh³Nh´NubjA)�”}”(hŒ�DMA_XOR - The device is able to perform XOR operations on memory areas - Used to accelerate XOR intensive tasks, such as RAID5 ”h]”(hÝ)�”}”(hŒDMA_XOR”h]”hŒDMA_XOR”…”�”}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K²hj¶ubj<)�”}”(hhh]”(jA)�”}”(hŒ=The device is able to perform XOR operations on memory areas ”h]”hÝ)�”}”(hŒDMA_CYCLIC - The device can handle cyclic transfers. - A cyclic transfer is a transfer where the chunk collection will loop over itself, with the last item pointing to the first. - It's usually used for audio transfers, where you want to operate on a single ring buffer that you will fill with your audio data. ”h]”(hÝ)�”}”(hŒ DMA_CYCLIC”h]”hŒ DMA_CYCLIC”…”�”}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KðhjGubj<)�”}”(hhh]”(jA)�”}”(hŒ(The device can handle cyclic transfers. ”h]”hÝ)�”}”(hŒ'The device can handle cyclic transfers.”h]”hŒ'The device can handle cyclic transfers.”…”�”}”(hj`h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kòhj\ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjYubjA)�”}”(hŒ|A cyclic transfer is a transfer where the chunk collection will loop over itself, with the last item pointing to the first. ”h]”hÝ)�”}”(hŒ{A cyclic transfer is a transfer where the chunk collection will loop over itself, with the last item pointing to the first.”h]”hŒ{A cyclic transfer is a transfer where the chunk collection will loop over itself, with the last item pointing to the first.”…”�”}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kôhjtubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjYubjA)�”}”(hŒ‚It's usually used for audio transfers, where you want to operate on a single ring buffer that you will fill with your audio data. ”h]”hÝ)�”}”(hŒ�It's usually used for audio transfers, where you want to operate on a single ring buffer that you will fill with your audio data.”h]”hŒƒIt’s usually used for audio transfers, where you want to operate on a single ring buffer that you will fill with your audio data.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K÷hjŒubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjYubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´KòhjGubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjh²hh³Nh´NubjA)�”}”(hX¨DMA_INTERLEAVE - The device supports interleaved transfer. - These transfers can transfer data from a non-contiguous buffer to a non-contiguous buffer, opposed to DMA_SLAVE that can transfer data from a non-contiguous data set to a continuous destination buffer. - It's usually used for 2d content transfers, in which case you want to transfer a portion of uncompressed data directly to the display to print it ”h]”(hÝ)�”}”(hŒDMA_INTERLEAVE”h]”hŒDMA_INTERLEAVE”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kúhj°ubj<)�”}”(hhh]”(jA)�”}”(hŒ*The device supports interleaved transfer. ”h]”hÝ)�”}”(hŒ)The device supports interleaved transfer.”h]”hŒ)The device supports interleaved transfer.”…”�”}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KühjÅubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÂubjA)�”}”(hŒÊThese transfers can transfer data from a non-contiguous buffer to a non-contiguous buffer, opposed to DMA_SLAVE that can transfer data from a non-contiguous data set to a continuous destination buffer. ”h]”hÝ)�”}”(hŒÉThese transfers can transfer data from a non-contiguous buffer to a non-contiguous buffer, opposed to DMA_SLAVE that can transfer data from a non-contiguous data set to a continuous destination buffer.”h]”hŒÉThese transfers can transfer data from a non-contiguous buffer to a non-contiguous buffer, opposed to DMA_SLAVE that can transfer data from a non-contiguous data set to a continuous destination buffer.”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KþhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÂubjA)�”}”(hŒ’It's usually used for 2d content transfers, in which case you want to transfer a portion of uncompressed data directly to the display to print it ”h]”hÝ)�”}”(hŒ‘It's usually used for 2d content transfers, in which case you want to transfer a portion of uncompressed data directly to the display to print it”h]”hŒ“It’s usually used for 2d content transfers, in which case you want to transfer a portion of uncompressed data directly to the display to print it”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhjõubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÂubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´Kühj°ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjh²hh³Nh´NubjA)�”}”(hXDMA_COMPLETION_NO_ORDER - The device does not support in order completion. - The driver should return DMA_OUT_OF_ORDER for device_tx_status if the device is setting this capability. - All cookie tracking and checking API should be treated as invalid if the device exports this capability. - At this point, this is incompatible with polling option for dmatest. - If this cap is set, the user is recommended to provide an unique identifier for each descriptor sent to the DMA device in order to properly track the completion. ”h]”(hÝ)�”}”(hŒDMA_COMPLETION_NO_ORDER”h]”hŒDMA_COMPLETION_NO_ORDER”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhjubj<)�”}”(hhh]”(jA)�”}”(hŒ1The device does not support in order completion. ”h]”hÝ)�”}”(hŒ0The device does not support in order completion.”h]”hŒ0The device does not support in order completion.”…”�”}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M hj.ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj+ubjA)�”}”(hŒiThe driver should return DMA_OUT_OF_ORDER for device_tx_status if the device is setting this capability. ”h]”hÝ)�”}”(hŒhThe driver should return DMA_OUT_OF_ORDER for device_tx_status if the device is setting this capability.”h]”hŒhThe driver should return DMA_OUT_OF_ORDER for device_tx_status if the device is setting this capability.”…”�”}”(hjJh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M hjFubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj+ubjA)�”}”(hŒiAll cookie tracking and checking API should be treated as invalid if the device exports this capability. ”h]”hÝ)�”}”(hŒhAll cookie tracking and checking API should be treated as invalid if the device exports this capability.”h]”hŒhAll cookie tracking and checking API should be treated as invalid if the device exports this capability.”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhj^ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj+ubjA)�”}”(hŒEAt this point, this is incompatible with polling option for dmatest. ”h]”hÝ)�”}”(hŒDAt this point, this is incompatible with polling option for dmatest.”h]”hŒDAt this point, this is incompatible with polling option for dmatest.”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhjvubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj+ubjA)�”}”(hŒ¢If this cap is set, the user is recommended to provide an unique identifier for each descriptor sent to the DMA device in order to properly track the completion. ”h]”hÝ)�”}”(hŒ¡If this cap is set, the user is recommended to provide an unique identifier for each descriptor sent to the DMA device in order to properly track the completion.”h]”hŒ¡If this cap is set, the user is recommended to provide an unique identifier for each descriptor sent to the DMA device in order to properly track the completion.”…”�”}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MhjŽubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj+ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´M hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjh²hh³Nh´NubjA)�”}”(hX'DMA_REPEAT - The device supports repeated transfers. A repeated transfer, indicated by the DMA_PREP_REPEAT transfer flag, is similar to a cyclic transfer in that it gets automatically repeated when it ends, but can additionally be replaced by the client. - This feature is limited to interleaved transfers, this flag should thus not be set if the DMA_INTERLEAVE flag isn't set. This limitation is based on the current needs of DMA clients, support for additional transfer types should be added in the future if and when the need arises. ”h]”(hÝ)�”}”(hŒ DMA_REPEAT”h]”hŒ DMA_REPEAT”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhj²ubj<)�”}”(hhh]”(jA)�”}”(hŒòThe device supports repeated transfers. A repeated transfer, indicated by the DMA_PREP_REPEAT transfer flag, is similar to a cyclic transfer in that it gets automatically repeated when it ends, but can additionally be replaced by the client. ”h]”hÝ)�”}”(hŒñThe device supports repeated transfers. A repeated transfer, indicated by the DMA_PREP_REPEAT transfer flag, is similar to a cyclic transfer in that it gets automatically repeated when it ends, but can additionally be replaced by the client.”h]”hŒñThe device supports repeated transfers. A repeated transfer, indicated by the DMA_PREP_REPEAT transfer flag, is similar to a cyclic transfer in that it gets automatically repeated when it ends, but can additionally be replaced by the client.”…”�”}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MhjÇubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÄubjA)�”}”(hXThis feature is limited to interleaved transfers, this flag should thus not be set if the DMA_INTERLEAVE flag isn't set. This limitation is based on the current needs of DMA clients, support for additional transfer types should be added in the future if and when the need arises. ”h]”hÝ)�”}”(hXThis feature is limited to interleaved transfers, this flag should thus not be set if the DMA_INTERLEAVE flag isn't set. This limitation is based on the current needs of DMA clients, support for additional transfer types should be added in the future if and when the need arises.”h]”hXThis feature is limited to interleaved transfers, this flag should thus not be set if the DMA_INTERLEAVE flag isn’t set. This limitation is based on the current needs of DMA clients, support for additional transfer types should be added in the future if and when the need arises.”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhjßubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÄubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´Mhj²ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjh²hh³Nh´NubjA)�”}”(hXmDMA_LOAD_EOT - The device supports replacing repeated transfers at end of transfer (EOT) by queuing a new transfer with the DMA_PREP_LOAD_EOT flag set. - Support for replacing a currently running transfer at another point (such as end of burst instead of end of transfer) will be added in the future based on DMA clients needs, if and when the need arises. ”h]”(hÝ)�”}”(hŒ DMA_LOAD_EOT”h]”hŒ DMA_LOAD_EOT”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M#hj ubj<)�”}”(hhh]”(jA)�”}”(hŒ‰The device supports replacing repeated transfers at end of transfer (EOT) by queuing a new transfer with the DMA_PREP_LOAD_EOT flag set. ”h]”hÝ)�”}”(hŒˆThe device supports replacing repeated transfers at end of transfer (EOT) by queuing a new transfer with the DMA_PREP_LOAD_EOT flag set.”h]”hŒˆThe device supports replacing repeated transfers at end of transfer (EOT) by queuing a new transfer with the DMA_PREP_LOAD_EOT flag set.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M%hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj ubjA)�”}”(hŒËSupport for replacing a currently running transfer at another point (such as end of burst instead of end of transfer) will be added in the future based on DMA clients needs, if and when the need arises. ”h]”hÝ)�”}”(hŒÊSupport for replacing a currently running transfer at another point (such as end of burst instead of end of transfer) will be added in the future based on DMA clients needs, if and when the need arises.”h]”hŒÊSupport for replacing a currently running transfer at another point (such as end of burst instead of end of transfer) will be added in the future based on DMA clients needs, if and when the need arises.”…”�”}”(hj4 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M(hj0 ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´M%hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´K¡hj™h²hubhÝ)�”}”(hŒ_These various types will also affect how the source and destination addresses change over time.”h]”hŒ_These various types will also affect how the source and destination addresses change over time.”…”�”}”(hjZ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M,hj™h²hubhÝ)�”}”(hŒÜAddresses pointing to RAM are typically incremented (or decremented) after each transfer. In case of a ring buffer, they may loop (DMA_CYCLIC). Addresses pointing to a device's register (e.g. a FIFO) are typically fixed.”h]”hŒÞAddresses pointing to RAM are typically incremented (or decremented) after each transfer. In case of a ring buffer, they may loop (DMA_CYCLIC). Addresses pointing to a device’s register (e.g. a FIFO) are typically fixed.”…”�”}”(hjh h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M/hj™h²hubeh}”(h]”Œsupported-transaction-types”ah ]”h"]”Œsupported transaction types”ah$]”h&]”uh1hµhjíh²hh³hÊh´K’ubh¶)�”}”(hhh]”(h»)�”}”(hŒPer descriptor metadata support”h]”hŒPer descriptor metadata support”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj~ h²hh³hÊh´M5ubhÝ)�”}”(hXLSome data movement architecture (DMA controller and peripherals) uses metadata associated with a transaction. The DMA controller role is to transfer the payload and the metadata alongside. The metadata itself is not used by the DMA engine itself, but it contains parameters, keys, vectors, etc for peripheral or from the peripheral.”h]”hXLSome data movement architecture (DMA controller and peripherals) uses metadata associated with a transaction. The DMA controller role is to transfer the payload and the metadata alongside. The metadata itself is not used by the DMA engine itself, but it contains parameters, keys, vectors, etc for peripheral or from the peripheral.”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M6hj~ h²hubhÝ)�”}”(hŒòThe DMAengine framework provides a generic ways to facilitate the metadata for descriptors. Depending on the architecture the DMA driver can implement either or both of the methods and it is up to the client driver to choose which one to use.”h]”hŒòThe DMAengine framework provides a generic ways to facilitate the metadata for descriptors. Depending on the architecture the DMA driver can implement either or both of the methods and it is up to the client driver to choose which one to use.”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M<hj~ h²hubj<)�”}”(hhh]”(jA)�”}”(hXðDESC_METADATA_CLIENT The metadata buffer is allocated/provided by the client driver and it is attached (via the dmaengine_desc_attach_metadata() helper to the descriptor. From the DMA driver the following is expected for this mode: - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM The data from the provided metadata buffer should be prepared for the DMA controller to be sent alongside of the payload data. Either by copying to a hardware descriptor, or highly coupled packet. - DMA_DEV_TO_MEM On transfer completion the DMA driver must copy the metadata to the client provided metadata buffer before notifying the client about the completion. After the transfer completion, DMA drivers must not touch the metadata buffer provided by the client. ”h]”(hÝ)�”}”(hŒDESC_METADATA_CLIENT”h]”hŒDESC_METADATA_CLIENT”…”�”}”(hj² h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MAhj® ubhÝ)�”}”(hŒ•The metadata buffer is allocated/provided by the client driver and it is attached (via the dmaengine_desc_attach_metadata() helper to the descriptor.”h]”hŒ•The metadata buffer is allocated/provided by the client driver and it is attached (via the dmaengine_desc_attach_metadata() helper to the descriptor.”…”�”}”(hjÀ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MChj® ubhÝ)�”}”(hŒubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj;ubjA)�”}”(hŒqThis command should NOT perform synchronously, or on any currently queued transfers, but only on subsequent ones ”h]”hÝ)�”}”(hŒpThis command should NOT perform synchronously, or on any currently queued transfers, but only on subsequent ones”h]”hŒpThis command should NOT perform synchronously, or on any currently queued transfers, but only on subsequent ones”…”�”}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MÞhjVubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj;ubjA)�”}”(hŒŽIn this case, the function will receive a ``dma_slave_config`` structure pointer as an argument, that will detail which configuration to use. ”h]”hÝ)�”}”(hŒ�In this case, the function will receive a ``dma_slave_config`` structure pointer as an argument, that will detail which configuration to use.”h]”(hŒ*In this case, the function will receive a ”…”�”}”(hjrh²hh³Nh´Nubj)�”}”(hŒ``dma_slave_config``”h]”hŒdma_slave_config”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjrubhŒO structure pointer as an argument, that will detail which configuration to use.”…”�”}”(hjrh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Máhjnubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj;ubjA)�”}”(hŒ‘Even though that structure contains a direction field, this field is deprecated in favor of the direction argument given to the prep_* functions ”h]”hÝ)�”}”(hŒ�Even though that structure contains a direction field, this field is deprecated in favor of the direction argument given to the prep_* functions”h]”hŒ�Even though that structure contains a direction field, this field is deprecated in favor of the direction argument given to the prep_* functions”…”�”}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Måhj˜ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj;ubjA)�”}”(hŒÛThis call is mandatory for slave operations only. This should NOT be set or expected to be set for memcpy operations. If a driver support both, it should use this call for slave operations only and not for memcpy ones. ”h]”hÝ)�”}”(hŒÚThis call is mandatory for slave operations only. This should NOT be set or expected to be set for memcpy operations. If a driver support both, it should use this call for slave operations only and not for memcpy ones.”h]”hŒÚThis call is mandatory for slave operations only. This should NOT be set or expected to be set for memcpy operations. If a driver support both, it should use this call for slave operations only and not for memcpy ones.”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Méhj°ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj;ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´MÜhj)ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hj h²hh³Nh´NubjA)�”}”(hŒ¡device_pause - Pauses a transfer on the channel - This command should operate synchronously on the channel, pausing right away the work of the given channel ”h]”(hÝ)�”}”(hŒ device_pause”h]”hŒ device_pause”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MîhjÔubj<)�”}”(hhh]”(jA)�”}”(hŒ!Pauses a transfer on the channel ”h]”hÝ)�”}”(hŒ Pauses a transfer on the channel”h]”hŒ Pauses a transfer on the channel”…”�”}”(hjíh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mðhjéubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjæubjA)�”}”(hŒkThis command should operate synchronously on the channel, pausing right away the work of the given channel ”h]”hÝ)�”}”(hŒjThis command should operate synchronously on the channel, pausing right away the work of the given channel”h]”hŒjThis command should operate synchronously on the channel, pausing right away the work of the given channel”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mòhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjæubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´MðhjÔubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hj h²hh³Nh´NubjA)�”}”(hŒ¤device_resume - Resumes a transfer on the channel - This command should operate synchronously on the channel, resuming right away the work of the given channel ”h]”(hÝ)�”}”(hŒ device_resume”h]”hŒ device_resume”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mõhj%ubj<)�”}”(hhh]”(jA)�”}”(hŒ"Resumes a transfer on the channel ”h]”hÝ)�”}”(hŒ!Resumes a transfer on the channel”h]”hŒ!Resumes a transfer on the channel”…”�”}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M÷hj:ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj7ubjA)�”}”(hŒlThis command should operate synchronously on the channel, resuming right away the work of the given channel ”h]”hÝ)�”}”(hŒkThis command should operate synchronously on the channel, resuming right away the work of the given channel”h]”hŒkThis command should operate synchronously on the channel, resuming right away the work of the given channel”…”�”}”(hjVh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MùhjRubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj7ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´M÷hj%ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hj h²hh³Nh´NubjA)�”}”(hXÑdevice_terminate_all - Aborts all the pending and ongoing transfers on the channel - For aborted transfers the complete callback should not be called - Can be called from atomic context or from within a complete callback of a descriptor. Must not sleep. Drivers must be able to handle this correctly. - Termination may be asynchronous. The driver does not have to wait until the currently active transfer has completely stopped. See device_synchronize. ”h]”(hÝ)�”}”(hŒdevice_terminate_all”h]”hŒdevice_terminate_all”…”�”}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mühjvubj<)�”}”(hhh]”(jA)�”}”(hŒhjõubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³hÊh´NubjA)�”}”(hŒvThe descriptor should be prepared for reuse by invoking ``dmaengine_desc_set_reuse()`` which will set DMA_CTRL_REUSE. ”h]”hÝ)�”}”(hŒuThe descriptor should be prepared for reuse by invoking ``dmaengine_desc_set_reuse()`` which will set DMA_CTRL_REUSE.”h]”(hŒ8The descriptor should be prepared for reuse by invoking ”…”�”}”(hjh²hh³Nh´Nubj)�”}”(hŒ``dmaengine_desc_set_reuse()``”h]”hŒdmaengine_desc_set_reuse()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhŒ which will set DMA_CTRL_REUSE.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MAhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³hÊh´NubjA)�”}”(hŒw``dmaengine_desc_set_reuse()`` will succeed only when channel support reusable descriptor as exhibited by capabilities ”h]”hÝ)�”}”(hŒv``dmaengine_desc_set_reuse()`` will succeed only when channel support reusable descriptor as exhibited by capabilities”h]”(j)�”}”(hŒ``dmaengine_desc_set_reuse()``”h]”hŒdmaengine_desc_set_reuse()”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj;ubhŒX will succeed only when channel support reusable descriptor as exhibited by capabilities”…”�”}”(hj;h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MDhj7ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³hÊh´NubjA)�”}”(hŒÔAs a consequence, if a device driver wants to skip the ``dma_map_sg()`` and ``dma_unmap_sg()`` in between 2 transfers, because the DMA'd data wasn't used, it can resubmit the transfer right after its completion. ”h]”hÝ)�”}”(hŒÓAs a consequence, if a device driver wants to skip the ``dma_map_sg()`` and ``dma_unmap_sg()`` in between 2 transfers, because the DMA'd data wasn't used, it can resubmit the transfer right after its completion.”h]”(hŒ7As a consequence, if a device driver wants to skip the ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ``dma_map_sg()``”h]”hŒ dma_map_sg()”…”�”}”(hjih²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒ and ”…”�”}”(hjah²hh³Nh´Nubj)�”}”(hŒ``dma_unmap_sg()``”h]”hŒdma_unmap_sg()”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubhŒy in between 2 transfers, because the DMA’d data wasn’t used, it can resubmit the transfer right after its completion.”…”�”}”(hjah²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MGhj]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³hÊh´NubjA)�”}”(hXDescriptor can be freed in few ways - Clearing DMA_CTRL_REUSE by invoking ``dmaengine_desc_clear_reuse()`` and submitting for last txn - Explicitly invoking ``dmaengine_desc_free()``, this can succeed only when DMA_CTRL_REUSE is already set - Terminating the channel ”h]”(hÝ)�”}”(hŒ#Descriptor can be freed in few ways”h]”hŒ#Descriptor can be freed in few ways”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MLhj™ubj<)�”}”(hhh]”(jA)�”}”(hŒaClearing DMA_CTRL_REUSE by invoking ``dmaengine_desc_clear_reuse()`` and submitting for last txn ”h]”hÝ)�”}”(hŒ`Clearing DMA_CTRL_REUSE by invoking ``dmaengine_desc_clear_reuse()`` and submitting for last txn”h]”(hŒ$Clearing DMA_CTRL_REUSE by invoking ”…”�”}”(hj²h²hh³Nh´Nubj)�”}”(hŒ ``dmaengine_desc_clear_reuse()``”h]”hŒdmaengine_desc_clear_reuse()”…”�”}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj²ubhŒ and submitting for last txn”…”�”}”(hj²h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MNhj®ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj«ubjA)�”}”(hŒhExplicitly invoking ``dmaengine_desc_free()``, this can succeed only when DMA_CTRL_REUSE is already set ”h]”hÝ)�”}”(hŒgExplicitly invoking ``dmaengine_desc_free()``, this can succeed only when DMA_CTRL_REUSE is already set”h]”(hŒExplicitly invoking ”…”�”}”(hjÜh²hh³Nh´Nubj)�”}”(hŒ``dmaengine_desc_free()``”h]”hŒdmaengine_desc_free()”…”�”}”(hjäh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÜubhŒ:, this can succeed only when DMA_CTRL_REUSE is already set”…”�”}”(hjÜh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MQhjØubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj«ubjA)�”}”(hŒTerminating the channel ”h]”hÝ)�”}”(hŒTerminating the channel”h]”hŒTerminating the channel”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MThjubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj«ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´MNhj™ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³Nh´NubjA)�”}”(hX_DMA_PREP_CMD - If set, the client driver tells DMA controller that passed data in DMA API is command data. - Interpretation of command data is DMA controller specific. It can be used for issuing commands to other peripherals/register reads/register writes for which the descriptor should be in different format from normal data descriptors. ”h]”(hÝ)�”}”(hŒ DMA_PREP_CMD”h]”hŒ DMA_PREP_CMD”…”�”}”(hj*h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MVhj&ubj<)�”}”(hhh]”(jA)�”}”(hŒ\If set, the client driver tells DMA controller that passed data in DMA API is command data. ”h]”hÝ)�”}”(hŒ[If set, the client driver tells DMA controller that passed data in DMA API is command data.”h]”hŒ[If set, the client driver tells DMA controller that passed data in DMA API is command data.”…”�”}”(hj?h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MXhj;ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj8ubjA)�”}”(hŒèInterpretation of command data is DMA controller specific. It can be used for issuing commands to other peripherals/register reads/register writes for which the descriptor should be in different format from normal data descriptors. ”h]”hÝ)�”}”(hŒçInterpretation of command data is DMA controller specific. It can be used for issuing commands to other peripherals/register reads/register writes for which the descriptor should be in different format from normal data descriptors.”h]”hŒçInterpretation of command data is DMA controller specific. It can be used for issuing commands to other peripherals/register reads/register writes for which the descriptor should be in different format from normal data descriptors.”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M[hjSubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj8ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´MXhj&ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³Nh´NubjA)�”}”(hX³DMA_PREP_REPEAT - If set, the transfer will be automatically repeated when it ends until a new transfer is queued on the same channel with the DMA_PREP_LOAD_EOT flag. If the next transfer to be queued on the channel does not have the DMA_PREP_LOAD_EOT flag set, the current transfer will be repeated until the client terminates all transfers. - This flag is only supported if the channel reports the DMA_REPEAT capability. ”h]”(hÝ)�”}”(hŒDMA_PREP_REPEAT”h]”hŒDMA_PREP_REPEAT”…”�”}”(hj{h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M`hjwubj<)�”}”(hhh]”(jA)�”}”(hXEIf set, the transfer will be automatically repeated when it ends until a new transfer is queued on the same channel with the DMA_PREP_LOAD_EOT flag. If the next transfer to be queued on the channel does not have the DMA_PREP_LOAD_EOT flag set, the current transfer will be repeated until the client terminates all transfers. ”h]”hÝ)�”}”(hXDIf set, the transfer will be automatically repeated when it ends until a new transfer is queued on the same channel with the DMA_PREP_LOAD_EOT flag. If the next transfer to be queued on the channel does not have the DMA_PREP_LOAD_EOT flag set, the current transfer will be repeated until the client terminates all transfers.”h]”hXDIf set, the transfer will be automatically repeated when it ends until a new transfer is queued on the same channel with the DMA_PREP_LOAD_EOT flag. If the next transfer to be queued on the channel does not have the DMA_PREP_LOAD_EOT flag set, the current transfer will be repeated until the client terminates all transfers.”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MbhjŒubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj‰ubjA)�”}”(hŒNThis flag is only supported if the channel reports the DMA_REPEAT capability. ”h]”hÝ)�”}”(hŒMThis flag is only supported if the channel reports the DMA_REPEAT capability.”h]”hŒMThis flag is only supported if the channel reports the DMA_REPEAT capability.”…”�”}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhhj¤ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj‰ubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´Mbhjwubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³Nh´NubjA)�”}”(hX´DMA_PREP_LOAD_EOT - If set, the transfer will replace the transfer currently being executed at the end of the transfer. - This is the default behaviour for non-repeated transfers, specifying DMA_PREP_LOAD_EOT for non-repeated transfers will thus make no difference. - When using repeated transfers, DMA clients will usually need to set the DMA_PREP_LOAD_EOT flag on all transfers, otherwise the channel will keep repeating the last repeated transfer and ignore the new transfers being queued. Failure to set DMA_PREP_LOAD_EOT will appear as if the channel was stuck on the previous transfer. - This flag is only supported if the channel reports the DMA_LOAD_EOT capability. ”h]”(hÝ)�”}”(hŒDMA_PREP_LOAD_EOT”h]”hŒDMA_PREP_LOAD_EOT”…”�”}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MkhjÈubj<)�”}”(hhh]”(jA)�”}”(hŒdIf set, the transfer will replace the transfer currently being executed at the end of the transfer. ”h]”hÝ)�”}”(hŒcIf set, the transfer will replace the transfer currently being executed at the end of the transfer.”h]”hŒcIf set, the transfer will replace the transfer currently being executed at the end of the transfer.”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MmhjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÚubjA)�”}”(hŒ�This is the default behaviour for non-repeated transfers, specifying DMA_PREP_LOAD_EOT for non-repeated transfers will thus make no difference. ”h]”hÝ)�”}”(hŒ�This is the default behaviour for non-repeated transfers, specifying DMA_PREP_LOAD_EOT for non-repeated transfers will thus make no difference.”h]”hŒ�This is the default behaviour for non-repeated transfers, specifying DMA_PREP_LOAD_EOT for non-repeated transfers will thus make no difference.”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mphjõubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÚubjA)�”}”(hXDWhen using repeated transfers, DMA clients will usually need to set the DMA_PREP_LOAD_EOT flag on all transfers, otherwise the channel will keep repeating the last repeated transfer and ignore the new transfers being queued. Failure to set DMA_PREP_LOAD_EOT will appear as if the channel was stuck on the previous transfer. ”h]”hÝ)�”}”(hXCWhen using repeated transfers, DMA clients will usually need to set the DMA_PREP_LOAD_EOT flag on all transfers, otherwise the channel will keep repeating the last repeated transfer and ignore the new transfers being queued. Failure to set DMA_PREP_LOAD_EOT will appear as if the channel was stuck on the previous transfer.”h]”hXCWhen using repeated transfers, DMA clients will usually need to set the DMA_PREP_LOAD_EOT flag on all transfers, otherwise the channel will keep repeating the last repeated transfer and ignore the new transfers being queued. Failure to set DMA_PREP_LOAD_EOT will appear as if the channel was stuck on the previous transfer.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mshj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÚubjA)�”}”(hŒPThis flag is only supported if the channel reports the DMA_LOAD_EOT capability. ”h]”hÝ)�”}”(hŒOThis flag is only supported if the channel reports the DMA_LOAD_EOT capability.”h]”hŒOThis flag is only supported if the channel reports the DMA_LOAD_EOT capability.”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Myhj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hjÚubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´MmhjÈubeh}”(h]”h ]”h"]”h$]”h&]”uh1j@hjòh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´M>hjŽh²hubeh}”(h]”Œ misc-notes”ah ]”h"]”Œ misc notes”ah$]”h&]”uh1hµhh·h²hh³hÊh´Mubh¶)�”}”(hhh]”(h»)�”}”(hŒGeneral Design Notes”h]”hŒGeneral Design Notes”…”�”}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjWh²hh³hÊh´M}ubhÝ)�”}”(hŒðMost of the DMAEngine drivers you'll see are based on a similar design that handles the end of transfer interrupts in the handler, but defer most work to a tasklet, including the start of a new transfer whenever the previous transfer ended.”h]”hŒòMost of the DMAEngine drivers you’ll see are based on a similar design that handles the end of transfer interrupts in the handler, but defer most work to a tasklet, including the start of a new transfer whenever the previous transfer ended.”…”�”}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MhjWh²hubhÝ)�”}”(hXThis is a rather inefficient design though, because the inter-transfer latency will be not only the interrupt latency, but also the scheduling latency of the tasklet, which will leave the channel idle in between, which will slow down the global transfer rate.”h]”hXThis is a rather inefficient design though, because the inter-transfer latency will be not only the interrupt latency, but also the scheduling latency of the tasklet, which will leave the channel idle in between, which will slow down the global transfer rate.”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M„hjWh²hubhÝ)�”}”(hŒÓYou should avoid this kind of practice, and instead of electing a new transfer in your tasklet, move that part to the interrupt handler in order to have a shorter idle window (that we can't really avoid anyway).”h]”hŒÕYou should avoid this kind of practice, and instead of electing a new transfer in your tasklet, move that part to the interrupt handler in order to have a shorter idle window (that we can’t really avoid anyway).”…”�”}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M‰hjWh²hubeh}”(h]”Œgeneral-design-notes”ah ]”h"]”Œgeneral design notes”ah$]”h&]”uh1hµhh·h²hh³hÊh´M}ubh¶)�”}”(hhh]”(h»)�”}”(hŒGlossary”h]”hŒGlossary”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjšh²hh³hÊh´M�ubj<)�”}”(hhh]”(jA)�”}”(hŒvBurst: A number of consecutive read or write operations that can be queued to buffers before being flushed to memory. ”h]”hÝ)�”}”(hŒuBurst: A number of consecutive read or write operations that can be queued to buffers before being flushed to memory.”h]”hŒuBurst: A number of consecutive read or write operations that can be queued to buffers before being flushed to memory.”…”�”}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M‘hj®ubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj«h²hh³hÊh´NubjA)�”}”(hŒ)Chunk: A contiguous collection of bursts ”h]”hÝ)�”}”(hŒ(Chunk: A contiguous collection of bursts”h]”hŒ(Chunk: A contiguous collection of bursts”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M”hjÆubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj«h²hh³hÊh´NubjA)�”}”(hŒ:Transfer: A collection of chunks (be it contiguous or not)”h]”hÝ)�”}”(hjàh]”hŒ:Transfer: A collection of chunks (be it contiguous or not)”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M–hjÞubah}”(h]”h ]”h"]”h$]”h&]”uh1j@hj«h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jKjLuh1j;h³hÊh´M‘hjšh²hubeh}”(h]”Œglossary”ah ]”h"]”Œglossary”ah$]”h&]”uh1hµhh·h²hh³hÊh´M�ubeh}”(h]”Œ"dmaengine-controller-documentation”ah ]”h"]”Œ"dmaengine controller documentation”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j.Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jjj§j¤jêjçj‹jˆj–j“j{ jx jÙ jÖ jƒj€jTjQj—j”jjýuŒ nametypes”}”(j‰j§‰jê‰j‹‰j–‰j{ ‰jÙ ‰jƒ‰jT‰j—‰j‰uh}”(jh·j¤hËjçjªjˆjíj“jþjx j™jÖ j~ j€jÜ jQjŽj”jWjýjšuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.