Kernel: Remove support for custom xHCI speed_ids

This gets really weird with hubs and I don't think even linux handles
them.
This commit is contained in:
Bananymous 2025-02-06 21:38:30 +02:00
parent f9b70d1b5b
commit 242ed4a3c2
6 changed files with 42 additions and 45 deletions

View File

@ -4,8 +4,8 @@
#include <BAN/NoCopyMove.h>
#include <kernel/Memory/DMARegion.h>
#include <kernel/USB/USBManager.h>
#include <kernel/USB/Controller.h>
#include <kernel/USB/USBManager.h>
namespace Kernel
{
@ -69,7 +69,8 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> send_request(const USBDeviceRequest&, paddr_t buffer) = 0;
virtual void send_data_buffer(uint8_t endpoint_id, paddr_t buffer, size_t buffer_len) = 0;
static USB::SpeedClass determine_speed_class(uint64_t bits_per_second);
USB::SpeedClass speed_class() const { return m_speed_class; }
uint8_t depth() const { return m_depth; }
protected:
void handle_stall(uint8_t endpoint_id);

View File

@ -5,6 +5,7 @@
#include <kernel/Lock/Mutex.h>
#include <kernel/Memory/DMARegion.h>
#include <kernel/ThreadBlocker.h>
#include <kernel/USB/Definitions.h>
#include <kernel/USB/USBManager.h>
#include <kernel/USB/XHCI/Definitions.h>
@ -25,17 +26,6 @@ namespace Kernel
uint8_t revision_minor { 0 };
uint8_t slot_type { 0 };
uint8_t slot_id { 0 };
uint64_t speed_id_to_speed[0x10] {
0,
12'000'000,
1'500'000,
480'000'000,
5'000'000'000,
10'000'000'000,
5'000'000'000,
10'000'000'000,
};
};
public:
@ -74,6 +64,9 @@ namespace Kernel
const volatile XHCI::TRB& current_event_trb();
uint8_t speed_class_to_id(USB::SpeedClass speed_class) const;
USB::SpeedClass speed_id_to_class(uint8_t) const;
private:
static constexpr uint32_t m_command_ring_trb_count = 256;
static constexpr uint32_t m_event_ring_trb_count = 252;

View File

@ -51,8 +51,6 @@ namespace Kernel
void advance_endpoint_enqueue(Endpoint&, bool chain);
static uint64_t calculate_port_bits_per_second(XHCIController&, uint32_t port_id);
private:
static constexpr uint32_t m_transfer_ring_trb_count = PAGE_SIZE / sizeof(XHCI::TRB);

View File

@ -340,15 +340,4 @@ namespace Kernel
driver->handle_input_data(byte_count, endpoint_id);
}
USB::SpeedClass USBDevice::determine_speed_class(uint64_t bits_per_second)
{
if (bits_per_second <= 1'500'000)
return USB::SpeedClass::LowSpeed;
if (bits_per_second <= 12'000'000)
return USB::SpeedClass::FullSpeed;
else if (bits_per_second <= 480'000'000)
return USB::SpeedClass::HighSpeed;
return USB::SpeedClass::SuperSpeed;
}
}

View File

@ -148,6 +148,8 @@ namespace Kernel
ASSERT(m_ports.size() == max_ports);
bool overrides_speed_ids = false;
{
uint16_t ext_offset = capabilities.hccparams1.xhci_extended_capabilities_pointer;
if (ext_offset == 0)
@ -159,11 +161,11 @@ namespace Kernel
vaddr_t ext_addr = m_configuration_bar->vaddr() + ext_offset * 4;
while (true)
{
auto& ext_cap = *reinterpret_cast<volatile XHCI::ExtendedCap*>(ext_addr);
const auto& ext_cap = *reinterpret_cast<volatile XHCI::ExtendedCap*>(ext_addr);
if (ext_cap.capability_id == XHCI::ExtendedCapabilityID::SupportedProtocol)
{
auto& protocol = reinterpret_cast<volatile XHCI::SupportedPrococolCap&>(ext_cap);
const auto& protocol = reinterpret_cast<const volatile XHCI::SupportedPrococolCap&>(ext_cap);
const uint32_t target_name_string {
('U' << 0) |
@ -183,21 +185,15 @@ namespace Kernel
return BAN::Error::from_errno(EFAULT);
}
if (protocol.protocol_speed_id_count != 0)
overrides_speed_ids = true;
for (size_t i = 0; i < protocol.compatible_port_count; i++)
{
auto& port = m_ports[protocol.compatible_port_offset + i - 1];
port.revision_major = protocol.major_revision;
port.revision_minor = protocol.minor_revision;
port.slot_type = protocol.protocol_slot_type;
for (size_t j = 0; j < protocol.protocol_speed_id_count; j++)
{
uint32_t speed_info = reinterpret_cast<const volatile uint32_t*>(ext_addr + sizeof(XHCI::SupportedPrococolCap))[j];
uint32_t port_speed = speed_info >> 16;
for (size_t exp = 0; exp < ((speed_info >> 4) & 0x03); exp++)
port_speed *= 1000;
port.speed_id_to_speed[speed_info & 0x0F] = port_speed;
}
}
}
@ -207,6 +203,9 @@ namespace Kernel
}
}
if (overrides_speed_ids)
dwarnln("xHCI overrides default speed ids, USB may not work");
// set max slots enabled
auto& operational = operational_regs();
operational.config.max_device_slots_enabled = capabilities.hcsparams1.max_slots;
@ -214,6 +213,30 @@ namespace Kernel
return {};
}
uint8_t XHCIController::speed_class_to_id(USB::SpeedClass speed_class) const
{
switch (speed_class)
{
case USB::SpeedClass::LowSpeed: return 2;
case USB::SpeedClass::FullSpeed: return 1;
case USB::SpeedClass::HighSpeed: return 3;
case USB::SpeedClass::SuperSpeed: return 4;
}
ASSERT_NOT_REACHED();
}
USB::SpeedClass XHCIController::speed_id_to_class(uint8_t speed_id) const
{
switch (speed_id)
{
case 2: return USB::SpeedClass::LowSpeed;
case 1: return USB::SpeedClass::FullSpeed;
case 3: return USB::SpeedClass::HighSpeed;
case 4: return USB::SpeedClass::SuperSpeed;
}
ASSERT_NOT_REACHED();
}
BAN::ErrorOr<void> XHCIController::initialize_primary_interrupter()
{
TRY(m_pci_device.reserve_interrupts(1));

View File

@ -13,15 +13,8 @@ namespace Kernel
return TRY(BAN::UniqPtr<XHCIDevice>::create(controller, port_id, slot_id));
}
uint64_t XHCIDevice::calculate_port_bits_per_second(XHCIController& controller, uint32_t port_id)
{
const uint32_t portsc = controller.operational_regs().ports[port_id - 1].portsc;
const uint32_t speed_id = (portsc >> XHCI::PORTSC::PORT_SPEED_SHIFT) & XHCI::PORTSC::PORT_SPEED_MASK;
return controller.port(port_id).speed_id_to_speed[speed_id];
}
XHCIDevice::XHCIDevice(XHCIController& controller, uint32_t port_id, uint32_t slot_id)
: USBDevice(determine_speed_class(calculate_port_bits_per_second(controller, port_id)))
: USBDevice(controller.speed_id_to_class((controller.operational_regs().ports[port_id - 1].portsc >> XHCI::PORTSC::PORT_SPEED_SHIFT) & XHCI::PORTSC::PORT_SPEED_MASK))
, m_controller(controller)
, m_port_id(port_id)
, m_slot_id(slot_id)