mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 22:18:12 +00:00
Kernel/VirtIO: Improve error handling during device initialization
Rename the initialize method to initialize_virtio_resources so it's clear what this method is intended for. To ensure healthier device initialization, we could also return the type of ErrorOr<void> from this method, so in all overriden instances and in the original method code, we could leverage TRY() pattern which also does simplify the code a bit.
This commit is contained in:
parent
aa985a0570
commit
87a32ab869
8 changed files with 89 additions and 86 deletions
|
@ -19,47 +19,49 @@ UNMAP_AFTER_INIT NonnullLockRefPtr<Console> Console::must_create(PCI::DeviceIden
|
|||
return adopt_lock_ref_if_nonnull(new Console(pci_device_identifier)).release_nonnull();
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT void Console::initialize()
|
||||
UNMAP_AFTER_INIT ErrorOr<void> Console::initialize_virtio_resources()
|
||||
{
|
||||
Device::initialize();
|
||||
if (auto const* cfg = get_config(ConfigurationType::Device)) {
|
||||
bool success = negotiate_features([&](u64 supported_features) {
|
||||
u64 negotiated = 0;
|
||||
if (is_feature_set(supported_features, VIRTIO_CONSOLE_F_SIZE))
|
||||
dbgln("VirtIO::Console: Console size is not yet supported!");
|
||||
if (is_feature_set(supported_features, VIRTIO_CONSOLE_F_MULTIPORT))
|
||||
negotiated |= VIRTIO_CONSOLE_F_MULTIPORT;
|
||||
return negotiated;
|
||||
});
|
||||
if (success) {
|
||||
u32 max_nr_ports = 0;
|
||||
u16 cols = 0, rows = 0;
|
||||
read_config_atomic([&]() {
|
||||
if (is_feature_accepted(VIRTIO_CONSOLE_F_SIZE)) {
|
||||
cols = config_read16(*cfg, 0x0);
|
||||
rows = config_read16(*cfg, 0x2);
|
||||
}
|
||||
if (is_feature_accepted(VIRTIO_CONSOLE_F_MULTIPORT)) {
|
||||
max_nr_ports = config_read32(*cfg, 0x4);
|
||||
m_ports.resize(max_nr_ports);
|
||||
}
|
||||
});
|
||||
dbgln("VirtIO::Console: cols: {}, rows: {}, max nr ports {}", cols, rows, max_nr_ports);
|
||||
// Base receiveq/transmitq for port0 + optional control queues and 2 per every additional port
|
||||
success = setup_queues(2 + max_nr_ports > 0 ? 2 + 2 * max_nr_ports : 0);
|
||||
TRY(Device::initialize_virtio_resources());
|
||||
auto const* cfg = get_config(VirtIO::ConfigurationType::Device);
|
||||
if (!cfg)
|
||||
return Error::from_errno(ENODEV);
|
||||
bool success = negotiate_features([&](u64 supported_features) {
|
||||
u64 negotiated = 0;
|
||||
if (is_feature_set(supported_features, VIRTIO_CONSOLE_F_SIZE))
|
||||
dbgln("VirtIO::Console: Console size is not yet supported!");
|
||||
if (is_feature_set(supported_features, VIRTIO_CONSOLE_F_MULTIPORT))
|
||||
negotiated |= VIRTIO_CONSOLE_F_MULTIPORT;
|
||||
return negotiated;
|
||||
});
|
||||
if (!success)
|
||||
return Error::from_errno(EIO);
|
||||
u32 max_nr_ports = 0;
|
||||
u16 cols = 0, rows = 0;
|
||||
read_config_atomic([&]() {
|
||||
if (is_feature_accepted(VIRTIO_CONSOLE_F_SIZE)) {
|
||||
cols = config_read16(*cfg, 0x0);
|
||||
rows = config_read16(*cfg, 0x2);
|
||||
}
|
||||
if (success) {
|
||||
finish_init();
|
||||
if (is_feature_accepted(VIRTIO_CONSOLE_F_MULTIPORT)) {
|
||||
max_nr_ports = config_read32(*cfg, 0x4);
|
||||
m_ports.resize(max_nr_ports);
|
||||
}
|
||||
});
|
||||
dbgln("VirtIO::Console: cols: {}, rows: {}, max nr ports {}", cols, rows, max_nr_ports);
|
||||
// Base receiveq/transmitq for port0 + optional control queues and 2 per every additional port
|
||||
success = setup_queues(2 + max_nr_ports > 0 ? 2 + 2 * max_nr_ports : 0);
|
||||
if (!success)
|
||||
return Error::from_errno(EIO);
|
||||
finish_init();
|
||||
|
||||
if (is_feature_accepted(VIRTIO_CONSOLE_F_MULTIPORT)) {
|
||||
setup_multiport();
|
||||
} else {
|
||||
auto port = MUST(DeviceManagement::the().try_create_device<VirtIO::ConsolePort>(0u, *this));
|
||||
port->init_receive_buffer({});
|
||||
m_ports.append(port);
|
||||
}
|
||||
}
|
||||
if (is_feature_accepted(VIRTIO_CONSOLE_F_MULTIPORT)) {
|
||||
setup_multiport();
|
||||
} else {
|
||||
auto port = TRY(DeviceManagement::the().try_create_device<VirtIO::ConsolePort>(0u, *this));
|
||||
port->init_receive_buffer({});
|
||||
m_ports.append(port);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
UNMAP_AFTER_INIT Console::Console(PCI::DeviceIdentifier const& pci_device_identifier)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue