drivers/hwtracing/intel_th/msu.c
Source file repositories/reference/linux-study-clean/drivers/hwtracing/intel_th/msu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwtracing/intel_th/msu.c- Extension
.c- Size
- 50317 bytes
- Lines
- 2205
- Domain
- Driver Families
- Bucket
- drivers/hwtracing
- 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.
- 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
linux/types.hlinux/module.hlinux/device.hlinux/uaccess.hlinux/sizes.hlinux/printk.hlinux/slab.hlinux/mm.hlinux/fs.hlinux/io.hlinux/workqueue.hlinux/dma-mapping.hasm/set_memory.hlinux/intel_th.hintel_th.hmsu.h
Detected Declarations
struct msc_windowstruct msc_iterstruct mscstruct msu_buffer_entrystruct msc_win_to_user_structenum lockout_statefunction list_for_each_entryfunction msu_buffer_getfunction msu_buffer_putfunction intel_th_msu_buffer_registerfunction intel_th_msu_buffer_unregisterfunction msc_block_is_emptyfunction msc_win_base_dmafunction msc_win_base_pfnfunction msc_is_last_winfunction msc_next_windowfunction msc_win_total_szfunction for_each_sgfunction msc_find_windowfunction msc_oldest_windowfunction msc_win_oldest_sgfunction msc_iter_removefunction msc_iter_block_startfunction msc_iter_win_startfunction msc_iter_win_advancefunction msc_iter_block_advancefunction msc_buffer_iteratefunction timefunction msc_buffer_clear_hw_headerfunction list_for_each_entryfunction for_each_sgfunction intel_th_msu_initfunction intel_th_msu_deinitfunction msc_win_set_lockoutfunction msc_configurefunction msc_disablefunction intel_th_msc_activatefunction intel_th_msc_deactivatefunction msc_buffer_contig_allocfunction msc_buffer_contig_freefunction msc_buffer_contig_get_pagefunction __msc_buffer_win_allocfunction for_each_sgfunction msc_buffer_set_ucfunction list_for_each_entryfunction msc_buffer_set_wbfunction list_for_each_entryfunction msc_buffer_set_uc
Annotated Snippet
static const struct file_operations intel_th_msc_fops = {
.open = intel_th_msc_open,
.release = intel_th_msc_release,
.read = intel_th_msc_read,
.mmap = intel_th_msc_mmap,
.owner = THIS_MODULE,
};
static void intel_th_msc_wait_empty(struct intel_th_device *thdev)
{
struct msc *msc = dev_get_drvdata(&thdev->dev);
unsigned long count;
u32 reg;
for (reg = 0, count = MSC_PLE_WAITLOOP_DEPTH;
count && !(reg & MSCSTS_PLE); count--) {
reg = __raw_readl(msc->reg_base + REG_MSU_MSC0STS);
cpu_relax();
}
if (!count)
dev_dbg(msc_dev(msc), "timeout waiting for MSC0 PLE\n");
}
static int intel_th_msc_init(struct msc *msc)
{
atomic_set(&msc->user_count, -1);
msc->mode = msc->multi_is_broken ? MSC_MODE_SINGLE : MSC_MODE_MULTI;
mutex_init(&msc->buf_mutex);
INIT_LIST_HEAD(&msc->win_list);
INIT_LIST_HEAD(&msc->iter_list);
msc->burst_len =
(ioread32(msc->reg_base + REG_MSU_MSC0CTL) & MSC_LEN) >>
__ffs(MSC_LEN);
return 0;
}
static int msc_win_switch(struct msc *msc)
{
struct msc_window *first;
if (list_empty(&msc->win_list))
return -EINVAL;
first = list_first_entry(&msc->win_list, struct msc_window, entry);
if (msc_is_last_win(msc->cur_win))
msc->cur_win = first;
else
msc->cur_win = list_next_entry(msc->cur_win, entry);
msc->base = msc_win_base(msc->cur_win);
msc->base_addr = msc_win_base_dma(msc->cur_win);
intel_th_trace_switch(msc->thdev);
return 0;
}
/**
* intel_th_msc_window_unlock - put the window back in rotation
* @dev: MSC device to which this relates
* @sgt: buffer's sg_table for the window, does nothing if NULL
*/
void intel_th_msc_window_unlock(struct device *dev, struct sg_table *sgt)
{
struct msc *msc = dev_get_drvdata(dev);
struct msc_window *win;
if (!sgt)
return;
win = msc_find_window(msc, sgt, false);
if (!win)
return;
msc_win_set_lockout(win, WIN_LOCKED, WIN_READY);
if (msc->switch_on_unlock == win) {
msc->switch_on_unlock = NULL;
msc_win_switch(msc);
}
}
EXPORT_SYMBOL_GPL(intel_th_msc_window_unlock);
static void msc_work(struct work_struct *work)
{
struct msc *msc = container_of(work, struct msc, work);
Annotation
- Immediate include surface: `linux/types.h`, `linux/module.h`, `linux/device.h`, `linux/uaccess.h`, `linux/sizes.h`, `linux/printk.h`, `linux/slab.h`, `linux/mm.h`.
- Detected declarations: `struct msc_window`, `struct msc_iter`, `struct msc`, `struct msu_buffer_entry`, `struct msc_win_to_user_struct`, `enum lockout_state`, `function list_for_each_entry`, `function msu_buffer_get`, `function msu_buffer_put`, `function intel_th_msu_buffer_register`.
- Atlas domain: Driver Families / drivers/hwtracing.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.