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());
|
||||
}
|
||||
|
||||
void NetNCDManage::DoState(PointerWrap& p)
|
||||
{
|
||||
Device::DoState(p);
|
||||
p.Do(m_ipc_fd);
|
||||
}
|
||||
|
||||
IPCCommandResult NetNCDManage::IOCtlV(const IOCtlVRequest& request)
|
||||
{
|
||||
s32 return_value = IPC_SUCCESS;
|
||||
|
@ -29,11 +35,51 @@ IPCCommandResult NetNCDManage::IOCtlV(const IOCtlVRequest& request)
|
|||
switch (request.request)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
case 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;
|
||||
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
|
@ -34,5 +36,6 @@ private:
|
|||
};
|
||||
|
||||
Net::WiiNetConfig config;
|
||||
u32 m_ipc_fd = 0;
|
||||
};
|
||||
} // namespace IOS::HLE::Device
|
||||
|
|
|
@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||
static std::thread g_save_thread;
|
||||
|
||||
// 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.
|
||||
// Versions after 42 don't need to be added to this list,
|
||||
|
|
Loading…
Reference in New Issue