mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 02:37:36 +00:00
Kernel: Activate queues and enable interrutps in VirtIODevices
This patch actually enables virtio queues after configuring them so the device can use them, it also enables interrupt handling in VirtIODevice so they are not ignored. Co-authored-by: Sahan <sahan.h.fernando@gmail.com>
This commit is contained in:
parent
4a467c553a
commit
42b1eb5af1
4 changed files with 30 additions and 6 deletions
|
@ -37,10 +37,14 @@ void VirtIO::detect()
|
|||
if (id.vendor_id != VIRTIO_PCI_VENDOR_ID)
|
||||
return;
|
||||
switch (id.device_id) {
|
||||
case VIRTIO_CONSOLE_PCI_DEVICE_ID:
|
||||
case VIRTIO_CONSOLE_PCI_DEVICE_ID: {
|
||||
[[maybe_unused]] auto& unused = adopt(*new VirtIOConsole(address)).leak_ref();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIO: Unknown VirtIO device with ID: {}", id.device_id);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -52,6 +56,8 @@ VirtIODevice::VirtIODevice(PCI::Address address, String class_name)
|
|||
dbgln("{}: Found @ {}", m_class_name, pci_address());
|
||||
|
||||
enable_bus_mastering(pci_address());
|
||||
PCI::enable_interrupt_line(pci_address());
|
||||
enable_irq();
|
||||
|
||||
reset_device();
|
||||
set_status_bit(DEVICE_STATUS_ACKNOWLEDGE);
|
||||
|
@ -249,7 +255,6 @@ void VirtIODevice::reset_device()
|
|||
while (config_read8(*m_common_cfg, COMMON_CFG_DEVICE_STATUS) != 0) {
|
||||
// TODO: delay a bit?
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool VirtIODevice::setup_queue(u16 queue_index)
|
||||
|
@ -274,12 +279,24 @@ bool VirtIODevice::setup_queue(u16 queue_index)
|
|||
config_write64(*m_common_cfg, COMMON_CFG_QUEUE_DRIVER, queue->driver_area().get());
|
||||
config_write64(*m_common_cfg, COMMON_CFG_QUEUE_DEVICE, queue->device_area().get());
|
||||
|
||||
dbgln_if(VIRTIO_DEBUG, "{}: Queue[{}] size: {}", m_class_name, queue_index, queue_size);
|
||||
dbgln_if(VIRTIO_DEBUG, "{}: Queue[{}] configured with size: {}", m_class_name, queue_index, queue_size);
|
||||
|
||||
m_queues.append(move(queue));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VirtIODevice::activate_queue(u16 queue_index)
|
||||
{
|
||||
if (!m_common_cfg)
|
||||
return false;
|
||||
|
||||
config_write16(*m_common_cfg, COMMON_CFG_QUEUE_SELECT, queue_index);
|
||||
config_write16(*m_common_cfg, COMMON_CFG_QUEUE_ENABLE, true);
|
||||
|
||||
dbgln_if(VIRTIO_DEBUG, "{}: Queue[{}] activated", m_class_name, queue_index);
|
||||
return true;
|
||||
}
|
||||
|
||||
void VirtIODevice::set_requested_queue_count(u16 count)
|
||||
{
|
||||
m_queue_count = count;
|
||||
|
@ -302,6 +319,10 @@ bool VirtIODevice::setup_queues()
|
|||
if (!setup_queue(i))
|
||||
return false;
|
||||
}
|
||||
for (u16 i = 0; i < m_queue_count; i++) { // Queues can only be activated *after* all others queues were also configured
|
||||
if (!activate_queue(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -335,7 +356,7 @@ u8 VirtIODevice::isr_status()
|
|||
void VirtIODevice::handle_irq(const RegisterState&)
|
||||
{
|
||||
u8 isr_type = isr_status();
|
||||
dbgln_if(VIRTIO_DEBUG, "VirtIODevice: Handling interrupt with status: {}", isr_type);
|
||||
dbgln_if(VIRTIO_DEBUG, "{}: Handling interrupt with status: {}", m_class_name, isr_type);
|
||||
if (isr_type & DEVICE_CONFIG_INTERRUPT) {
|
||||
if (!handle_device_config_change()) {
|
||||
set_status_bit(DEVICE_STATUS_FAILED);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue