瀏覽代碼

Kernel/USB: Create controller base class and introduce USBManagement

This removes Pipes dependency on the UHCIController by introducing a
controller base class. This will be used to implement other controllers
such as OHCI.

Additionally, there can be multiple instances of a UHCI controller.
For example, multiple UHCI instances can be required for systems with
EHCI controllers. EHCI relies on using multiple of either UHCI or OHCI
controllers to drive USB 1.x devices.

This means UHCIController can no longer be a singleton. Multiple
instances of it can now be created and passed to the device and then to
the pipe.

To handle finding and creating these instances, USBManagement has been
introduced. It has the same pattern as the other management classes
such as NetworkManagement.
Luke 4 年之前
父節點
當前提交
7a86a8df90

+ 36 - 32
Kernel/Bus/USB/UHCIController.cpp

@@ -27,8 +27,6 @@ static constexpr u8 RETRY_COUNTER_RELOAD = 3;
 
 namespace Kernel::USB {
 
-static UHCIController* s_the;
-
 static constexpr u16 UHCI_USBCMD_RUN = 0x0001;
 static constexpr u16 UHCI_USBCMD_HOST_CONTROLLER_RESET = 0x0002;
 static constexpr u16 UHCI_USBCMD_GLOBAL_RESET = 0x0004;
@@ -211,43 +209,44 @@ NonnullRefPtr<SysFSUSBDeviceInformation> SysFSUSBDeviceInformation::create(USB::
     return adopt_ref(*new SysFSUSBDeviceInformation(device));
 }
 
-UHCIController& UHCIController::the()
+KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::Address address)
 {
-    return *s_the;
+    // NOTE: This assumes that address is pointing to a valid UHCI controller.
+    auto controller = adopt_ref_if_nonnull(new (nothrow) UHCIController(address));
+    if (!controller)
+        return ENOMEM;
+
+    auto init_result = controller->initialize();
+    if (init_result.is_error())
+        return init_result;
+
+    return controller.release_nonnull();
 }
 
-UNMAP_AFTER_INIT void UHCIController::detect()
+KResult UHCIController::initialize()
 {
-    if (kernel_command_line().disable_uhci_controller())
-        return;
-
     // FIXME: We create the /proc/bus/usb representation here, but it should really be handled
     // in a more broad singleton than this once we refactor things in USB subsystem.
     SysFSUSBBusDirectory::initialize();
 
-    PCI::enumerate([&](const PCI::Address& address, PCI::ID id) {
-        if (address.is_null())
-            return;
+    dmesgln("UHCI: Controller found {} @ {}", PCI::get_id(pci_address()), pci_address());
+    dmesgln("UHCI: I/O base {}", m_io_base);
+    dmesgln("UHCI: Interrupt line: {}", PCI::get_interrupt_line(pci_address()));
 
-        if (PCI::get_class(address) == 0xc && PCI::get_subclass(address) == 0x03 && PCI::get_programming_interface(address) == 0) {
-            if (!s_the) {
-                s_the = new UHCIController(address, id);
-                s_the->spawn_port_proc();
-            }
-        }
-    });
+    spawn_port_proc();
+
+    auto reset_result = reset();
+    if (reset_result.is_error())
+        return reset_result;
+
+    auto start_result = start();
+    return start_result;
 }
 
-UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address, PCI::ID id)
+UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address)
     : PCI::Device(address)
     , m_io_base(PCI::get_BAR4(pci_address()) & ~1)
 {
-    dmesgln("UHCI: Controller found {} @ {}", id, address);
-    dmesgln("UHCI: I/O base {}", m_io_base);
-    dmesgln("UHCI: Interrupt line: {}", PCI::get_interrupt_line(pci_address()));
-
-    reset();
-    start();
 }
 
 UNMAP_AFTER_INIT UHCIController::~UHCIController()
@@ -275,9 +274,10 @@ RefPtr<USB::Device> const UHCIController::get_device_from_address(u8 device_addr
     return nullptr;
 }
 
