IOS HLE: Deduplicate request code in USB_HID

This commit is contained in:
Léo Lam 2017-01-15 11:48:52 +01:00
parent 0e979ec75f
commit 6bf0b487d1
2 changed files with 51 additions and 88 deletions

View File

@ -37,13 +37,10 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid)
std::lock_guard<std::mutex> 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<std::mutex> 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 */

View File

@ -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);