drivers/char/virtio_console.c
Source file repositories/reference/linux-study-clean/drivers/char/virtio_console.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/virtio_console.c- Extension
.c- Size
- 54060 bytes
- Lines
- 2240
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/cdev.hlinux/debugfs.hlinux/completion.hlinux/device.hlinux/err.hlinux/freezer.hlinux/fs.hlinux/splice.hlinux/pagemap.hlinux/idr.hlinux/init.hlinux/list.hlinux/poll.hlinux/sched.hlinux/slab.hlinux/spinlock.hlinux/virtio.hlinux/virtio_console.hlinux/wait.hlinux/workqueue.hlinux/module.hlinux/dma-mapping.hlinux/string_choices.h../tty/hvc/hvc_console.h
Detected Declarations
struct ports_driver_datastruct consolestruct port_bufferstruct ports_devicestruct port_statsstruct portstruct sg_listfunction is_console_portfunction is_rproc_serialfunction use_multiportfunction free_buffunction reclaim_dma_bufsfunction add_inbuffunction discard_port_datafunction port_has_datafunction __send_control_msgfunction send_control_msgfunction reclaim_consumed_buffersfunction __send_to_portfunction fill_readbuffunction will_read_blockfunction will_write_blockfunction port_fops_readfunction wait_port_writablefunction port_fops_writefunction pipe_to_sgfunction port_fops_splice_writefunction port_fops_pollfunction port_fops_releasefunction port_fops_openfunction port_fops_fasyncfunction put_charsfunction get_charsfunction resize_consolefunction notifier_add_viofunction notifier_del_viofunction init_port_consolefunction show_port_namefunction port_debugfs_showfunction set_console_sizefunction fill_queuefunction send_sigio_to_portfunction add_portfunction remove_portfunction remove_port_datafunction unplug_portfunction handle_control_messagefunction control_work_handler
Annotated Snippet
static const struct file_operations port_fops = {
.owner = THIS_MODULE,
.open = port_fops_open,
.read = port_fops_read,
.write = port_fops_write,
.splice_write = port_fops_splice_write,
.poll = port_fops_poll,
.release = port_fops_release,
.fasync = port_fops_fasync,
};
/*
* The put_chars() callback is pretty straightforward.
*
* We turn the characters into a scatter-gather list, add it to the
* output queue and then kick the Host. Then we sit here waiting for
* it to finish: inefficient in theory, but in practice
* implementations will do it immediately.
*/
static ssize_t put_chars(u32 vtermno, const u8 *buf, size_t count)
{
struct port *port;
struct scatterlist sg[1];
void *data;
int ret;
port = find_port_by_vtermno(vtermno);
if (!port)
return -EPIPE;
data = kmemdup(buf, count, GFP_ATOMIC);
if (!data)
return -ENOMEM;
sg_init_one(sg, data, count);
ret = __send_to_port(port, sg, 1, count, data, false);
kfree(data);
return ret;
}
/*
* get_chars() is the callback from the hvc_console infrastructure
* when an interrupt is received.
*
* We call out to fill_readbuf that gets us the required data from the
* buffers that are queued up.
*/
static ssize_t get_chars(u32 vtermno, u8 *buf, size_t count)
{
struct port *port;
port = find_port_by_vtermno(vtermno);
if (!port)
return -EPIPE;
/* If we don't have an input queue yet, we can't get input. */
BUG_ON(!port->in_vq);
return fill_readbuf(port, (__force u8 __user *)buf, count, false);
}
static void resize_console(struct port *port)
{
struct virtio_device *vdev;
/* The port could have been hot-unplugged */
if (!port || !is_console_port(port))
return;
vdev = port->portdev->vdev;
/* Don't test F_SIZE at all if we're rproc: not a valid feature! */
if (!is_rproc_serial(vdev) &&
virtio_has_feature(vdev, VIRTIO_CONSOLE_F_SIZE))
hvc_resize(port->cons.hvc, port->cons.ws);
}
/* We set the configuration at this point, since we now have a tty */
static int notifier_add_vio(struct hvc_struct *hp, int data)
{
struct port *port;
port = find_port_by_vtermno(hp->vtermno);
if (!port)
return -EINVAL;
hp->irq_requested = 1;
resize_console(port);
return 0;
Annotation
- Immediate include surface: `linux/cdev.h`, `linux/debugfs.h`, `linux/completion.h`, `linux/device.h`, `linux/err.h`, `linux/freezer.h`, `linux/fs.h`, `linux/splice.h`.
- Detected declarations: `struct ports_driver_data`, `struct console`, `struct port_buffer`, `struct ports_device`, `struct port_stats`, `struct port`, `struct sg_list`, `function is_console_port`, `function is_rproc_serial`, `function use_multiport`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.