From 9bf67d4bb1db516a83f8e5c53bf6efee32131579 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Wed, 28 Mar 2012 21:52:17 +1300 Subject: Implemented /dev/usb/hid as libusb, but this will not work on mac. Code started for using hidapi instead. --- Source/Core/Common/Src/Log.h | 1 + Source/Core/Common/Src/LogManager.cpp | 1 + Source/Core/Core/Core.vcxproj | 14 +- Source/Core/Core/Core.vcxproj.filters | 9 + Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 3 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 416 +++++++++++++++++++++ .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 126 +++++++ Source/VSProps/Dolphin.Win32.props | 4 +- Source/VSProps/Dolphin.x64.props | 4 +- 9 files changed, 567 insertions(+), 11 deletions(-) create mode 100644 Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp create mode 100644 Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h (limited to 'Source') diff --git a/Source/Core/Common/Src/Log.h b/Source/Core/Common/Src/Log.h index 3be97d54d4..4892886693 100644 --- a/Source/Core/Common/Src/Log.h +++ b/Source/Core/Common/Src/Log.h @@ -64,6 +64,7 @@ enum LOG_TYPE { WII_IPC_DVD, WII_IPC_ES, WII_IPC_FILEIO, + WII_IPC_HID, WII_IPC_HLE, WII_IPC_NET, WII_IPC_SD, diff --git a/Source/Core/Common/Src/LogManager.cpp b/Source/Core/Common/Src/LogManager.cpp index a79c413cf8..df55f018c6 100644 --- a/Source/Core/Common/Src/LogManager.cpp +++ b/Source/Core/Common/Src/LogManager.cpp @@ -71,6 +71,7 @@ LogManager::LogManager() m_Log[LogTypes::WIIMOTE] = new LogContainer("Wiimote", "Wiimote"); m_Log[LogTypes::WII_IOB] = new LogContainer("WII_IOB", "WII IO Bridge"); m_Log[LogTypes::WII_IPC] = new LogContainer("WII_IPC", "WII IPC"); + m_Log[LogTypes::WII_IPC_HID] = new LogContainer("WII_IPC_HID", "WII IPC HID"); m_Log[LogTypes::WII_IPC_HLE] = new LogContainer("WII_IPC_HLE", "WII IPC HLE"); m_Log[LogTypes::WII_IPC_DVD] = new LogContainer("WII_IPC_DVD", "WII IPC DVD"); m_Log[LogTypes::WII_IPC_ES] = new LogContainer("WII_IPC_ES", "WII IPC ES"); diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index e03d40e43a..25ede66e60 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -115,7 +115,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -127,7 +127,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -139,7 +139,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories) true @@ -153,7 +153,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -167,7 +167,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories) true @@ -181,7 +181,7 @@ - .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories) + .\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include true @@ -326,6 +326,7 @@ + @@ -526,6 +527,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 020cf76ad0..475861b64a 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -556,6 +556,9 @@ HW %28Flipper/Hollywood%29\GCMemcard + + IPC HLE %28IOS/Starlet%29\USB + @@ -1033,6 +1036,9 @@ HW %28Flipper/Hollywood%29\GCMemcard + + IPC HLE %28IOS/Starlet%29\USB + @@ -1173,5 +1179,8 @@ {3e9e6e83-c1bf-45f9-aeff-231f98f60d29} + + {321a9af5-9b3d-4620-888c-fe9d02e9559e} + \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index cd4f679db9..40c31c9e2b 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -50,6 +50,7 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC #include "WII_IPC_HLE_Device_usb.h" #include "WII_IPC_HLE_Device_usb_kbd.h" #include "WII_IPC_HLE_Device_sdio_slot0.h" +#include "WII_IPC_HLE_Device_hid.h" #include "FileUtil.h" // For Copy #include "../ConfigManager.h" @@ -113,7 +114,7 @@ void Init() g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++; - g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++; + g_DeviceMap[i] = new CWII_IPC_HLE_Device_hid(i, std::string("/dev/usb/hid")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++; g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp new file mode 100644 index 0000000000..0103a534c3 --- /dev/null +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -0,0 +1,416 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "../Core.h" +#include "../Debugger/Debugger_SymbolMap.h" +#include "../HW/WII_IPC.h" +#include "WII_IPC_HLE.h" +#include "WII_IPC_HLE_Device_hid.h" +#include "lusb0_usb.h" +#include "hidapi.h" + +CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) + : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) +{ + + usb_init(); /* initialize the library */ + +} + +CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() +{ + +} + +bool CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode) +{ + Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); + DEBUG_LOG(WII_IPC_HID, "HID::Open"); + Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); + return true; +} + +bool CWII_IPC_HLE_Device_hid::Close(u32 _CommandAddress, bool _bForce) +{ + DEBUG_LOG(WII_IPC_HID, "HID::Close"); + if (!_bForce) + Memory::Write_U32(0, _CommandAddress + 4); + return true; +} + +bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) +{ + static u32 replyAddress = 0; + static bool hasRun = false; + 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) + { + case IOCTL_HID_GET_ATTACHED: + { + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + BufferIn, BufferInSize, BufferOut, BufferOutSize); + if(!hasRun) + { + FillOutDevices(BufferOut, BufferOutSize); + hasRun = true; + } + else + { + replyAddress = _CommandAddress; + return false; + } + break; + } + case IOCTL_HID_OPEN: + { + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Open) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + BufferIn, BufferInSize, BufferOut, BufferOutSize); + + //hid version, apparently + ReturnValue = 0x40001; + break; + } + case IOCTL_HID_SET_SUSPEND: + { + DEBUG_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; + + if (replyAddress != 0){ + FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); + WII_IPC_HLE_Interface::EnqReply(replyAddress); + replyAddress = 0; + hasRun = false; + } + + 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); + + if (replyAddress != 0){ + FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); + WII_IPC_HLE_Interface::EnqReply(replyAddress); + replyAddress = 0; + hasRun = false; + } + + ReturnValue = 0; + break; + } + case IOCTL_HID_CONTROL: + { + /* + ERROR CODES: + -4 Cant find device specified + */ + u32 dev_num = Memory::Read_U32(BufferIn+0x10); + u8 requesttype = Memory::Read_U8(BufferIn+0x14); + u8 request = Memory::Read_U8(BufferIn+0x15); + u16 value = Memory::Read_U16(BufferIn+0x16); + u16 index = Memory::Read_U16(BufferIn+0x18); + u16 size = Memory::Read_U16(BufferIn+0x1A); + u32 data = Memory::Read_U32(BufferIn+0x1C); + + static int upto = 0; + int i; + usb_find_busses(); /* find all busses */ + usb_find_devices(); /* find all connected devices */ + + struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + + if (dev_handle == NULL) + { + ReturnValue = -4; + break; + } + + ReturnValue = usb_control_msg(dev_handle, requesttype, request, + value, index, (char*)Memory::GetPointer(data), size, + 0); + + if(ReturnValue>=0) + { + ReturnValue += sizeof(usb_ctrl_setup); + } + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", + requesttype, request, ReturnValue); + + usb_close(dev_handle); + + u8 test_out[0x20]; + Memory::ReadBigEData(test_out, BufferIn, BufferInSize); + char file[0x50]; + snprintf(file, 0x50, "ctrl_ctrlprotocol_%d.bin", upto); + FILE* test = fopen (file, "wb"); + for(i=0;i<0x20;i++) + fwrite(&test_out[i], 1, 1, test); + if (size > 0) + fwrite((char*)Memory::GetPointer(data), 1, size, test); + fclose(test); + upto++; + break; + } + case IOCTL_HID_INTERRUPT_IN: + { + + + u32 dev_num = Memory::Read_U32(BufferIn+0x10); + u32 end_point = Memory::Read_U32(BufferIn+0x14); + u32 length = Memory::Read_U32(BufferIn+0x18); + + u32 data = Memory::Read_U32(BufferIn+0x1C); + + struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + + if (dev_handle == NULL) + { + ReturnValue = -4; + break; + } + + usb_claim_interface(dev_handle,0); + ReturnValue = usb_interrupt_read(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 1000); + + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt In)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + + usb_close(dev_handle); + break; + } + case IOCTL_HID_INTERRUPT_OUT: + { + + + u32 dev_num = Memory::Read_U32(BufferIn+0x10); + u32 end_point = Memory::Read_U32(BufferIn+0x14); + u32 length = Memory::Read_U32(BufferIn+0x18); + + u32 data = Memory::Read_U32(BufferIn+0x1C); + + struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + + if (dev_handle == NULL) + { + ReturnValue = -4; + break; + } + + usb_claim_interface(dev_handle,0); + ReturnValue = usb_interrupt_write(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 0); + + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt Out) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + + usb_close(dev_handle); + break; + } + default: + { + DEBUG_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); + + return true; +} + +bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) +{ + + Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); + u32 ReturnValue = 0; + SIOCtlVBuffer CommandBuffer(_CommandAddress); + + switch (CommandBuffer.Parameter) + { + + default: + { + DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); + DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); + DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); + DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); + DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); + DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); + DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); + #if defined(_DEBUG) || defined(DEBUGFAST) + DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); + #endif + } + break; + } + + Memory::Write_U32(ReturnValue, _CommandAddress + 4); + return true; +} + + + +void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDDeviceDescriptor)); + dest->bcdUSB = Common::swap16(dest->bcdUSB); + dest->idVendor = Common::swap16(dest->idVendor); + dest->idProduct = Common::swap16(dest->idProduct); + dest->bcdDevice = Common::swap16(dest->bcdDevice); +} + +void CWII_IPC_HLE_Device_hid::ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDConfigDescriptor)); + dest->wTotalLength = Common::swap16(dest->wTotalLength); +} + +void CWII_IPC_HLE_Device_hid::ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDInterfaceDescriptor)); +} + +void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src) +{ + memcpy(dest,src,sizeof(WiiHIDEndpointDescriptor)); + dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); +} +/* +// hidapi version +void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +{ + // Enumerate and print the HID devices on the system + struct hid_device_info *devs, *cur_dev; + + devs = hid_enumerate(0x0, 0x0); + cur_dev = devs; + while (cur_dev) { + printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", + cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); + printf("\n"); + printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string); + printf(" Product: %ls\n", cur_dev->product_string); + printf("\n"); + cur_dev = cur_dev->next; + } + hid_free_enumeration(devs); +} +*/ + +// libusb version +void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +{ + usb_find_busses(); // find all busses + usb_find_devices(); // find all connected devices + struct usb_bus *bus; + struct usb_device *dev; + int OffsetBuffer = BufferOut; + int OffsetStart = 0; + int c,ic,i,e; // config, interface container, interface, endpoint + for (bus = usb_get_busses(); bus; bus = bus->next) + { + for (dev = bus->devices; dev; dev = dev->next) + { + struct usb_device_descriptor *device = &dev->descriptor; + DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d",device->idVendor, device->idProduct, dev->devnum); + + OffsetStart = OffsetBuffer; + OffsetBuffer += 4; // skip length for now, fill at end + + Memory::Write_U32(dev->devnum, OffsetBuffer); //write device num + OffsetBuffer += 4; + + WiiHIDDeviceDescriptor wii_device; + ConvertDeviceToWii(&wii_device, device); + Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); + OffsetBuffer += Align(wii_device.bLength, 4); + + for (c = 0; c < device->bNumConfigurations; c++) + { + struct usb_config_descriptor *config = &dev->config[c]; + + WiiHIDConfigDescriptor wii_config; + ConvertConfigToWii(&wii_config, config); + Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4)); + OffsetBuffer += Align(wii_config.bLength, 4); + + for (ic = 0; ic < config->bNumInterfaces; ic++) + { + struct usb_interface *interfaceContainer = &config->interface[ic]; + for (i = 0; i < interfaceContainer->num_altsetting; i++) + { + struct usb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; + + WiiHIDInterfaceDescriptor wii_interface; + ConvertInterfaceToWii(&wii_interface, interface); + Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4)); + OffsetBuffer += Align(wii_interface.bLength, 4); + + for (e = 0; e < interface->bNumEndpoints; e++) + { + struct usb_endpoint_descriptor *endpoint = &interface->endpoint[e]; + + WiiHIDEndpointDescriptor wii_endpoint; + ConvertEndpointToWii(&wii_endpoint, endpoint); + Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(wii_endpoint.bLength, 4)); + OffsetBuffer += Align(wii_endpoint.bLength, 4); + + } //endpoints + } // interfaces + } // interface containters + } // configs + + Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length + + } // devices + } // buses + + Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices + + +} + + + +int CWII_IPC_HLE_Device_hid::Align(int num, int alignment) +{ + return (num + (alignment-1)) & ~(alignment-1); +} + + +struct usb_dev_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) +{ + for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) + { + for (struct usb_device *dev = bus->devices; dev; dev = dev->next) + { + if(dev->devnum == devNum){ + return usb_open(dev); + } + } + } + return NULL; +} \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h new file mode 100644 index 0000000000..2bb7f47a59 --- /dev/null +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -0,0 +1,126 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#pragma once + +#include "WII_IPC_HLE.h" +#include "WII_IPC_HLE_Device.h" + +class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device +{ +public: + CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName); + + virtual ~CWII_IPC_HLE_Device_hid(); + + virtual bool Open(u32 _CommandAddress, u32 _Mode); + virtual bool Close(u32 _CommandAddress, bool _bForce); + + virtual bool IOCtlV(u32 _CommandAddress); + virtual bool IOCtl(u32 _CommandAddress); +private: + + + std::map deviceList; + + enum + { + IOCTL_HID_GET_ATTACHED = 0x00, + IOCTL_HID_SET_SUSPEND = 0x01, + IOCTL_HID_CONTROL = 0x02, + IOCTL_HID_INTERRUPT_IN = 0x03, + IOCTL_HID_INTERRUPT_OUT = 0x04, + IOCTL_HID_GET_US_STRING = 0x05, + IOCTL_HID_OPEN = 0x06, + IOCTL_HID_SHUTDOWN = 0x07, + IOCTL_HID_CANCEL_INTERRUPT = 0x08, + }; + + /* Device descriptor */ + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u16 idVendor; + u16 idProduct; + u16 bcdDevice; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; + u8 pad[2]; + } WiiHIDDeviceDescriptor; + + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u8 MaxPower; + u8 pad[3]; + } WiiHIDConfigDescriptor; + + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + u8 iInterface; + u8 pad[3]; + } WiiHIDInterfaceDescriptor; + + typedef struct + { + u8 bLength; + u8 bDescriptorType; + u8 bEndpointAddress; + u8 bmAttributes; + u16 wMaxPacketSize; + u8 bInterval; + u8 bRefresh; + u8 bSynchAddress; + u8 pad[1]; + } WiiHIDEndpointDescriptor; + + + void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize); + + void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src); + void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src); + void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src); + void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src); + + int Align(int num, int alignment); + + struct usb_dev_handle * GetDeviceByDevNum(u32 devNum); + + +}; diff --git a/Source/VSProps/Dolphin.Win32.props b/Source/VSProps/Dolphin.Win32.props index 5adc4159e0..a78f75c4ac 100644 --- a/Source/VSProps/Dolphin.Win32.props +++ b/Source/VSProps/Dolphin.Win32.props @@ -7,8 +7,8 @@ - ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies) + ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) + portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;hidapi.lib;%(AdditionalDependencies) diff --git a/Source/VSProps/Dolphin.x64.props b/Source/VSProps/Dolphin.x64.props index 557e6350e7..c9cc2eb7ff 100644 --- a/Source/VSProps/Dolphin.x64.props +++ b/Source/VSProps/Dolphin.x64.props @@ -8,8 +8,8 @@ - ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies) + ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) + portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;hidapi.lib;%(AdditionalDependencies) -- cgit v1.2.3 From db6e981728f65ab1df047a87a1c16f7fcdb82f94 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 3 Apr 2012 19:26:12 +1200 Subject: Added hidapi start. x64 doesn't work... not sure why. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 143 +++++++++++++++++---- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 5 +- 2 files changed, 121 insertions(+), 27 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 0103a534c3..2e1e3c1823 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -248,24 +248,16 @@ bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) u32 ReturnValue = 0; SIOCtlVBuffer CommandBuffer(_CommandAddress); - switch (CommandBuffer.Parameter) - { - - default: - { - DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); - DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); - DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); - #if defined(_DEBUG) || defined(DEBUGFAST) - DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); - #endif - } - break; - } + DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); + DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); + DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); + DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); + DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); + DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); + DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); + #if defined(_DEBUG) || defined(DEBUGFAST) + DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); + #endif Memory::Write_U32(ReturnValue, _CommandAddress + 4); return true; @@ -298,31 +290,130 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *des memcpy(dest,src,sizeof(WiiHIDEndpointDescriptor)); dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); } -/* + +u32 CWII_IPC_HLE_Device_hid::GetAvailableID(char* path) +{ + return 0; +} + // hidapi version -void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) +void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutSize) { // Enumerate and print the HID devices on the system struct hid_device_info *devs, *cur_dev; + int OffsetBuffer = BufferOut; + int OffsetStart = 0; + int c,ic,i,e; // config, interface container, interface, endpoint + devs = hid_enumerate(0x0, 0x0); cur_dev = devs; while (cur_dev) { - printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", + + OffsetStart = OffsetBuffer; + OffsetBuffer += 4; // skip length for now, fill at end + + Memory::Write_U32(GetAvailableID(cur_dev->path), OffsetBuffer); //write device num + OffsetBuffer += 4; + + WiiHIDDeviceDescriptor wii_device; + /* + u8 bDescriptorType; + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u16 idVendor; + u16 idProduct; + u16 bcdDevice; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; + u8 pad[2]; + + */ + + wii_device.bLength = Common::swap8(0x12); + wii_device.bcdUSB = Common::swap16(0x0002); + wii_device.bDeviceClass = Common::swap8(0); + wii_device.bDeviceSubClass = Common::swap8(0); + wii_device.bDeviceProtocol = Common::swap8(0); + wii_device.bMaxPacketSize0 = Common::swap8(0x20); + wii_device.idVendor = Common::swap16(cur_dev->vendor_id); + wii_device.idProduct = Common::swap16(cur_dev->product_id); + wii_device.bcdDevice = Common::swap16(0x100); + wii_device.iManufacturer = Common::swap8(0x1); + wii_device.iProduct = Common::swap8(0x2); + wii_device.iSerialNumber = Common::swap8(0); + wii_device.bNumConfigurations = Common::swap8(0x1); + + Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); + + OffsetBuffer += Align(wii_device.bLength, 4); + + + for (c = 0; c < Common::swap8(wii_device.bNumConfigurations); c++) + { + + WiiHIDConfigDescriptor wii_config; + wii_config.bLength = Common::swap8(0x9); + wii_config.bDescriptorType = Common::swap8(0x2); + wii_config.wTotalLength = Common::swap16(0x29); + wii_config.bNumInterfaces = Common::swap8(0x1); + wii_config.bConfigurationValue = Common::swap8(0x1); + wii_config.iConfiguration = Common::swap8(0); + wii_config.bmAttributes = Common::swap8(0x80); + wii_config.MaxPower = Common::swap8(0x96); + + Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4)); + OffsetBuffer += Align(wii_config.bLength, 4); + + for (ic = 0; ic < wii_config.bNumInterfaces; ic++) + { +/* struct usb_interface *interfaceContainer = &config->interface[ic]; + for (i = 0; i < interfaceContainer->num_altsetting; i++) + { + struct usb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; + + WiiHIDInterfaceDescriptor wii_interface; + ConvertInterfaceToWii(&wii_interface, interface); + Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4)); + OffsetBuffer += Align(wii_interface.bLength, 4); + + for (e = 0; e < interface->bNumEndpoints; e++) + { + struct usb_endpoint_descriptor *endpoint = &interface->endpoint[e]; + + WiiHIDEndpointDescriptor wii_endpoint; + ConvertEndpointToWii(&wii_endpoint, endpoint); + Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(wii_endpoint.bLength, 4)); + OffsetBuffer += Align(wii_endpoint.bLength, 4); + + } //endpoints + } // interfaces + */ + } // interface containters + } // configs + + + NOTICE_LOG(WII_IPC_HID, "Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); - printf("\n"); - printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string); - printf(" Product: %ls\n", cur_dev->product_string); - printf("\n"); + NOTICE_LOG(WII_IPC_HID, "\n"); + NOTICE_LOG(WII_IPC_HID, " Manufacturer: %ls\n", cur_dev->manufacturer_string); + NOTICE_LOG(WII_IPC_HID, " Product: %ls\n", cur_dev->product_string); + NOTICE_LOG(WII_IPC_HID, "\n"); cur_dev = cur_dev->next; } hid_free_enumeration(devs); } -*/ + // libusb version void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { + //FillOutDevicesHidApi(BufferOut, BufferOutSize); usb_find_busses(); // find all busses usb_find_devices(); // find all connected devices struct usb_bus *bus; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index 2bb7f47a59..ef3b8912f1 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -111,7 +111,10 @@ private: } WiiHIDEndpointDescriptor; - void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize); + u32 GetAvailableID(char* path); + + void FillOutDevices(u32 BufferOut, u32 BufferOutSize); + void FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutSize); void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src); void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src); -- cgit v1.2.3 From d188233b130ef777e4bfd261265c10306d0bc0ca Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 12 Nov 2012 19:12:10 +1300 Subject: Moving to libHID --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 102 +++++++++++---------- 1 file changed, 55 insertions(+), 47 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 2e1e3c1823..70edc1805b 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -127,6 +127,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ERROR CODES: -4 Cant find device specified */ + u32 dev_num = Memory::Read_U32(BufferIn+0x10); u8 requesttype = Memory::Read_U8(BufferIn+0x14); u8 request = Memory::Read_U8(BufferIn+0x15); @@ -135,10 +136,11 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u16 size = Memory::Read_U16(BufferIn+0x1A); u32 data = Memory::Read_U32(BufferIn+0x1C); + /* //libusb way static int upto = 0; int i; - usb_find_busses(); /* find all busses */ - usb_find_devices(); /* find all connected devices */ + usb_find_busses(); + usb_find_devices(); struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); @@ -172,6 +174,13 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) fwrite((char*)Memory::GetPointer(data), 1, size, test); fclose(test); upto++; + */ + + ReturnValue = size + sizeof(usb_ctrl_setup); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", + requesttype, request, ReturnValue); + + break; } case IOCTL_HID_INTERRUPT_IN: @@ -291,20 +300,22 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *des dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); } +static int x = 0; u32 CWII_IPC_HLE_Device_hid::GetAvailableID(char* path) { - return 0; + return x++; } // hidapi version void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutSize) { + x = 0; // Enumerate and print the HID devices on the system struct hid_device_info *devs, *cur_dev; int OffsetBuffer = BufferOut; int OffsetStart = 0; - int c,ic,i,e; // config, interface container, interface, endpoint + int c,i,e; // config, interface container, interface, endpoint devs = hid_enumerate(0x0, 0x0); cur_dev = devs; @@ -317,33 +328,17 @@ void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutS OffsetBuffer += 4; WiiHIDDeviceDescriptor wii_device; - /* - u8 bDescriptorType; - u16 bcdUSB; - u8 bDeviceClass; - u8 bDeviceSubClass; - u8 bDeviceProtocol; - u8 bMaxPacketSize0; - u16 idVendor; - u16 idProduct; - u16 bcdDevice; - u8 iManufacturer; - u8 iProduct; - u8 iSerialNumber; - u8 bNumConfigurations; - u8 pad[2]; - - */ wii_device.bLength = Common::swap8(0x12); - wii_device.bcdUSB = Common::swap16(0x0002); + wii_device.bDescriptorType = Common::swap8(0x1); + wii_device.bcdUSB = Common::swap16(0x0200); wii_device.bDeviceClass = Common::swap8(0); wii_device.bDeviceSubClass = Common::swap8(0); wii_device.bDeviceProtocol = Common::swap8(0); wii_device.bMaxPacketSize0 = Common::swap8(0x20); wii_device.idVendor = Common::swap16(cur_dev->vendor_id); wii_device.idProduct = Common::swap16(cur_dev->product_id); - wii_device.bcdDevice = Common::swap16(0x100); + wii_device.bcdDevice = Common::swap16(cur_dev->release_number); wii_device.iManufacturer = Common::swap8(0x1); wii_device.iProduct = Common::swap8(0x2); wii_device.iSerialNumber = Common::swap8(0); @@ -367,36 +362,44 @@ void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutS wii_config.bmAttributes = Common::swap8(0x80); wii_config.MaxPower = Common::swap8(0x96); - Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4)); - OffsetBuffer += Align(wii_config.bLength, 4); + Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(Common::swap8(wii_config.bLength), 4)); + OffsetBuffer += Align(Common::swap8(wii_config.bLength), 4); - for (ic = 0; ic < wii_config.bNumInterfaces; ic++) + for (i = 0; i < wii_config.bNumInterfaces; i++) { -/* struct usb_interface *interfaceContainer = &config->interface[ic]; - for (i = 0; i < interfaceContainer->num_altsetting; i++) - { - struct usb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; - WiiHIDInterfaceDescriptor wii_interface; - ConvertInterfaceToWii(&wii_interface, interface); - Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4)); - OffsetBuffer += Align(wii_interface.bLength, 4); - for (e = 0; e < interface->bNumEndpoints; e++) + wii_interface.bLength = Common::swap8(0x9); + wii_interface.bDescriptorType = Common::swap8(0x4); + wii_interface.bInterfaceNumber = Common::swap8(i); + wii_interface.bAlternateSetting = Common::swap8(0); + wii_interface.bNumEndpoints = Common::swap8(0x2); + wii_interface.bInterfaceClass = Common::swap8(0x3); + wii_interface.bInterfaceSubClass = Common::swap8(0); + wii_interface.bInterfaceProtocol = Common::swap8(0); + wii_interface.iInterface = Common::swap8(0); + + Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(Common::swap8(wii_interface.bLength), 4)); + OffsetBuffer += Align(Common::swap8(wii_interface.bLength), 4); + + for (e = 0; e < Common::swap8(wii_interface.bNumEndpoints); e++) { - struct usb_endpoint_descriptor *endpoint = &interface->endpoint[e]; - WiiHIDEndpointDescriptor wii_endpoint; - ConvertEndpointToWii(&wii_endpoint, endpoint); - Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(wii_endpoint.bLength, 4)); - OffsetBuffer += Align(wii_endpoint.bLength, 4); + wii_endpoint.bLength = Common::swap8(0x7); + wii_endpoint.bDescriptorType = Common::swap8(0x5); + wii_endpoint.bEndpointAddress = Common::swap8(e == 0 ? 0x1 : 0x81); + wii_endpoint.bmAttributes = Common::swap8(0x3); + wii_endpoint.wMaxPacketSize = Common::swap16(0x20); + wii_endpoint.bInterval = Common::swap8(0x1); + + Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(Common::swap8(wii_endpoint.bLength), 4)); + OffsetBuffer += Align(Common::swap8(wii_endpoint.bLength), 4); } //endpoints - } // interfaces - */ - } // interface containters + } // interfaces } // configs - + + Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length NOTICE_LOG(WII_IPC_HID, "Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); @@ -406,6 +409,11 @@ void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutS NOTICE_LOG(WII_IPC_HID, "\n"); cur_dev = cur_dev->next; } + Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices + + FILE* test = fopen ("mattsbin.bin", "wb"); + fwrite(Memory::GetPointer(BufferOut), BufferOutSize, 1, test); + fclose(test); hid_free_enumeration(devs); } @@ -413,8 +421,8 @@ void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutS // libusb version void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { - //FillOutDevicesHidApi(BufferOut, BufferOutSize); - usb_find_busses(); // find all busses + FillOutDevicesHidApi(BufferOut, BufferOutSize); + /*usb_find_busses(); // find all busses usb_find_devices(); // find all connected devices struct usb_bus *bus; struct usb_device *dev; @@ -480,7 +488,7 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) } // buses Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices - + */ } -- cgit v1.2.3 From 586813b1504669b434f47bb216379561fb3f0f16 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 13 Nov 2012 00:14:47 +1300 Subject: Basic HID works on windows! I had to customise HIDAPI. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 79 ++++++++++++++++++---- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 3 +- 2 files changed, 66 insertions(+), 16 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 70edc1805b..4d3c7ff8e8 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -23,17 +23,23 @@ #include "lusb0_usb.h" #include "hidapi.h" +static std::map loaded_devices; +static std::map loaded_devices_rev; +static std::map opened_devices; + + + CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) { - usb_init(); /* initialize the library */ - + //usb_init(); /* initialize the library */ + hid_init(); } CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() { - + hid_exit(); } bool CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode) @@ -175,7 +181,29 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) fclose(test); upto++; */ + + hid_device * dev_handle = GetDeviceByDevNumHidLib(dev_num); + if (dev_handle == NULL) + { + ReturnValue = -4; + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", + requesttype, request, ReturnValue); + break; + } + + // this is our write request + if(request == 0x09) + { + #define rw_buf_size 0x21 + unsigned char buf[rw_buf_size]; + memset(&buf[0], 0, rw_buf_size); + memcpy(&buf[1], (unsigned char*)Memory::GetPointer(data), size); + int success = hid_write_report(dev_handle, buf, size+1); + + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control) success = %d", success); + } + ReturnValue = size + sizeof(usb_ctrl_setup); DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", requesttype, request, ReturnValue); @@ -193,21 +221,29 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u32 data = Memory::Read_U32(BufferIn+0x1C); - struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + hid_device * dev_handle = GetDeviceByDevNumHidLib(dev_num); if (dev_handle == NULL) { ReturnValue = -4; + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt In)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } - usb_claim_interface(dev_handle,0); - ReturnValue = usb_interrupt_read(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 1000); + //ReturnValue = -5; + ReturnValue = hid_read(dev_handle, (unsigned char*)Memory::GetPointer(data), length); + //ReturnValue = usb_interrupt_read(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 1000); + + FILE* test = fopen ("readdata.bin", "wb"); + fwrite(Memory::GetPointer(data), ReturnValue, 1, test); + fclose(test); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt In)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - usb_close(dev_handle); + break; } case IOCTL_HID_INTERRUPT_OUT: @@ -220,21 +256,22 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u32 data = Memory::Read_U32(BufferIn+0x1C); - struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + hid_device * dev_handle = GetDeviceByDevNumHidLib(dev_num); if (dev_handle == NULL) { ReturnValue = -4; + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt Out) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } - usb_claim_interface(dev_handle,0); - ReturnValue = usb_interrupt_write(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 0); + ReturnValue = -5; + //ReturnValue = usb_interrupt_write(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 0); DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt Out) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - usb_close(dev_handle); break; } default: @@ -303,7 +340,12 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *des static int x = 0; u32 CWII_IPC_HLE_Device_hid::GetAvailableID(char* path) { - return x++; + std::string dev_path = path; + if(loaded_devices.find(dev_path) == loaded_devices.end()){ + loaded_devices_rev[x] = dev_path; + loaded_devices[dev_path] = x++; + } + return loaded_devices[dev_path]; } // hidapi version @@ -411,9 +453,6 @@ void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutS } Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices - FILE* test = fopen ("mattsbin.bin", "wb"); - fwrite(Memory::GetPointer(BufferOut), BufferOutSize, 1, test); - fclose(test); hid_free_enumeration(devs); } @@ -499,6 +538,16 @@ int CWII_IPC_HLE_Device_hid::Align(int num, int alignment) return (num + (alignment-1)) & ~(alignment-1); } +hid_device * CWII_IPC_HLE_Device_hid::GetDeviceByDevNumHidLib(u32 devNum) +{ + if (loaded_devices_rev.find(devNum) == loaded_devices_rev.end()) + return NULL; + if (opened_devices.find(devNum) != opened_devices.end()) + return opened_devices[devNum]; + + hid_device * phPortalHandle = opened_devices[devNum] = hid_open_path(loaded_devices_rev[devNum].c_str()); + return phPortalHandle; +} struct usb_dev_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index ef3b8912f1..2fc4ba9a22 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -19,6 +19,7 @@ #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device.h" +#include "hidapi.h" class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device { @@ -122,7 +123,7 @@ private: void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src); int Align(int num, int alignment); - + hid_device * GetDeviceByDevNumHidLib(u32 devNum); struct usb_dev_handle * GetDeviceByDevNum(u32 devNum); -- cgit v1.2.3 From d8b879a4ee844b693af2d7af85e2cd3d6d2712b3 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Thu, 15 Nov 2012 01:09:25 +1300 Subject: Movd back to libusb for full support on windows --- Source/Core/Common/Src/Log.h | 2 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 373 +++++++-------------- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 25 +- Source/VSProps/Dolphin.x64.props | 2 +- 4 files changed, 139 insertions(+), 263 deletions(-) (limited to 'Source') diff --git a/Source/Core/Common/Src/Log.h b/Source/Core/Common/Src/Log.h index 7383e56c92..9664387cf0 100644 --- a/Source/Core/Common/Src/Log.h +++ b/Source/Core/Common/Src/Log.h @@ -101,7 +101,7 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, #define MAX_LOGLEVEL DEBUG_LEVEL #else #ifndef MAX_LOGLEVEL -#define MAX_LOGLEVEL WARNING_LEVEL +#define MAX_LOGLEVEL DEBUG_LEVEL #endif // loglevel #endif // logging diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 4d3c7ff8e8..fb75386a4a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -21,31 +21,29 @@ #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device_hid.h" #include "lusb0_usb.h" -#include "hidapi.h" - -static std::map loaded_devices; -static std::map loaded_devices_rev; -static std::map opened_devices; - - +#include "errno.h" CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) { - //usb_init(); /* initialize the library */ - hid_init(); + usb_init(); /* initialize the library */ + } CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() { - hid_exit(); + for ( std::map::const_iterator iter = open_devices.begin(); iter != open_devices.end(); ++iter ) + { + usb_close(iter->second); + } + open_devices.clear(); } bool CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode) { - Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING); DEBUG_LOG(WII_IPC_HID, "HID::Open"); + m_Active = true; Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); return true; } @@ -53,11 +51,48 @@ bool CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode) bool CWII_IPC_HLE_Device_hid::Close(u32 _CommandAddress, bool _bForce) { DEBUG_LOG(WII_IPC_HID, "HID::Close"); + m_Active = false; if (!_bForce) Memory::Write_U32(0, _CommandAddress + 4); return true; } +u32 CWII_IPC_HLE_Device_hid::Update() +{ + u32 work_done = 0; + int ret = -4; + + std::list<_hidevent>::iterator ev = event_list.begin(); + while (ev != event_list.end()) { + + bool ev_finished = false; + + + switch (ev->type) + { + case IOCTL_HID_INTERRUPT_OUT: + case IOCTL_HID_INTERRUPT_IN: + { + ret = usb_reap_async_nocancel(ev->context, 0); + if(ret >= 0) + { + Memory::Write_U32(ret, ev->enq_address + 4); + WII_IPC_HLE_Interface::EnqReply(ev->enq_address); + work_done = ev_finished = true; + } + + break; + } + } + + if (ev_finished) + event_list.erase(ev++); + else + ev++; + } + return work_done; +} + bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { static u32 replyAddress = 0; @@ -75,6 +110,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, BufferInSize, BufferOut, BufferOutSize); + //Memory::Write_U32(0xFFFFFFFF, BufferOut); if(!hasRun) { FillOutDevices(BufferOut, BufferOutSize); @@ -133,7 +169,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ERROR CODES: -4 Cant find device specified */ - u32 dev_num = Memory::Read_U32(BufferIn+0x10); u8 requesttype = Memory::Read_U8(BufferIn+0x14); u8 request = Memory::Read_U8(BufferIn+0x15); @@ -142,11 +177,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u16 size = Memory::Read_U16(BufferIn+0x1A); u32 data = Memory::Read_U32(BufferIn+0x1C); - /* //libusb way - static int upto = 0; - int i; - usb_find_busses(); - usb_find_devices(); + usb_find_busses(); /* find all busses */ + usb_find_devices(); /* find all connected devices */ struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); @@ -155,7 +187,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ReturnValue = -4; break; } - + ReturnValue = usb_control_msg(dev_handle, requesttype, request, value, index, (char*)Memory::GetPointer(data), size, 0); @@ -164,113 +196,68 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { ReturnValue += sizeof(usb_ctrl_setup); } - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", - requesttype, request, ReturnValue); - - usb_close(dev_handle); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + requesttype, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - u8 test_out[0x20]; - Memory::ReadBigEData(test_out, BufferIn, BufferInSize); - char file[0x50]; - snprintf(file, 0x50, "ctrl_ctrlprotocol_%d.bin", upto); - FILE* test = fopen (file, "wb"); - for(i=0;i<0x20;i++) - fwrite(&test_out[i], 1, 1, test); - if (size > 0) - fwrite((char*)Memory::GetPointer(data), 1, size, test); - fclose(test); - upto++; - */ - - hid_device * dev_handle = GetDeviceByDevNumHidLib(dev_num); - if (dev_handle == NULL) - { - ReturnValue = -4; - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", - requesttype, request, ReturnValue); - break; - } - - // this is our write request - if(request == 0x09) - { - #define rw_buf_size 0x21 - unsigned char buf[rw_buf_size]; - memset(&buf[0], 0, rw_buf_size); - memcpy(&buf[1], (unsigned char*)Memory::GetPointer(data), size); - int success = hid_write_report(dev_handle, buf, size+1); - - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control) success = %d", success); - } - - ReturnValue = size + sizeof(usb_ctrl_setup); - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d", - requesttype, request, ReturnValue); - - break; } + case IOCTL_HID_INTERRUPT_OUT: case IOCTL_HID_INTERRUPT_IN: { + u32 dev_num = Memory::Read_U32(BufferIn+0x10); u32 end_point = Memory::Read_U32(BufferIn+0x14); u32 length = Memory::Read_U32(BufferIn+0x18); u32 data = Memory::Read_U32(BufferIn+0x1C); - - hid_device * dev_handle = GetDeviceByDevNumHidLib(dev_num); + int ret = 0; + void * context = NULL; + + struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); if (dev_handle == NULL) { ReturnValue = -4; - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt In)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - break; + goto int_in_end_print; } - //ReturnValue = -5; - ReturnValue = hid_read(dev_handle, (unsigned char*)Memory::GetPointer(data), length); - //ReturnValue = usb_interrupt_read(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 1000); - - - FILE* test = fopen ("readdata.bin", "wb"); - fwrite(Memory::GetPointer(data), ReturnValue, 1, test); - fclose(test); - - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt In)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + usb_claim_interface(dev_handle,0); - - break; - } - case IOCTL_HID_INTERRUPT_OUT: - { - - - u32 dev_num = Memory::Read_U32(BufferIn+0x10); - u32 end_point = Memory::Read_U32(BufferIn+0x14); - u32 length = Memory::Read_U32(BufferIn+0x18); - - u32 data = Memory::Read_U32(BufferIn+0x1C); - - hid_device * dev_handle = GetDeviceByDevNumHidLib(dev_num); - - if (dev_handle == NULL) + ret = usb_interrupt_setup_async(dev_handle, &context, end_point); + if (ret< 0) { ReturnValue = -4; - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt Out) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - break; + goto int_in_end_print; } - - ReturnValue = -5; - //ReturnValue = usb_interrupt_write(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 0); - - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt Out) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + ret = usb_submit_async(context, (char*)Memory::GetPointer(data), length); + if (ret< 0) + { + ReturnValue = -4; + goto int_in_end_print; + } + + ret = usb_reap_async_nocancel(context, 0); + if (ret >= 0) + { + ReturnValue = ret; + } + else + { + _hidevent ev; + ev.enq_address = _CommandAddress; + ev.type = Parameter; + ev.context = context; + event_list.push_back(ev); + return false; + } + + int_in_end_print: + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + break; } @@ -294,16 +281,24 @@ bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) u32 ReturnValue = 0; SIOCtlVBuffer CommandBuffer(_CommandAddress); - DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); - DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); - DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); - #if defined(_DEBUG) || defined(DEBUGFAST) - DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); - #endif + switch (CommandBuffer.Parameter) + { + + default: + { + DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); + DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); + DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); + DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); + DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); + DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); + DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); + #if defined(_DEBUG) || defined(DEBUGFAST) + DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); + #endif + } + break; + } Memory::Write_U32(ReturnValue, _CommandAddress + 4); return true; @@ -337,137 +332,15 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *des dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); } -static int x = 0; -u32 CWII_IPC_HLE_Device_hid::GetAvailableID(char* path) -{ - std::string dev_path = path; - if(loaded_devices.find(dev_path) == loaded_devices.end()){ - loaded_devices_rev[x] = dev_path; - loaded_devices[dev_path] = x++; - } - return loaded_devices[dev_path]; -} - -// hidapi version -void CWII_IPC_HLE_Device_hid::FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutSize) -{ - x = 0; - // Enumerate and print the HID devices on the system - struct hid_device_info *devs, *cur_dev; - - int OffsetBuffer = BufferOut; - int OffsetStart = 0; - int c,i,e; // config, interface container, interface, endpoint - - devs = hid_enumerate(0x0, 0x0); - cur_dev = devs; - while (cur_dev) { - - OffsetStart = OffsetBuffer; - OffsetBuffer += 4; // skip length for now, fill at end - - Memory::Write_U32(GetAvailableID(cur_dev->path), OffsetBuffer); //write device num - OffsetBuffer += 4; - - WiiHIDDeviceDescriptor wii_device; - - wii_device.bLength = Common::swap8(0x12); - wii_device.bDescriptorType = Common::swap8(0x1); - wii_device.bcdUSB = Common::swap16(0x0200); - wii_device.bDeviceClass = Common::swap8(0); - wii_device.bDeviceSubClass = Common::swap8(0); - wii_device.bDeviceProtocol = Common::swap8(0); - wii_device.bMaxPacketSize0 = Common::swap8(0x20); - wii_device.idVendor = Common::swap16(cur_dev->vendor_id); - wii_device.idProduct = Common::swap16(cur_dev->product_id); - wii_device.bcdDevice = Common::swap16(cur_dev->release_number); - wii_device.iManufacturer = Common::swap8(0x1); - wii_device.iProduct = Common::swap8(0x2); - wii_device.iSerialNumber = Common::swap8(0); - wii_device.bNumConfigurations = Common::swap8(0x1); - - Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); - - OffsetBuffer += Align(wii_device.bLength, 4); - - - for (c = 0; c < Common::swap8(wii_device.bNumConfigurations); c++) - { - - WiiHIDConfigDescriptor wii_config; - wii_config.bLength = Common::swap8(0x9); - wii_config.bDescriptorType = Common::swap8(0x2); - wii_config.wTotalLength = Common::swap16(0x29); - wii_config.bNumInterfaces = Common::swap8(0x1); - wii_config.bConfigurationValue = Common::swap8(0x1); - wii_config.iConfiguration = Common::swap8(0); - wii_config.bmAttributes = Common::swap8(0x80); - wii_config.MaxPower = Common::swap8(0x96); - - Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(Common::swap8(wii_config.bLength), 4)); - OffsetBuffer += Align(Common::swap8(wii_config.bLength), 4); - - for (i = 0; i < wii_config.bNumInterfaces; i++) - { - WiiHIDInterfaceDescriptor wii_interface; - - wii_interface.bLength = Common::swap8(0x9); - wii_interface.bDescriptorType = Common::swap8(0x4); - wii_interface.bInterfaceNumber = Common::swap8(i); - wii_interface.bAlternateSetting = Common::swap8(0); - wii_interface.bNumEndpoints = Common::swap8(0x2); - wii_interface.bInterfaceClass = Common::swap8(0x3); - wii_interface.bInterfaceSubClass = Common::swap8(0); - wii_interface.bInterfaceProtocol = Common::swap8(0); - wii_interface.iInterface = Common::swap8(0); - - Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(Common::swap8(wii_interface.bLength), 4)); - OffsetBuffer += Align(Common::swap8(wii_interface.bLength), 4); - - for (e = 0; e < Common::swap8(wii_interface.bNumEndpoints); e++) - { - WiiHIDEndpointDescriptor wii_endpoint; - wii_endpoint.bLength = Common::swap8(0x7); - wii_endpoint.bDescriptorType = Common::swap8(0x5); - wii_endpoint.bEndpointAddress = Common::swap8(e == 0 ? 0x1 : 0x81); - wii_endpoint.bmAttributes = Common::swap8(0x3); - wii_endpoint.wMaxPacketSize = Common::swap16(0x20); - wii_endpoint.bInterval = Common::swap8(0x1); - - Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(Common::swap8(wii_endpoint.bLength), 4)); - OffsetBuffer += Align(Common::swap8(wii_endpoint.bLength), 4); - - } //endpoints - } // interfaces - } // configs - - Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length - - NOTICE_LOG(WII_IPC_HID, "Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", - cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); - NOTICE_LOG(WII_IPC_HID, "\n"); - NOTICE_LOG(WII_IPC_HID, " Manufacturer: %ls\n", cur_dev->manufacturer_string); - NOTICE_LOG(WII_IPC_HID, " Product: %ls\n", cur_dev->product_string); - NOTICE_LOG(WII_IPC_HID, "\n"); - cur_dev = cur_dev->next; - } - Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices - - hid_free_enumeration(devs); -} - - -// libusb version void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { - FillOutDevicesHidApi(BufferOut, BufferOutSize); - /*usb_find_busses(); // find all busses - usb_find_devices(); // find all connected devices + usb_find_busses(); /* find all busses */ + usb_find_devices(); /* find all connected devices */ struct usb_bus *bus; struct usb_device *dev; int OffsetBuffer = BufferOut; int OffsetStart = 0; - int c,ic,i,e; // config, interface container, interface, endpoint + int c,ic,i,e; /* config, interface container, interface, endpoint */ for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) @@ -527,38 +400,34 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) } // buses Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices - */ + } - - int CWII_IPC_HLE_Device_hid::Align(int num, int alignment) { return (num + (alignment-1)) & ~(alignment-1); } -hid_device * CWII_IPC_HLE_Device_hid::GetDeviceByDevNumHidLib(u32 devNum) -{ - if (loaded_devices_rev.find(devNum) == loaded_devices_rev.end()) - return NULL; - if (opened_devices.find(devNum) != opened_devices.end()) - return opened_devices[devNum]; - - hid_device * phPortalHandle = opened_devices[devNum] = hid_open_path(loaded_devices_rev[devNum].c_str()); - return phPortalHandle; -} struct usb_dev_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) { + + if (open_devices.find(devNum) != open_devices.end()) + return open_devices[devNum]; + + usb_dev_handle * device = NULL; + for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) { for (struct usb_device *dev = bus->devices; dev; dev = dev->next) { if(dev->devnum == devNum){ - return usb_open(dev); + open_devices[devNum] = device = usb_open(dev); + + return device; } } } - return NULL; + return device; } \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index 2fc4ba9a22..099f4deff4 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -19,7 +19,9 @@ #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device.h" -#include "hidapi.h" +#include + +/* Connection timed out */ #define ETRANSFER_TIMEDOUT -116 class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device { @@ -30,13 +32,12 @@ public: virtual bool Open(u32 _CommandAddress, u32 _Mode); virtual bool Close(u32 _CommandAddress, bool _bForce); + virtual u32 Update(); virtual bool IOCtlV(u32 _CommandAddress); virtual bool IOCtl(u32 _CommandAddress); private: - - std::map deviceList; enum { @@ -112,10 +113,7 @@ private: } WiiHIDEndpointDescriptor; - u32 GetAvailableID(char* path); - - void FillOutDevices(u32 BufferOut, u32 BufferOutSize); - void FillOutDevicesHidApi(u32 BufferOut, u32 BufferOutSize); + void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize); void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src); void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src); @@ -123,8 +121,17 @@ private: void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src); int Align(int num, int alignment); - hid_device * GetDeviceByDevNumHidLib(u32 devNum); - struct usb_dev_handle * GetDeviceByDevNum(u32 devNum); + struct usb_dev_handle * GetDeviceByDevNum(u32 devNum); + std::map open_devices; + + typedef struct + { + u32 enq_address; + u32 type; + void * context; + } _hidevent; + + std::list<_hidevent> event_list; }; diff --git a/Source/VSProps/Dolphin.x64.props b/Source/VSProps/Dolphin.x64.props index c9cc2eb7ff..fd692daa60 100644 --- a/Source/VSProps/Dolphin.x64.props +++ b/Source/VSProps/Dolphin.x64.props @@ -9,7 +9,7 @@ ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;hidapi.lib;%(AdditionalDependencies) + portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;%(AdditionalDependencies) -- cgit v1.2.3 From c626d5aae3f34ee93626c4d26c76bf5fbd7ef76a Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 24 Dec 2012 08:31:50 +1300 Subject: Move to 1.0 libusb. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 217 ++++++++++++--------- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 13 +- Source/VSProps/Dolphin.Win32.props | 2 +- Source/VSProps/Dolphin.x64.props | 2 +- 4 files changed, 136 insertions(+), 98 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index fb75386a4a..486ec062e6 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -20,24 +20,28 @@ #include "../HW/WII_IPC.h" #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device_hid.h" -#include "lusb0_usb.h" +#include "libusb.h" #include "errno.h" +#include CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) { - usb_init(); /* initialize the library */ - + //usb_init(); /* initialize the library */ + libusb_init(NULL); } CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() { - for ( std::map::const_iterator iter = open_devices.begin(); iter != open_devices.end(); ++iter ) + /*for ( std::map::const_iterator iter = open_devices.begin(); iter != open_devices.end(); ++iter ) { usb_close(iter->second); } open_devices.clear(); + */ + + libusb_exit(NULL); } bool CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode) @@ -61,7 +65,11 @@ u32 CWII_IPC_HLE_Device_hid::Update() { u32 work_done = 0; int ret = -4; - + //timeval tv; + + + //libusb_handle_events_timeout_completed(NULL, &tv, NULL); + /* std::list<_hidevent>::iterator ev = event_list.begin(); while (ev != event_list.end()) { @@ -89,7 +97,7 @@ u32 CWII_IPC_HLE_Device_hid::Update() event_list.erase(ev++); else ev++; - } + }*/ return work_done; } @@ -170,17 +178,17 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) -4 Cant find device specified */ u32 dev_num = Memory::Read_U32(BufferIn+0x10); - u8 requesttype = Memory::Read_U8(BufferIn+0x14); + u8 requestType = Memory::Read_U8(BufferIn+0x14); u8 request = Memory::Read_U8(BufferIn+0x15); u16 value = Memory::Read_U16(BufferIn+0x16); u16 index = Memory::Read_U16(BufferIn+0x18); u16 size = Memory::Read_U16(BufferIn+0x1A); u32 data = Memory::Read_U32(BufferIn+0x1C); - usb_find_busses(); /* find all busses */ - usb_find_devices(); /* find all connected devices */ - - struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + + libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); if (dev_handle == NULL) { @@ -188,76 +196,63 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) break; } - ReturnValue = usb_control_msg(dev_handle, requesttype, request, + /*ReturnValue = usb_control_msg(dev_handle, requesttype, request, value, index, (char*)Memory::GetPointer(data), size, 0); - + */ + ReturnValue = libusb_control_transfer (dev_handle, requestType, request, value, index, (unsigned char*)Memory::GetPointer(data), size, 0); if(ReturnValue>=0) { - ReturnValue += sizeof(usb_ctrl_setup); + ReturnValue += sizeof(libusb_control_setup); } + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - requesttype, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - + requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } case IOCTL_HID_INTERRUPT_OUT: case IOCTL_HID_INTERRUPT_IN: { - - u32 dev_num = Memory::Read_U32(BufferIn+0x10); - u32 end_point = Memory::Read_U32(BufferIn+0x14); + u32 endpoint = Memory::Read_U32(BufferIn+0x14); u32 length = Memory::Read_U32(BufferIn+0x18); u32 data = Memory::Read_U32(BufferIn+0x1C); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); int ret = 0; void * context = NULL; + ReturnValue = -4; - struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num); + libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); if (dev_handle == NULL) { ReturnValue = -4; goto int_in_end_print; } + int transfered = 0; - usb_claim_interface(dev_handle,0); - - ret = usb_interrupt_setup_async(dev_handle, &context, end_point); - if (ret< 0) + if(libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 0 ) == 0) { - ReturnValue = -4; - goto int_in_end_print; - } - ret = usb_submit_async(context, (char*)Memory::GetPointer(data), length); - if (ret< 0) - { - ReturnValue = -4; - goto int_in_end_print; + ReturnValue = transfered; } - ret = usb_reap_async_nocancel(context, 0); - if (ret >= 0) - { - ReturnValue = ret; - } - else - { + /* _hidevent ev; ev.enq_address = _CommandAddress; ev.type = Parameter; ev.context = context; event_list.push_back(ev); return false; - } + */ + int_in_end_print: DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - + Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } @@ -274,6 +269,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) return true; } + bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) { @@ -283,7 +279,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) switch (CommandBuffer.Parameter) { - + case 0x1337: + break; default: { DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); @@ -306,7 +303,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) -void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src) +void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, const struct libusb_device_descriptor *src) { memcpy(dest,src,sizeof(WiiHIDDeviceDescriptor)); dest->bcdUSB = Common::swap16(dest->bcdUSB); @@ -315,18 +312,18 @@ void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, s dest->bcdDevice = Common::swap16(dest->bcdDevice); } -void CWII_IPC_HLE_Device_hid::ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src) +void CWII_IPC_HLE_Device_hid::ConvertConfigToWii(WiiHIDConfigDescriptor *dest, const struct libusb_config_descriptor *src) { memcpy(dest,src,sizeof(WiiHIDConfigDescriptor)); dest->wTotalLength = Common::swap16(dest->wTotalLength); } -void CWII_IPC_HLE_Device_hid::ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src) +void CWII_IPC_HLE_Device_hid::ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, const struct libusb_interface_descriptor *src) { memcpy(dest,src,sizeof(WiiHIDInterfaceDescriptor)); } -void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src) +void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, const struct libusb_endpoint_descriptor *src) { memcpy(dest,src,sizeof(WiiHIDEndpointDescriptor)); dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize); @@ -334,35 +331,45 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *des void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { - usb_find_busses(); /* find all busses */ - usb_find_devices(); /* find all connected devices */ - struct usb_bus *bus; - struct usb_device *dev; int OffsetBuffer = BufferOut; int OffsetStart = 0; - int c,ic,i,e; /* config, interface container, interface, endpoint */ - for (bus = usb_get_busses(); bus; bus = bus->next) + int OffsetDevice = 0; + int d, c,ic,i,e; /* config, interface container, interface, endpoint */ + + libusb_device **list; + libusb_device *found = NULL; + ssize_t cnt = libusb_get_device_list(NULL, &list); + + for (d = 0; d < cnt; d++) { - for (dev = bus->devices; dev; dev = dev->next) - { - struct usb_device_descriptor *device = &dev->descriptor; - DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d",device->idVendor, device->idProduct, dev->devnum); + libusb_device *device = list[d]; + struct libusb_device_descriptor desc; + int dRet = libusb_get_device_descriptor (device, &desc); + + DEBUG_LOG(WII_IPC_HID, "Vendor: %d Product: %X Devnum: %X",desc.idVendor, desc.idProduct); + if (desc.idVendor != 0x21A4) + continue; - OffsetStart = OffsetBuffer; - OffsetBuffer += 4; // skip length for now, fill at end + u32 devNum = 0;//(libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); + DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d, Error: %d",desc.idVendor, desc.idProduct, devNum, dRet); - Memory::Write_U32(dev->devnum, OffsetBuffer); //write device num - OffsetBuffer += 4; + OffsetStart = OffsetBuffer; + OffsetBuffer += 4; // skip length for now, fill at end - WiiHIDDeviceDescriptor wii_device; - ConvertDeviceToWii(&wii_device, device); - Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); - OffsetBuffer += Align(wii_device.bLength, 4); + Memory::Write_U32(devNum, OffsetBuffer); //write device num + OffsetBuffer += 4; - for (c = 0; c < device->bNumConfigurations; c++) + WiiHIDDeviceDescriptor wii_device; + ConvertDeviceToWii(&wii_device, &desc); + Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); + OffsetBuffer += Align(wii_device.bLength, 4); + bool deviceValid = true; + for (c = 0; deviceValid && c < desc.bNumConfigurations; c++) + { + struct libusb_config_descriptor *config = NULL; + int cRet = libusb_get_config_descriptor(device, c, &config); + if(cRet == 0) { - struct usb_config_descriptor *config = &dev->config[c]; - WiiHIDConfigDescriptor wii_config; ConvertConfigToWii(&wii_config, config); Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4)); @@ -370,10 +377,10 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) for (ic = 0; ic < config->bNumInterfaces; ic++) { - struct usb_interface *interfaceContainer = &config->interface[ic]; + const struct libusb_interface *interfaceContainer = &config->interface[ic]; for (i = 0; i < interfaceContainer->num_altsetting; i++) { - struct usb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; + const struct libusb_interface_descriptor *interface = &interfaceContainer->altsetting[i]; WiiHIDInterfaceDescriptor wii_interface; ConvertInterfaceToWii(&wii_interface, interface); @@ -382,7 +389,7 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) for (e = 0; e < interface->bNumEndpoints; e++) { - struct usb_endpoint_descriptor *endpoint = &interface->endpoint[e]; + const struct libusb_endpoint_descriptor *endpoint = &interface->endpoint[e]; WiiHIDEndpointDescriptor wii_endpoint; ConvertEndpointToWii(&wii_endpoint, endpoint); @@ -392,42 +399,72 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) } //endpoints } // interfaces } // interface containters - } // configs - - Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length + libusb_free_config_descriptor(config); + config = NULL; + } + else + { + DEBUG_LOG(WII_IPC_HID, "Could not open the device %d", cRet); + deviceValid = false; + OffsetBuffer = OffsetStart; + } + } // configs + Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length - } // devices - } // buses + } + libusb_free_device_list(list, TRUE); + Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices + char file[0x50]; + snprintf(file, 0x50, "device_list.bin"); + FILE* test = fopen (file, "wb"); + fwrite((char*)Memory::GetPointer(BufferOut), 1, (OffsetBuffer - BufferOut)+4, test); + + fclose(test); } - + int CWII_IPC_HLE_Device_hid::Align(int num, int alignment) { return (num + (alignment-1)) & ~(alignment-1); } -struct usb_dev_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) +libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) { - + int i; + libusb_device **list; + libusb_device_handle *handle = NULL; + ssize_t cnt; + if (open_devices.find(devNum) != open_devices.end()) return open_devices[devNum]; + + cnt = libusb_get_device_list(NULL, &list); + + if (cnt < 0) + return NULL; + + for (i = 0; i < cnt; i++) { + libusb_device *device = list[i]; - usb_dev_handle * device = NULL; - - for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) - { - for (struct usb_device *dev = bus->devices; dev; dev = dev->next) + if (libusb_open(device, &handle)) + break; + //struct libusb_device_descriptor desc; + u32 deviceID = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); + if (deviceID == devNum) + open_devices[devNum] = handle; + else { - if(dev->devnum == devNum){ - open_devices[devNum] = device = usb_open(dev); - - return device; - } + libusb_close(handle); + handle = NULL; } } - return device; + + libusb_free_device_list(list, TRUE); + + + return handle; } \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index 099f4deff4..be7e1b5926 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -115,15 +115,16 @@ private: void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize); - void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src); - void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src); - void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src); - void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src); + void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, const struct libusb_device_descriptor *src); + void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, const struct libusb_config_descriptor *src); + void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, const struct libusb_interface_descriptor *src); + void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, const struct libusb_endpoint_descriptor *src); int Align(int num, int alignment); - struct usb_dev_handle * GetDeviceByDevNum(u32 devNum); - std::map open_devices; + struct libusb_device_handle * GetDeviceByDevNum(u32 devNum); + std::map open_devices; + std::map device_identifiers; typedef struct diff --git a/Source/VSProps/Dolphin.Win32.props b/Source/VSProps/Dolphin.Win32.props index a78f75c4ac..383ed36590 100644 --- a/Source/VSProps/Dolphin.Win32.props +++ b/Source/VSProps/Dolphin.Win32.props @@ -8,7 +8,7 @@ ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;hidapi.lib;%(AdditionalDependencies) + portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;libusb-1.0.lib;%(AdditionalDependencies) diff --git a/Source/VSProps/Dolphin.x64.props b/Source/VSProps/Dolphin.x64.props index fd692daa60..28ae77d1b5 100644 --- a/Source/VSProps/Dolphin.x64.props +++ b/Source/VSProps/Dolphin.x64.props @@ -9,7 +9,7 @@ ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;%(AdditionalDependencies) + portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;libusb-1.0.lib;%(AdditionalDependencies) -- cgit v1.2.3 From d9dd94ac8b696ceb0e6b32eaafcc302b41f43bd1 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 24 Dec 2012 12:58:11 +1300 Subject: Add Libusb to cmake and HID files. --- Source/Core/Core/CMakeLists.txt | 7 ++++ .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 48 +++++++++++++--------- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 8 ++-- 3 files changed, 40 insertions(+), 23 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 734d966781..dd19d36d36 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -138,6 +138,7 @@ set(SRCS Src/ActionReplay.cpp Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp + Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -194,6 +195,12 @@ set(SRCS Src/ActionReplay.cpp set(LIBS bdisasm inputcommon videoogl videosoftware sfml-network) + +if(LIBUSB_FOUND) + # Using shared LibUSB + set(LIBS ${LIBS} ${LIBUSB_LIBRARIES}) +endif(LIBUSB_FOUND) + if(WIN32) set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Win32.cpp Src/stdafx.cpp Src/HW/WiimoteReal/IOWin.cpp) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 486ec062e6..250ff7021e 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -64,7 +64,7 @@ bool CWII_IPC_HLE_Device_hid::Close(u32 _CommandAddress, bool _bForce) u32 CWII_IPC_HLE_Device_hid::Update() { u32 work_done = 0; - int ret = -4; + //int ret = -4; //timeval tv; @@ -214,16 +214,15 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) case IOCTL_HID_INTERRUPT_OUT: case IOCTL_HID_INTERRUPT_IN: { - + + int transfered = 0; u32 dev_num = Memory::Read_U32(BufferIn+0x10); u32 endpoint = Memory::Read_U32(BufferIn+0x14); u32 length = Memory::Read_U32(BufferIn+0x18); u32 data = Memory::Read_U32(BufferIn+0x1C); - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - int ret = 0; - void * context = NULL; ReturnValue = -4; libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); @@ -233,7 +232,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ReturnValue = -4; goto int_in_end_print; } - int transfered = 0; if(libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 0 ) == 0) { @@ -251,7 +249,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) int_in_end_print: - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; @@ -333,11 +331,11 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { int OffsetBuffer = BufferOut; int OffsetStart = 0; - int OffsetDevice = 0; - int d, c,ic,i,e; /* config, interface container, interface, endpoint */ + //int OffsetDevice = 0; + int d,c,ic,i,e; /* config, interface container, interface, endpoint */ libusb_device **list; - libusb_device *found = NULL; + //libusb_device *found = NULL; ssize_t cnt = libusb_get_device_list(NULL, &list); for (d = 0; d < cnt; d++) @@ -346,17 +344,18 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) struct libusb_device_descriptor desc; int dRet = libusb_get_device_descriptor (device, &desc); - DEBUG_LOG(WII_IPC_HID, "Vendor: %d Product: %X Devnum: %X",desc.idVendor, desc.idProduct); + u32 devNum = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); + + DEBUG_LOG(WII_IPC_HID, "Vendor: %d Product: %X Devnum: %X",desc.idVendor, desc.idProduct, devNum); if (desc.idVendor != 0x21A4) continue; - u32 devNum = 0;//(libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d, Error: %d",desc.idVendor, desc.idProduct, devNum, dRet); OffsetStart = OffsetBuffer; OffsetBuffer += 4; // skip length for now, fill at end - Memory::Write_U32(devNum, OffsetBuffer); //write device num + Memory::Write_U32( 0/*devNum*/, OffsetBuffer); //write device num OffsetBuffer += 4; WiiHIDDeviceDescriptor wii_device; @@ -413,7 +412,7 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) } - libusb_free_device_list(list, TRUE); + libusb_free_device_list(list, 1); Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices @@ -439,6 +438,8 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) libusb_device_handle *handle = NULL; ssize_t cnt; + devNum = 0x204; + if (open_devices.find(devNum) != open_devices.end()) return open_devices[devNum]; @@ -449,13 +450,22 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) for (i = 0; i < cnt; i++) { libusb_device *device = list[i]; - - if (libusb_open(device, &handle)) - break; + int ret = libusb_open(device, &handle); + if (ret) + { + + DEBUG_LOG(WII_IPC_HID, "Failed to open device with error = %d", ret); + continue; + } + //struct libusb_device_descriptor desc; u32 deviceID = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); + DEBUG_LOG(WII_IPC_HID, "Testing device id == %d", deviceID); if (deviceID == devNum) + { open_devices[devNum] = handle; + break; + } else { libusb_close(handle); @@ -463,8 +473,8 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) } } - libusb_free_device_list(list, TRUE); + libusb_free_device_list(list, 1); return handle; -} \ No newline at end of file +} diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index be7e1b5926..7f70324772 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -21,7 +21,7 @@ #include "WII_IPC_HLE_Device.h" #include -/* Connection timed out */ #define ETRANSFER_TIMEDOUT -116 +/* Connection timed out */ class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device { @@ -45,8 +45,8 @@ private: IOCTL_HID_SET_SUSPEND = 0x01, IOCTL_HID_CONTROL = 0x02, IOCTL_HID_INTERRUPT_IN = 0x03, - IOCTL_HID_INTERRUPT_OUT = 0x04, - IOCTL_HID_GET_US_STRING = 0x05, + IOCTL_HID_INTERRUPT_OUT = 0x04, + IOCTL_HID_GET_US_STRING = 0x05, IOCTL_HID_OPEN = 0x06, IOCTL_HID_SHUTDOWN = 0x07, IOCTL_HID_CANCEL_INTERRUPT = 0x08, @@ -113,7 +113,7 @@ private: } WiiHIDEndpointDescriptor; - void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize); + void FillOutDevices(u32 BufferOut, u32 BufferOutSize); void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, const struct libusb_device_descriptor *src); void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, const struct libusb_config_descriptor *src); -- cgit v1.2.3 From bc385cbdd8e0c3eabdadee22f567f2f141b1fb17 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Fri, 28 Dec 2012 01:26:20 +1300 Subject: libusb 1.0 hacky working on linux. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 31 +++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 250ff7021e..af66f2a307 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -216,6 +216,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { int transfered = 0; + int checkme = 34; + int worked = 35; u32 dev_num = Memory::Read_U32(BufferIn+0x10); u32 endpoint = Memory::Read_U32(BufferIn+0x14); u32 length = Memory::Read_U32(BufferIn+0x18); @@ -232,8 +234,26 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ReturnValue = -4; goto int_in_end_print; } + if (libusb_kernel_driver_active(dev_handle, 0) == 1) + { + DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); + worked = libusb_detach_kernel_driver(dev_handle, 0); + if (worked) + { + DEBUG_LOG(WII_IPC_HID, "Attempt to detach interface failed with error: %d", worked); + } + } - if(libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 0 ) == 0) + worked = libusb_claim_interface(dev_handle, 0); + if (worked) + { + DEBUG_LOG(WII_IPC_HID, "Attempt to claim interface failed with error: %d", worked); + ReturnValue = -4; + goto int_in_end_print; + } + + checkme = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 3000 ); + if(checkme == 0) { ReturnValue = transfered; } @@ -249,8 +269,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) int_in_end_print: - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i), err = %d", + Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize, checkme); break; } @@ -438,10 +458,13 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) libusb_device_handle *handle = NULL; ssize_t cnt; - devNum = 0x204; + devNum = 0x304; if (open_devices.find(devNum) != open_devices.end()) + { + DEBUG_LOG(WII_IPC_HID, "Found it... "); return open_devices[devNum]; + } cnt = libusb_get_device_list(NULL, &list); -- cgit v1.2.3 From de0798f4f7fb0d4010567351e34f658ab51348ef Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sat, 29 Dec 2012 17:46:44 +1300 Subject: More stable hackyness. :) --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 88 ++++++++++++---------- 1 file changed, 50 insertions(+), 38 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index af66f2a307..50c70e9c6a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -177,6 +177,9 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ERROR CODES: -4 Cant find device specified */ + int ret = -1; + int worked = 32; + u32 dev_num = Memory::Read_U32(BufferIn+0x10); u8 requestType = Memory::Read_U8(BufferIn+0x14); u8 request = Memory::Read_U8(BufferIn+0x15); @@ -185,8 +188,10 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u16 size = Memory::Read_U16(BufferIn+0x1A); u32 data = Memory::Read_U32(BufferIn+0x1C); - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + ReturnValue = -4; + + //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + // requestType, request, BufferIn, BufferInSize, BufferOut, BufferOutSize); libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); @@ -200,10 +205,30 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) value, index, (char*)Memory::GetPointer(data), size, 0); */ - ReturnValue = libusb_control_transfer (dev_handle, requestType, request, value, index, (unsigned char*)Memory::GetPointer(data), size, 0); - if(ReturnValue>=0) + + if (libusb_kernel_driver_active(dev_handle, 0) == 1) + { + //DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); + worked = libusb_detach_kernel_driver(dev_handle, 0); + if (worked) + { + //DEBUG_LOG(WII_IPC_HID, "Attempt to detach interface failed with error: %d", worked); + } + } + + worked = libusb_claim_interface(dev_handle, 0); + if (worked) { - ReturnValue += sizeof(libusb_control_setup); + DEBUG_LOG(WII_IPC_HID, "Attempt to claim interface failed with error: %d", worked); + ReturnValue = -4; + break; + } + + ret = libusb_control_transfer (dev_handle, requestType, request, value, index, (unsigned char*)Memory::GetPointer(data), size, 0); + if(ret>=0) + { + ret += sizeof(libusb_control_setup); + ReturnValue = ret; } DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", @@ -223,8 +248,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u32 length = Memory::Read_U32(BufferIn+0x18); u32 data = Memory::Read_U32(BufferIn+0x1C); - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + //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); ReturnValue = -4; libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); @@ -236,23 +261,23 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) } if (libusb_kernel_driver_active(dev_handle, 0) == 1) { - DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); + //DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); worked = libusb_detach_kernel_driver(dev_handle, 0); if (worked) { - DEBUG_LOG(WII_IPC_HID, "Attempt to detach interface failed with error: %d", worked); + //DEBUG_LOG(WII_IPC_HID, "Attempt to detach interface failed with error: %d", worked); } } worked = libusb_claim_interface(dev_handle, 0); if (worked) { - DEBUG_LOG(WII_IPC_HID, "Attempt to claim interface failed with error: %d", worked); + //DEBUG_LOG(WII_IPC_HID, "Attempt to claim interface failed with error: %d", worked); ReturnValue = -4; goto int_in_end_print; } - checkme = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 3000 ); + checkme = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 20 ); if(checkme == 0) { ReturnValue = transfered; @@ -295,25 +320,16 @@ bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) u32 ReturnValue = 0; SIOCtlVBuffer CommandBuffer(_CommandAddress); - switch (CommandBuffer.Parameter) - { - case 0x1337: - break; - default: - { - DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); - DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); - DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); - DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); - DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); - DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); - DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); - #if defined(_DEBUG) || defined(DEBUGFAST) - DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); - #endif - } - break; - } + DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str()); + DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter); + DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer); + DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer); + DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector); + DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address); + DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size); + #if defined(_DEBUG) || defined(DEBUGFAST) + DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer); + #endif Memory::Write_U32(ReturnValue, _CommandAddress + 4); return true; @@ -367,15 +383,15 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) u32 devNum = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); DEBUG_LOG(WII_IPC_HID, "Vendor: %d Product: %X Devnum: %X",desc.idVendor, desc.idProduct, devNum); - if (desc.idVendor != 0x21A4) - continue; + //if (desc.idVendor != 0x21A4) + // continue; DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d, Error: %d",desc.idVendor, desc.idProduct, devNum, dRet); OffsetStart = OffsetBuffer; OffsetBuffer += 4; // skip length for now, fill at end - Memory::Write_U32( 0/*devNum*/, OffsetBuffer); //write device num + Memory::Write_U32( d /*devNum*/, OffsetBuffer); //write device num OffsetBuffer += 4; WiiHIDDeviceDescriptor wii_device; @@ -458,11 +474,8 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) libusb_device_handle *handle = NULL; ssize_t cnt; - devNum = 0x304; - if (open_devices.find(devNum) != open_devices.end()) { - DEBUG_LOG(WII_IPC_HID, "Found it... "); return open_devices[devNum]; } @@ -483,8 +496,7 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) //struct libusb_device_descriptor desc; u32 deviceID = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); - DEBUG_LOG(WII_IPC_HID, "Testing device id == %d", deviceID); - if (deviceID == devNum) + if (i == devNum) { open_devices[devNum] = handle; break; -- cgit v1.2.3 From 3b459fb500b1a87532cc33b1c38363591c3b667f Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sun, 30 Dec 2012 16:57:37 +1300 Subject: Add better FindLibUsb support for MacOSX. Make LibUSB optional, don't compile HID support if it doesn't exist. A lot less hacky. Works quite well on Ubuntu now. --- Source/Core/Core/CMakeLists.txt | 8 +- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 9 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 116 ++++++++++----------- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 3 + 4 files changed, 70 insertions(+), 66 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 20c611544a..3541e33713 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -70,8 +70,8 @@ set(SRCS Src/ActionReplay.cpp Src/HW/CPU.cpp Src/HW/DSP.cpp Src/HW/DSPHLE/UCodes/UCode_AX.cpp - Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp - Src/HW/DSPHLE/UCodes/UCode_NewAXWii.cpp + Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp + Src/HW/DSPHLE/UCodes/UCode_NewAXWii.cpp Src/HW/DSPHLE/UCodes/UCode_CARD.cpp Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp Src/HW/DSPHLE/UCodes/UCode_ROM.cpp @@ -138,7 +138,6 @@ set(SRCS Src/ActionReplay.cpp Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp - Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -202,7 +201,8 @@ endif() if(LIBUSB_FOUND) # Using shared LibUSB - set(LIBS ${LIBS} ${LIBUSB_LIBRARIES}) + set(LIBS ${LIBS} ${LIBUSB_LIBRARIES}) + set(SRCS ${SRCS} Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp) endif(LIBUSB_FOUND) if(WIN32) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 1c9a51bcbd..59f5a638cf 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -50,7 +50,10 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC #include "WII_IPC_HLE_Device_usb.h" #include "WII_IPC_HLE_Device_usb_kbd.h" #include "WII_IPC_HLE_Device_sdio_slot0.h" -#include "WII_IPC_HLE_Device_hid.h" + +#ifdef __LIBUSB__ + #include "WII_IPC_HLE_Device_hid.h" +#endif #include "FileUtil.h" // For Copy #include "../ConfigManager.h" @@ -114,7 +117,9 @@ void Init() g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++; - g_DeviceMap[i] = new CWII_IPC_HLE_Device_hid(i, std::string("/dev/usb/hid")); i++; + #ifdef __LIBUSB__ + g_DeviceMap[i] = new CWII_IPC_HLE_Device_hid(i, std::string("/dev/usb/hid")); i++; + #endif g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++; g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 50c70e9c6a..b214c13f63 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -20,26 +20,23 @@ #include "../HW/WII_IPC.h" #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device_hid.h" -#include "libusb.h" #include "errno.h" #include CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) { - - //usb_init(); /* initialize the library */ libusb_init(NULL); } CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() { - /*for ( std::map::const_iterator iter = open_devices.begin(); iter != open_devices.end(); ++iter ) + for ( std::map::const_iterator iter = open_devices.begin(); iter != open_devices.end(); ++iter ) { - usb_close(iter->second); + libusb_close(iter->second); } open_devices.clear(); - */ + libusb_exit(NULL); } @@ -146,29 +143,27 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) BufferIn, BufferInSize, BufferOut, BufferOutSize); // not actually implemented in IOS ReturnValue = 0; - if (replyAddress != 0){ FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); WII_IPC_HLE_Interface::EnqReply(replyAddress); replyAddress = 0; hasRun = false; } - 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; + if (replyAddress != 0){ FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); WII_IPC_HLE_Interface::EnqReply(replyAddress); replyAddress = 0; hasRun = false; } - - ReturnValue = 0; + break; } case IOCTL_HID_CONTROL: @@ -178,7 +173,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) -4 Cant find device specified */ int ret = -1; - int worked = 32; u32 dev_num = Memory::Read_U32(BufferIn+0x10); u8 requestType = Memory::Read_U8(BufferIn+0x14); @@ -188,8 +182,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u16 size = Memory::Read_U16(BufferIn+0x1A); u32 data = Memory::Read_U32(BufferIn+0x1C); - ReturnValue = -4; - //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", // requestType, request, BufferIn, BufferInSize, BufferOut, BufferOutSize); @@ -197,29 +189,14 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) if (dev_handle == NULL) { + DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num); ReturnValue = -4; break; } - - /*ReturnValue = usb_control_msg(dev_handle, requesttype, request, - value, index, (char*)Memory::GetPointer(data), size, - 0); - */ - if (libusb_kernel_driver_active(dev_handle, 0) == 1) + if (!ClaimDevice(dev_handle)) { - //DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); - worked = libusb_detach_kernel_driver(dev_handle, 0); - if (worked) - { - //DEBUG_LOG(WII_IPC_HID, "Attempt to detach interface failed with error: %d", worked); - } - } - - worked = libusb_claim_interface(dev_handle, 0); - if (worked) - { - DEBUG_LOG(WII_IPC_HID, "Attempt to claim interface failed with error: %d", worked); + DEBUG_LOG(WII_IPC_HID, "Could not claim the device for handle: %X", dev_num); ReturnValue = -4; break; } @@ -230,6 +207,10 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ret += sizeof(libusb_control_setup); ReturnValue = ret; } + else + { + ReturnValue = -4; + } DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); @@ -241,8 +222,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { int transfered = 0; - int checkme = 34; - int worked = 35; + int ret; u32 dev_num = Memory::Read_U32(BufferIn+0x10); u32 endpoint = Memory::Read_U32(BufferIn+0x14); u32 length = Memory::Read_U32(BufferIn+0x18); @@ -250,38 +230,31 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u32 data = Memory::Read_U32(BufferIn+0x1C); //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); - ReturnValue = -4; - libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); if (dev_handle == NULL) { + DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num); ReturnValue = -4; - goto int_in_end_print; - } - if (libusb_kernel_driver_active(dev_handle, 0) == 1) - { - //DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); - worked = libusb_detach_kernel_driver(dev_handle, 0); - if (worked) - { - //DEBUG_LOG(WII_IPC_HID, "Attempt to detach interface failed with error: %d", worked); - } + break; } - worked = libusb_claim_interface(dev_handle, 0); - if (worked) + if (!ClaimDevice(dev_handle)) { - //DEBUG_LOG(WII_IPC_HID, "Attempt to claim interface failed with error: %d", worked); + DEBUG_LOG(WII_IPC_HID, "Could not claim the device for handle: %X", dev_num); ReturnValue = -4; - goto int_in_end_print; + break; } - checkme = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 20 ); - if(checkme == 0) + ret = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 20 ); + if(ret == 0) { ReturnValue = transfered; } + else + { + ReturnValue = -4; + } /* _hidevent ev; @@ -291,11 +264,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) event_list.push_back(ev); return false; */ - - - int_in_end_print: - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i), err = %d", - Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize, checkme); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } @@ -313,6 +283,33 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) } +bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle * dev) +{ + int ret = 0; + if ((ret = libusb_kernel_driver_active(dev, 0)) == 1) + { + //DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); + if ((ret = libusb_detach_kernel_driver(dev, 0))) + { + DEBUG_LOG(WII_IPC_HID, "libusb_detach_kernel_driver failed with error: %d", ret); + return false; + } + } + else if (ret != 0) + { + DEBUG_LOG(WII_IPC_HID, "libusb_kernel_driver_active error ret = %d", ret); + return false; + } + + if ((ret = libusb_claim_interface(dev, 0))) + { + DEBUG_LOG(WII_IPC_HID, "libusb_claim_interface failed with error: %d", ret); + return false; + } + + return true; +} + bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress) { @@ -469,7 +466,7 @@ int CWII_IPC_HLE_Device_hid::Align(int num, int alignment) libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) { - int i; + u32 i; libusb_device **list; libusb_device_handle *handle = NULL; ssize_t cnt; @@ -494,8 +491,7 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) continue; } - //struct libusb_device_descriptor desc; - u32 deviceID = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); + // u32 deviceID = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); if (i == devNum) { open_devices[devNum] = handle; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index 7f70324772..c776d4bb7a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -19,6 +19,7 @@ #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device.h" +#include "libusb.h" #include /* Connection timed out */ @@ -114,6 +115,8 @@ private: void FillOutDevices(u32 BufferOut, u32 BufferOutSize); + + bool ClaimDevice(libusb_device_handle * dev); void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, const struct libusb_device_descriptor *src); void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, const struct libusb_config_descriptor *src); -- cgit v1.2.3 From 35466fb54f95b78ffabfde5ade398f54de6f6b91 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sun, 30 Dec 2012 17:48:33 +1300 Subject: Remove saving of debug file. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index b214c13f63..21b58d2d91 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -449,13 +449,6 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices - char file[0x50]; - snprintf(file, 0x50, "device_list.bin"); - FILE* test = fopen (file, "wb"); - fwrite((char*)Memory::GetPointer(BufferOut), 1, (OffsetBuffer - BufferOut)+4, test); - - fclose(test); - } int CWII_IPC_HLE_Device_hid::Align(int num, int alignment) -- cgit v1.2.3 From 510e08370ef7491c6106453248cee8e93771692e Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 31 Dec 2012 01:08:41 +1300 Subject: Now supports hotplugging. Much more stable but slow. Still missing proper cleanup of old handles. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 174 ++++++++++++++++----- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 1 + 2 files changed, 133 insertions(+), 42 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 21b58d2d91..9108a971a4 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -23,9 +23,13 @@ #include "errno.h" #include +#define MAX_DEVICE_DEVNUM 256 +static u64 hidDeviceAliases[MAX_DEVICE_DEVNUM]; + CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) { + memset(hidDeviceAliases, 0, sizeof(hidDeviceAliases)); libusb_init(NULL); } @@ -58,9 +62,36 @@ bool CWII_IPC_HLE_Device_hid::Close(u32 _CommandAddress, bool _bForce) return true; } +static u32 replyAddress = 0; +static bool hasRun = false; + u32 CWII_IPC_HLE_Device_hid::Update() { + static u16 timeToFill = 0; u32 work_done = 0; + + if (timeToFill == 0) + { + if (replyAddress != 0){ + FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); + + Memory::Write_U32(8, replyAddress); + // IOS seems to write back the command that was responded to + Memory::Write_U32(/*COMMAND_IOCTL*/ 6, replyAddress + 8); + + // Return value + Memory::Write_U32(0, replyAddress + 4); + + WII_IPC_HLE_Interface::EnqReply(replyAddress); + replyAddress = 0; + hasRun = false; + } + } + + timeToFill+=2; + + work_done = 1; + //int ret = -4; //timeval tv; @@ -84,7 +115,15 @@ u32 CWII_IPC_HLE_Device_hid::Update() Memory::Write_U32(ret, ev->enq_address + 4); WII_IPC_HLE_Interface::EnqReply(ev->enq_address); work_done = ev_finished = true; - } +} + +if (replyAddress != 0){ + FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); + WII_IPC_HLE_Interface::EnqReply(replyAddress); + replyAddress = 0; + hasRun = false; +} + break; } @@ -100,8 +139,6 @@ u32 CWII_IPC_HLE_Device_hid::Update() bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { - static u32 replyAddress = 0; - static bool hasRun = false; u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); @@ -143,12 +180,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) BufferIn, BufferInSize, BufferOut, BufferOutSize); // not actually implemented in IOS ReturnValue = 0; - if (replyAddress != 0){ - FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); - WII_IPC_HLE_Interface::EnqReply(replyAddress); - replyAddress = 0; - hasRun = false; - } break; } case IOCTL_HID_CANCEL_INTERRUPT: @@ -156,14 +187,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, BufferInSize, BufferOut, BufferOutSize); ReturnValue = 0; - - if (replyAddress != 0){ - FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); - WII_IPC_HLE_Interface::EnqReply(replyAddress); - replyAddress = 0; - hasRun = false; - } - break; } case IOCTL_HID_CONTROL: @@ -212,8 +235,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ReturnValue = -4; } - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + // requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } @@ -246,7 +269,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) break; } - ret = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 20 ); + ret = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 40 ); if(ret == 0) { ReturnValue = transfered; @@ -264,8 +287,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) event_list.push_back(ev); return false; */ - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + // Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } @@ -289,13 +312,13 @@ bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle * dev) if ((ret = libusb_kernel_driver_active(dev, 0)) == 1) { //DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); - if ((ret = libusb_detach_kernel_driver(dev, 0))) + if ((ret = libusb_detach_kernel_driver(dev, 0)) && ret != LIBUSB_ERROR_NOT_SUPPORTED) { DEBUG_LOG(WII_IPC_HID, "libusb_detach_kernel_driver failed with error: %d", ret); return false; } } - else if (ret != 0) + else if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED) { DEBUG_LOG(WII_IPC_HID, "libusb_kernel_driver_active error ret = %d", ret); return false; @@ -370,25 +393,31 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) libusb_device **list; //libusb_device *found = NULL; ssize_t cnt = libusb_get_device_list(NULL, &list); - + DEBUG_LOG(WII_IPC_HID, "Hello plane???? %ld", cnt); for (d = 0; d < cnt; d++) { libusb_device *device = list[d]; struct libusb_device_descriptor desc; int dRet = libusb_get_device_descriptor (device, &desc); - u32 devNum = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); + //u32 devNum = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); - DEBUG_LOG(WII_IPC_HID, "Vendor: %d Product: %X Devnum: %X",desc.idVendor, desc.idProduct, devNum); - //if (desc.idVendor != 0x21A4) - // continue; + int devNum = GetAvaiableDevNum(desc.idVendor, + desc.idProduct, + libusb_get_bus_number (device), + libusb_get_device_address (device)); + if (devNum < 0 ) + { + DEBUG_LOG(WII_IPC_HID, "Too many snakes on thsi motherfucking plane."); + // too many devices to handle. + continue; + } DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d, Error: %d",desc.idVendor, desc.idProduct, devNum, dRet); - OffsetStart = OffsetBuffer; OffsetBuffer += 4; // skip length for now, fill at end - Memory::Write_U32( d /*devNum*/, OffsetBuffer); //write device num + Memory::Write_U32( devNum , OffsetBuffer); //write device num OffsetBuffer += 4; WiiHIDDeviceDescriptor wii_device; @@ -464,9 +493,21 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) libusb_device_handle *handle = NULL; ssize_t cnt; + if(devNum >= MAX_DEVICE_DEVNUM) + return NULL; + if (open_devices.find(devNum) != open_devices.end()) { - return open_devices[devNum]; + handle = open_devices[devNum]; + if(libusb_kernel_driver_active(handle, 0) != LIBUSB_ERROR_NO_DEVICE) + { + return handle; + } + else + { + libusb_close(handle); + open_devices.erase(devNum); + } } cnt = libusb_get_device_list(NULL, &list); @@ -476,23 +517,46 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) for (i = 0; i < cnt; i++) { libusb_device *device = list[i]; - int ret = libusb_open(device, &handle); - if (ret) + struct libusb_device_descriptor desc; + int dRet = libusb_get_device_descriptor (device, &desc); + u8 bus = libusb_get_bus_number (device); + u8 port = libusb_get_device_address (device); + u64 unique_id = ((u64)desc.idVendor << 32) | (desc.idProduct << 16) | (bus << 8) | port; + if (hidDeviceAliases[devNum] == unique_id) { + int ret = libusb_open(device, &handle); + if (ret) + { + if (ret == LIBUSB_ERROR_ACCESS) + { + if( dRet ) + { + DEBUG_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID ????:???? (couldn't get id).", + bus, + port + ); + } + else{ + DEBUG_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID %04X:%04X.", + bus, + port, + desc.idVendor, + desc.idProduct + ); + } + } + else + { + DEBUG_LOG(WII_IPC_HID, "Failed to open device with error = %d", ret); + } + continue; + } - DEBUG_LOG(WII_IPC_HID, "Failed to open device with error = %d", ret); - continue; - } - - // u32 deviceID = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); - if (i == devNum) - { open_devices[devNum] = handle; break; } else { - libusb_close(handle); handle = NULL; } } @@ -502,3 +566,29 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) return handle; } + + +int CWII_IPC_HLE_Device_hid::GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port) +{ + int i; + int pos = -1; + u64 unique_id = ((u64)idVendor << 32) | (idProduct << 16) | (bus << 8) | port; + for (i=0; i< MAX_DEVICE_DEVNUM; i++) + { + u64 id = hidDeviceAliases[i]; + if(id == 0 && pos == -1) + { + pos = i; + } + else if (id == unique_id) + { + return i; + } + } + if(pos != -1) + { + hidDeviceAliases[pos] = unique_id; + return pos; + } + return -1; +} diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index c776d4bb7a..1ab9a95875 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -115,6 +115,7 @@ private: void FillOutDevices(u32 BufferOut, u32 BufferOutSize); + int GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port); bool ClaimDevice(libusb_device_handle * dev); -- cgit v1.2.3 From 5240d2877662af026e93c0f0e589482abba689ab Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 31 Dec 2012 01:50:16 +1300 Subject: Small fixes. --- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 9108a971a4..41f1a9976c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -115,16 +115,7 @@ u32 CWII_IPC_HLE_Device_hid::Update() Memory::Write_U32(ret, ev->enq_address + 4); WII_IPC_HLE_Interface::EnqReply(ev->enq_address); work_done = ev_finished = true; -} - -if (replyAddress != 0){ - FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); - WII_IPC_HLE_Interface::EnqReply(replyAddress); - replyAddress = 0; - hasRun = false; -} - - + } break; } } @@ -235,8 +226,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ReturnValue = -4; } - //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - // requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } @@ -287,8 +278,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) event_list.push_back(ev); return false; */ - //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - // Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); break; } -- cgit v1.2.3 From 21fa664c2d9aac2277fdb8326babbe19dce8e226 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 31 Dec 2012 03:51:34 +1300 Subject: Hopefully fix win32 build issues. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 6 ++++-- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 1 + Source/VSProps/Dolphin.Win32.props | 4 ++-- Source/VSProps/Dolphin.x64.props | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 59f5a638cf..9a47e97d0c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -51,7 +51,7 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC #include "WII_IPC_HLE_Device_usb_kbd.h" #include "WII_IPC_HLE_Device_sdio_slot0.h" -#ifdef __LIBUSB__ +#if defined(__LIBUSB__) || defined (_WIN32) #include "WII_IPC_HLE_Device_hid.h" #endif @@ -117,8 +117,10 @@ void Init() g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++; - #ifdef __LIBUSB__ + #if defined(__LIBUSB__) || defined(_WIN32) g_DeviceMap[i] = new CWII_IPC_HLE_Device_hid(i, std::string("/dev/usb/hid")); i++; + #else + g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++; #endif g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++; g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 41f1a9976c..70e379bfca 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -457,6 +457,7 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) else { DEBUG_LOG(WII_IPC_HID, "Could not open the device %d", cRet); + hidDeviceAliases[devNum] = 0; deviceValid = false; OffsetBuffer = OffsetStart; } diff --git a/Source/VSProps/Dolphin.Win32.props b/Source/VSProps/Dolphin.Win32.props index 77e7131a92..78e145b6d6 100644 --- a/Source/VSProps/Dolphin.Win32.props +++ b/Source/VSProps/Dolphin.Win32.props @@ -8,8 +8,8 @@ ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;libusb-1.0.lib;%(AdditionalDependencies) + libusb-1.0.lib;portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew32s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies) - + \ No newline at end of file diff --git a/Source/VSProps/Dolphin.x64.props b/Source/VSProps/Dolphin.x64.props index d5a97aa693..5fe05be766 100644 --- a/Source/VSProps/Dolphin.x64.props +++ b/Source/VSProps/Dolphin.x64.props @@ -9,8 +9,8 @@ ..\..\..\Externals\SDL\$(PlatformName);..\..\..\Externals\GLew;..\..\..\Externals\Cg64;..\..\..\Externals\portaudio\$(PlatformName)\$(ConfigurationName);..\..\..\Externals\libusb\$(PlatformName) - portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;libusb.lib;libusb-1.0.lib;%(AdditionalDependencies) + libusb-1.0.lib;portaudio.lib;dsound.lib;dxerr.lib;iphlpapi.lib;winmm.lib;setupapi.lib;xinput.lib;vfw32.lib;cg.lib;cgGL.lib;opengl32.lib;glew64s.lib;glu32.lib;rpcrt4.lib;comctl32.lib;%(AdditionalDependencies) - + \ No newline at end of file -- cgit v1.2.3 From c1b8aa75f29025a0d1b1043a572a8e4fd537ce36 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 31 Dec 2012 18:05:38 +1300 Subject: Tidy up and fix for my Windows crash :D --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 89 +++++++++------------- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 4 + 2 files changed, 41 insertions(+), 52 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 70e379bfca..f06bd98313 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -196,22 +196,13 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u16 size = Memory::Read_U16(BufferIn+0x1A); u32 data = Memory::Read_U32(BufferIn+0x1C); - //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - // requestType, request, BufferIn, BufferInSize, BufferOut, BufferOutSize); - + ReturnValue = HIDERR_NO_DEVICE_FOUND; + libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); if (dev_handle == NULL) { DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num); - ReturnValue = -4; - break; - } - - if (!ClaimDevice(dev_handle)) - { - DEBUG_LOG(WII_IPC_HID, "Could not claim the device for handle: %X", dev_num); - ReturnValue = -4; break; } @@ -221,10 +212,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ret += sizeof(libusb_control_setup); ReturnValue = ret; } - else - { - ReturnValue = -4; - } DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); @@ -242,21 +229,14 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) u32 length = Memory::Read_U32(BufferIn+0x18); u32 data = Memory::Read_U32(BufferIn+0x1C); - //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); + + ReturnValue = HIDERR_NO_DEVICE_FOUND; + libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); if (dev_handle == NULL) { DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num); - ReturnValue = -4; - break; - } - - if (!ClaimDevice(dev_handle)) - { - DEBUG_LOG(WII_IPC_HID, "Could not claim the device for handle: %X", dev_num); - ReturnValue = -4; break; } @@ -265,19 +245,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { ReturnValue = transfered; } - else - { - ReturnValue = -4; - } - /* - _hidevent ev; - ev.enq_address = _CommandAddress; - ev.type = Parameter; - ev.context = context; - event_list.push_back(ev); - return false; - */ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); @@ -302,7 +270,6 @@ bool CWII_IPC_HLE_Device_hid::ClaimDevice(libusb_device_handle * dev) int ret = 0; if ((ret = libusb_kernel_driver_active(dev, 0)) == 1) { - //DEBUG_LOG(WII_IPC_HID, "Kernel has the interface, gtfo kernel!"); if ((ret = libusb_detach_kernel_driver(dev, 0)) && ret != LIBUSB_ERROR_NOT_SUPPORTED) { DEBUG_LOG(WII_IPC_HID, "libusb_detach_kernel_driver failed with error: %d", ret); @@ -384,27 +351,31 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) libusb_device **list; //libusb_device *found = NULL; ssize_t cnt = libusb_get_device_list(NULL, &list); - DEBUG_LOG(WII_IPC_HID, "Hello plane???? %ld", cnt); + DEBUG_LOG(WII_IPC_HID, "Found %ld viable USB devices.", cnt); for (d = 0; d < cnt; d++) { libusb_device *device = list[d]; struct libusb_device_descriptor desc; int dRet = libusb_get_device_descriptor (device, &desc); - - //u32 devNum = (libusb_get_bus_number (device) << 8) | libusb_get_device_address (device); - + if (dRet) + { + // could not aquire the descriptor, no point in trying to use it. + DEBUG_LOG(WII_IPC_HID, "libusb_get_device_descriptor failed with error: %d", dRet); + continue; + } int devNum = GetAvaiableDevNum(desc.idVendor, desc.idProduct, libusb_get_bus_number (device), libusb_get_device_address (device)); if (devNum < 0 ) { - DEBUG_LOG(WII_IPC_HID, "Too many snakes on thsi motherfucking plane."); // too many devices to handle. + ERROR_LOG(WII_IPC_HID, "Exhausted device list, you have way too many usb devices plugged in." + "Or it might be our fault. Let us know at https://code.google.com/p/dolphin-emu/issues/entry?template=Defect%%20report"); continue; } - DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d, Error: %d",desc.idVendor, desc.idProduct, devNum, dRet); + DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d", desc.idVendor, desc.idProduct, devNum); OffsetStart = OffsetBuffer; OffsetBuffer += 4; // skip length for now, fill at end @@ -416,18 +387,21 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4)); OffsetBuffer += Align(wii_device.bLength, 4); bool deviceValid = true; + for (c = 0; deviceValid && c < desc.bNumConfigurations; c++) { struct libusb_config_descriptor *config = NULL; int cRet = libusb_get_config_descriptor(device, c, &config); - if(cRet == 0) + + // do not try to use usb devices with more than one interface, games can crash + if(cRet == 0 && config->bNumInterfaces <= MAX_HID_INTERFACES) { WiiHIDConfigDescriptor wii_config; ConvertConfigToWii(&wii_config, config); Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4)); OffsetBuffer += Align(wii_config.bLength, 4); - - for (ic = 0; ic < config->bNumInterfaces; ic++) + + for (ic = 0; ic < config->bNumInterfaces; ic++) { const struct libusb_interface *interfaceContainer = &config->interface[ic]; for (i = 0; i < interfaceContainer->num_altsetting; i++) @@ -456,13 +430,16 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) } else { - DEBUG_LOG(WII_IPC_HID, "Could not open the device %d", cRet); + if(cRet) + DEBUG_LOG(WII_IPC_HID, "libusb_get_config_descriptor failed with: %d", cRet); hidDeviceAliases[devNum] = 0; deviceValid = false; OffsetBuffer = OffsetStart; } } // configs - Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length + + if (deviceValid) + Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length } @@ -523,13 +500,13 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) { if( dRet ) { - DEBUG_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID ????:???? (couldn't get id).", + ERROR_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID ????:???? (couldn't get id).", bus, port ); } else{ - DEBUG_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID %04X:%04X.", + ERROR_LOG(WII_IPC_HID, "Dolphin does not have access to this device: Bus %03d Device %03d: ID %04X:%04X.", bus, port, desc.idVendor, @@ -539,11 +516,19 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) } else { - DEBUG_LOG(WII_IPC_HID, "Failed to open device with error = %d", ret); + ERROR_LOG(WII_IPC_HID, "libusb_open failed to open device with error = %d", ret); } continue; } + + if (!ClaimDevice(handle)) + { + ERROR_LOG(WII_IPC_HID, "Could not claim the device for handle: %X", devNum); + libusb_close(handle); + continue; + } + open_devices[devNum] = handle; break; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index 1ab9a95875..51057d536c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -22,6 +22,10 @@ #include "libusb.h" #include +#define MAX_HID_INTERFACES 1 + +#define HIDERR_NO_DEVICE_FOUND -4 + /* Connection timed out */ class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device -- cgit v1.2.3 From 90ce6ad3718637a51bfd2cd83656f80ada149b63 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 31 Dec 2012 18:15:52 +1300 Subject: Better warning for windows. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index f06bd98313..22c08d6baf 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -514,6 +514,12 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) ); } } +#ifdef _WIN32 + else if (ret == LIBUSB_ERROR_NOT_SUPPORTED) + { + WARN_LOG(WII_IPC_HID, "Please install the libusb drivers for the device %04X:%04X", ret, desc.idVendor, desc.idProduct); + } +#endif else { ERROR_LOG(WII_IPC_HID, "libusb_open failed to open device with error = %d", ret); -- cgit v1.2.3 From cda82eb1fca49434ef8fdb16e5aa7bb4816dd86e Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 31 Dec 2012 18:20:16 +1300 Subject: Left in a ret value. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 22c08d6baf..47b267f574 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -517,7 +517,7 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) #ifdef _WIN32 else if (ret == LIBUSB_ERROR_NOT_SUPPORTED) { - WARN_LOG(WII_IPC_HID, "Please install the libusb drivers for the device %04X:%04X", ret, desc.idVendor, desc.idProduct); + WARN_LOG(WII_IPC_HID, "Please install the libusb drivers for the device %04X:%04X", desc.idVendor, desc.idProduct); } #endif else -- cgit v1.2.3 From 40a6649dfeb3c0ac9e96eb8327051034d42894ad Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Mon, 31 Dec 2012 20:51:10 +1300 Subject: Fix unique_id creation, damn sign extension! Cleanup removed devices. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 126 +++++++++------------ .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 3 +- 2 files changed, 56 insertions(+), 73 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 47b267f574..2e7b56efc6 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -88,43 +88,9 @@ u32 CWII_IPC_HLE_Device_hid::Update() } } - timeToFill+=2; + timeToFill+=8; work_done = 1; - - //int ret = -4; - //timeval tv; - - - //libusb_handle_events_timeout_completed(NULL, &tv, NULL); - /* - std::list<_hidevent>::iterator ev = event_list.begin(); - while (ev != event_list.end()) { - - bool ev_finished = false; - - - switch (ev->type) - { - case IOCTL_HID_INTERRUPT_OUT: - case IOCTL_HID_INTERRUPT_IN: - { - ret = usb_reap_async_nocancel(ev->context, 0); - if(ret >= 0) - { - Memory::Write_U32(ret, ev->enq_address + 4); - WII_IPC_HLE_Interface::EnqReply(ev->enq_address); - work_done = ev_finished = true; - } - break; - } - } - - if (ev_finished) - event_list.erase(ev++); - else - ev++; - }*/ return work_done; } @@ -143,17 +109,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, BufferInSize, BufferOut, BufferOutSize); - //Memory::Write_U32(0xFFFFFFFF, BufferOut); - if(!hasRun) - { - FillOutDevices(BufferOut, BufferOutSize); - hasRun = true; - } - else - { - replyAddress = _CommandAddress; - return false; - } + replyAddress = _CommandAddress; + return false; break; } case IOCTL_HID_OPEN: @@ -213,8 +170,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ReturnValue = ret; } - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); + DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i) = %d", + requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize, ret); break; } @@ -343,6 +300,7 @@ void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *des void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { + static u16 check = 1; int OffsetBuffer = BufferOut; int OffsetStart = 0; //int OffsetDevice = 0; @@ -363,24 +321,10 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) DEBUG_LOG(WII_IPC_HID, "libusb_get_device_descriptor failed with error: %d", dRet); continue; } - int devNum = GetAvaiableDevNum(desc.idVendor, - desc.idProduct, - libusb_get_bus_number (device), - libusb_get_device_address (device)); - if (devNum < 0 ) - { - // too many devices to handle. - ERROR_LOG(WII_IPC_HID, "Exhausted device list, you have way too many usb devices plugged in." - "Or it might be our fault. Let us know at https://code.google.com/p/dolphin-emu/issues/entry?template=Defect%%20report"); - continue; - } - - DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d", desc.idVendor, desc.idProduct, devNum); OffsetStart = OffsetBuffer; OffsetBuffer += 4; // skip length for now, fill at end - Memory::Write_U32( devNum , OffsetBuffer); //write device num - OffsetBuffer += 4; + OffsetBuffer += 4; // skip devNum for now WiiHIDDeviceDescriptor wii_device; ConvertDeviceToWii(&wii_device, &desc); @@ -432,17 +376,54 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) { if(cRet) DEBUG_LOG(WII_IPC_HID, "libusb_get_config_descriptor failed with: %d", cRet); - hidDeviceAliases[devNum] = 0; deviceValid = false; OffsetBuffer = OffsetStart; } } // configs if (deviceValid) + { Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length - + + int devNum = GetAvaiableDevNum(desc.idVendor, + desc.idProduct, + libusb_get_bus_number (device), + libusb_get_device_address (device), + check); + if (devNum < 0 ) + { + // too many devices to handle. + ERROR_LOG(WII_IPC_HID, "Exhausted device list, you have way too many usb devices plugged in." + "Or it might be our fault. Let us know at https://code.google.com/p/dolphin-emu/issues/entry?template=Defect%%20report"); + OffsetBuffer = OffsetStart; + continue; + } + + DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %X Product: %X Devnum: %d", desc.idVendor, desc.idProduct, devNum); + + Memory::Write_U32(devNum , OffsetStart+4); //write device num + } } + // Find devices that no longer exists and free them + for (i=0; i> 48); + if(hidDeviceAliases[i] != 0 && check_cur != check) + { + DEBUG_LOG(WII_IPC_HID, "Removing: device %d %hX %hX", i, check, check_cur); + if (open_devices.find(i) != open_devices.end()) + { + libusb_device_handle *handle = open_devices[i]; + libusb_close(handle); + open_devices.erase(i); + } + hidDeviceAliases[i] = 0; + } + } + check++; + + libusb_free_device_list(list, 1); Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices @@ -490,8 +471,8 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) int dRet = libusb_get_device_descriptor (device, &desc); u8 bus = libusb_get_bus_number (device); u8 port = libusb_get_device_address (device); - u64 unique_id = ((u64)desc.idVendor << 32) | (desc.idProduct << 16) | (bus << 8) | port; - if (hidDeviceAliases[devNum] == unique_id) + u64 unique_id = ((u64)desc.idVendor << 32) | ((u64)desc.idProduct << 16) | ((u64)bus << 8) | (u64)port; + if ((hidDeviceAliases[devNum] & HID_ID_MASK) == unique_id) { int ret = libusb_open(device, &handle); if (ret) @@ -551,26 +532,27 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) } -int CWII_IPC_HLE_Device_hid::GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port) +int CWII_IPC_HLE_Device_hid::GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check) { int i; int pos = -1; - u64 unique_id = ((u64)idVendor << 32) | (idProduct << 16) | (bus << 8) | port; - for (i=0; i< MAX_DEVICE_DEVNUM; i++) + u64 unique_id = ((u64)idVendor << 32) | ((u64)idProduct << 16) | ((u64)bus << 8) | (u64)port; + for (i=0; i +#define HID_ID_MASK 0x0000FFFFFFFFFFFF #define MAX_HID_INTERFACES 1 #define HIDERR_NO_DEVICE_FOUND -4 @@ -119,7 +120,7 @@ private: void FillOutDevices(u32 BufferOut, u32 BufferOutSize); - int GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port); + int GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check); bool ClaimDevice(libusb_device_handle * dev); -- cgit v1.2.3 From f695f088a748008c8341c10b41301bb3bd43747b Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 1 Jan 2013 16:53:59 +1300 Subject: Add usb thread to check for usb updates. --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 34 +++++++++++++++++++++- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 7 +++-- 2 files changed, 38 insertions(+), 3 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index 2e7b56efc6..b0b3f349aa 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -21,20 +21,52 @@ #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device_hid.h" #include "errno.h" -#include + +#if defined(_MSC_VER) || defined(__MINGW32__) +# include +#ifndef _TIMEVAL_DEFINED /* also in winsock[2].h */ +#define _TIMEVAL_DEFINED +struct timeval { + long tv_sec; + long tv_usec; +}; +#endif /* _TIMEVAL_DEFINED */ +#else +# include +#endif #define MAX_DEVICE_DEVNUM 256 static u64 hidDeviceAliases[MAX_DEVICE_DEVNUM]; +// Regular thread +void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) +{ + timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 500; + + while (hid->usb_thread_running) + libusb_handle_events_timeout(NULL, &tv); + + return; +} + + CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) { memset(hidDeviceAliases, 0, sizeof(hidDeviceAliases)); libusb_init(NULL); + + usb_thread_running = true; + usb_thread = std::thread(checkUsbUpdates, this); } CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() { + usb_thread_running = false; + usb_thread.join(); + for ( std::map::const_iterator iter = open_devices.begin(); iter != open_devices.end(); ++iter ) { libusb_close(iter->second); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index 2acc2e0e7f..58c3c88da2 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -20,6 +20,7 @@ #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device.h" #include "libusb.h" +#include "Thread.h" #include #define HID_ID_MASK 0x0000FFFFFFFFFFFF @@ -130,11 +131,13 @@ private: void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, const struct libusb_endpoint_descriptor *src); int Align(int num, int alignment); - + static void checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid); + struct libusb_device_handle * GetDeviceByDevNum(u32 devNum); std::map open_devices; std::map device_identifiers; - + std::thread usb_thread; + bool usb_thread_running; typedef struct { -- cgit v1.2.3 From d3f199273b2fec600af1017ddfae37873a3e47f7 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 1 Jan 2013 19:23:45 +1300 Subject: Fix warning level... someone let me commit this to master ;D --- Source/Core/Common/Src/Log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source') diff --git a/Source/Core/Common/Src/Log.h b/Source/Core/Common/Src/Log.h index 9664387cf0..8ae845b303 100644 --- a/Source/Core/Common/Src/Log.h +++ b/Source/Core/Common/Src/Log.h @@ -98,7 +98,7 @@ void GenericLog(LOGTYPES_LEVELS level, LOGTYPES_TYPE type, ; #if defined LOGGING || defined _DEBUG || defined DEBUGFAST -#define MAX_LOGLEVEL DEBUG_LEVEL +#define MAX_LOGLEVEL WARNING_LEVEL #else #ifndef MAX_LOGLEVEL #define MAX_LOGLEVEL DEBUG_LEVEL -- cgit v1.2.3 From 8fdc8af1cb83381228c04c60021eb9d2abe30761 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 1 Jan 2013 19:24:00 +1300 Subject: Thread safe enq_reply. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 9a47e97d0c..fc2118ea20 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -83,6 +83,7 @@ IWII_IPC_HLE_Device* es_handles[ES_MAX_COUNT]; typedef std::deque ipc_msg_queue; static ipc_msg_queue request_queue; // ppc -> arm static ipc_msg_queue reply_queue; // arm -> ppc +static std::mutex s_reply_queue; void Init() { @@ -159,7 +160,12 @@ void Reset(bool _bHard) g_DeviceMap.erase(g_DeviceMap.begin(), g_DeviceMap.end()); } request_queue.clear(); - reply_queue.clear(); + + // lock due to using reply_queue + { + std::lock_guard lk(s_reply_queue); + reply_queue.clear(); + } } void Shutdown() @@ -241,6 +247,8 @@ IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName void DoState(PointerWrap &p) { + std::lock_guard lk(s_reply_queue); + p.Do(request_queue); p.Do(reply_queue); @@ -536,6 +544,7 @@ void EnqRequest(u32 _Address) // Called when IOS module has some reply void EnqReply(u32 _Address) { + std::lock_guard lk(s_reply_queue); reply_queue.push_back(_Address); } @@ -560,12 +569,16 @@ void Update() Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HLE, LogTypes::LDEBUG); #endif } - - if (reply_queue.size()) + + // lock due to using reply_queue { - WII_IPCInterface::GenerateReply(reply_queue.front()); - INFO_LOG(WII_IPC_HLE, "<<-- Reply to IPC Request @ 0x%08x", reply_queue.front()); - reply_queue.pop_front(); + std::lock_guard lk(s_reply_queue); + if (reply_queue.size()) + { + WII_IPCInterface::GenerateReply(reply_queue.front()); + INFO_LOG(WII_IPC_HLE, "<<-- Reply to IPC Request @ 0x%08x", reply_queue.front()); + reply_queue.pop_front(); + } } } -- cgit v1.2.3 From b5ec6609052d7c4f1d37cc2d7dd29a447cfaa6fa Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 1 Jan 2013 19:24:53 +1300 Subject: Async USB HID :D --- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 131 ++++++++++++--------- .../Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 4 + 2 files changed, 80 insertions(+), 55 deletions(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp index b0b3f349aa..2996cdf563 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp @@ -44,17 +44,58 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid) timeval tv; tv.tv_sec = 0; tv.tv_usec = 500; - while (hid->usb_thread_running) + { + + static u16 timeToFill = 0; + if (timeToFill == 0) + { + if (hid->deviceCommandAddress != 0){ + hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18), Memory::Read_U32(hid->deviceCommandAddress + 0x1C)); + + Memory::Write_U32(8, hid->deviceCommandAddress); + // IOS seems to write back the command that was responded to + Memory::Write_U32(/*COMMAND_IOCTL*/ 6, hid->deviceCommandAddress + 8); + + // Return value + Memory::Write_U32(0, hid->deviceCommandAddress + 4); + + WII_IPC_HLE_Interface::EnqReply(hid->deviceCommandAddress); + hid->deviceCommandAddress = 0; + } + } + timeToFill+=8; libusb_handle_events_timeout(NULL, &tv); + } return; } +void CWII_IPC_HLE_Device_hid::handleUsbUpdates(struct libusb_transfer *transfer) +{ + int ret = HIDERR_NO_DEVICE_FOUND; + u32 replyAddress = (u32)(size_t)transfer->user_data; + if (transfer->status == LIBUSB_TRANSFER_COMPLETED) + { + ret = transfer->length; + } + + Memory::Write_U32(8, replyAddress); + // IOS seems to write back the command that was responded to + Memory::Write_U32(/*COMMAND_IOCTL*/ 6, replyAddress + 8); + + // Return value + Memory::Write_U32(ret, replyAddress + 4); + + WII_IPC_HLE_Interface::EnqReply(replyAddress); + //DEBUG_LOG(WII_IPC_HID, "OMG OMG OMG I GOT A CALLBACK, IMMA BE FAMOUS %d %d %d", transfer->actual_length, transfer->length, transfer->status); +} + CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) { + deviceCommandAddress = 0; memset(hidDeviceAliases, 0, sizeof(hidDeviceAliases)); libusb_init(NULL); @@ -94,35 +135,10 @@ bool CWII_IPC_HLE_Device_hid::Close(u32 _CommandAddress, bool _bForce) return true; } -static u32 replyAddress = 0; -static bool hasRun = false; - u32 CWII_IPC_HLE_Device_hid::Update() { - static u16 timeToFill = 0; - u32 work_done = 0; - - if (timeToFill == 0) - { - if (replyAddress != 0){ - FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); - - Memory::Write_U32(8, replyAddress); - // IOS seems to write back the command that was responded to - Memory::Write_U32(/*COMMAND_IOCTL*/ 6, replyAddress + 8); - - // Return value - Memory::Write_U32(0, replyAddress + 4); - - WII_IPC_HLE_Interface::EnqReply(replyAddress); - replyAddress = 0; - hasRun = false; - } - } - timeToFill+=8; - - work_done = 1; + u32 work_done = 0; return work_done; } @@ -141,7 +157,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) { DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", BufferIn, BufferInSize, BufferOut, BufferOutSize); - replyAddress = _CommandAddress; + deviceCommandAddress = _CommandAddress; return false; break; } @@ -175,14 +191,13 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) ERROR CODES: -4 Cant find device specified */ - int ret = -1; u32 dev_num = Memory::Read_U32(BufferIn+0x10); - u8 requestType = Memory::Read_U8(BufferIn+0x14); - u8 request = Memory::Read_U8(BufferIn+0x15); - u16 value = Memory::Read_U16(BufferIn+0x16); - u16 index = Memory::Read_U16(BufferIn+0x18); - u16 size = Memory::Read_U16(BufferIn+0x1A); + 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); ReturnValue = HIDERR_NO_DEVICE_FOUND; @@ -194,25 +209,25 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num); break; } + struct libusb_transfer *transfer = libusb_alloc_transfer(0); + transfer->flags |= LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER; - ret = libusb_control_transfer (dev_handle, requestType, request, value, index, (unsigned char*)Memory::GetPointer(data), size, 0); - if(ret>=0) - { - ret += sizeof(libusb_control_setup); - ReturnValue = ret; - } - - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i) = %d", - requestType, request, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize, ret); + u8 * buffer = (u8*)malloc(wLength + LIBUSB_CONTROL_SETUP_SIZE); + libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength); + memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, Memory::GetPointer(data), wLength); + libusb_fill_control_transfer(transfer, dev_handle, buffer, handleUsbUpdates, (void*)(size_t)_CommandAddress, /* no timeout */ 0); + libusb_submit_transfer(transfer); + + //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", + // bmRequestType, bRequest, BufferIn, BufferInSize, BufferOut, BufferOutSize); + // It's the async way! + return false; break; } case IOCTL_HID_INTERRUPT_OUT: case IOCTL_HID_INTERRUPT_IN: { - - int transfered = 0; - int ret; u32 dev_num = Memory::Read_U32(BufferIn+0x10); u32 endpoint = Memory::Read_U32(BufferIn+0x14); u32 length = Memory::Read_U32(BufferIn+0x18); @@ -229,15 +244,17 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) break; } - ret = libusb_interrupt_transfer(dev_handle, endpoint, (unsigned char*)Memory::GetPointer(data), length, &transfered, 40 ); - if(ret == 0) - { - ReturnValue = transfered; - } - - DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt %s)(%d,%d,%X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", - Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize); - + 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); + 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 false; break; } default: @@ -444,6 +461,7 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize) if(hidDeviceAliases[i] != 0 && check_cur != check) { DEBUG_LOG(WII_IPC_HID, "Removing: device %d %hX %hX", i, check, check_cur); + std::lock_guard lk(s_open_devices); if (open_devices.find(i) != open_devices.end()) { libusb_device_handle *handle = open_devices[i]; @@ -478,6 +496,9 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum) if(devNum >= MAX_DEVICE_DEVNUM) return NULL; + + std::lock_guard lk(s_open_devices); + if (open_devices.find(devNum) != open_devices.end()) { handle = open_devices[devNum]; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index 58c3c88da2..b0b1dbda46 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -120,6 +120,7 @@ private: } WiiHIDEndpointDescriptor; + u32 deviceCommandAddress; void FillOutDevices(u32 BufferOut, u32 BufferOutSize); int GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check); @@ -132,10 +133,13 @@ private: int Align(int num, int alignment); static void checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid); + static void handleUsbUpdates(struct libusb_transfer *transfer); struct libusb_device_handle * GetDeviceByDevNum(u32 devNum); std::map open_devices; + std::mutex s_open_devices; std::map device_identifiers; + std::thread usb_thread; bool usb_thread_running; -- cgit v1.2.3 From 08cc460e963f50361678a4b207d8d0c7db349e12 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 1 Jan 2013 19:49:45 +1300 Subject: This was not obvious from API docs :( Fixed Win32 builds. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source') diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h index b0b1dbda46..3cf9d9add2 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h @@ -133,7 +133,7 @@ private: int Align(int num, int alignment); static void checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid); - static void handleUsbUpdates(struct libusb_transfer *transfer); + static void LIBUSB_CALL handleUsbUpdates(struct libusb_transfer *transfer); struct libusb_device_handle * GetDeviceByDevNum(u32 devNum); std::map open_devices; -- cgit v1.2.3