From 3b459fb500b1a87532cc33b1c38363591c3b667f Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Sun, 30 Dec 2012 16:57:37 +1300 Subject: [PATCH] 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. --- CMakeLists.txt | 6 +- CMakeTests/FindLibUSB.cmake | 1 + Source/Core/Core/CMakeLists.txt | 8 +- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 9 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 138 +++++++++--------- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 3 + 6 files changed, 85 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d10ed2585..a2908d27b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -427,11 +427,11 @@ else(SDL2_FOUND) endif(SDL_FOUND) endif(SDL2_FOUND) -if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - include(FindLibUSB OPTIONAL) -endif() +include(FindLibUSB OPTIONAL) if(LIBUSB_FOUND) message("Using shared LibUSB") + + add_definitions(-D__LIBUSB__) include_directories(${LIBUSB_INCLUDE_DIR}) else(LIBUSB_FOUND) diff --git a/CMakeTests/FindLibUSB.cmake b/CMakeTests/FindLibUSB.cmake index 5d7af82e7a..789e6f8416 100644 --- a/CMakeTests/FindLibUSB.cmake +++ b/CMakeTests/FindLibUSB.cmake @@ -16,6 +16,7 @@ if (NOT LIBUSB_FOUND) ${LIBUSB_PKG_INCLUDE_DIRS} /usr/include/libusb-1.0 /usr/include + /usr/local/include/libusb-1.0 /usr/local/include ) 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,6 +143,19 @@ 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)); @@ -153,22 +163,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress) 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: @@ -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);