Serenity Operating System
at master 82 lines 2.5 kB view raw
1/* 2 * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/Singleton.h> 8#include <Kernel/Bus/PCI/API.h> 9#include <Kernel/Bus/USB/UHCI/UHCIController.h> 10#include <Kernel/Bus/USB/USBManagement.h> 11#include <Kernel/CommandLine.h> 12#include <Kernel/FileSystem/SysFS/Subsystems/Bus/USB/BusDirectory.h> 13#include <Kernel/Sections.h> 14 15namespace Kernel::USB { 16 17static Singleton<USBManagement> s_the; 18READONLY_AFTER_INIT bool s_initialized_sys_fs_directory = false; 19 20UNMAP_AFTER_INIT USBManagement::USBManagement() 21{ 22 enumerate_controllers(); 23} 24 25UNMAP_AFTER_INIT void USBManagement::enumerate_controllers() 26{ 27 if (kernel_command_line().disable_usb()) 28 return; 29 30 MUST(PCI::enumerate([this](PCI::DeviceIdentifier const& device_identifier) { 31 if (!(device_identifier.class_code().value() == 0xc && device_identifier.subclass_code().value() == 0x3)) 32 return; 33 if (device_identifier.prog_if().value() == 0x0) { 34 if (kernel_command_line().disable_uhci_controller()) 35 return; 36 37 if (auto uhci_controller_or_error = UHCIController::try_to_initialize(device_identifier); !uhci_controller_or_error.is_error()) 38 m_controllers.append(uhci_controller_or_error.release_value()); 39 40 return; 41 } 42 43 if (device_identifier.prog_if().value() == 0x10) { 44 dmesgln("USBManagement: OHCI controller found at {} is not currently supported.", device_identifier.address()); 45 return; 46 } 47 48 if (device_identifier.prog_if().value() == 0x20) { 49 dmesgln("USBManagement: EHCI controller found at {} is not currently supported.", device_identifier.address()); 50 return; 51 } 52 53 if (device_identifier.prog_if().value() == 0x30) { 54 dmesgln("USBManagement: xHCI controller found at {} is not currently supported.", device_identifier.address()); 55 return; 56 } 57 58 dmesgln("USBManagement: Unknown/unsupported controller at {} with programming interface 0x{:02x}", device_identifier.address(), device_identifier.prog_if().value()); 59 })); 60} 61 62bool USBManagement::initialized() 63{ 64 return s_the.is_initialized(); 65} 66 67UNMAP_AFTER_INIT void USBManagement::initialize() 68{ 69 if (!s_initialized_sys_fs_directory) { 70 SysFSUSBBusDirectory::initialize(); 71 s_initialized_sys_fs_directory = true; 72 } 73 74 s_the.ensure_instance(); 75} 76 77USBManagement& USBManagement::the() 78{ 79 return *s_the; 80} 81 82}