drivers/char/hw_random/core.c
Source file repositories/reference/linux-study-clean/drivers/char/hw_random/core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/hw_random/core.c- Extension
.c- Size
- 15407 bytes
- Lines
- 732
- Domain
- Driver Families
- Bucket
- drivers/char
- 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
linux/delay.hlinux/device.hlinux/err.hlinux/fs.hlinux/hw_random.hlinux/kernel.hlinux/kthread.hlinux/miscdevice.hlinux/module.hlinux/random.hlinux/rcupdate.hlinux/sched.hlinux/sched/signal.hlinux/slab.hlinux/string.hlinux/sysfs.hlinux/uaccess.hlinux/workqueue.h
Detected Declarations
function rng_buffer_sizefunction cleanup_rng_workfunction cleanup_rngfunction set_current_rngfunction drop_current_rngfunction put_rngfunction hwrng_initfunction rng_dev_openfunction rng_get_datafunction rng_dev_readfunction enable_best_rngfunction rng_current_storefunction list_for_each_entryfunction rng_current_showfunction rng_available_showfunction rng_selected_showfunction rng_quality_showfunction rng_quality_storefunction hwrng_fillfnfunction hwrng_registerfunction hwrng_unregisterfunction devm_hwrng_releasefunction devm_hwrng_matchfunction devm_hwrng_registerfunction devm_hwrng_unregisterfunction hwrng_msleepfunction hwrng_yieldfunction hwrng_modinitfunction hwrng_modexitmodule init hwrng_modinitexport hwrng_registerexport hwrng_unregisterexport devm_hwrng_registerexport devm_hwrng_unregisterexport hwrng_msleepexport hwrng_yield
Annotated Snippet
static const struct file_operations rng_chrdev_ops = {
.owner = THIS_MODULE,
.open = rng_dev_open,
.read = rng_dev_read,
.llseek = noop_llseek,
};
static const struct attribute_group *rng_dev_groups[];
static struct miscdevice rng_miscdev = {
.minor = HWRNG_MINOR,
.name = RNG_MODULE_NAME,
.nodename = "hwrng",
.fops = &rng_chrdev_ops,
.groups = rng_dev_groups,
};
static int enable_best_rng(void)
{
struct hwrng *rng, *cur_rng, *new_rng = NULL;
int ret = -ENODEV;
BUG_ON(!mutex_is_locked(&rng_mutex));
/* no rng to use? */
if (list_empty(&rng_list)) {
drop_current_rng();
cur_rng_set_by_user = 0;
return 0;
}
/* use the rng which offers the best quality */
list_for_each_entry(rng, &rng_list, list) {
if (!new_rng || rng->quality > new_rng->quality)
new_rng = rng;
}
cur_rng = rcu_dereference_protected(current_rng,
lockdep_is_held(&rng_mutex));
ret = ((new_rng == cur_rng) ? 0 : set_current_rng(new_rng));
if (!ret)
cur_rng_set_by_user = 0;
return ret;
}
static ssize_t rng_current_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
int err;
struct hwrng *rng, *new_rng;
err = mutex_lock_interruptible(&rng_mutex);
if (err)
return -ERESTARTSYS;
if (sysfs_streq(buf, "")) {
err = enable_best_rng();
} else if (sysfs_streq(buf, "none")) {
cur_rng_set_by_user = 1;
drop_current_rng();
} else {
list_for_each_entry(rng, &rng_list, list) {
if (sysfs_streq(rng->name, buf)) {
err = set_current_rng(rng);
if (!err)
cur_rng_set_by_user = 1;
break;
}
}
}
new_rng = get_current_rng_nolock();
mutex_unlock(&rng_mutex);
if (new_rng)
put_rng(new_rng);
return err ? : len;
}
static ssize_t rng_current_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
ssize_t ret;
struct hwrng *rng;
rng = get_current_rng();
Annotation
- Immediate include surface: `linux/delay.h`, `linux/device.h`, `linux/err.h`, `linux/fs.h`, `linux/hw_random.h`, `linux/kernel.h`, `linux/kthread.h`, `linux/miscdevice.h`.
- Detected declarations: `function rng_buffer_size`, `function cleanup_rng_work`, `function cleanup_rng`, `function set_current_rng`, `function drop_current_rng`, `function put_rng`, `function hwrng_init`, `function rng_dev_open`, `function rng_get_data`, `function rng_dev_read`.
- Atlas domain: Driver Families / drivers/char.
- 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.