// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include #include "common/logging.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" #include "core/hle/service/usb/usb.h" #include "frontend_common/firmware_manager.h" namespace Service::USB { class IDsInterface final : public ServiceFramework { public: explicit IDsInterface(Core::System& system_) : ServiceFramework{system_, "IDsInterface"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "AddEndpoint"}, FunctionInfo{1, nullptr, "GetSetupEvent"}, FunctionInfo{2, nullptr, "GetSetupPacket"}, FunctionInfo{3, nullptr, "Enable"}, FunctionInfo{4, nullptr, "Disable"}, FunctionInfo{5, nullptr, "CtrlIn"}, FunctionInfo{6, nullptr, "CtrlOut"}, FunctionInfo{7, nullptr, "GetCtrlInCompletionEvent"}, FunctionInfo{8, nullptr, "GetCtrlInUrbReport"}, FunctionInfo{9, nullptr, "GetCtrlOutCompletionEvent"}, FunctionInfo{10, nullptr, "GetCtrlOutUrbReport"}, FunctionInfo{11, nullptr, "CtrlStall"}, FunctionInfo{12, nullptr, "AppendConfigurationData"} }; // clang-format on RegisterHandlers(functions); } }; class IDsRootSession final : public ServiceFramework { public: explicit IDsRootSession(Core::System& system_) : ServiceFramework{system_, "usb:ds"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "OpenDsService"} }; // clang-format on RegisterHandlers(functions); } }; class IClientEpSession final : public ServiceFramework { public: explicit IClientEpSession(Core::System& system_) : ServiceFramework{system_, "IClientEpSession"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "ReOpen"}, FunctionInfo{1, nullptr, "Close"}, FunctionInfo{2, nullptr, "GetCompletionEvent"}, FunctionInfo{3, nullptr, "PopulateRing"}, FunctionInfo{4, nullptr, "PostBufferAsync"}, FunctionInfo{5, nullptr, "GetXferReport"}, FunctionInfo{6, nullptr, "PostBufferMultiAsync"}, FunctionInfo{7, nullptr, "CreateSmmuSpace"}, FunctionInfo{8, nullptr, "ShareReportRing"} }; // clang-format on RegisterHandlers(functions); } }; class IClientIfSession final : public ServiceFramework { public: explicit IClientIfSession(Core::System& system_) : ServiceFramework{system_, "IClientIfSession"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "GetStateChangeEvent"}, FunctionInfo{1, nullptr, "SetInterface"}, FunctionInfo{2, nullptr, "GetInterface"}, FunctionInfo{3, nullptr, "GetAlternateInterface"}, FunctionInfo{4, nullptr, "GetCurrentFrame"}, FunctionInfo{5, nullptr, "CtrlXferAsync"}, FunctionInfo{6, nullptr, "GetCtrlXferCompletionEvent"}, FunctionInfo{7, nullptr, "GetCtrlXferReport"}, FunctionInfo{8, nullptr, "ResetDevice"}, FunctionInfo{9, nullptr, "OpenUsbEp"} }; // clang-format on RegisterHandlers(functions); } }; class IClientRootSession final : public ServiceFramework { public: explicit IClientRootSession(Core::System& system_) : ServiceFramework{system_, "usb:hs"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "BindClientProcess"}, FunctionInfo{1, nullptr, "QueryAllInterfaces"}, FunctionInfo{2, nullptr, "QueryAvailableInterfaces"}, FunctionInfo{3, nullptr, "QueryAcquiredInterfaces"}, FunctionInfo{4, nullptr, "CreateInterfaceAvailableEvent"}, FunctionInfo{5, nullptr, "DestroyInterfaceAvailableEvent"}, FunctionInfo{6, nullptr, "GetInterfaceStateChangeEvent"}, FunctionInfo{7, nullptr, "AcquireUsbIf"}, FunctionInfo{8, nullptr, "SetTestMode"} }; // clang-format on RegisterHandlers(functions); } }; class IPdSession final : public ServiceFramework { public: explicit IPdSession(Core::System& system_) : ServiceFramework{system_, "IPdSession"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "BindNoticeEvent"}, FunctionInfo{1, nullptr, "UnbindNoticeEvent"}, FunctionInfo{2, nullptr, "GetStatus"}, FunctionInfo{3, nullptr, "GetNotice"}, FunctionInfo{4, nullptr, "EnablePowerRequestNotice"}, FunctionInfo{5, nullptr, "DisablePowerRequestNotice"}, FunctionInfo{6, nullptr, "ReplyPowerRequest"} }; // clang-format on RegisterHandlers(functions); } }; class IPdManager final : public ServiceFramework { public: explicit IPdManager(Core::System& system_) : ServiceFramework{system_, "usb:pd"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, &IPdManager::OpenSession, "OpenSession"} }; // clang-format on RegisterHandlers(functions); } private: void OpenSession(HLERequestContext& ctx) { LOG_DEBUG(Service_USB, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); rb.PushIpcInterface(ctx, system); } }; class IPdCradleSession final : public ServiceFramework { public: explicit IPdCradleSession(Core::System& system_) : ServiceFramework{system_, "IPdCradleSession"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "SetCradleVdo"}, FunctionInfo{1, nullptr, "GetCradleVdo"}, FunctionInfo{2, nullptr, "ResetCradleUsbHub"}, FunctionInfo{3, nullptr, "GetHostPdcFirmwareType"}, FunctionInfo{4, nullptr, "GetHostPdcFirmwareRevision"}, FunctionInfo{5, nullptr, "GetHostPdcManufactureId"}, FunctionInfo{6, nullptr, "GetHostPdcDeviceId"}, FunctionInfo{7, nullptr, "EnableCradleRecovery"}, FunctionInfo{8, nullptr, "DisableCradleRecovery"} }; // clang-format on RegisterHandlers(functions); } }; class IPdCradleManager final : public ServiceFramework { public: explicit IPdCradleManager(Core::System& system_) : ServiceFramework{system_, "usb:pd:c"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, &IPdCradleManager::OpenCradleSession, "OpenCradleSession"} }; // clang-format on RegisterHandlers(functions); } private: void OpenCradleSession(HLERequestContext& ctx) { LOG_DEBUG(Service_USB, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); rb.PushIpcInterface(ctx, system); } }; class IPmMainService final : public ServiceFramework { public: explicit IPmMainService(Core::System& system_) : ServiceFramework{system_, "usb:pm"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "GetPowerEvent"}, FunctionInfo{1, nullptr, "GetPowerState"}, FunctionInfo{2, nullptr, "GetDataEvent"}, FunctionInfo{3, nullptr, "GetDataRole"}, FunctionInfo{4, nullptr, "SetDiagData"}, FunctionInfo{5, nullptr, "GetDiagData"} }; // clang-format on RegisterHandlers(functions); } }; class IPdManufactureManager final : public ServiceFramework { public: explicit IPdManufactureManager(Core::System& system_) : ServiceFramework{system_, "usb:pd:m"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "OpenManufactureSession"} }; // clang-format on RegisterHandlers(functions); } }; class IQdbManager final : public ServiceFramework { public: explicit IQdbManager(Core::System& system_) : ServiceFramework{system_, "usb:qdb"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "ImportQuirkDevices"}, FunctionInfo{1, nullptr, "HasQuirk"} }; // clang-format on RegisterHandlers(functions); } }; class IPmObserverService final : public ServiceFramework { public: explicit IPmObserverService(Core::System& system_) : ServiceFramework{system_, "usb:obsv"} { // clang-format off static const FunctionInfo functions[] = { FunctionInfo{0, nullptr, "GetTopologyChangeEvent"}, FunctionInfo{1, nullptr, "GetFlattenedTopology"} }; // clang-format on RegisterHandlers(functions); } }; void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); server_manager->RegisterNamedService("usb:ds", std::make_shared(system)); server_manager->RegisterNamedService("usb:hs", std::make_shared(system)); server_manager->RegisterNamedService("usb:pd", std::make_shared(system), 6); server_manager->RegisterNamedService("usb:pd:c", std::make_shared(system), 4); server_manager->RegisterNamedService("usb:pd:m", std::make_shared(system)); server_manager->RegisterNamedService("usb:pm", std::make_shared(system), 5); // +7.0.0 if (FirmwareManager::GetFirmwareVersion(system).first.major >= 7) { server_manager->RegisterNamedService("usb:qdb", std::make_shared(system)); } // +8.0.0 if (FirmwareManager::GetFirmwareVersion(system).first.major >= 8) { server_manager->RegisterNamedService("usb:obsv", std::make_shared(system), 2); } ServerManager::RunServer(std::move(server_manager)); } } // namespace Service::USB