Bläddra i källkod

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

Luke 3 år sedan
förälder
incheckning
4b4525dfc7
4 ändrade filer med 30 tillägg och 3 borttagningar
  1. 6 0
      Kernel/Bus/USB/SysFSUSB.cpp
  2. 2 0
      Kernel/Bus/USB/SysFSUSB.h
  3. 20 3
      Kernel/Bus/USB/USBHub.cpp
  4. 2 0
      Kernel/Bus/USB/USBHub.h

+ 6 - 0
Kernel/Bus/USB/SysFSUSB.cpp

@@ -107,6 +107,12 @@ void SysFSUSBBusDirectory::unplug(USB::Device& deleted_device)
     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)
     : SysFSDirectory("usb"sv, buses_directory)
 {

+ 2 - 0
Kernel/Bus/USB/SysFSUSB.h

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

+ 20 - 3
Kernel/Bus/USB/USBHub.cpp

@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <Kernel/Bus/USB/SysFSUSB.h>
 #include <Kernel/Bus/USB/USBClasses.h>
 #include <Kernel/Bus/USB/USBController.h>
 #include <Kernel/Bus/USB/USBHub.h>
@@ -152,6 +153,12 @@ KResult Hub::set_port_feature(u8 port, HubFeatureSelector feature_selector)
     return KSuccess;
 }
 
+void Hub::remove_children_from_sysfs()
+{
+    for (auto& child : m_children)
+        SysFSUSBBusDirectory::the().unplug(child);
+}
+
 void Hub::check_for_port_updates()
 {
     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());
 
-                    m_children.append(hub_or_error.release_value());
+                    auto hub = hub_or_error.release_value();
+                    m_children.append(hub);
+                    SysFSUSBBusDirectory::the().plug(hub);
                 } else {
                     m_children.append(device);
+                    SysFSUSBBusDirectory::the().plug(device);
                 }
 
             } else {
@@ -295,10 +305,17 @@ void Hub::check_for_port_updates()
                     }
                 }
 
-                if (device_to_remove)
+                if (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);
+                }
             }
         }
     }

+ 2 - 0
Kernel/Bus/USB/USBHub.h

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