-void UHCIController::reset()
+KResult UHCIController::reset()
 {
-    stop();
+    if (auto stop_result = stop(); stop_result.is_error())
+        return stop_result;
 
     write_usbcmd(UHCI_USBCMD_HOST_CONTROLLER_RESET);
 
@@ -305,6 +305,8 @@ void UHCIController::reset()
     // Disable UHCI Controller from raising an IRQ
     write_usbintr(0);
     dbgln("UHCI: Reset completed");
+
+    return KSuccess;
 }
 
 UNMAP_AFTER_INIT void UHCIController::create_structures()
@@ -464,7 +466,7 @@ TransferDescriptor* UHCIController::allocate_transfer_descriptor() const
     return nullptr; // Huh?! We're outta TDs!!
 }
 
-void UHCIController::stop()
+KResult UHCIController::stop()
 {
     write_usbcmd(read_usbcmd() & ~UHCI_USBCMD_RUN);
     // FIXME: Timeout
@@ -472,9 +474,10 @@ void UHCIController::stop()
         if (read_usbsts() & UHCI_USBSTS_HOST_CONTROLLER_HALTED)
             break;
     }
+    return KSuccess;
 }
 
-void UHCIController::start()
+KResult UHCIController::start()
 {
     write_usbcmd(read_usbcmd() | UHCI_USBCMD_RUN);
     // FIXME: Timeout
@@ -483,6 +486,7 @@ void UHCIController::start()
             break;
     }
     dbgln("UHCI: Started");
+    return KSuccess;
 }
 
 TransferDescriptor* UHCIController::create_transfer_descriptor(Pipe& pipe, PacketID direction, size_t data_len)
@@ -713,7 +717,7 @@ void UHCIController::spawn_port_proc()
                             dbgln("port should be enabled now: {:#04x}\n", read_portsc1());
 
                             USB::Device::DeviceSpeed speed = (port_data & UHCI_PORTSC_LOW_SPEED_DEVICE) ? USB::Device::DeviceSpeed::LowSpeed : USB::Device::DeviceSpeed::FullSpeed;
-                            auto device = USB::Device::try_create(USB::Device::PortNumber::Port1, speed);
+                            auto device = USB::Device::try_create(*this, USB::Device::PortNumber::Port1, speed);
 
                             if (device.is_error())
                                 dmesgln("UHCI: Device creation failed on port 1 ({})", device.error());
