diff --git a/kernel/include/kernel/USB/Device.h b/kernel/include/kernel/USB/Device.h index 2dd91348..55abe030 100644 --- a/kernel/include/kernel/USB/Device.h +++ b/kernel/include/kernel/USB/Device.h @@ -4,8 +4,8 @@ #include #include -#include #include +#include namespace Kernel { @@ -69,7 +69,8 @@ namespace Kernel virtual BAN::ErrorOr 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); diff --git a/kernel/include/kernel/USB/XHCI/Controller.h b/kernel/include/kernel/USB/XHCI/Controller.h index 3eac91c5..70ff3e4e 100644 --- a/kernel/include/kernel/USB/XHCI/Controller.h +++ b/kernel/include/kernel/USB/XHCI/Controller.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/kernel/include/kernel/USB/XHCI/Device.h b/kernel/include/kernel/USB/XHCI/Device.h index 20034735..ce3cea10 100644 --- a/kernel/include/kernel/USB/XHCI/Device.h +++ b/kernel/include/kernel/USB/XHCI/Device.h @@ -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); diff --git a/kernel/kernel/USB/Device.cpp b/kernel/kernel/USB/Device.cpp index 87517cf6..9df2da56 100644 --- a/kernel/kernel/USB/Device.cpp +++ b/kernel/kernel/USB/Device.cpp @@ -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; - } - } diff --git a/kernel/kernel/USB/XHCI/Controller.cpp b/kernel/kernel/USB/XHCI/Controller.cpp index f1516b7c..a059ad74 100644 --- a/kernel/kernel/USB/XHCI/Controller.cpp +++ b/kernel/kernel/USB/XHCI/Controller.cpp @@ -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(ext_addr); + const auto& ext_cap = *reinterpret_cast(ext_addr); if (ext_cap.capability_id == XHCI::ExtendedCapabilityID::SupportedProtocol) { - auto& protocol = reinterpret_cast(ext_cap); + const auto& protocol = reinterpret_cast(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(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 XHCIController::initialize_primary_interrupter() { TRY(m_pci_device.reserve_interrupts(1)); diff --git a/kernel/kernel/USB/XHCI/Device.cpp b/kernel/kernel/USB/XHCI/Device.cpp index 59ffbb6e..3bc78bdd 100644 --- a/kernel/kernel/USB/XHCI/Device.cpp +++ b/kernel/kernel/USB/XHCI/Device.cpp @@ -13,15 +13,8 @@ namespace Kernel return TRY(BAN::UniqPtr::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)