drivers/tty/sysrq.c

Source file repositories/reference/linux-study-clean/drivers/tty/sysrq.c

File Facts

System
Linux kernel
Corpus path
drivers/tty/sysrq.c
Extension
.c
Size
29557 bytes
Lines
1260
Domain
Driver Families
Bucket
drivers/tty
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

subsys_initcall(init_sysrq_sysctl);

static int __sysrq_swap_key_ops(u8 key, const struct sysrq_key_op *insert_op_p,
				const struct sysrq_key_op *remove_op_p)
{
	int retval;

	spin_lock(&sysrq_key_table_lock);
	if (__sysrq_get_key_op(key) == remove_op_p) {
		__sysrq_put_key_op(key, insert_op_p);
		retval = 0;
	} else {
		retval = -1;
	}
	spin_unlock(&sysrq_key_table_lock);

	/*
	 * A concurrent __handle_sysrq either got the old op or the new op.
	 * Wait for it to go away before returning, so the code for an old
	 * op is not freed (eg. on module unload) while it is in use.
	 */
	synchronize_rcu();

	return retval;
}

int register_sysrq_key(u8 key, const struct sysrq_key_op *op_p)
{
	return __sysrq_swap_key_ops(key, op_p, NULL);
}
EXPORT_SYMBOL(register_sysrq_key);

int unregister_sysrq_key(u8 key, const struct sysrq_key_op *op_p)
{
	return __sysrq_swap_key_ops(key, NULL, op_p);
}
EXPORT_SYMBOL(unregister_sysrq_key);

#ifdef CONFIG_PROC_FS
/*
 * writing 'C' to /proc/sysrq-trigger is like sysrq-C
 * Normally, only the first character written is processed.
 * However, if the first character is an underscore,
 * all characters are processed.
 */
static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
				   size_t count, loff_t *ppos)
{
	bool bulk = false;
	size_t i;

	for (i = 0; i < count; i++) {
		char c;

		if (get_user(c, buf + i))
			return -EFAULT;

		if (c == '_')
			bulk = true;
		else
			__handle_sysrq(c, false);

		if (!bulk)
			break;
	}

	return count;
}

static const struct proc_ops sysrq_trigger_proc_ops = {
	.proc_write	= write_sysrq_trigger,
	.proc_lseek	= noop_llseek,
};

static void sysrq_init_procfs(void)
{
	if (!proc_create("sysrq-trigger", S_IWUSR, NULL,
			 &sysrq_trigger_proc_ops))
		pr_err("Failed to register proc interface\n");
}

#else

static inline void sysrq_init_procfs(void)
{
}

#endif /* CONFIG_PROC_FS */

static int __init sysrq_init(void)

Annotation

Implementation Notes