Skip to content

Commit

Permalink
Add better FindLibUsb support for MacOSX.
Browse files Browse the repository at this point in the history
Make LibUSB optional, don't compile HID support if it doesn't exist.
A lot less hacky. Works quite well on Ubuntu now.
  • Loading branch information
Parlane committed Dec 30, 2012
1 parent 13bd235 commit 3b459fb
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 69 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Expand Up @@ -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)

Expand Down
1 change: 1 addition & 0 deletions CMakeTests/FindLibUSB.cmake
Expand Up @@ -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
)

Expand Down
8 changes: 4 additions & 4 deletions Source/Core/Core/CMakeLists.txt
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 7 additions & 2 deletions Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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++;
}
Expand Down
116 changes: 56 additions & 60 deletions Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp
Expand Up @@ -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 <time.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 */
libusb_init(NULL);
}

CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid()
{
/*for ( std::map<u32,usb_dev_handle*>::const_iterator iter = open_devices.begin(); iter != open_devices.end(); ++iter )
for ( std::map<u32,libusb_device_handle*>::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);
}
Expand Down Expand Up @@ -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:
Expand All @@ -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);
Expand All @@ -188,38 +182,21 @@ 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);

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;
}

/*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;
}
Expand All @@ -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);
Expand All @@ -241,47 +222,39 @@ 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);

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;
Expand All @@ -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;
}
Expand All @@ -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)
{

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h
Expand Up @@ -19,6 +19,7 @@

#include "WII_IPC_HLE.h"
#include "WII_IPC_HLE_Device.h"
#include "libusb.h"
#include <list>

/* Connection timed out */
Expand Down Expand Up @@ -114,6 +115,8 @@ class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device


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);
Expand Down

0 comments on commit 3b459fb

Please sign in to comment.