mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-12 06:39:14 +01:00
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);
|
std::lock_guard<std::mutex> lk(hid->m_device_list_reply_mutex);
|
||||||
if (hid->deviceCommandAddress != 0)
|
if (hid->deviceCommandAddress != 0)
|
||||||
{
|
{
|
||||||
hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18),
|
IOSIOCtlRequest request{hid->deviceCommandAddress};
|
||||||
Memory::Read_U32(hid->deviceCommandAddress + 0x1C));
|
hid->FillOutDevices(request);
|
||||||
|
request.SetReturnValue(IPC_SUCCESS);
|
||||||
// Return value
|
WII_IPC_HLE_Interface::EnqueueReply(request, 0, CoreTiming::FromThread::NON_CPU);
|
||||||
Memory::Write_U32(0, hid->deviceCommandAddress + 4);
|
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(hid->deviceCommandAddress, 0,
|
|
||||||
CoreTiming::FromThread::NON_CPU);
|
|
||||||
hid->deviceCommandAddress = 0;
|
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)
|
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;
|
u32 replyAddress = (u32)(size_t)transfer->user_data;
|
||||||
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
|
||||||
{
|
{
|
||||||
ret = transfer->length;
|
ret = transfer->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return value
|
IOSIOCtlRequest request{replyAddress};
|
||||||
Memory::Write_U32(ret, replyAddress + 4);
|
request.SetReturnValue(ret);
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(replyAddress, 0, CoreTiming::FromThread::NON_CPU);
|
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)
|
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);
|
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)
|
if (Core::g_want_determinism)
|
||||||
{
|
{
|
||||||
Memory::Write_U32(-1, _CommandAddress + 0x4);
|
request.SetReturnValue(-1);
|
||||||
return GetDefaultReply();
|
return GetDefaultReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
s32 return_value = IPC_SUCCESS;
|
||||||
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
switch (request.request)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
case IOCTL_HID_GET_ATTACHED:
|
case IOCTL_HID_GET_ATTACHED:
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
deviceCommandAddress = request.address;
|
||||||
BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
|
||||||
deviceCommandAddress = _CommandAddress;
|
|
||||||
return GetNoReply();
|
return GetNoReply();
|
||||||
}
|
}
|
||||||
case IOCTL_HID_OPEN:
|
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
|
// hid version, apparently
|
||||||
ReturnValue = 0x40001;
|
return_value = 0x40001;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_HID_SET_SUSPEND:
|
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
|
// not actually implemented in IOS
|
||||||
ReturnValue = 0;
|
return_value = IPC_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_HID_CANCEL_INTERRUPT:
|
case IOCTL_HID_CANCEL_INTERRUPT:
|
||||||
{
|
{
|
||||||
DEBUG_LOG(WII_IPC_HID,
|
return_value = IPC_SUCCESS;
|
||||||
"HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn,
|
|
||||||
BufferInSize, BufferOut, BufferOutSize);
|
|
||||||
ReturnValue = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_HID_CONTROL:
|
case IOCTL_HID_CONTROL:
|
||||||
@ -161,15 +142,15 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
|
|||||||
-4 Can't find device specified
|
-4 Can't find device specified
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u32 dev_num = Memory::Read_U32(BufferIn + 0x10);
|
u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10);
|
||||||
u8 bmRequestType = Memory::Read_U8(BufferIn + 0x14);
|
u8 bmRequestType = Memory::Read_U8(request.buffer_in + 0x14);
|
||||||
u8 bRequest = Memory::Read_U8(BufferIn + 0x15);
|
u8 bRequest = Memory::Read_U8(request.buffer_in + 0x15);
|
||||||
u16 wValue = Memory::Read_U16(BufferIn + 0x16);
|
u16 wValue = Memory::Read_U16(request.buffer_in + 0x16);
|
||||||
u16 wIndex = Memory::Read_U16(BufferIn + 0x18);
|
u16 wIndex = Memory::Read_U16(request.buffer_in + 0x18);
|
||||||
u16 wLength = Memory::Read_U16(BufferIn + 0x1A);
|
u16 wLength = Memory::Read_U16(request.buffer_in + 0x1A);
|
||||||
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);
|
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);
|
libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength);
|
||||||
Memory::CopyFromEmu(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);
|
Memory::CopyFromEmu(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);
|
||||||
libusb_fill_control_transfer(transfer, dev_handle, buffer, handleUsbUpdates,
|
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);
|
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)",
|
// (%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!
|
// It's the async way!
|
||||||
return GetNoReply();
|
return GetNoReply();
|
||||||
@ -198,13 +181,13 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
|
|||||||
case IOCTL_HID_INTERRUPT_OUT:
|
case IOCTL_HID_INTERRUPT_OUT:
|
||||||
case IOCTL_HID_INTERRUPT_IN:
|
case IOCTL_HID_INTERRUPT_IN:
|
||||||
{
|
{
|
||||||
u32 dev_num = Memory::Read_U32(BufferIn + 0x10);
|
u32 dev_num = Memory::Read_U32(request.buffer_in + 0x10);
|
||||||
u32 endpoint = Memory::Read_U32(BufferIn + 0x14);
|
u32 endpoint = Memory::Read_U32(request.buffer_in + 0x14);
|
||||||
u32 length = Memory::Read_U32(BufferIn + 0x18);
|
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);
|
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);
|
struct libusb_transfer* transfer = libusb_alloc_transfer(0);
|
||||||
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, Memory::GetPointer(data), length,
|
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);
|
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!
|
// It's the async way!
|
||||||
return GetNoReply();
|
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);
|
std::lock_guard<std::mutex> lk(m_device_list_reply_mutex);
|
||||||
if (deviceCommandAddress != 0)
|
if (deviceCommandAddress != 0)
|
||||||
{
|
{
|
||||||
Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18));
|
IOSIOCtlRequest pending_request{deviceCommandAddress};
|
||||||
|
Memory::Write_U32(0xFFFFFFFF, pending_request.buffer_out);
|
||||||
// Return value
|
pending_request.SetReturnValue(-1);
|
||||||
Memory::Write_U32(-1, deviceCommandAddress + 4);
|
WII_IPC_HLE_Interface::EnqueueReply(pending_request);
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(deviceCommandAddress);
|
|
||||||
deviceCommandAddress = 0;
|
deviceCommandAddress = 0;
|
||||||
}
|
}
|
||||||
INFO_LOG(WII_IPC_HID, "HID::IOCtl(Shutdown) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
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;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
request.Log(GetDeviceName(), LogTypes::WII_IPC_HID);
|
||||||
INFO_LOG(WII_IPC_HID, "HID::IOCtl(0x%x) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
|
||||||
Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 4);
|
request.SetReturnValue(return_value);
|
||||||
|
|
||||||
return GetDefaultReply();
|
return GetDefaultReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,21 +256,11 @@ bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle* dev)
|
|||||||
return true;
|
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);
|
Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING);
|
||||||
u32 ReturnValue = 0;
|
request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_HID);
|
||||||
SIOCtlVBuffer CommandBuffer(_CommandAddress);
|
request.SetReturnValue(IPC_SUCCESS);
|
||||||
|
|
||||||
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);
|
|
||||||
return GetDefaultReply();
|
return GetDefaultReply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,10 +303,10 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor* des
|
|||||||
dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize);
|
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;
|
static u16 check = 1;
|
||||||
int OffsetBuffer = BufferOut;
|
int OffsetBuffer = request.buffer_out;
|
||||||
int OffsetStart = 0;
|
int OffsetStart = 0;
|
||||||
// int OffsetDevice = 0;
|
// int OffsetDevice = 0;
|
||||||
int d, c, ic, i, e; /* config, interface container, interface, endpoint */
|
int d, c, ic, i, e; /* config, interface container, interface, endpoint */
|
||||||
|
@ -38,8 +38,8 @@ public:
|
|||||||
|
|
||||||
virtual ~CWII_IPC_HLE_Device_hid();
|
virtual ~CWII_IPC_HLE_Device_hid();
|
||||||
|
|
||||||
IPCCommandResult IOCtlV(u32 _CommandAddress) override;
|
IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override;
|
||||||
IPCCommandResult IOCtl(u32 _CommandAddress) override;
|
IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
@ -115,7 +115,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
u32 deviceCommandAddress;
|
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);
|
int GetAvailableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check);
|
||||||
bool ClaimDevice(libusb_device_handle* dev);
|
bool ClaimDevice(libusb_device_handle* dev);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user