USBManagement.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Singleton.h>
  7. #include <Kernel/Bus/PCI/Access.h>
  8. #include <Kernel/Bus/USB/SysFSUSB.h>
  9. #include <Kernel/Bus/USB/UHCI/UHCIController.h>
  10. #include <Kernel/Bus/USB/USBManagement.h>
  11. #include <Kernel/CommandLine.h>
  12. #include <Kernel/Sections.h>
  13. namespace Kernel::USB {
  14. static Singleton<USBManagement> s_the;
  15. READONLY_AFTER_INIT bool s_initialized_sys_fs_directory = false;
  16. UNMAP_AFTER_INIT USBManagement::USBManagement()
  17. {
  18. enumerate_controllers();
  19. }
  20. UNMAP_AFTER_INIT void USBManagement::enumerate_controllers()
  21. {
  22. if (kernel_command_line().disable_usb())
  23. return;
  24. PCI::enumerate([this](PCI::Address const& address, PCI::ID) {
  25. if (!(PCI::get_class(address) == 0xc && PCI::get_subclass(address) == 0x3))
  26. return;
  27. if (PCI::get_programming_interface(address) == 0x0) {
  28. if (kernel_command_line().disable_uhci_controller())
  29. return;
  30. if (auto uhci_controller_or_error = UHCIController::try_to_initialize(address); !uhci_controller_or_error.is_error())
  31. m_controllers.append(uhci_controller_or_error.release_value());
  32. return;
  33. }
  34. if (PCI::get_programming_interface(address) == 0x10) {
  35. dmesgln("USBManagement: OHCI controller found at {} is not currently supported.", address);
  36. return;
  37. }
  38. if (PCI::get_programming_interface(address) == 0x20) {
  39. dmesgln("USBManagement: EHCI controller found at {} is not currently supported.", address);
  40. return;
  41. }
  42. if (PCI::get_programming_interface(address) == 0x30) {
  43. dmesgln("USBManagement: xHCI controller found at {} is not currently supported.", address);
  44. return;
  45. }
  46. dmesgln("USBManagement: Unknown/unsupported controller at {} with programming interface 0x{:02x}", address, PCI::get_programming_interface(address));
  47. });
  48. }
  49. bool USBManagement::initialized()
  50. {
  51. return s_the.is_initialized();
  52. }
  53. UNMAP_AFTER_INIT void USBManagement::initialize()
  54. {
  55. if (!s_initialized_sys_fs_directory) {
  56. USB::SysFSUSBBusDirectory::initialize();
  57. s_initialized_sys_fs_directory = true;
  58. }
  59. s_the.ensure_instance();
  60. }
  61. USBManagement& USBManagement::the()
  62. {
  63. return *s_the;
  64. }
  65. }