mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:18:13 +00:00
Kernel/Devices: Ensure appropriate locking on the Device map singleton
Devices might be removed and inserted at anytime, so let's ensure we always do these kind of operations with a good known state of the HashMap. The VirtIO code was modified to create devices outside the IRQ handler, so now it works with the new locking of the devices singleton, but a better approach might be needed later on.
This commit is contained in:
parent
21b6d84ff0
commit
009feefee0
5 changed files with 57 additions and 37 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <Kernel/Bus/VirtIO/Console.h>
|
||||
#include <Kernel/Sections.h>
|
||||
#include <Kernel/WorkQueue.h>
|
||||
|
||||
namespace Kernel::VirtIO {
|
||||
|
||||
|
@ -51,8 +52,11 @@ UNMAP_AFTER_INIT void Console::initialize()
|
|||
|
||||
if (is_feature_accepted(VIRTIO_CONSOLE_F_MULTIPORT))
|
||||
setup_multiport();
|
||||
else
|
||||
m_ports.append(make_ref_counted<VirtIO::ConsolePort>(0u, *this));
|
||||
else {
|
||||
auto port = make_ref_counted<VirtIO::ConsolePort>(0u, *this);
|
||||
port->init_receive_buffer({});
|
||||
m_ports.append(port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -146,23 +150,26 @@ void Console::process_control_message(ControlMessage message)
|
|||
{
|
||||
switch (message.event) {
|
||||
case (u16)ControlEvent::DeviceAdd: {
|
||||
u32 id = message.id;
|
||||
if (id >= m_ports.size()) {
|
||||
dbgln("Device provided an invalid port number {}. max_nr_ports: {}", id, m_ports.size());
|
||||
return;
|
||||
} else if (!m_ports.at(id).is_null()) {
|
||||
dbgln("Device tried to add port {} which was already added!", id);
|
||||
return;
|
||||
}
|
||||
g_io_work->queue([message, this]() -> void {
|
||||
u32 id = message.id;
|
||||
if (id >= m_ports.size()) {
|
||||
dbgln("Device provided an invalid port number {}. max_nr_ports: {}", id, m_ports.size());
|
||||
return;
|
||||
} else if (!m_ports.at(id).is_null()) {
|
||||
dbgln("Device tried to add port {} which was already added!", id);
|
||||
return;
|
||||
}
|
||||
|
||||
m_ports.at(id) = make_ref_counted<VirtIO::ConsolePort>(id, *this);
|
||||
ControlMessage ready_event {
|
||||
.id = static_cast<u32>(id),
|
||||
.event = (u16)ControlEvent::PortReady,
|
||||
.value = (u16)ControlMessage::Status::Success
|
||||
};
|
||||
m_ports.at(id) = make_ref_counted<VirtIO::ConsolePort>(id, *this);
|
||||
ControlMessage ready_event {
|
||||
.id = static_cast<u32>(id),
|
||||
.event = (u16)ControlEvent::PortReady,
|
||||
.value = (u16)ControlMessage::Status::Success
|
||||
};
|
||||
|
||||
write_control_message(ready_event);
|
||||
});
|
||||
|
||||
write_control_message(ready_event);
|
||||
break;
|
||||
}
|
||||
case (u16)ControlEvent::ConsolePort:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue