atc_get_llis_residue(9)
π atc_get_llis_residue β from the Kernel API Manual, bestie
okay so this is a <pink>kernel API</pink> page, section 9, and it's literally all about getting the residue for a hardware linked list transfer. no cap. let's get into it π«Ά
β¨ NAME β¨
atc_get_llis_residue β Get residue for a hardware linked list transfer π
πΈ SYNOPSIS πΈ
int atc_get_llis_residue (struct at_dma_chan *atchan , struct at_desc
*desc , u32 *residue );
like, that's the whole signature, slay π
π¦ ARGUMENTS π¦
atchanβ pointer to an atmel hdmac channel. that's your channel, bestie πdescβ pointer to the descriptor for which the residue is calculated. it's giving "the thing we're doing math on" β¨residueβ the residue to be set todma_tx_state. this is where the answer goes π
π DESCRIPTION π
so here's the vibe: we're calculating the residue by removing the length of the Linked List Item (LLI) that's already been transferred from the total length. to get the current LLI, we can use the value in the channel's DSCR register and compare it against the DSCR value of each LLI. lowkey iconic π₯
the CTRLA register hands us the amount of data already read from the source for the LLI. so we can compute a way more accurate residue by also removing the number of bytes that correspond to this amount of data. highkey precise π
but β and this is the part where it gets messy π β the DSCR and CTRLA registers cannot be read both atomically. so a race condition may occur: the first read register may refer to one LLI, whereas the second read may refer to a later LLI in the list, because of the DMA transfer progression in between the two reads. it's giving "two different chapters of the same book" π
one solution could have been to pause the DMA transfer, read the DSCR and CTRLA, then resume the DMA transfer. nonetheless, this approach presents some drawbacks:
- if the DMA transfer is paused, RX overruns or TX underruns are more likely to occur, depending on the system latency. taking the
USARTdriver as an example: it uses a cyclic DMA transfer to read data from the Receive Holding Register (RHR) to avoid RX overruns, since theRHRis not protected by any FIFO on most Atmel SoCs. so pausing the DMA transfer to compute the residue would break theUSARTdriver design. not the move π - the
atc_pausefunction masks interrupts, but we'd rather avoid doing so, for system latency purposes. yeah. no thanks β¨
so we'd rather use another solution instead: the DSCR is read a first time, the CTRLA is read in turn, and next the DSCR is read a second time. if the two consecutive read values of the DSCR are the same, then we assume both refer to the very same LLI β and that the CTRLA value read in between does too. for cyclic transfers, the assumption is that a full loop is "not so fast". if the two DSCR values are different, we read the CTRLA again, then the DSCR, till two consecutive read values from DSCR are equal, or till the maximum trials is reached. this algorithm is very unlikely not to find a stable value for DSCR. she's persistent, okay? πͺ
β RETURN β
0 on success, -errno otherwise. classic π
π SEE ALSO π
- Kernel file
./drivers/dma/at_hdmac.c struct atdma_sg(9)struct at_desc(9)enum atc_status(9)struct at_dma_chan(9)struct at_dma(9)atc_chan_is_enabled(9)atc_chan_is_paused(9)atc_chan_is_cyclic(9)set_lli_eol(9)struct at_dma_platform_data(9)struct at_dma_slave(9)atc_dostart(9)atc_calc_bytes_left(9)atc_get_residue(9)atc_handle_error(9)atc_prep_dma_interleaved(9)atc_prep_dma_memcpy(9)atc_prep_dma_memset(9)atc_prep_slave_sg(9)atc_prep_dma_cyclic(9)atc_tx_status(9)atc_alloc_chan_resources(9)atc_free_chan_resources(9)at_dma_off(9)
okay that's the whole page, go read the source bestie, ily π§ββοΈπ
this one lives in ./drivers/dma, dated October 2026. periodt. ππ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms