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.
This commit is contained in:
Matthew Parlane 2012-12-30 16:57:37 +13:00
parent 13bd235c11
commit 3b459fb500
6 changed files with 85 additions and 80 deletions

View File

@ -427,11 +427,11 @@ else(SDL2_FOUND)
endif(SDL_FOUND) endif(SDL_FOUND)
endif(SDL2_FOUND) endif(SDL2_FOUND)
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") include(FindLibUSB OPTIONAL)
include(FindLibUSB OPTIONAL)
endif()
if(LIBUSB_FOUND) if(LIBUSB_FOUND)
message("Using shared LibUSB") message("Using shared LibUSB")
add_definitions(-D__LIBUSB__)
include_directories(${LIBUSB_INCLUDE_DIR}) include_directories(${LIBUSB_INCLUDE_DIR})
else(LIBUSB_FOUND) else(LIBUSB_FOUND)

View File

@ -16,6 +16,7 @@ if (NOT LIBUSB_FOUND)
${LIBUSB_PKG_INCLUDE_DIRS} ${LIBUSB_PKG_INCLUDE_DIRS}
/usr/include/libusb-1.0 /usr/include/libusb-1.0
/usr/include /usr/include
/usr/local/include/libusb-1.0
/usr/local/include /usr/local/include
) )

View File

@ -70,8 +70,8 @@ set(SRCS Src/ActionReplay.cpp
Src/HW/CPU.cpp Src/HW/CPU.cpp
Src/HW/DSP.cpp Src/HW/DSP.cpp
Src/HW/DSPHLE/UCodes/UCode_AX.cpp Src/HW/DSPHLE/UCodes/UCode_AX.cpp
Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp Src/HW/DSPHLE/UCodes/UCode_AXWii.cpp
Src/HW/DSPHLE/UCodes/UCode_NewAXWii.cpp Src/HW/DSPHLE/UCodes/UCode_NewAXWii.cpp
Src/HW/DSPHLE/UCodes/UCode_CARD.cpp Src/HW/DSPHLE/UCodes/UCode_CARD.cpp
Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp Src/HW/DSPHLE/UCodes/UCode_InitAudioSystem.cpp
Src/HW/DSPHLE/UCodes/UCode_ROM.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_es.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.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_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_net.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp
Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp
@ -202,7 +201,8 @@ endif()
if(LIBUSB_FOUND) if(LIBUSB_FOUND)
# Using shared LibUSB # 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) endif(LIBUSB_FOUND)
if(WIN32) if(WIN32)

View File

@ -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.h"
#include "WII_IPC_HLE_Device_usb_kbd.h" #include "WII_IPC_HLE_Device_usb_kbd.h"
#include "WII_IPC_HLE_Device_sdio_slot0.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 "FileUtil.h" // For Copy
#include "../ConfigManager.h" #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_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_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/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 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++; g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++;
} }

View File

@ -20,26 +20,23 @@
#include "../HW/WII_IPC.h" #include "../HW/WII_IPC.h"
#include "WII_IPC_HLE.h" #include "WII_IPC_HLE.h"
#include "WII_IPC_HLE_Device_hid.h" #include "WII_IPC_HLE_Device_hid.h"
#include "libusb.h"
#include "errno.h" #include "errno.h"
#include <time.h> #include <time.h>
CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName) CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
{ {
//usb_init(); /* initialize the library */
libusb_init(NULL); libusb_init(NULL);
} }
CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid() 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(); open_devices.clear();
*/
libusb_exit(NULL); libusb_exit(NULL);
} }
@ -146,20 +143,19 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
BufferIn, BufferInSize, BufferOut, BufferOutSize); BufferIn, BufferInSize, BufferOut, BufferOutSize);
// not actually implemented in IOS // not actually implemented in IOS
ReturnValue = 0; ReturnValue = 0;
if (replyAddress != 0){ if (replyAddress != 0){
FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C));
WII_IPC_HLE_Interface::EnqReply(replyAddress); WII_IPC_HLE_Interface::EnqReply(replyAddress);
replyAddress = 0; replyAddress = 0;
hasRun = false; hasRun = false;
} }
break; break;
} }
case IOCTL_HID_CANCEL_INTERRUPT: case IOCTL_HID_CANCEL_INTERRUPT:
{ {
DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
BufferIn, BufferInSize, BufferOut, BufferOutSize); BufferIn, BufferInSize, BufferOut, BufferOutSize);
ReturnValue = 0;
if (replyAddress != 0){ if (replyAddress != 0){
FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C)); FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C));
@ -168,7 +164,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
hasRun = false; hasRun = false;
} }
ReturnValue = 0;
break; break;
} }
case IOCTL_HID_CONTROL: case IOCTL_HID_CONTROL:
@ -178,7 +173,6 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
-4 Cant find device specified -4 Cant find device specified
*/ */
int ret = -1; int ret = -1;
int worked = 32;
u32 dev_num = Memory::Read_U32(BufferIn+0x10); u32 dev_num = Memory::Read_U32(BufferIn+0x10);
u8 requestType = Memory::Read_U8(BufferIn+0x14); 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); u16 size = Memory::Read_U16(BufferIn+0x1A);
u32 data = Memory::Read_U32(BufferIn+0x1C); 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)", //DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
// requestType, request, BufferIn, BufferInSize, BufferOut, BufferOutSize); // requestType, request, BufferIn, BufferInSize, BufferOut, BufferOutSize);
@ -197,29 +189,14 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
if (dev_handle == NULL) if (dev_handle == NULL)
{ {
DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num);
ReturnValue = -4; ReturnValue = -4;
break; break;
} }
/*ReturnValue = usb_control_msg(dev_handle, requesttype, request, if (!ClaimDevice(dev_handle))
value, index, (char*)Memory::GetPointer(data), size,
0);
*/
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, "Could not claim the device for handle: %X", dev_num);
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);
ReturnValue = -4; ReturnValue = -4;
break; break;
} }
@ -230,6 +207,10 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
ret += sizeof(libusb_control_setup); ret += sizeof(libusb_control_setup);
ReturnValue = ret; ReturnValue = ret;
} }
else
{
ReturnValue = -4;
}
DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)", 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);
@ -241,8 +222,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
{ {
int transfered = 0; int transfered = 0;
int checkme = 34; int ret;
int worked = 35;
u32 dev_num = Memory::Read_U32(BufferIn+0x10); u32 dev_num = Memory::Read_U32(BufferIn+0x10);
u32 endpoint = Memory::Read_U32(BufferIn+0x14); u32 endpoint = Memory::Read_U32(BufferIn+0x14);
u32 length = Memory::Read_U32(BufferIn+0x18); 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); 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)", //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); // Parameter == IOCTL_HID_INTERRUPT_IN ? "In" : "Out", endpoint, length, data, BufferIn, BufferInSize, BufferOut, BufferOutSize);
ReturnValue = -4;
libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num); libusb_device_handle * dev_handle = GetDeviceByDevNum(dev_num);
if (dev_handle == NULL) if (dev_handle == NULL)
{ {
DEBUG_LOG(WII_IPC_HID, "Could not find handle: %X", dev_num);
ReturnValue = -4; ReturnValue = -4;
goto int_in_end_print; break;
}
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 (!ClaimDevice(dev_handle))
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; ReturnValue = -4;
goto int_in_end_print; break;
} }
checkme = 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, 20 );
if(checkme == 0) if(ret == 0)
{ {
ReturnValue = transfered; ReturnValue = transfered;
} }
else
{
ReturnValue = -4;
}
/* /*
_hidevent ev; _hidevent ev;
@ -291,11 +264,8 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
event_list.push_back(ev); event_list.push_back(ev);
return false; 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);
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);
break; 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) 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) libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum)
{ {
int i; u32 i;
libusb_device **list; libusb_device **list;
libusb_device_handle *handle = NULL; libusb_device_handle *handle = NULL;
ssize_t cnt; ssize_t cnt;
@ -494,8 +491,7 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum)
continue; 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) if (i == devNum)
{ {
open_devices[devNum] = handle; open_devices[devNum] = handle;

View File

@ -19,6 +19,7 @@
#include "WII_IPC_HLE.h" #include "WII_IPC_HLE.h"
#include "WII_IPC_HLE_Device.h" #include "WII_IPC_HLE_Device.h"
#include "libusb.h"
#include <list> #include <list>
/* Connection timed out */ /* Connection timed out */
@ -115,6 +116,8 @@ private:
void FillOutDevices(u32 BufferOut, u32 BufferOutSize); void FillOutDevices(u32 BufferOut, u32 BufferOutSize);
bool ClaimDevice(libusb_device_handle * dev);
void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, const struct libusb_device_descriptor *src); void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, const struct libusb_device_descriptor *src);
void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, const struct libusb_config_descriptor *src); void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, const struct libusb_config_descriptor *src);
void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, const struct libusb_interface_descriptor *src); void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, const struct libusb_interface_descriptor *src);