Kernel/USB: Update SysFS from the generic hub instead of from UHCI

This commit is contained in:
Luke 2021-08-11 03:13:47 +01:00 committed by Andreas Kling
parent 872c75ac44
commit 4b4525dfc7
Notes: sideshowbarker 2024-07-18 05:43:36 +09:00
4 changed files with 30 additions and 3 deletions

View File

@ -107,6 +107,12 @@ void SysFSUSBBusDirectory::unplug(USB::Device& deleted_device)
device_node->m_list_node.remove(); device_node->m_list_node.remove();
} }
SysFSUSBBusDirectory& SysFSUSBBusDirectory::the()
{
VERIFY(s_procfs_usb_bus_directory);
return *s_procfs_usb_bus_directory;
}
UNMAP_AFTER_INIT SysFSUSBBusDirectory::SysFSUSBBusDirectory(SysFSBusDirectory& buses_directory) UNMAP_AFTER_INIT SysFSUSBBusDirectory::SysFSUSBBusDirectory(SysFSBusDirectory& buses_directory)
: SysFSDirectory("usb"sv, buses_directory) : SysFSDirectory("usb"sv, buses_directory)
{ {

View File

@ -34,6 +34,8 @@ protected:
class SysFSUSBBusDirectory final : public SysFSDirectory { class SysFSUSBBusDirectory final : public SysFSDirectory {
public: public:
static void initialize(); static void initialize();
static SysFSUSBBusDirectory& the();
void plug(USB::Device&); void plug(USB::Device&);
void unplug(USB::Device&); void unplug(USB::Device&);

View File

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <Kernel/Bus/USB/SysFSUSB.h>
#include <Kernel/Bus/USB/USBClasses.h> #include <Kernel/Bus/USB/USBClasses.h>
#include <Kernel/Bus/USB/USBController.h> #include <Kernel/Bus/USB/USBController.h>
#include <Kernel/Bus/USB/USBHub.h> #include <Kernel/Bus/USB/USBHub.h>
@ -152,6 +153,12 @@ KResult Hub::set_port_feature(u8 port, HubFeatureSelector feature_selector)
return KSuccess; return KSuccess;
} }
void Hub::remove_children_from_sysfs()
{
for (auto& child : m_children)
SysFSUSBBusDirectory::the().unplug(child);
}
void Hub::check_for_port_updates() void Hub::check_for_port_updates()
{ {
for (u8 port_number = 1; port_number < m_hub_descriptor.number_of_downstream_ports + 1; ++port_number) { for (u8 port_number = 1; port_number < m_hub_descriptor.number_of_downstream_ports + 1; ++port_number) {
@ -279,9 +286,12 @@ void Hub::check_for_port_updates()
dbgln_if(USB_DEBUG, "USB Hub: Upgraded device at address {} to hub!", device->address()); dbgln_if(USB_DEBUG, "USB Hub: Upgraded device at address {} to hub!", device->address());
m_children.append(hub_or_error.release_value()); auto hub = hub_or_error.release_value();
m_children.append(hub);
SysFSUSBBusDirectory::the().plug(hub);
} else { } else {
m_children.append(device); m_children.append(device);
SysFSUSBBusDirectory::the().plug(device);
} }
} else { } else {
@ -295,13 +305,20 @@ void Hub::check_for_port_updates()
} }
} }
if (device_to_remove) if (device_to_remove) {
m_children.remove(*device_to_remove); m_children.remove(*device_to_remove);
else SysFSUSBBusDirectory::the().unplug(*device_to_remove);
if (device_to_remove->device_descriptor().device_class == USB_CLASS_HUB) {
auto* hub_child = static_cast<Hub*>(device_to_remove);
hub_child->remove_children_from_sysfs();
}
} else {
dbgln_if(USB_DEBUG, "USB Hub: No child set up on port {}, ignoring detachment.", port_number); dbgln_if(USB_DEBUG, "USB Hub: No child set up on port {}, ignoring detachment.", port_number);
} }
} }
} }
}
for (auto& child : m_children) { for (auto& child : m_children) {
if (child.device_descriptor().device_class == USB_CLASS_HUB) { if (child.device_descriptor().device_class == USB_CLASS_HUB) {

View File

@ -102,6 +102,8 @@ private:
USBHubDescriptor m_hub_descriptor; USBHubDescriptor m_hub_descriptor;
Device::List m_children; Device::List m_children;
void remove_children_from_sysfs();
}; };
} }