sound/soc/sof/sof-client-ipc-msg-injector.c
Source file repositories/reference/linux-study-clean/sound/soc/sof/sof-client-ipc-msg-injector.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/sof/sof-client-ipc-msg-injector.c- Extension
.c- Size
- 8679 bytes
- Lines
- 344
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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
linux/auxiliary_bus.hlinux/completion.hlinux/debugfs.hlinux/ktime.hlinux/mod_devicetable.hlinux/module.hlinux/pm_runtime.hlinux/slab.hlinux/uaccess.hsound/sof/header.hsound/sof/ipc4/header.hsof-client.h
Detected Declarations
struct sof_msg_inject_privfunction sof_msg_inject_dfs_openfunction sof_msg_inject_dfs_readfunction sof_msg_inject_ipc4_dfs_readfunction sof_msg_inject_send_messagefunction sof_msg_inject_dfs_writefunction sof_msg_inject_ipc4_dfs_writefunction sof_msg_inject_dfs_releasefunction sof_msg_inject_probefunction sof_msg_inject_remove
Annotated Snippet
static const struct file_operations sof_msg_inject_fops = {
.open = sof_msg_inject_dfs_open,
.read = sof_msg_inject_dfs_read,
.write = sof_msg_inject_dfs_write,
.llseek = default_llseek,
.release = sof_msg_inject_dfs_release,
.owner = THIS_MODULE,
};
static const struct file_operations sof_msg_inject_ipc4_fops = {
.open = sof_msg_inject_dfs_open,
.read = sof_msg_inject_ipc4_dfs_read,
.write = sof_msg_inject_ipc4_dfs_write,
.llseek = default_llseek,
.release = sof_msg_inject_dfs_release,
.owner = THIS_MODULE,
};
static int sof_msg_inject_probe(struct auxiliary_device *auxdev,
const struct auxiliary_device_id *id)
{
struct sof_client_dev *cdev = auxiliary_dev_to_sof_client_dev(auxdev);
struct dentry *debugfs_root = sof_client_get_debugfs_root(cdev);
static const struct file_operations *fops;
struct device *dev = &auxdev->dev;
struct sof_msg_inject_priv *priv;
size_t alloc_size;
/* allocate memory for client data */
priv = devm_kzalloc(&auxdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->ipc_type = sof_client_get_ipc_type(cdev);
priv->max_msg_size = sof_client_get_ipc_max_payload_size(cdev);
alloc_size = priv->max_msg_size;
if (priv->ipc_type == SOF_IPC_TYPE_4)
alloc_size += sizeof(struct sof_ipc4_msg);
priv->tx_buffer = devm_kmalloc(dev, alloc_size, GFP_KERNEL);
priv->rx_buffer = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
if (!priv->tx_buffer || !priv->rx_buffer)
return -ENOMEM;
if (priv->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_msg *ipc4_msg;
ipc4_msg = priv->tx_buffer;
ipc4_msg->data_ptr = priv->tx_buffer + sizeof(struct sof_ipc4_msg);
ipc4_msg = priv->rx_buffer;
ipc4_msg->data_ptr = priv->rx_buffer + sizeof(struct sof_ipc4_msg);
fops = &sof_msg_inject_ipc4_fops;
} else {
fops = &sof_msg_inject_fops;
}
cdev->data = priv;
priv->dfs_file = debugfs_create_file("ipc_msg_inject", 0644, debugfs_root,
cdev, fops);
/* enable runtime PM */
pm_runtime_set_autosuspend_delay(dev, SOF_IPC_CLIENT_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);
pm_runtime_mark_last_busy(dev);
pm_runtime_idle(dev);
return 0;
}
static void sof_msg_inject_remove(struct auxiliary_device *auxdev)
{
struct sof_client_dev *cdev = auxiliary_dev_to_sof_client_dev(auxdev);
struct sof_msg_inject_priv *priv = cdev->data;
pm_runtime_disable(&auxdev->dev);
debugfs_remove(priv->dfs_file);
}
static const struct auxiliary_device_id sof_msg_inject_client_id_table[] = {
{ .name = "snd_sof.msg_injector" },
{},
};
Annotation
- Immediate include surface: `linux/auxiliary_bus.h`, `linux/completion.h`, `linux/debugfs.h`, `linux/ktime.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/pm_runtime.h`, `linux/slab.h`.
- Detected declarations: `struct sof_msg_inject_priv`, `function sof_msg_inject_dfs_open`, `function sof_msg_inject_dfs_read`, `function sof_msg_inject_ipc4_dfs_read`, `function sof_msg_inject_send_message`, `function sof_msg_inject_dfs_write`, `function sof_msg_inject_ipc4_dfs_write`, `function sof_msg_inject_dfs_release`, `function sof_msg_inject_probe`, `function sof_msg_inject_remove`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
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.