Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys_fs: Fixed up sys_fs_fcntl(0xc0000007, 0xc0000015, and 0xc000001c) according to real hardware testing #14368

Merged
merged 2 commits into from Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
69 changes: 29 additions & 40 deletions rpcs3/Emu/Cell/lv2/sys_fs.cpp
Expand Up @@ -2064,27 +2064,18 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
{
const auto arg = vm::static_ptr_cast<lv2_file_c0000007>(_arg);

std::string_view device{arg->device.get_ptr(), arg->device_size};

// Trim trailing '\0'
if (const auto trim_pos = device.find('\0'); trim_pos != umax)
device.remove_suffix(device.size() - trim_pos);

if (device != "CELL_FS_IOS:ATA_HDD"sv)
{
arg->out_code = CELL_ENOTSUP;
return {CELL_ENOTSUP, device};
}

const auto model = g_cfg.sys.hdd_model.to_string();
const auto serial = g_cfg.sys.hdd_serial.to_string();
arg->out_code = CELL_OK;

strcpy_trunc(std::span(arg->model.get_ptr(), arg->model_size), model);
strcpy_trunc(std::span(arg->serial.get_ptr(), arg->serial_size), serial);
if (const auto size = arg->model_size; size > 0)
strcpy_trunc(std::span(arg->model.get_ptr(), size),
fmt::format("%-*s", size - 1, g_cfg.sys.hdd_model.to_string())); // Example: "TOSHIBA MK3265GSX H "

arg->out_code = CELL_OK;
if (const auto size = arg->serial_size; size > 0)
strcpy_trunc(std::span(arg->serial.get_ptr(), size),
fmt::format("%*s", size - 1, g_cfg.sys.hdd_serial.to_string())); // Example: " 0A1B2C3D4"
else
return CELL_EFAULT; // CELL_EFAULT is returned only when arg->serial_size == 0

sys_fs.trace("sys_fs_fcntl(0xc0000007): found device \"%s\" (model=\"%s\", serial=\"%s\")", device, model, serial);
return CELL_OK;
}

Expand Down Expand Up @@ -2190,39 +2181,37 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
break;
}

std::string_view vpath{arg->name.get_ptr(), arg->name_size};
std::string_view vpath{arg->path.get_ptr(), arg->path_size};

if (vpath.size() == 0)
return CELL_ENOMEM;

// Trim trailing '\0'
if (const auto trim_pos = vpath.find('\0'); trim_pos != umax)
vpath.remove_suffix(vpath.size() - trim_pos);

if (vfs::get(vpath).empty())
{
arg->out_code = CELL_ENOTMOUNTED;
return {CELL_ENOTMOUNTED, vpath};
}

const auto& mp = g_fxo->get<lv2_fs_mount_info_map>().lookup(vpath, true);
arg->out_code = CELL_ENOTMOUNTED; // arg->out_code is set to CELL_ENOTMOUNTED on real hardware when the device doesn't exist or when the device isn't USB

if (mp != &g_mp_sys_dev_usb)
if (!vfs::get(vpath).empty())
{
arg->out_code = CELL_ENOTSUP;
return {CELL_ENOTSUP, vpath};
}
if (const auto& mp = g_fxo->get<lv2_fs_mount_info_map>().lookup(vpath, true); mp == &g_mp_sys_dev_usb)
{
const cfg::device_info device = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, fmt::format("%s%s", mp->root, mp.device.substr(mp->device.size())));
const auto usb_ids = device.get_usb_ids();
std::tie(arg->vendorID, arg->productID) = usb_ids;

const cfg::device_info device = g_cfg_vfs.get_device(g_cfg_vfs.dev_usb, fmt::format("%s%s", mp->root, mp.device.substr(mp->device.size())));
std::tie(arg->vendorID, arg->productID) = device.get_usb_ids();
if (with_serial)
{
const auto arg_c000001c = vm::static_ptr_cast<lv2_file_c000001c>(_arg);
const std::u16string serial = utf8_to_utf16(device.serial); // Serial needs to be encoded to utf-16 BE
std::copy_n(serial.begin(), std::min(serial.size(), sizeof(arg_c000001c->serial) / sizeof(u16)), arg_c000001c->serial);
}

if (with_serial)
{
const auto arg_c000001c = vm::static_ptr_cast<lv2_file_c000001c>(_arg);
const std::u16string serial = utf8_to_utf16(device.serial); // Serial needs to be encoded to utf-16 BE
std::copy_n(serial.begin(), std::min(serial.size(), sizeof(arg_c000001c->serial) / sizeof(u16)), arg_c000001c->serial);
arg->out_code = CELL_OK;
sys_fs.trace("sys_fs_fcntl(0x%08x): found device \"%s\" (vid=0x%04x, pid=0x%04x, serial=\"%s\")", op, mp.device, usb_ids.first, usb_ids.second, device.serial);
}
}

arg->out_code = CELL_OK;

sys_fs.trace("sys_fs_fcntl(0x%08x): found device \"%s\" (vid=0x%04x, pid=0x%04x, serial=\"%s\")", op, mp.device, arg->vendorID, arg->productID, device.serial);
return CELL_OK;
}

Expand Down
12 changes: 6 additions & 6 deletions rpcs3/Emu/Cell/lv2/sys_fs.h
Expand Up @@ -529,8 +529,8 @@ CHECK_SIZE(lv2_file_c0000006, 0x20);
// sys_fs_fcntl: cellFsArcadeHddSerialNumber
struct lv2_file_c0000007 : lv2_file_op
{
be_t<u32> out_code;
vm::bcptr<char> device;
be_t<u32> out_code; // set to 0
vm::bcptr<char> device; // CELL_FS_IOS:ATA_HDD
be_t<u32> device_size; // 0x14
vm::bptr<char> model;
be_t<u32> model_size; // 0x29
Expand Down Expand Up @@ -562,8 +562,8 @@ struct lv2_file_c0000015 : lv2_file_op
be_t<u32> size; // 0x20
be_t<u32> _x4; // 0x10
be_t<u32> _x8; // 0x18 - offset of out_code
be_t<u32> name_size;
vm::bcptr<char> name;
be_t<u32> path_size;
vm::bcptr<char> path;
be_t<u32> _x14; //
be_t<u16> vendorID;
be_t<u16> productID;
Expand All @@ -590,8 +590,8 @@ struct lv2_file_c000001c : lv2_file_op
be_t<u32> size; // 0x60
be_t<u32> _x4; // 0x10
be_t<u32> _x8; // 0x18 - offset of out_code
be_t<u32> name_size;
vm::bcptr<char> name;
be_t<u32> path_size;
vm::bcptr<char> path;
be_t<u32> unk1;
be_t<u16> vendorID;
be_t<u16> productID;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Io/usio.cpp
Expand Up @@ -334,7 +334,7 @@ void usb_device_usio::translate_input_tekken()
}
break;
case usio_btn::down:
if ( pressed)
if (pressed)
{
digital_input |= 0x100000ULL << shift;
if (player == 0)
Expand Down