IOS/NCD: Implement Lock/Unlock more accurately
NCD returns an error if it receives a request to lock the driver when it is already locked. Emulating this may seem pointless, but it turns out PPC-side code expects NCD to return an error and will immediately fail and stop initialising wireless stuff if NCD succeeds.
This commit is contained in:
parent
3f68aceaca
commit
4fea832f49
|
@ -20,6 +20,12 @@ NetNCDManage::NetNCDManage(Kernel& ios, const std::string& device_name) : Device
|
||||||
config.ReadConfig(ios.GetFS().get());
|
config.ReadConfig(ios.GetFS().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetNCDManage::DoState(PointerWrap& p)
|
||||||
|
{
|
||||||
|
Device::DoState(p);
|
||||||
|
p.Do(m_ipc_fd);
|
||||||
|
}
|
||||||
|
|
||||||
IPCCommandResult NetNCDManage::IOCtlV(const IOCtlVRequest& request)
|
IPCCommandResult NetNCDManage::IOCtlV(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
s32 return_value = IPC_SUCCESS;
|
s32 return_value = IPC_SUCCESS;
|
||||||
|
@ -29,11 +35,51 @@ IPCCommandResult NetNCDManage::IOCtlV(const IOCtlVRequest& request)
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
{
|
{
|
||||||
case IOCTLV_NCD_LOCKWIRELESSDRIVER:
|
case IOCTLV_NCD_LOCKWIRELESSDRIVER:
|
||||||
|
if (!request.HasNumberOfValidVectors(0, 1))
|
||||||
|
return GetDefaultReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
if (request.io_vectors[0].size < 2 * sizeof(u32))
|
||||||
|
return GetDefaultReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
if (m_ipc_fd != 0)
|
||||||
|
{
|
||||||
|
// It is an error to lock the driver again when it is already locked.
|
||||||
|
common_result = IPC_EINVAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// NCD writes the internal address of the request's file descriptor.
|
||||||
|
// We will just write the value of the file descriptor.
|
||||||
|
// The value will be positive so this will work fine.
|
||||||
|
m_ipc_fd = request.fd;
|
||||||
|
Memory::Write_U32(request.fd, request.io_vectors[0].address + 4);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTLV_NCD_UNLOCKWIRELESSDRIVER:
|
case IOCTLV_NCD_UNLOCKWIRELESSDRIVER:
|
||||||
// Memory::Read_U32(request.in_vectors.at(0).address);
|
{
|
||||||
|
if (!request.HasNumberOfValidVectors(1, 1))
|
||||||
|
return GetDefaultReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
if (request.in_vectors[0].size < sizeof(u32))
|
||||||
|
return GetDefaultReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
if (request.io_vectors[0].size < sizeof(u32))
|
||||||
|
return GetDefaultReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
const u32 request_handle = Memory::Read_U32(request.in_vectors[0].address);
|
||||||
|
if (m_ipc_fd == request_handle)
|
||||||
|
{
|
||||||
|
m_ipc_fd = 0;
|
||||||
|
common_result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
common_result = -3;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case IOCTLV_NCD_GETCONFIG:
|
case IOCTLV_NCD_GETCONFIG:
|
||||||
INFO_LOG_FMT(IOS_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETCONFIG");
|
INFO_LOG_FMT(IOS_NET, "NET_NCD_MANAGE: IOCTLV_NCD_GETCONFIG");
|
||||||
|
|
|
@ -20,6 +20,8 @@ public:
|
||||||
|
|
||||||
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
IPCCommandResult IOCtlV(const IOCtlVRequest& request) override;
|
||||||
|
|
||||||
|
void DoState(PointerWrap& p) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -34,5 +36,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
Net::WiiNetConfig config;
|
Net::WiiNetConfig config;
|
||||||
|
u32 m_ipc_fd = 0;
|
||||||
};
|
};
|
||||||
} // namespace IOS::HLE::Device
|
} // namespace IOS::HLE::Device
|
||||||
|
|
|
@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
||||||
static std::thread g_save_thread;
|
static std::thread g_save_thread;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
constexpr u32 STATE_VERSION = 126; // Last changed in PR 9348
|
constexpr u32 STATE_VERSION = 127; // Last changed in PR 9300 (temp)
|
||||||
|
|
||||||
// Maps savestate versions to Dolphin versions.
|
// Maps savestate versions to Dolphin versions.
|
||||||
// Versions after 42 don't need to be added to this list,
|
// Versions after 42 don't need to be added to this list,
|
||||||
|
|
Loading…
Reference in New Issue