drivers/tty/hvc/hvc_xen.c

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

File Facts

System
Linux kernel
Corpus path
drivers/tty/hvc/hvc_xen.c
Extension
.c
Size
18267 bytes
Lines
795
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

device_initcall(xen_hvc_init);

static int __init xen_cons_init(void)
{
	const struct hv_ops *ops;

	xen_console_io = opt_console_io >= 0 ? opt_console_io :
					       xen_initial_domain();

	if (!xen_domain())
		return 0;

	if (xen_console_io)
		ops = &dom0_hvc_ops;
	else {
		int r;
		ops = &domU_hvc_ops;

		if (xen_hvm_domain())
			r = xen_hvm_console_init();
		else
			r = xen_pv_console_init();
		if (r < 0)
			return r;
	}

	hvc_instantiate(HVC_COOKIE, 0, ops);
	return 0;
}
console_initcall(xen_cons_init);

#ifdef CONFIG_X86
static void xen_hvm_early_write(uint32_t vtermno, const char *str, int len)
{
	if (xen_cpuid_base())
		outsb(0xe9, str, len);
}
#else
static void xen_hvm_early_write(uint32_t vtermno, const char *str, int len) { }
#endif

#ifdef CONFIG_EARLY_PRINTK
static int __init xenboot_console_setup(struct console *console, char *string)
{
	static struct xencons_info xenboot;

	if (xen_initial_domain() || !xen_pv_domain())
		return 0;

	return xencons_info_pv_init(&xenboot, 0);
}

static void xenboot_write_console(struct console *console, const char *string,
				  unsigned len)
{
	unsigned int linelen, off = 0;
	const char *pos;

	if (dom0_write_console(0, string, len) >= 0)
		return;

	if (!xen_pv_domain()) {
		xen_hvm_early_write(0, string, len);
		return;
	}

	if (domU_write_console(0, "(early) ", 8) < 0)
		return;
	while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
		linelen = pos-string+off;
		if (off + linelen > len)
			break;
		domU_write_console(0, string+off, linelen);
		domU_write_console(0, "\r\n", 2);
		off += linelen + 1;
	}
	if (off < len)
		domU_write_console(0, string+off, len-off);
}

struct console xenboot_console = {
	.name		= "xenboot",
	.write		= xenboot_write_console,
	.setup		= xenboot_console_setup,
	.flags		= CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
	.index		= -1,
};
#endif	/* CONFIG_EARLY_PRINTK */

void xen_raw_console_write(const char *str)

Annotation

Implementation Notes