diff --git a/Kernel/Bus/USB/USBDevice.cpp b/Kernel/Bus/USB/USBDevice.cpp index 49c449427c..3dcd2c7fe3 100644 --- a/Kernel/Bus/USB/USBDevice.cpp +++ b/Kernel/Bus/USB/USBDevice.cpp @@ -39,6 +39,7 @@ ErrorOr> Device::try_create(USBController const& contr if (result.is_error()) continue; dbgln_if(USB_DEBUG, "Found driver {} for device {:04x}:{:04x}!", driver->name(), device->m_vendor_id, device->m_product_id); + device->set_driver(driver); break; } diff --git a/Kernel/Bus/USB/USBDevice.h b/Kernel/Bus/USB/USBDevice.h index 47144d36ed..81c2b7e04c 100644 --- a/Kernel/Bus/USB/USBDevice.h +++ b/Kernel/Bus/USB/USBDevice.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,14 @@ public: Vector const& configurations() const { return m_configurations; } + void set_driver(Driver& driver) { m_driver = driver; } + void detach() + { + if (m_driver) + m_driver->detach(*this); + m_driver = nullptr; + } + SpinlockProtected, LockRank::None>& sysfs_device_info_node(Badge) { return m_sysfs_device_info_node; } protected: @@ -76,6 +85,8 @@ protected: NonnullLockRefPtr m_controller; NonnullOwnPtr m_default_pipe; // Default communication pipe (endpoint0) used during enumeration + LockRefPtr m_driver; + private: IntrusiveListNode> m_hub_child_node; diff --git a/Kernel/Bus/USB/USBHub.cpp b/Kernel/Bus/USB/USBHub.cpp index 290d7e2734..44540af3e0 100644 --- a/Kernel/Bus/USB/USBHub.cpp +++ b/Kernel/Bus/USB/USBHub.cpp @@ -295,6 +295,9 @@ void Hub::check_for_port_updates() auto* hub_child = static_cast(device_to_remove.ptr()); hub_child->remove_children_from_sysfs(); } + + device_to_remove->detach(); + m_children.remove(*device_to_remove); } else { dbgln_if(USB_DEBUG, "USB Hub: No child set up on port {}, ignoring detachment.", port_number);