sound/soc/sof/intel/hda-stream.c
Source file repositories/reference/linux-study-clean/sound/soc/sof/intel/hda-stream.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/sof/intel/hda-stream.c- Extension
.c- Size
- 39109 bytes
- Lines
- 1366
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
sound/hdaudio_ext.hsound/hda_register.hsound/sof.htrace/events/sof_intel.h../ops.h../sof-audio.h../ipc4-priv.hhda.h
Detected Declarations
function hda_setup_bdlefunction Listfunction hda_dsp_stream_spib_configfunction _hda_dsp_stream_getfunction hda_dsp_stream_getfunction hda_dsp_stream_pair_getfunction _hda_dsp_stream_putfunction hda_dsp_stream_putfunction hda_dsp_stream_pair_putfunction hda_dsp_stream_resetfunction hda_dsp_stream_triggerfunction hda_dsp_iccmax_stream_hw_paramsfunction hda_dsp_stream_hw_paramsfunction hda_dsp_stream_hw_freefunction hda_dsp_check_stream_irqfunction hda_dsp_compr_bytes_transferredfunction hda_dsp_stream_checkfunction list_for_each_entryfunction hda_dsp_stream_threaded_handlerfunction hda_dsp_stream_initfunction hda_dsp_stream_freefunction list_for_each_entry_safefunction hda_dsp_stream_get_positionfunction hda_dsp_get_stream_llpfunction hda_dsp_get_stream_ldpfunction hda_data_stream_preparefunction stackfunction hda_data_stream_cleanup
Annotated Snippet
if (hstream->frags >= HDA_DSP_MAX_BDL_ENTRIES) {
dev_err(sdev->dev, "error: stream frags exceeded\n");
return -EINVAL;
}
addr = snd_sgbuf_get_addr(dmab, offset);
/* program BDL addr */
bdl->addr_l = cpu_to_le32(lower_32_bits(addr));
bdl->addr_h = cpu_to_le32(upper_32_bits(addr));
/* program BDL size */
chunk = snd_sgbuf_get_chunk_size(dmab, offset, size);
/* one BDLE should not cross 4K boundary */
if (bus->align_bdle_4k) {
u32 remain = 0x1000 - (offset & 0xfff);
if (chunk > remain)
chunk = remain;
}
bdl->size = cpu_to_le32(chunk);
/* only program IOC when the whole segment is processed */
size -= chunk;
bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01);
bdl++;
hstream->frags++;
offset += chunk;
}
*bdlp = bdl;
return offset;
}
/*
* set up Buffer Descriptor List (BDL) for host memory transfer
* BDL describes the location of the individual buffers and is little endian.
*/
int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
struct snd_dma_buffer *dmab,
struct hdac_stream *hstream)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct sof_intel_dsp_bdl *bdl;
int i, offset, period_bytes, periods;
int remain, ioc;
period_bytes = hstream->period_bytes;
dev_dbg(sdev->dev, "period_bytes: %#x, bufsize: %#x\n", period_bytes,
hstream->bufsize);
if (!period_bytes) {
unsigned int chunk_size;
chunk_size = snd_sgbuf_get_chunk_size(dmab, 0, hstream->bufsize);
period_bytes = hstream->bufsize;
/*
* HDA spec demands that the LVI value must be at least one
* before the DMA operation can begin. This means that there
* must be at least two BDLE present for the transfer.
*
* If the buffer is not a single continuous area then the
* hda_setup_bdle() will create multiple BDLEs for each segment.
* If the memory is a single continuous area, force it to be
* split into two 'periods', otherwise the transfer will be
* split to multiple BDLE for each chunk in hda_setup_bdle()
*
* Note: period_bytes == 0 can only happen for firmware or
* library loading. The data size is 4K aligned, which ensures
* that the second chunk's start address will be 128-byte
* aligned.
*/
if (chunk_size == hstream->bufsize)
period_bytes /= 2;
}
periods = hstream->bufsize / period_bytes;
dev_dbg(sdev->dev, "periods: %d\n", periods);
remain = hstream->bufsize % period_bytes;
if (remain)
periods++;
/* program the initial BDL entries */
bdl = (struct sof_intel_dsp_bdl *)hstream->bdl.area;
offset = 0;
hstream->frags = 0;
/*
* set IOC if don't use position IPC
Annotation
- Immediate include surface: `sound/hdaudio_ext.h`, `sound/hda_register.h`, `sound/sof.h`, `trace/events/sof_intel.h`, `../ops.h`, `../sof-audio.h`, `../ipc4-priv.h`, `hda.h`.
- Detected declarations: `function hda_setup_bdle`, `function List`, `function hda_dsp_stream_spib_config`, `function _hda_dsp_stream_get`, `function hda_dsp_stream_get`, `function hda_dsp_stream_pair_get`, `function _hda_dsp_stream_put`, `function hda_dsp_stream_put`, `function hda_dsp_stream_pair_put`, `function hda_dsp_stream_reset`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.