mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
Kernel/VirtIO: Determine VirtIO device class also with the PCI device ID
According to the VirtIO 1.0 specification: "Non-transitional devices SHOULD have a PCI Device ID in the range 0x1040 to 0x107f. Non-transitional devices SHOULD have a PCI Revision ID of 1 or higher. Non-transitional devices SHOULD have a PCI Subsystem Device ID of 0x40 or higher." It also says that: "Transitional devices MUST have a PCI Revision ID of 0. Transitional devices MUST have the PCI Subsystem Device ID matching the Virtio Device ID, as indicated in section 5. Transitional devices MUST have the Transitional PCI Device ID in the range 0x1000 to 0x103f." So, for legacy devices, we know that revision ID in the PCI header won't be 1, so we probe for PCI_SUBSYSTEM_ID value. Instead of using the subsystem device ID, we can probe the DEVICE_ID value directly in case it's not a legacy device. This should cover all possibilities for identifying VirtIO devices, both per the specification of 0.9.5, and future revisions from 1.0 onwards.
This commit is contained in:
parent
24ef8b118a
commit
e606ff3751
Notes:
sideshowbarker
2024-07-18 04:45:51 +09:00
Author: https://github.com/supercomputer7 Commit: https://github.com/SerenityOS/serenity/commit/e606ff3751e Pull-request: https://github.com/SerenityOS/serenity/pull/9816 Issue: https://github.com/SerenityOS/serenity/issues/9780
2 changed files with 34 additions and 11 deletions
|
@ -19,6 +19,8 @@ enum VendorID {
|
|||
};
|
||||
|
||||
enum DeviceID {
|
||||
VirtIONetAdapter = 0x1000,
|
||||
VirtIOBlockDevice = 0x1001,
|
||||
VirtIOConsole = 0x1003,
|
||||
VirtIOEntropy = 0x1005,
|
||||
VirtIOGPU = 0x1050,
|
||||
|
|
|
@ -47,18 +47,39 @@ UNMAP_AFTER_INIT void detect()
|
|||
|
||||
StringView determine_device_class(const PCI::Address& address)
|
||||
{
|
||||
auto subsystem_device_id = PCI::get_subsystem_id(address);
|
||||
switch (subsystem_device_id) {
|
||||
case 1:
|
||||
return "VirtIONetAdapter";
|
||||
case 2:
|
||||
return "VirtIOBlockDevice";
|
||||
case 3:
|
||||
return "VirtIOConsole";
|
||||
case 4:
|
||||
return "VirtIORNG";
|
||||
if (PCI::get_revision_id(address) == 0) {
|
||||
// Note: If the device is a legacy (or transitional) device, therefore,
|
||||
// probe the subsystem ID in the PCI header and figure out the
|
||||
auto subsystem_device_id = PCI::get_subsystem_id(address);
|
||||
switch (subsystem_device_id) {
|
||||
case 1:
|
||||
return "VirtIONetAdapter";
|
||||
case 2:
|
||||
return "VirtIOBlockDevice";
|
||||
case 3:
|
||||
return "VirtIOConsole";
|
||||
case 4:
|
||||
return "VirtIORNG";
|
||||
}
|
||||
dbgln("VirtIO: Unknown subsystem_device_id {}", subsystem_device_id);
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
dbgln("VirtIO: Unknown subsystem_device_id {}", subsystem_device_id);
|
||||
|
||||
auto id = PCI::get_id(address);
|
||||
VERIFY(id.vendor_id == PCI::VendorID::VirtIO);
|
||||
switch (id.device_id) {
|
||||
case PCI::DeviceID::VirtIONetAdapter:
|
||||
return "VirtIONetAdapter";
|
||||
case PCI::DeviceID::VirtIOBlockDevice:
|
||||
return "VirtIOBlockDevice";
|
||||
case PCI::DeviceID::VirtIOConsole:
|
||||
return "VirtIOConsole";
|
||||
case PCI::DeviceID::VirtIOEntropy:
|
||||
return "VirtIORNG";
|
||||
case PCI::DeviceID::VirtIOGPU:
|
||||
return "VirtIOGPU";
|
||||
}
|
||||
dbgln("VirtIO: Unknown device_id {}", id.vendor_id);
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue