IOS: Change devices to always return IPCCommandResult

This commit changes devices to always return IPCCommandResult rather
than just a return code for Open() and Close() in order to be able
to better emulate reply timing.

In hindsight, I should have considered we would want to emulate
timing when I cleaned up the device interface, but alas.
This rectifies that mistake.
This commit is contained in:
Léo Lam 2018-02-27 20:48:57 +01:00
parent 9282be1058
commit 80b1bf13c2
30 changed files with 68 additions and 79 deletions

View File

@ -161,16 +161,16 @@ void Device::DoStateShared(PointerWrap& p)
p.Do(m_is_active);
}
ReturnCode Device::Open(const OpenRequest& request)
IPCCommandResult Device::Open(const OpenRequest& request)
{
m_is_active = true;
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
ReturnCode Device::Close(u32 fd)
IPCCommandResult Device::Close(u32 fd)
{
m_is_active = false;
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult Device::Unsupported(const Request& request)

View File

@ -188,8 +188,8 @@ public:
const std::string& GetDeviceName() const { return m_name; }
// Replies to Open and Close requests are sent by the IPC request handler (HandleCommand),
// not by the devices themselves.
virtual ReturnCode Open(const OpenRequest& request);
virtual ReturnCode Close(u32 fd);
virtual IPCCommandResult Open(const OpenRequest& request);
virtual IPCCommandResult Close(u32 fd);
virtual IPCCommandResult Seek(const SeekRequest& seek) { return Unsupported(seek); }
virtual IPCCommandResult Read(const ReadWriteRequest& read) { return Unsupported(read); }
virtual IPCCommandResult Write(const ReadWriteRequest& write) { return Unsupported(write); }

View File

@ -12,11 +12,11 @@ namespace HLE
{
namespace Device
{
ReturnCode Stub::Open(const OpenRequest& request)
IPCCommandResult Stub::Open(const OpenRequest& request)
{
WARN_LOG(IOS, "%s faking Open()", m_name.c_str());
m_is_active = true;
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult Stub::IOCtl(const IOCtlRequest& request)

View File

@ -21,7 +21,7 @@ class Stub final : public Device
public:
// Inherit the constructor from the Device class, since we don't need to do anything special.
using Device::Device;
ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
};

View File

@ -372,11 +372,11 @@ ES::ContextArray::iterator ES::FindInactiveContext()
[](const auto& context) { return !context.active; });
}
ReturnCode ES::Open(const OpenRequest& request)
IPCCommandResult ES::Open(const OpenRequest& request)
{
auto context = FindInactiveContext();
if (context == m_contexts.end())
return ES_FD_EXHAUSTED;
return GetDefaultReply(ES_FD_EXHAUSTED);
context->active = true;
context->uid = request.uid;
@ -385,18 +385,18 @@ ReturnCode ES::Open(const OpenRequest& request)
return Device::Open(request);
}
ReturnCode ES::Close(u32 fd)
IPCCommandResult ES::Close(u32 fd)
{
auto context = FindActiveContext(fd);
if (context == m_contexts.end())
return ES_EINVAL;
return GetDefaultReply(ES_EINVAL);
context->active = false;
context->ipc_fd = -1;
INFO_LOG(IOS_ES, "ES: Close");
m_is_active = false;
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
IPCCommandResult ES::IOCtlV(const IOCtlVRequest& request)

View File

@ -46,8 +46,8 @@ public:
void DoState(PointerWrap& p) override;
ReturnCode Open(const OpenRequest& request) override;
ReturnCode Close(u32 fd) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult Close(u32 fd) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
struct TitleImportExportContext

View File

@ -138,12 +138,6 @@ void FS::DoState(PointerWrap& p)
}
}
ReturnCode FS::Open(const OpenRequest& request)
{
m_is_active = true;
return IPC_SUCCESS;
}
// Get total filesize of contents of a directory (recursive)
// Only used for ES_GetUsage atm, could be useful elsewhere?
static u64 ComputeTotalFileSize(const File::FSTEntry& parentEntry)

View File

@ -36,7 +36,6 @@ public:
void DoState(PointerWrap& p) override;
ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;

View File

@ -79,7 +79,7 @@ FileIO::FileIO(Kernel& ios, const std::string& device_name)
{
}
ReturnCode FileIO::Close(u32 fd)
IPCCommandResult FileIO::Close(u32 fd)
{
INFO_LOG(IOS_FILEIO, "FileIO: Close %s", m_name.c_str());
m_Mode = 0;
@ -89,10 +89,10 @@ ReturnCode FileIO::Close(u32 fd)
m_file.reset();
m_is_active = false;
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
ReturnCode FileIO::Open(const OpenRequest& request)
IPCCommandResult FileIO::Open(const OpenRequest& request)
{
m_Mode = request.flags;
@ -106,14 +106,14 @@ ReturnCode FileIO::Open(const OpenRequest& request)
{
WARN_LOG(IOS_FILEIO, "FileIO: Open (%s) failed - File doesn't exist %s", Modes[m_Mode],
m_filepath.c_str());
return FS_ENOENT;
return GetDefaultReply(FS_ENOENT);
}
INFO_LOG(IOS_FILEIO, "FileIO: Open %s (%s == %08X)", m_name.c_str(), Modes[m_Mode], m_Mode);
OpenFile();
m_is_active = true;
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
// This isn't theadsafe, but it's only called from the CPU thread.

View File

@ -32,8 +32,8 @@ class FileIO : public Device
public:
FileIO(Kernel& ios, const std::string& device_name);
ReturnCode Close(u32 fd) override;
ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult Close(u32 fd) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult Seek(const SeekRequest& request) override;
IPCCommandResult Read(const ReadWriteRequest& request) override;
IPCCommandResult Write(const ReadWriteRequest& request) override;

View File

@ -468,14 +468,14 @@ std::shared_ptr<Device::Device> EmulationKernel::GetDeviceByName(const std::stri
}
// Returns the FD for the newly opened device (on success) or an error code.
s32 Kernel::OpenDevice(OpenRequest& request)
IPCCommandResult Kernel::OpenDevice(OpenRequest& request)
{
const s32 new_fd = GetFreeDeviceID();
INFO_LOG(IOS, "Opening %s (mode %d, fd %d)", request.path.c_str(), request.flags, new_fd);
if (new_fd < 0 || new_fd >= IPC_MAX_FDS)
{
ERROR_LOG(IOS, "Couldn't get a free fd, too many open files");
return FS_EFDEXHAUSTED;
return Device::Device::GetDefaultReply(FS_EFDEXHAUSTED);
}
request.fd = new_fd;
@ -497,14 +497,13 @@ s32 Kernel::OpenDevice(OpenRequest& request)
if (!device)
{
ERROR_LOG(IOS, "Unknown device: %s", request.path.c_str());
return IPC_ENOENT;
return Device::Device::GetDefaultReply(IPC_ENOENT);
}
const ReturnCode code = device->Open(request);
if (code < IPC_SUCCESS)
return code;
m_fdmap[new_fd] = device;
return new_fd;
const IPCCommandResult result = device->Open(request);
if (result.return_value >= IPC_SUCCESS)
m_fdmap[new_fd] = device;
return result;
}
IPCCommandResult Kernel::HandleIPCCommand(const Request& request)
@ -512,8 +511,7 @@ IPCCommandResult Kernel::HandleIPCCommand(const Request& request)
if (request.command == IPC_CMD_OPEN)
{
OpenRequest open_request{request.address};
const s32 new_fd = OpenDevice(open_request);
return Device::Device::GetDefaultReply(new_fd);
return OpenDevice(open_request);
}
const auto device = (request.fd < IPC_MAX_FDS) ? m_fdmap[request.fd] : nullptr;
@ -527,7 +525,7 @@ IPCCommandResult Kernel::HandleIPCCommand(const Request& request)
{
case IPC_CMD_CLOSE:
m_fdmap[request.fd].reset();
ret = Device::Device::GetDefaultReply(device->Close(request.fd));
ret = device->Close(request.fd);
break;
case IPC_CMD_READ:
ret = device->Read(ReadWriteRequest{request.address});

View File

@ -126,7 +126,7 @@ protected:
void AddStaticDevices();
std::shared_ptr<Device::Device> GetDeviceByName(const std::string& device_name);
s32 GetFreeDeviceID();
s32 OpenDevice(OpenRequest& request);
IPCCommandResult OpenDevice(OpenRequest& request);
bool m_is_responsible_for_nand_root = false;
u64 m_title_id = 0;

View File

@ -80,17 +80,17 @@ void SDIOSlot0::OpenInternal()
}
}
ReturnCode SDIOSlot0::Open(const OpenRequest& request)
IPCCommandResult SDIOSlot0::Open(const OpenRequest& request)
{
OpenInternal();
m_registers.fill(0);
m_is_active = true;
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
ReturnCode SDIOSlot0::Close(u32 fd)
IPCCommandResult SDIOSlot0::Close(u32 fd)
{
m_card.Close();
m_block_length = 0;

View File

@ -30,8 +30,8 @@ public:
void DoState(PointerWrap& p) override;
ReturnCode Open(const OpenRequest& request) override;
ReturnCode Close(u32 fd) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult Close(u32 fd) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;

View File

@ -66,7 +66,7 @@ IPCCommandResult STMImmediate::IOCtl(const IOCtlRequest& request)
return GetDefaultReply(return_value);
}
ReturnCode STMEventHook::Close(u32 fd)
IPCCommandResult STMEventHook::Close(u32 fd)
{
s_event_hook_request.reset();
return Device::Close(fd);

View File

@ -55,7 +55,7 @@ class STMEventHook final : public Device
{
public:
using Device::Device;
ReturnCode Close(u32 fd) override;
IPCCommandResult Close(u32 fd) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
void DoState(PointerWrap& p) override;

View File

@ -133,7 +133,7 @@ bool BluetoothEmu::RemoteDisconnect(u16 _connectionHandle)
return SendEventDisconnect(_connectionHandle, 0x13);
}
ReturnCode BluetoothEmu::Close(u32 fd)
IPCCommandResult BluetoothEmu::Close(u32 fd)
{
// Clean up state
m_ScanEnable = 0;

View File

@ -49,7 +49,7 @@ public:
virtual ~BluetoothEmu();
ReturnCode Close(u32 fd) override;
IPCCommandResult Close(u32 fd) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
void Update() override;

View File

@ -86,10 +86,10 @@ BluetoothReal::~BluetoothReal()
SaveLinkKeys();
}
ReturnCode BluetoothReal::Open(const OpenRequest& request)
IPCCommandResult BluetoothReal::Open(const OpenRequest& request)
{
if (!m_libusb_context)
return IPC_EACCES;
return GetDefaultReply(IPC_EACCES);
libusb_device** list;
const ssize_t cnt = libusb_get_device_list(m_libusb_context, &list);
@ -97,7 +97,7 @@ ReturnCode BluetoothReal::Open(const OpenRequest& request)
{
ERROR_LOG(IOS_WIIMOTE, "Couldn't get device list: %s",
libusb_error_name(static_cast<int>(cnt)));
return IPC_ENOENT;
return GetDefaultReply(IPC_ENOENT);
}
for (ssize_t i = 0; i < cnt; ++i)
@ -142,16 +142,15 @@ ReturnCode BluetoothReal::Open(const OpenRequest& request)
PanicAlertT("Bluetooth passthrough mode is enabled, "
"but no usable Bluetooth USB device was found. Aborting.");
Core::QueueHostJob(Core::Stop);
return IPC_ENOENT;
return GetDefaultReply(IPC_ENOENT);
}
StartTransferThread();
m_is_active = true;
return IPC_SUCCESS;
return Device::Open(request);
}
ReturnCode BluetoothReal::Close(u32 fd)
IPCCommandResult BluetoothReal::Close(u32 fd)
{
if (m_handle)
{

View File

@ -51,8 +51,8 @@ public:
BluetoothReal(Kernel& ios, const std::string& device_name);
~BluetoothReal() override;
ReturnCode Open(const OpenRequest& request) override;
ReturnCode Close(u32 fd) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult Close(u32 fd) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
void DoState(PointerWrap& p) override;

View File

@ -14,11 +14,11 @@ namespace HLE
{
namespace Device
{
ReturnCode BluetoothStub::Open(const OpenRequest& request)
IPCCommandResult BluetoothStub::Open(const OpenRequest& request)
{
PanicAlertT("Bluetooth passthrough mode is enabled, but Dolphin was built without libusb."
" Passthrough mode cannot be used.");
return IPC_ENOENT;
return GetDefaultReply(IPC_ENOENT);
}
void BluetoothStub::DoState(PointerWrap& p)

View File

@ -22,7 +22,7 @@ class BluetoothStub final : public BluetoothBase
{
public:
using BluetoothBase::BluetoothBase;
ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult Open(const OpenRequest& request) override;
void DoState(PointerWrap& p) override;
};
} // namespace Device

View File

@ -47,7 +47,7 @@ USBHost::~USBHost()
#endif
}
ReturnCode USBHost::Open(const OpenRequest& request)
IPCCommandResult USBHost::Open(const OpenRequest& request)
{
// Force a device scan to complete, because some games (including Your Shape) only care
// about the initial device list (in the first GETDEVICECHANGE reply).
@ -55,7 +55,7 @@ ReturnCode USBHost::Open(const OpenRequest& request)
{
}
StartThreads();
return IPC_SUCCESS;
return GetDefaultReply(IPC_SUCCESS);
}
void USBHost::UpdateWantDeterminism(const bool new_want_determinism)

View File

@ -36,7 +36,7 @@ public:
USBHost(Kernel& ios, const std::string& device_name);
virtual ~USBHost();
ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult Open(const OpenRequest& request) override;
void UpdateWantDeterminism(bool new_want_determinism) override;
void DoState(PointerWrap& p) override;

View File

@ -35,10 +35,10 @@ OH0::~OH0()
StopThreads();
}
ReturnCode OH0::Open(const OpenRequest& request)
IPCCommandResult OH0::Open(const OpenRequest& request)
{
if (HasFeature(m_ios.GetVersion(), Feature::NewUSB))
return IPC_EACCES;
return GetDefaultReply(IPC_EACCES);
return USBHost::Open(request);
}

View File

@ -41,7 +41,7 @@ public:
OH0(Kernel& ios, const std::string& device_name);
~OH0() override;
ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;

View File

@ -55,19 +55,19 @@ void OH0Device::DoState(PointerWrap& p)
p.Do(m_device_id);
}
ReturnCode OH0Device::Open(const OpenRequest& request)
IPCCommandResult OH0Device::Open(const OpenRequest& request)
{
if (m_vid == 0 && m_pid == 0)
return IPC_ENOENT;
return GetDefaultReply(IPC_ENOENT);
m_oh0 = std::static_pointer_cast<OH0>(GetIOS()->GetDeviceByName("/dev/usb/oh0"));
ReturnCode return_code;
std::tie(return_code, m_device_id) = m_oh0->DeviceOpen(m_vid, m_pid);
return return_code;
return GetDefaultReply(return_code);
}
ReturnCode OH0Device::Close(u32 fd)
IPCCommandResult OH0Device::Close(u32 fd)
{
m_oh0->DeviceClose(m_device_id);
return Device::Close(fd);

View File

@ -24,8 +24,8 @@ class OH0Device final : public Device
public:
OH0Device(Kernel& ios, const std::string& device_name);
ReturnCode Open(const OpenRequest& request) override;
ReturnCode Close(u32 fd) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult Close(u32 fd) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
void DoState(PointerWrap& p) override;

View File

@ -45,7 +45,7 @@ USB_KBD::USB_KBD(Kernel& ios, const std::string& device_name) : Device(ios, devi
{
}
ReturnCode USB_KBD::Open(const OpenRequest& request)
IPCCommandResult USB_KBD::Open(const OpenRequest& request)
{
INFO_LOG(IOS, "USB_KBD: Open");
IniFile ini;
@ -61,8 +61,7 @@ ReturnCode USB_KBD::Open(const OpenRequest& request)
m_OldModifiers = 0x00;
// m_MessageQueue.push(SMessageData(MSG_KBD_CONNECT, 0, nullptr));
m_is_active = true;
return IPC_SUCCESS;
return Device::Open(request);
}
IPCCommandResult USB_KBD::Write(const ReadWriteRequest& request)

View File

@ -22,7 +22,7 @@ class USB_KBD : public Device
public:
USB_KBD(Kernel& ios, const std::string& device_name);
ReturnCode Open(const OpenRequest& request) override;
IPCCommandResult Open(const OpenRequest& request) override;
IPCCommandResult Write(const ReadWriteRequest& request) override;
IPCCommandResult IOCtl(const IOCtlRequest& request) override;
void Update() override;