From 6bf0b487d1a66b14a1110deed6c4adf2deae87a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 15 Jan 2017 11:48:52 +0100 Subject: [PATCH] IOS HLE: Deduplicate request code in USB_HID --- .../Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 133 +++++++----------- .../Core/IPC_HLE/WII_IPC_HLE_Device_hid.h | 6 +- 2 files changed, 51 insertions(+), 88 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 829c5ff873..04d5002dbe 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -37,13 +37,10 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) std::lock_guard lk(hid->m_device_list_reply_mutex); if (hid->deviceCommandAddress != 0) { - hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18), - Memory::Read_U32(hid->deviceCommandAddress + 0x1C)); - - // Return value - Memory::Write_U32(0, hid->deviceCommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(hid->deviceCommandAddress, 0, - CoreTiming::FromThread::NON_CPU); + IOSIOCtlRequest request{hid->deviceCommandAddress}; + hid->FillOutDevices(request); + request.SetReturnValue(IPC_SUCCESS); + WII_IPC_HLE_Interface::EnqueueReply(request, 0, CoreTiming::FromThread::NON_CPU); hid->deviceCommandAddress = 0; } } @@ -56,16 +53,16 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) void CWII_IPC_HLE_Device_hid::handleUsbUpdates(struct libusb_transfer* transfer) { - int ret = IPC_EINVAL; + s32 ret = IPC_EINVAL; u32 replyAddress = (u32)(size_t)transfer->user_data; if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { ret = transfer->length; } - // Return value - Memory::Write_U32(ret, replyAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(replyAddress, 0, CoreTiming::FromThread::NON_CPU); + IOSIOCtlRequest request{replyAddress}; + request.SetReturnValue(ret); + WII_IPC_HLE_Interface::EnqueueReply(request, 0, CoreTiming::FromThread::NON_CPU); } CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) @@ -105,53 +102,37 @@ CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() libusb_exit(nullptr); } -IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(const IOSIOCtlRequest& request) { if (Core::g_want_determinism) { - Memory::Write_U32(-1, _CommandAddress + 0x4); + request.SetReturnValue(-1); return GetDefaultReply(); } - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = 0; - switch (Parameter) + s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_HID_GET_ATTACHED: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); - deviceCommandAddress = _CommandAddress; + deviceCommandAddress = request.address; return GetNoReply(); } case IOCTL_HID_OPEN: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Open) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, - BufferInSize, BufferOut, BufferOutSize); - // hid version, apparently - ReturnValue = 0x40001; + return_value = 0x40001; break; } case IOCTL_HID_SET_SUSPEND: { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(Set Suspend) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); // not actually implemented in IOS - ReturnValue = 0; + return_value = IPC_SUCCESS; break; } case IOCTL_HID_CANCEL_INTERRUPT: { - DEBUG_LOG(WII_IPC_HID, - "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, - BufferInSize, BufferOut, BufferOutSize); - ReturnValue = 0; + return_value = IPC_SUCCESS; break; } case IOCTL_HID_CONTROL: @@ -161,15 +142,15 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) -4 Can't find device specified */ - u32 dev_num = Memory::Read_U32(BufferIn + 0x10); - u8 bmRequestType = Memory::Read_U8(BufferIn + 0x14); - u8 bRequest = Memory::Read_U8(BufferIn + 0x15); - u16 wValue = Memory::Read_U16(BufferIn + 0x16); - u16 wIndex = Memory::Read_U16(BufferIn + 0x18); - u16 wLength = Memory::Read_U16(BufferIn + 0x1A); - u32 data = Memory::Read_U32(BufferIn + 0x1C); + u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10); + u8 bmRequestType = Memory::Read_U8(request.buffer_in + 0x14); + u8 bRequest = Memory::Read_U8(request.buffer_in + 0x15); + u16 wValue = Memory::Read_U16(request.buffer_in + 0x16); + u16 wIndex = Memory::Read_U16(request.buffer_in + 0x18); + u16 wLength = Memory::Read_U16(request.buffer_in + 0x1A); + u32 data = Memory::Read_U32(request.buffer_in + 0x1C); - ReturnValue = IPC_EINVAL; + return_value = IPC_EINVAL; libusb_device_handle* dev_handle = GetDeviceByDevNum(dev_num); @@ -185,12 +166,14 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength); Memory::CopyFromEmu(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); libusb_fill_control_transfer(transfer, dev_handle, buffer, handleUsbUpdates, - (void*)(size_t)_CommandAddress, /* no timeout */ 0); + (void*)(size_t)request.address, /* no timeout */ 0); libusb_submit_transfer(transfer); - // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: + // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), + // request.buffer_out: // (%08x, %i)", - // bmRequestType, bRequest, BufferIn, BufferInSize, BufferOut, BufferOutSize); + // bmRequestType, bRequest, BufferIn, request.buffer_in_size, request.buffer_out, + // request.buffer_out_size); // It's the async way! return GetNoReply(); @@ -198,13 +181,13 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) case IOCTL_HID_INTERRUPT_OUT: case IOCTL_HID_INTERRUPT_IN: { - u32 dev_num = Memory::Read_U32(BufferIn + 0x10); - u32 endpoint = Memory::Read_U32(BufferIn + 0x14); - u32 length = Memory::Read_U32(BufferIn + 0x18); + u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10); + u32 endpoint = Memory::Read_U32(request.buffer_in + 0x14); + u32 length = Memory::Read_U32(request.buffer_in + 0x18); - u32 data = Memory::Read_U32(BufferIn + 0x1C); + u32 data = Memory::Read_U32(request.buffer_in + 0x1C); - ReturnValue = IPC_EINVAL; + return_value = IPC_EINVAL; libusb_device_handle* dev_handle = GetDeviceByDevNum(dev_num); @@ -217,14 +200,9 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) struct libusb_transfer* transfer = libusb_alloc_transfer(0); transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER; libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, Memory::GetPointer(data), length, - handleUsbUpdates, (void*)(size_t)_CommandAddress, 0); + handleUsbUpdates, (void*)(size_t)request.address, 0); libusb_submit_transfer(transfer); - // DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) (BufferIn: (%08x, %i), BufferOut: - // (%08x, %i)", - // Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, - // BufferIn, BufferInSize, BufferOut, BufferOutSize); - // It's the async way! return GetNoReply(); } @@ -233,27 +211,22 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) std::lock_guard lk(m_device_list_reply_mutex); if (deviceCommandAddress != 0) { - Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18)); - - // Return value - Memory::Write_U32(-1, deviceCommandAddress + 4); - WII_IPC_HLE_Interface::EnqueueReply(deviceCommandAddress); + IOSIOCtlRequest pending_request{deviceCommandAddress}; + Memory::Write_U32(0xFFFFFFFF, pending_request.buffer_out); + pending_request.SetReturnValue(-1); + WII_IPC_HLE_Interface::EnqueueReply(pending_request); deviceCommandAddress = 0; } INFO_LOG(WII_IPC_HID, "HID::IOCtl(Shutdown) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - BufferIn, BufferInSize, BufferOut, BufferOutSize); + request.buffer_in, request.buffer_in_size, request.buffer_out, + request.buffer_out_size); break; } default: - { - INFO_LOG(WII_IPC_HID, "HID::IOCtl(0x%x) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - break; - } + request.Log(GetDeviceName(), LogTypes::WII_IPC_HID); } - Memory::Write_U32(ReturnValue, _CommandAddress + 4); - + request.SetReturnValue(return_value); return GetDefaultReply(); } @@ -283,21 +256,11 @@ bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle* dev) return true; } -IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) +IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtlV(const IOSIOCtlVRequest& request) { Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); - u32 ReturnValue = 0; - SIOCtlVBuffer CommandBuffer(_CommandAddress); - - INFO_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); - INFO_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); - INFO_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - INFO_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - INFO_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - INFO_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - INFO_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); - - Memory::Write_U32(ReturnValue, _CommandAddress + 4); + request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HID); + request.SetReturnValue(IPC_SUCCESS); return GetDefaultReply(); } @@ -340,10 +303,10 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor* des dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); } -void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +void CWII_IPC_HLE_Device_hid::FillOutDevices(const IOSIOCtlRequest& request) { static u16 check = 1; - int OffsetBuffer = BufferOut; + int OffsetBuffer = request.buffer_out; int OffsetStart = 0; // int OffsetDevice = 0; int d, c, ic, i, e; /* config, interface container, interface, endpoint */ diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h index 8a8d3ddb04..f88a42f4d0 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -38,8 +38,8 @@ public: virtual ~CWII_IPC_HLE_Device_hid(); - IPCCommandResult IOCtlV(u32 _CommandAddress) override; - IPCCommandResult IOCtl(u32 _CommandAddress) override; + IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override; + IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override; private: enum @@ -115,7 +115,7 @@ private: }; u32 deviceCommandAddress; - void FillOutDevices(u32 BufferOut, u32 BufferOutSize); + void FillOutDevices(const IOSIOCtlRequest& request); int GetAvailableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check); bool ClaimDevice(libusb_device_handle* dev);