Files
dolphin/Source/Core/Core/IOS/Device.h
Léo Lam ef5a855b8e Update log types names from IPC_HLE to IOS
For consistency with the other changes.

WII_IPC_DVD was changed to IOS_DI, as this describes what the log type
is used for in a more specific way.
2017-01-18 21:43:37 +01:00

180 lines
5.8 KiB
C++

// Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <cstddef>
#include <string>
#include <vector>
#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
#include "Core/IOS/IPC.h"
namespace IOS
{
namespace HLE
{
enum IOSReturnCode : s32
{
IPC_SUCCESS = 0, // Success
IPC_EACCES = -1, // Permission denied
IPC_EEXIST = -2, // File exists
IPC_EINVAL = -4, // Invalid argument or fd
IPC_ENOENT = -6, // File not found
IPC_EQUEUEFULL = -8, // Queue full
IPC_EIO = -12, // ECC error
IPC_ENOMEM = -22, // Alloc failed during request
FS_EINVAL = -101, // Invalid path
FS_EACCESS = -102, // Permission denied
FS_ECORRUPT = -103, // Corrupted NAND
FS_EEXIST = -105, // File exists
FS_ENOENT = -106, // No such file or directory
FS_ENFILE = -107, // Too many fds open
FS_EFBIG = -108, // Max block count reached?
FS_EFDEXHAUSTED = -109, // Too many fds open
FS_ENAMELEN = -110, // Pathname is too long
FS_EFDOPEN = -111, // FD is already open
FS_EIO = -114, // ECC error
FS_ENOTEMPTY = -115, // Directory not empty
FS_EDIRDEPTH = -116, // Max directory depth exceeded
FS_EBUSY = -118, // Resource busy
IPC_EESEXHAUSTED = -1016, // Max of 2 ES handles exceeded
};
struct IOSRequest
{
u32 address = 0;
IPCCommandType command = IPC_CMD_OPEN;
u32 fd = 0;
explicit IOSRequest(u32 address);
virtual ~IOSRequest() = default;
};
enum IOSOpenMode : s32
{
IOS_OPEN_READ = 1,
IOS_OPEN_WRITE = 2,
IOS_OPEN_RW = (IOS_OPEN_READ | IOS_OPEN_WRITE)
};
struct IOSOpenRequest final : IOSRequest
{
std::string path;
IOSOpenMode flags = IOS_OPEN_READ;
explicit IOSOpenRequest(u32 address);
};
struct IOSReadWriteRequest final : IOSRequest
{
u32 buffer = 0;
u32 size = 0;
explicit IOSReadWriteRequest(u32 address);
};
struct IOSSeekRequest final : IOSRequest
{
enum SeekMode
{
IOS_SEEK_SET = 0,
IOS_SEEK_CUR = 1,
IOS_SEEK_END = 2,
};
u32 offset = 0;
SeekMode mode = IOS_SEEK_SET;
explicit IOSSeekRequest(u32 address);
};
struct IOSIOCtlRequest final : IOSRequest
{
u32 request = 0;
u32 buffer_in = 0;
u32 buffer_in_size = 0;
// Contrary to the name, the output buffer can also be used for input.
u32 buffer_out = 0;
u32 buffer_out_size = 0;
explicit IOSIOCtlRequest(u32 address);
void Log(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::IOS,
LogTypes::LOG_LEVELS level = LogTypes::LINFO) const;
void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::IOS,
LogTypes::LOG_LEVELS level = LogTypes::LINFO) const;
void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::IOS,
LogTypes::LOG_LEVELS level = LogTypes::LERROR) const;
};
struct IOSIOCtlVRequest final : IOSRequest
{
struct IOVector
{
u32 address = 0;
u32 size = 0;
};
u32 request = 0;
// In vectors are *mostly* used for input buffers. Sometimes they are also used as
// output buffers (notably in the network code).
// IO vectors are *mostly* used for output buffers. However, as indicated in the name,
// they're also used as input buffers.
// So both of them are technically IO vectors. But we're keeping them separated because
// merging them into a single std::vector would make using the first out vector more complicated.
std::vector<IOVector> in_vectors;
std::vector<IOVector> io_vectors;
explicit IOSIOCtlVRequest(u32 address);
bool HasInputVectorWithAddress(u32 vector_address) const;
void Dump(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::IOS,
LogTypes::LOG_LEVELS level = LogTypes::LINFO) const;
void DumpUnknown(const std::string& description, LogTypes::LOG_TYPE type = LogTypes::IOS,
LogTypes::LOG_LEVELS level = LogTypes::LERROR) const;
};
namespace Device
{
class Device
{
public:
enum class DeviceType : u32
{
Static, // Devices which appear in s_device_map.
FileIO, // FileIO devices which are created dynamically.
};
Device(u32 device_id, const std::string& device_name, DeviceType type = DeviceType::Static);
virtual ~Device() = default;
// Release any resources which might interfere with savestating.
virtual void PrepareForState(PointerWrap::Mode mode) {}
virtual void DoState(PointerWrap& p);
void DoStateShared(PointerWrap& p);
const std::string& GetDeviceName() const { return m_name; }
u32 GetDeviceID() const { return m_device_id; }
// Replies to Open and Close requests are sent by the IPC request handler (HandleCommand),
// not by the devices themselves.
virtual IOSReturnCode Open(const IOSOpenRequest& request);
virtual void Close();
virtual IPCCommandResult Seek(const IOSSeekRequest& seek) { return Unsupported(seek); }
virtual IPCCommandResult Read(const IOSReadWriteRequest& read) { return Unsupported(read); }
virtual IPCCommandResult Write(const IOSReadWriteRequest& write) { return Unsupported(write); }
virtual IPCCommandResult IOCtl(const IOSIOCtlRequest& ioctl) { return Unsupported(ioctl); }
virtual IPCCommandResult IOCtlV(const IOSIOCtlVRequest& ioctlv) { return Unsupported(ioctlv); }
virtual void Update() {}
virtual DeviceType GetDeviceType() const { return m_device_type; }
virtual bool IsOpened() const { return m_is_active; }
static IPCCommandResult GetDefaultReply(s32 return_value);
static IPCCommandResult GetNoReply();
protected:
std::string m_name;
// STATE_TO_SAVE
u32 m_device_id;
DeviceType m_device_type;
bool m_is_active = false;
private:
IPCCommandResult Unsupported(const IOSRequest& request);
};
} // namespace Device
} // namespace HLE
} // namespace IOS