devices/virtio/console/
output.rs

1// Copyright 2024 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Virtio console device output handling.
6
7use std::io;
8use std::io::Read;
9
10use base::error;
11
12use crate::virtio::Queue;
13use crate::virtio::Reader;
14
15/// Writes the available data from the reader into the given output queue.
16///
17/// # Arguments
18///
19/// * `reader` - The Reader with the data we want to write.
20/// * `output` - The output sink we are going to write the data to.
21fn process_transmit_request(reader: &mut Reader, output: &mut dyn io::Write) -> io::Result<()> {
22    let len = reader.available_bytes();
23    let mut data = vec![0u8; len];
24    reader.read_exact(&mut data)?;
25    output.write_all(&data)?;
26    output.flush()?;
27    Ok(())
28}
29
30/// Processes the data taken from the given transmit queue into the output sink.
31///
32/// # Arguments
33///
34/// * `interrupt` - Interrupt used to signal (if required) that the queue has been used
35/// * `transmit_queue` - The transmit virtio Queue
36/// * `output` - The output sink we are going to write the data into
37pub fn process_transmit_queue(transmit_queue: &mut Queue, output: &mut dyn io::Write) {
38    let mut needs_interrupt = false;
39    while let Some(mut avail_desc) = transmit_queue.pop() {
40        if let Err(e) = process_transmit_request(&mut avail_desc.reader, output) {
41            error!("console: process_transmit_request failed: {}", e);
42        }
43
44        transmit_queue.add_used(avail_desc);
45        needs_interrupt = true;
46    }
47
48    if needs_interrupt {
49        transmit_queue.trigger_interrupt();
50    }
51}