drivers/char/hw_random/n2-drv.c
Source file repositories/reference/linux-study-clean/drivers/char/hw_random/n2-drv.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/hw_random/n2-drv.c- Extension
.c- Size
- 20682 bytes
- Lines
- 865
- Domain
- Driver Families
- Bucket
- drivers/char
- 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.
- 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/kernel.hlinux/module.hlinux/types.hlinux/delay.hlinux/slab.hlinux/workqueue.hlinux/preempt.hlinux/hw_random.hlinux/of.hlinux/platform_device.hlinux/property.hasm/hypervisor.hn2rng.h
Detected Declarations
function modefunction n2rng_generic_read_control_v2function n2rng_control_settle_v2function n2rng_write_ctl_onefunction n2rng_generic_read_datafunction n2rng_read_diag_data_onefunction n2rng_generic_read_diag_datafunction n2rng_generic_write_controlfunction n2rng_try_read_ctlfunction n2rng_control_defaultfunction n2rng_control_swstate_initfunction n2rng_grab_diag_controlfunction n2rng_init_controlfunction n2rng_data_readfunction n2rng_guest_checkfunction n2rng_entropy_diag_readfunction advance_polynomialfunction n2rng_test_buffer_findfunction n2rng_dump_test_bufferfunction n2rng_check_selftest_bufferfunction n2rng_control_selftestfunction n2rng_control_checkfunction n2rng_control_configure_unitsfunction n2rng_workfunction n2rng_driver_versionfunction n2rng_probefunction n2rng_remove
Annotated Snippet
if (hv_err == HV_EBUSY) {
if (++busy >= N2RNG_BUSY_LIMIT)
break;
udelay(1);
} else if (hv_err == HV_EWOULDBLOCK) {
if (++block >= N2RNG_BLOCK_LIMIT)
break;
__delay(ticks);
} else
break;
}
return hv_err;
}
/* In multi-socket situations, the hypervisor might need to
* queue up the RNG control register write if it's for a unit
* that is on a cpu socket other than the one we are executing on.
*
* We poll here waiting for a successful read of that control
* register to make sure the write has been actually performed.
*/
static unsigned long n2rng_control_settle_v2(struct n2rng *np, int unit)
{
unsigned long ra = __pa(&np->scratch_control[0]);
return n2rng_generic_read_control_v2(ra, unit);
}
static unsigned long n2rng_write_ctl_one(struct n2rng *np, int unit,
unsigned long state,
unsigned long control_ra,
unsigned long watchdog_timeout,
unsigned long *ticks)
{
unsigned long hv_err;
if (np->hvapi_major == 1) {
hv_err = sun4v_rng_ctl_write_v1(control_ra, state,
watchdog_timeout, ticks);
} else {
hv_err = sun4v_rng_ctl_write_v2(control_ra, state,
watchdog_timeout, unit);
if (hv_err == HV_EOK)
hv_err = n2rng_control_settle_v2(np, unit);
*ticks = N2RNG_ACCUM_CYCLES_DEFAULT;
}
return hv_err;
}
static int n2rng_generic_read_data(unsigned long data_ra)
{
unsigned long ticks, hv_err;
int block = 0, hcheck = 0;
while (1) {
hv_err = sun4v_rng_data_read(data_ra, &ticks);
if (hv_err == HV_EOK)
return 0;
if (hv_err == HV_EWOULDBLOCK) {
if (++block >= N2RNG_BLOCK_LIMIT)
return -EWOULDBLOCK;
__delay(ticks);
} else if (hv_err == HV_ENOACCESS) {
return -EPERM;
} else if (hv_err == HV_EIO) {
if (++hcheck >= N2RNG_HCHECK_LIMIT)
return -EIO;
udelay(10000);
} else
return -ENODEV;
}
}
static unsigned long n2rng_read_diag_data_one(struct n2rng *np,
unsigned long unit,
unsigned long data_ra,
unsigned long data_len,
unsigned long *ticks)
{
unsigned long hv_err;
if (np->hvapi_major == 1) {
hv_err = sun4v_rng_data_read_diag_v1(data_ra, data_len, ticks);
} else {
hv_err = sun4v_rng_data_read_diag_v2(data_ra, data_len,
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/types.h`, `linux/delay.h`, `linux/slab.h`, `linux/workqueue.h`, `linux/preempt.h`, `linux/hw_random.h`.
- Detected declarations: `function mode`, `function n2rng_generic_read_control_v2`, `function n2rng_control_settle_v2`, `function n2rng_write_ctl_one`, `function n2rng_generic_read_data`, `function n2rng_read_diag_data_one`, `function n2rng_generic_read_diag_data`, `function n2rng_generic_write_control`, `function n2rng_try_read_ctl`, `function n2rng_control_default`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: source implementation candidate.
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.