mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 05:38:11 +00:00

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.
74 lines
2.2 KiB
C++
74 lines
2.2 KiB
C++
/*
|
|
* 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;
|
|
}
|
|
|
|
}
|