drivers/misc/bcm-vk/bcm_vk_msg.c
Source file repositories/reference/linux-study-clean/drivers/misc/bcm-vk/bcm_vk_msg.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/misc/bcm-vk/bcm_vk_msg.c- Extension
.c- Size
- 35330 bytes
- Lines
- 1357
- Domain
- Driver Families
- Bucket
- drivers/misc
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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/delay.hlinux/fs.hlinux/hash.hlinux/interrupt.hlinux/list.hlinux/module.hlinux/poll.hlinux/sizes.hlinux/spinlock.hlinux/timer.hbcm_vk.hbcm_vk_msg.hbcm_vk_sg.h
Detected Declarations
function hb_mon_is_onfunction get_q_numfunction set_q_numfunction get_msg_idfunction set_msg_idfunction msgq_incfunction msgq_occupiedfunction msgq_avail_spacefunction bcm_vk_drv_access_okfunction bcm_vk_set_host_alertfunction bcm_vk_hb_pollfunction bcm_vk_hb_initfunction bcm_vk_hb_deinitfunction bcm_vk_msgid_bitmap_clearfunction bcm_vk_get_msg_idfunction bcm_vk_free_ctxfunction list_for_each_entryfunction bcm_vk_free_wkentfunction bcm_vk_drain_all_pendfunction list_for_each_entry_safefunction bcm_vk_drain_msg_on_resetfunction bcm_vk_sync_msgqfunction bcm_vk_msg_chan_initfunction bcm_vk_append_pendqfunction bcm_vk_append_ib_sglfunction bcm_to_v_q_doorbellfunction bcm_to_v_msg_enqueuefunction bcm_vk_send_shutdown_msgfunction bcm_vk_handle_last_sessfunction bcm_to_h_msg_dequeuefunction bcm_vk_data_initfunction bcm_vk_msgq_irqhandlerfunction bcm_vk_openfunction bcm_vk_readfunction list_for_each_entryfunction bcm_vk_writefunction bcm_vk_pollfunction bcm_vk_releasefunction bcm_vk_msg_initfunction bcm_vk_msg_remove
Annotated Snippet
if (!vk->ctx[i].in_use) {
vk->ctx[i].in_use = true;
ctx = &vk->ctx[i];
break;
}
}
if (!ctx) {
dev_err(&vk->pdev->dev, "All context in use\n");
goto all_in_use_exit;
}
/* set the pid and insert it to hash table */
ctx->pid = pid;
ctx->hash_idx = hash_idx;
list_add_tail(&ctx->node, &vk->pid_ht[hash_idx].head);
/* increase kref */
kref_get(&vk->kref);
/* clear counter */
atomic_set(&ctx->pend_cnt, 0);
atomic_set(&ctx->dma_cnt, 0);
init_waitqueue_head(&ctx->rd_wq);
all_in_use_exit:
in_reset_exit:
spin_unlock(&vk->ctx_lock);
return ctx;
}
static u16 bcm_vk_get_msg_id(struct bcm_vk *vk)
{
u16 rc = VK_MSG_ID_OVERFLOW;
u16 test_bit_count = 0;
spin_lock(&vk->msg_id_lock);
while (test_bit_count < (VK_MSG_ID_BITMAP_SIZE - 1)) {
/*
* first time come in this loop, msg_id will be 0
* and the first one tested will be 1. We skip
* VK_SIMPLEX_MSG_ID (0) for one way host2vk
* communication
*/
vk->msg_id++;
if (vk->msg_id == VK_MSG_ID_BITMAP_SIZE)
vk->msg_id = 1;
if (test_bit(vk->msg_id, vk->bmap)) {
test_bit_count++;
continue;
}
rc = vk->msg_id;
bitmap_set(vk->bmap, vk->msg_id, 1);
break;
}
spin_unlock(&vk->msg_id_lock);
return rc;
}
static int bcm_vk_free_ctx(struct bcm_vk *vk, struct bcm_vk_ctx *ctx)
{
u32 idx;
u32 hash_idx;
pid_t pid;
struct bcm_vk_ctx *entry;
int count = 0;
if (!ctx) {
dev_err(&vk->pdev->dev, "NULL context detected\n");
return -EINVAL;
}
idx = ctx->idx;
pid = ctx->pid;
spin_lock(&vk->ctx_lock);
if (!vk->ctx[idx].in_use) {
dev_err(&vk->pdev->dev, "context[%d] not in use!\n", idx);
} else {
vk->ctx[idx].in_use = false;
vk->ctx[idx].miscdev = NULL;
/* Remove it from hash list and see if it is the last one. */
list_del(&ctx->node);
hash_idx = ctx->hash_idx;
list_for_each_entry(entry, &vk->pid_ht[hash_idx].head, node) {
Annotation
- Immediate include surface: `linux/delay.h`, `linux/fs.h`, `linux/hash.h`, `linux/interrupt.h`, `linux/list.h`, `linux/module.h`, `linux/poll.h`, `linux/sizes.h`.
- Detected declarations: `function hb_mon_is_on`, `function get_q_num`, `function set_q_num`, `function get_msg_id`, `function set_msg_id`, `function msgq_inc`, `function msgq_occupied`, `function msgq_avail_space`, `function bcm_vk_drv_access_ok`, `function bcm_vk_set_host_alert`.
- Atlas domain: Driver Families / drivers/misc.
- Implementation status: source 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.