drivers/tty/hvc/hvc_console.c

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

File Facts

System
Linux kernel
Corpus path
drivers/tty/hvc/hvc_console.c
Extension
.c
Size
25359 bytes
Lines
1067
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

if (hp->index == index) {
			tty_port_get(&hp->port);
			spin_unlock_irqrestore(&hp->lock, flags);
			mutex_unlock(&hvc_structs_mutex);
			return hp;
		}
		spin_unlock_irqrestore(&hp->lock, flags);
	}
	hp = NULL;
	mutex_unlock(&hvc_structs_mutex);

	return hp;
}

static int __hvc_flush(const struct hv_ops *ops, uint32_t vtermno, bool wait)
{
	if (wait)
		might_sleep();

	if (ops->flush)
		return ops->flush(vtermno, wait);
	return 0;
}

static int hvc_console_flush(const struct hv_ops *ops, uint32_t vtermno)
{
	return __hvc_flush(ops, vtermno, false);
}

/*
 * Wait for the console to flush before writing more to it. This sleeps.
 */
static int hvc_flush(struct hvc_struct *hp)
{
	return __hvc_flush(hp->ops, hp->vtermno, true);
}

/*
 * Initial console vtermnos for console API usage prior to full console
 * initialization.  Any vty adapter outside this range will not have usable
 * console interfaces but can still be used as a tty device.  This has to be
 * static because kmalloc will not work during early console init.
 */
static const struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
	{[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};

/*
 * Console APIs, NOT TTY.  These APIs are available immediately when
 * hvc_console_setup() finds adapters.
 */

static void hvc_console_print(struct console *co, const char *b,
			      unsigned count)
{
	char c[N_OUTBUF] __ALIGNED__;
	unsigned i = 0, n = 0;
	int r, donecr = 0, index = co->index;

	/* Console access attempt outside of acceptable console range. */
	if (index >= MAX_NR_HVC_CONSOLES)
		return;

	/* This console adapter was removed so it is not usable. */
	if (vtermnos[index] == -1)
		return;

	while (count > 0 || i > 0) {
		if (count > 0 && i < sizeof(c)) {
			if (b[n] == '\n' && !donecr) {
				c[i++] = '\r';
				donecr = 1;
			} else {
				c[i++] = b[n++];
				donecr = 0;
				--count;
			}
		} else {
			r = cons_ops[index]->put_chars(vtermnos[index], c, i);
			if (r <= 0) {
				/* throw away characters on error
				 * but spin in case of -EAGAIN */
				if (r != -EAGAIN) {
					i = 0;
				} else {
					hvc_console_flush(cons_ops[index],
						      vtermnos[index]);
				}
			} else {
				i -= r;

Annotation

Implementation Notes