@@ -730,7 +734,7 @@ void UHCIController::spawn_port_proc()
                         }
                     }
                 } else {
-                    port_data = UHCIController::the().read_portsc2();
+                    port_data = read_portsc2();
                     if (port_data & UHCI_PORTSC_CONNECT_STATUS_CHANGED) {
                         if (port_data & UHCI_PORTSC_CURRRENT_CONNECT_STATUS) {
                             dmesgln("UHCI: Device attach detected on Root Port 2");
@@ -751,7 +755,7 @@ void UHCIController::spawn_port_proc()
                             write_portsc2(port_data | UHCI_PORTSC_PORT_ENABLED);
                             dbgln("port should be enabled now: {:#04x}\n", read_portsc2());
                             USB::Device::DeviceSpeed speed = (port_data & UHCI_PORTSC_LOW_SPEED_DEVICE) ? USB::Device::DeviceSpeed::LowSpeed : USB::Device::DeviceSpeed::FullSpeed;
-                            auto device = USB::Device::try_create(USB::Device::PortNumber::Port2, speed);
+                            auto device = USB::Device::try_create(*this, USB::Device::PortNumber::Port2, speed);
 
                             if (device.is_error())
                                 dmesgln("UHCI: Device creation failed on port 2 ({})", device.error());

+ 13 - 13
Kernel/Bus/USB/UHCIController.h

@@ -12,8 +12,7 @@
 #include <AK/NonnullOwnPtr.h>
 #include <Kernel/Bus/PCI/Device.h>
 #include <Kernel/Bus/USB/UHCIDescriptorTypes.h>
-#include <Kernel/Bus/USB/USBDevice.h>
-#include <Kernel/Bus/USB/USBTransfer.h>
+#include <Kernel/Bus/USB/USBController.h>
 #include <Kernel/IO.h>
 #include <Kernel/Memory/AnonymousVMObject.h>
 #include <Kernel/Process.h>
@@ -21,30 +20,31 @@
 
 namespace Kernel::USB {
 
-class UHCIController final : public PCI::Device {
+class UHCIController final
+    : public USBController
+    , public PCI::Device {
 
 public:
-    static void detect();
-    static UHCIController& the();
-
+    static KResultOr<NonnullRefPtr<UHCIController>> try_to_initialize(PCI::Address address);
     virtual ~UHCIController() override;
 
     virtual StringView purpose() const override { return "UHCI"; }
 
-    void reset();
-    void stop();
-    void start();
+    virtual KResult initialize() override;
+    virtual KResult reset() override;
+    virtual KResult stop() override;
+    virtual KResult start() override;
     void spawn_port_proc();
 
     void do_debug_transfer();
 
-    KResultOr<size_t> submit_control_transfer(Transfer& transfer);
+    virtual KResultOr<size_t> submit_control_transfer(Transfer& transfer) override;
 
-    RefPtr<USB::Device> const get_device_at_port(USB::Device::PortNumber);
-    RefPtr<USB::Device> const get_device_from_address(u8 device_address);
+    virtual RefPtr<USB::Device> const get_device_at_port(USB::Device::PortNumber) override;
+    virtual RefPtr<USB::Device> const get_device_from_address(u8 device_address) override;
 
 private:
-    UHCIController(PCI::Address, PCI::ID);
+    explicit UHCIController(PCI::Address);
 
     u16 read_usbcmd() { return m_io_base.offset(0).in<u16>(); }
     u16 read_usbsts() { return m_io_base.offset(0x2).in<u16>(); }

+ 17 - 0
Kernel/Bus/USB/USBController.cpp

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <Kernel/Bus/USB/USBController.h>
+
+namespace Kernel::USB {
+
+u8 USBController::allocate_address()
+{
+    // FIXME: This can be smarter.
+    return m_next_device_index++;
+}
+
+}

+ 42 - 0
Kernel/Bus/USB/USBController.h

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/RefCounted.h>
+#include <Kernel/Bus/USB/USBDevice.h>
+#include <Kernel/Bus/USB/USBTransfer.h>
+#include <Kernel/KResult.h>
+
+namespace Kernel::USB {
+
+class USBController : public RefCounted<USBController> {
+public:
+    virtual ~USBController() = default;
+
+    virtual KResult initialize() = 0;
+
+    virtual KResult reset() = 0;
+    virtual KResult stop() = 0;
+    virtual KResult start() = 0;
+
+    virtual KResultOr<size_t> submit_control_transfer(Transfer&) = 0;
+
+    virtual RefPtr<USB::Device> const get_device_at_port(USB::Device::PortNumber) = 0;
+    virtual RefPtr<USB::Device> const get_device_from_address(u8) = 0;
+
+    u8 allocate_address();
+
+private:
+    u8 m_next_device_index { 1 };
+
+    IntrusiveListNode<USBController, NonnullRefPtr<USBController>> m_controller_list_node;
+
+public:
+    using List = IntrusiveList<USBController, NonnullRefPtr<USBController>, &USBController::m_controller_list_node>;
+};
+
+}

+ 11 - 9
Kernel/Bus/USB/USBDevice.cpp

@@ -5,24 +5,24 @@
  */
 
 #include <AK/OwnPtr.h>
+#include <AK/String.h>
 #include <AK/Types.h>
 #include <AK/Vector.h>
-#include <Kernel/Bus/USB/UHCIController.h>
+#include <Kernel/Bus/USB/USBController.h>
 #include <Kernel/Bus/USB/USBDescriptors.h>
 #include <Kernel/Bus/USB/USBDevice.h>
 #include <Kernel/Bus/USB/USBRequest.h>
-
-static u32 s_next_usb_address = 1; // Next address we hand out to a device once it's plugged into the machine
+#include <Kernel/StdLib.h>
 
 namespace Kernel::USB {
 
-KResultOr<NonnullRefPtr<Device>> Device::try_create(PortNumber port, DeviceSpeed speed)
+KResultOr<NonnullRefPtr<Device>> Device::try_create(USBController const& controller, PortNumber port, DeviceSpeed speed)
 {
-    auto pipe_or_error = Pipe::try_create_pipe(Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0);
+    auto pipe_or_error = Pipe::try_create_pipe(controller, Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0);
     if (pipe_or_error.is_error())
         return pipe_or_error.error();
 
-    auto device = AK::try_create<Device>(port, speed, pipe_or_error.release_value());
+    auto device = AK::try_create<Device>(controller, port, speed, pipe_or_error.release_value());
     if (!device)
         return ENOMEM;
 
@@ -33,10 +33,11 @@ KResultOr<NonnullRefPtr<Device>> Device::try_create(PortNumber port, DeviceSpeed
     return device.release_nonnull();
 }
 
-Device::Device(PortNumber port, DeviceSpeed speed, NonnullOwnPtr<Pipe> default_pipe)
+Device::Device(USBController const& controller, PortNumber port, DeviceSpeed speed, NonnullOwnPtr<Pipe> default_pipe)
     : m_device_port(port)
     , m_device_speed(speed)
     , m_address(0)
+    , m_controller(controller)
     , m_default_pipe(move(default_pipe))
 {
 }
@@ -83,8 +84,10 @@ KResult Device::enumerate()
         dbgln("Number of configurations: {:02x}", dev_descriptor.num_configurations);
     }
 
+    m_address = m_controller->allocate_address();
+
     // Attempt to set devices address on the bus
-    transfer_length_or_error = m_default_pipe->control_transfer(USB_DEVICE_REQUEST_HOST_TO_DEVICE, USB_REQUEST_SET_ADDRESS, s_next_usb_address, 0, 0, nullptr);
+    transfer_length_or_error = m_default_pipe->control_transfer(USB_DEVICE_REQUEST_HOST_TO_DEVICE, USB_REQUEST_SET_ADDRESS, m_address, 0, 0, nullptr);
 
     if (transfer_length_or_error.is_error())
         return transfer_length_or_error.error();
@@ -92,7 +95,6 @@ KResult Device::enumerate()
     transfer_length = transfer_length_or_error.release_value();
 
     VERIFY(transfer_length > 0);
-    m_address = s_next_usb_address++;
 
     memcpy(&m_device_descriptor, &dev_descriptor, sizeof(USBDeviceDescriptor));
     return KSuccess;

+ 5 - 2
Kernel/Bus/USB/USBDevice.h

@@ -12,6 +12,8 @@
 
 namespace Kernel::USB {
 
+class USBController;
+
 //
 // Some nice info from FTDI on device enumeration and how some of this
 // glues together:
@@ -30,9 +32,9 @@ public:
     };
 
 public:
-    static KResultOr<NonnullRefPtr<Device>> try_create(PortNumber, DeviceSpeed);
+    static KResultOr<NonnullRefPtr<Device>> try_create(USBController const&, PortNumber, DeviceSpeed);
 
-    Device(PortNumber, DeviceSpeed, NonnullOwnPtr<Pipe> default_pipe);
+    Device(USBController const&, PortNumber, DeviceSpeed, NonnullOwnPtr<Pipe> default_pipe);
     ~Device();
 
     KResult enumerate();
@@ -54,6 +56,7 @@ private:
     u16 m_product_id { 0 };                  // This device's product ID assigned by the USB group
     USBDeviceDescriptor m_device_descriptor; // Device Descriptor obtained from USB Device
 
+    NonnullRefPtr<USBController> m_controller;
     NonnullOwnPtr<Pipe> m_default_pipe; // Default communication pipe (endpoint0) used during enumeration
 };
 }

+ 74 - 0
Kernel/Bus/USB/USBManagement.cpp

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/Singleton.h>
+#include <Kernel/Bus/PCI/Access.h>
+#include <Kernel/Bus/USB/UHCIController.h>
+#include <Kernel/Bus/USB/USBManagement.h>
+#include <Kernel/CommandLine.h>
+#include <Kernel/Sections.h>
+
+namespace Kernel::USB {
+
+static Singleton<USBManagement> s_the;
+
+UNMAP_AFTER_INIT USBManagement::USBManagement()
+{
+    enumerate_controllers();
+}
+
+UNMAP_AFTER_INIT void USBManagement::enumerate_controllers()
+{
+    if (!kernel_command_line().disable_usb()) {
+        PCI::enumerate([this](PCI::Address const& address, PCI::ID) {
+            if (PCI::get_class(address) == 0xc && PCI::get_subclass(address) == 0x3) {
+                if (PCI::get_programming_interface(address) == 0x0) {
+                    if (kernel_command_line().disable_uhci_controller())
+                        return;
+
+                    if (auto uhci_controller_or_error = UHCIController::try_to_initialize(address); !uhci_controller_or_error.is_error())
+                        m_controllers.append(uhci_controller_or_error.release_value());
+
+                    return;
+                }
+
+                if (PCI::get_programming_interface(address) == 0x10) {
+                    dmesgln("USBManagement: OHCI controller found at {} is not currently supported.", address);
+                    return;
+                }
+
+                if (PCI::get_programming_interface(address) == 0x20) {
+                    dmesgln("USBManagement: EHCI controller found at {} is not currently supported.", address);
+                    return;
+                }
+
+                if (PCI::get_programming_interface(address) == 0x30) {
+                    dmesgln("USBManagement: xHCI controller found at {} is not currently supported.", address);
+                    return;
+                }
+
+                dmesgln("USBManagement: Unknown/unsupported controller at {} with programming interface 0x{:02x}", address, PCI::get_programming_interface(address));
+            }
+        });
+    }
+}
+
+bool USBManagement::initialized()
+{
+    return s_the.is_initialized();
+}
+
+UNMAP_AFTER_INIT void USBManagement::initialize()
+{
+    s_the.ensure_instance();
+}
+
+USBManagement& USBManagement::the()
+{
+    return *s_the;
+}
+
+}

+ 30 - 0
Kernel/Bus/USB/USBManagement.h

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/NonnullRefPtr.h>
+#include <AK/NonnullRefPtrVector.h>
+#include <Kernel/Bus/USB/USBController.h>
+
+namespace Kernel::USB {
+
+class USBManagement {
+    AK_MAKE_ETERNAL;
+
+public:
+    USBManagement();
+    static bool initialized();
+    static void initialize();
+    static USBManagement& the();
+
+private:
+    void enumerate_controllers();
+
+    USBController::List m_controllers;
+};
+
+}

+ 12 - 9
Kernel/Bus/USB/USBPipe.cpp

@@ -11,17 +11,18 @@
 
 namespace Kernel::USB {
 
-KResultOr<NonnullOwnPtr<Pipe>> Pipe::try_create_pipe(Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, u8 poll_interval)
+KResultOr<NonnullOwnPtr<Pipe>> Pipe::try_create_pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, u8 poll_interval)
 {
-    auto pipe = adopt_own_if_nonnull(new (nothrow) Pipe(type, direction, endpoint_address, max_packet_size, device_address, poll_interval));
+    auto pipe = adopt_own_if_nonnull(new (nothrow) Pipe(controller, type, direction, endpoint_address, max_packet_size, device_address, poll_interval));
     if (!pipe)
         return ENOMEM;
 
     return pipe.release_nonnull();
 }
 
-Pipe::Pipe(Type type, Pipe::Direction direction, u16 max_packet_size)
-    : m_type(type)
+Pipe::Pipe(USBController const& controller, Type type, Pipe::Direction direction, u16 max_packet_size)
+    : m_controller(controller)
+    , m_type(type)
     , m_direction(direction)
     , m_endpoint_address(0)
     , m_max_packet_size(max_packet_size)
@@ -30,15 +31,17 @@ Pipe::Pipe(Type type, Pipe::Direction direction, u16 max_packet_size)
 {
 }
 
-Pipe::Pipe(Type type, Direction direction, USBEndpointDescriptor& endpoint [[maybe_unused]])
-    : m_type(type)
+Pipe::Pipe(USBController const& controller, Type type, Direction direction, USBEndpointDescriptor& endpoint [[maybe_unused]])
+    : m_controller(controller)
+    , m_type(type)
     , m_direction(direction)
 {
     // TODO: decode endpoint structure
 }
 
-Pipe::Pipe(Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, u8 poll_interval, i8 device_address)
-    : m_type(type)
+Pipe::Pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, u8 poll_interval, i8 device_address)
+    : m_controller(controller)
+    , m_type(type)
     , m_direction(direction)
     , m_device_address(device_address)
     , m_endpoint_address(endpoint_address)
@@ -66,7 +69,7 @@ KResultOr<size_t> Pipe::control_transfer(u8 request_type, u8 request, u16 value,
     transfer->set_setup_packet(usb_request);
 
     dbgln_if(USB_DEBUG, "Pipe: Transfer allocated @ {}", transfer->buffer_physical());
-    auto transfer_len_or_error = UHCIController::the().submit_control_transfer(*transfer);
+    auto transfer_len_or_error = m_controller->submit_control_transfer(*transfer);
 
     if (transfer_len_or_error.is_error())
         return transfer_len_or_error.error();

+ 8 - 4
Kernel/Bus/USB/USBPipe.h

@@ -13,6 +13,8 @@
 
 namespace Kernel::USB {
 
+class USBController;
+
 //
 // A pipe is the logical connection between a memory buffer on the PC (host) and
 // an endpoint on the device. In this implementation, the data buffer the pipe connects
@@ -39,7 +41,7 @@ public:
     };
 
 public:
-    static KResultOr<NonnullOwnPtr<Pipe>> try_create_pipe(Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, u8 poll_interval = 0);
+    static KResultOr<NonnullOwnPtr<Pipe>> try_create_pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, u8 poll_interval = 0);
 
     Type type() const { return m_type; }
     Direction direction() const { return m_direction; }
@@ -57,13 +59,15 @@ public:
 
     KResultOr<size_t> control_transfer(u8 request_type, u8 request, u16 value, u16 index, u16 length, void* data);
 
-    Pipe(Type type, Direction direction, u16 max_packet_size);
-    Pipe(Type type, Direction direction, USBEndpointDescriptor& endpoint);
-    Pipe(Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, u8 poll_interval, i8 device_address);
+    Pipe(USBController const& controller, Type type, Direction direction, u16 max_packet_size);
+    Pipe(USBController const& controller, Type type, Direction direction, USBEndpointDescriptor& endpoint);
+    Pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, u8 poll_interval, i8 device_address);
 
 private:
     friend class Device;
 
+    NonnullRefPtr<USBController> m_controller;
+
     Type m_type;
     Direction m_direction;
     DeviceSpeed m_speed;

+ 2 - 0
Kernel/CMakeLists.txt

@@ -32,7 +32,9 @@ set(KERNEL_SOURCES
     Bus/PCI/Initializer.cpp
     Bus/PCI/WindowedMMIOAccess.cpp
     Bus/USB/UHCIController.cpp
+    Bus/USB/USBController.cpp
     Bus/USB/USBDevice.cpp
+    Bus/USB/USBManagement.cpp
     Bus/USB/USBPipe.cpp
     Bus/USB/USBTransfer.cpp
     CMOS.cpp

+ 5 - 0
Kernel/CommandLine.cpp

@@ -177,6 +177,11 @@ UNMAP_AFTER_INIT bool CommandLine::disable_uhci_controller() const
     return contains("disable_uhci_controller"sv);
 }
 
+UNMAP_AFTER_INIT bool CommandLine::disable_usb() const
+{
+    return contains("disable_usb"sv);
+}
+
 UNMAP_AFTER_INIT bool CommandLine::disable_virtio() const
 {
     return contains("disable_virtio"sv);

+ 1 - 0
Kernel/CommandLine.h

@@ -73,6 +73,7 @@ public:
     [[nodiscard]] bool disable_physical_storage() const;
     [[nodiscard]] bool disable_ps2_controller() const;
     [[nodiscard]] bool disable_uhci_controller() const;
+    [[nodiscard]] bool disable_usb() const;
     [[nodiscard]] bool disable_virtio() const;
     [[nodiscard]] AHCIResetMode ahci_reset_mode() const;
     [[nodiscard]] String userspace_init() const;

+ 2 - 2
Kernel/init.cpp

@@ -13,7 +13,7 @@
 #include <Kernel/BootInfo.h>
 #include <Kernel/Bus/PCI/Access.h>
 #include <Kernel/Bus/PCI/Initializer.h>
-#include <Kernel/Bus/USB/UHCIController.h>
+#include <Kernel/Bus/USB/USBManagement.h>
 #include <Kernel/CMOS.h>
 #include <Kernel/CommandLine.h>
 #include <Kernel/Devices/FullDevice.h>
@@ -300,7 +300,7 @@ void init_stage2(void*)
 
     auto boot_profiling = kernel_command_line().is_boot_profiling_enabled();
 
-    USB::UHCIController::detect();
+    USB::USBManagement::initialize();
 
     BIOSSysFSDirectory::initialize();
     ACPI::ACPISysFSDirectory::initialize();