IOS HLE: Deduplicate request code in USB_HID
This commit is contained in:
parent
0e979ec75f
commit
6bf0b487d1
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue