drivers/net/wireless/ath/ath6kl/debug.c
Source file repositories/reference/linux-study-clean/drivers/net/wireless/ath/ath6kl/debug.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/wireless/ath/ath6kl/debug.c- Extension
.c- Size
- 46460 bytes
- Lines
- 1873
- Domain
- Driver Families
- Bucket
- drivers/net
- 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.
- 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
core.hlinux/skbuff.hlinux/fs.hlinux/hex.hlinux/vmalloc.hlinux/export.hdebug.htarget.h
Detected Declarations
struct ath6kl_fwlog_slotstruct ath6kl_diag_reg_infofunction ath6kl_printkfunction ath6kl_infofunction ath6kl_errfunction ath6kl_warnfunction ath6kl_read_tgt_statsfunction ath6kl_dbgfunction ath6kl_dbg_dumpfunction ath6kl_dump_registersfunction dump_cred_distfunction dump_cred_dist_statsfunction ath6kl_debug_warfunction read_file_war_statsfunction ath6kl_debug_fwlog_eventfunction ath6kl_fwlog_openfunction ath6kl_fwlog_releasefunction ath6kl_fwlog_readfunction ath6kl_fwlog_block_readfunction ath6kl_fwlog_mask_readfunction ath6kl_fwlog_mask_writefunction read_file_tgt_statsfunction read_file_credit_dist_statsfunction list_for_each_entryfunction print_endpoint_statfunction ath6kl_endpoint_stats_readfunction ath6kl_endpoint_stats_writefunction ath6kl_get_num_regfunction ath6kl_dbg_is_diag_reg_validfunction ath6kl_regread_readfunction ath6kl_regread_writefunction ath6kl_regdump_openfunction ath6kl_regdump_readfunction ath6kl_regdump_releasefunction ath6kl_lrssi_roam_writefunction ath6kl_lrssi_roam_readfunction ath6kl_regwrite_readfunction ath6kl_regwrite_writefunction ath6kl_debug_roam_tbl_eventfunction ath6kl_roam_table_readfunction ath6kl_force_roam_writefunction ath6kl_roam_mode_writefunction ath6kl_debug_set_keepalivefunction ath6kl_keepalive_readfunction ath6kl_keepalive_writefunction ath6kl_debug_set_disconnect_timeoutfunction ath6kl_disconnect_timeout_readfunction ath6kl_disconnect_timeout_write
Annotated Snippet
static const struct file_operations fops_war_stats = {
.read = read_file_war_stats,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len)
{
struct ath6kl_fwlog_slot *slot;
struct sk_buff *skb;
size_t slot_len;
if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
return;
slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE;
skb = alloc_skb(slot_len, GFP_KERNEL);
if (!skb)
return;
slot = skb_put(skb, slot_len);
slot->timestamp = cpu_to_le32(jiffies);
slot->length = cpu_to_le32(len);
memcpy(slot->payload, buf, len);
/* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */
memset(slot->payload + len, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - len);
spin_lock(&ar->debug.fwlog_queue.lock);
__skb_queue_tail(&ar->debug.fwlog_queue, skb);
complete(&ar->debug.fwlog_completion);
/* drop oldest entries */
while (skb_queue_len(&ar->debug.fwlog_queue) >
ATH6KL_FWLOG_MAX_ENTRIES) {
skb = __skb_dequeue(&ar->debug.fwlog_queue);
kfree_skb(skb);
}
spin_unlock(&ar->debug.fwlog_queue.lock);
return;
}
static int ath6kl_fwlog_open(struct inode *inode, struct file *file)
{
struct ath6kl *ar = inode->i_private;
if (ar->debug.fwlog_open)
return -EBUSY;
ar->debug.fwlog_open = true;
file->private_data = inode->i_private;
return 0;
}
static int ath6kl_fwlog_release(struct inode *inode, struct file *file)
{
struct ath6kl *ar = inode->i_private;
ar->debug.fwlog_open = false;
return 0;
}
static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath6kl *ar = file->private_data;
struct sk_buff *skb;
ssize_t ret_cnt;
size_t len = 0;
char *buf;
buf = vmalloc(count);
if (!buf)
return -ENOMEM;
/* read undelivered logs from firmware */
ath6kl_read_fwlogs(ar);
spin_lock(&ar->debug.fwlog_queue.lock);
while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) {
if (skb->len > count - len) {
/* not enough space, put skb back and leave */
Annotation
- Immediate include surface: `core.h`, `linux/skbuff.h`, `linux/fs.h`, `linux/hex.h`, `linux/vmalloc.h`, `linux/export.h`, `debug.h`, `target.h`.
- Detected declarations: `struct ath6kl_fwlog_slot`, `struct ath6kl_diag_reg_info`, `function ath6kl_printk`, `function ath6kl_info`, `function ath6kl_err`, `function ath6kl_warn`, `function ath6kl_read_tgt_stats`, `function ath6kl_dbg`, `function ath6kl_dbg_dump`, `function ath6kl_dump_registers`.
- Atlas domain: Driver Families / drivers/net.
- 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.
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.