Kernel: Make sure USB class driver is deinitialized before xhci device

This commit is contained in:
Bananymous 2025-02-06 22:00:26 +02:00
parent 6a5367dbe3
commit a2a7302964
3 changed files with 19 additions and 6 deletions

View File

@ -61,6 +61,9 @@ namespace Kernel
{} {}
virtual ~USBDevice() = default; virtual ~USBDevice() = default;
// Class drivers have to be destroyed before derived class destructor is called
void destroy() { m_class_drivers.clear(); }
BAN::ErrorOr<void> initialize(); BAN::ErrorOr<void> initialize();
const BAN::Vector<ConfigurationDescriptor>& configurations() { return m_descriptor.configurations; } const BAN::Vector<ConfigurationDescriptor>& configurations() { return m_descriptor.configurations; }

View File

@ -46,7 +46,8 @@ namespace Kernel
void port_updater_task(); void port_updater_task();
BAN::ErrorOr<void> initialize_slot(int port_index); BAN::ErrorOr<uint8_t> initialize_slot(int port_index);
void deinitialize_slot(uint8_t slot_id);
BAN::ErrorOr<XHCI::TRB> send_command(const XHCI::TRB&); BAN::ErrorOr<XHCI::TRB> send_command(const XHCI::TRB&);
void advance_command_enqueue(); void advance_command_enqueue();

View File

@ -336,10 +336,9 @@ namespace Kernel
if (!(op_port.portsc & XHCI::PORTSC::CCS)) if (!(op_port.portsc & XHCI::PORTSC::CCS))
{ {
// if device detached, clear the port
if (my_port.slot_id != 0) if (my_port.slot_id != 0)
{ {
m_slots[my_port.slot_id - 1].clear(); deinitialize_slot(my_port.slot_id);
my_port.slot_id = 0; my_port.slot_id = 0;
} }
continue; continue;
@ -364,7 +363,9 @@ namespace Kernel
continue; continue;
} }
if (auto ret = initialize_slot(i); ret.is_error()) if (auto ret = initialize_slot(i); !ret.is_error())
my_port.slot_id = ret.value();
else
{ {
dwarnln("Could not initialize USB {H}.{H} device: {}", dwarnln("Could not initialize USB {H}.{H} device: {}",
my_port.revision_major, my_port.revision_major,
@ -376,7 +377,7 @@ namespace Kernel
} }
} }
BAN::ErrorOr<void> XHCIController::initialize_slot(int port_index) BAN::ErrorOr<uint8_t> XHCIController::initialize_slot(int port_index)
{ {
auto& my_port = m_ports[port_index]; auto& my_port = m_ports[port_index];
@ -406,7 +407,15 @@ namespace Kernel
dprintln_if(DEBUG_XHCI, "device on slot {} initialized", slot_id); dprintln_if(DEBUG_XHCI, "device on slot {} initialized", slot_id);
return {}; return slot_id;
}
void XHCIController::deinitialize_slot(uint8_t slot_id)
{
ASSERT(0 < slot_id && slot_id <= m_slots.size());
ASSERT(m_slots[slot_id - 1]);
m_slots[slot_id - 1]->destroy();
m_slots[slot_id - 1].clear();
} }
BAN::ErrorOr<void> XHCIController::reset_controller() BAN::ErrorOr<void> XHCIController::reset_controller()