Only call HIDSetup/HidTeardown once
== DETAILS I did a minimalist edit of the HID thread that stripped out all HID* syscalls, and this stopped the crashing. I then re-added just the HIDSetup() and HIDTeardown() calls, and the crash came back. This smells like an OS bug. To work around it, I've put the HIDSetup() and HIDTeardown() calls into the app init/shutdown section, so they only get called once in the application lifetime and not each time the input driver is initialized.
This commit is contained in:
parent
d0368124e6
commit
1beba28d02
|
@ -49,7 +49,7 @@
|
|||
#include "system/memory.h"
|
||||
#include "system/exception_handler.h"
|
||||
#include <sys/iosupport.h>
|
||||
|
||||
#include <wiiu/syshid.h>
|
||||
#include <wiiu/os/foreground.h>
|
||||
#include <wiiu/gx2/event.h>
|
||||
#include <wiiu/procui.h>
|
||||
|
@ -641,9 +641,16 @@ void _start(int argc, char **argv)
|
|||
memoryInitialize();
|
||||
__init();
|
||||
fsdev_init();
|
||||
#ifdef HAVE_HID
|
||||
HIDSetup();
|
||||
#endif
|
||||
|
||||
main(argc, argv);
|
||||
|
||||
#ifdef HAVE_HID
|
||||
HIDTeardown();
|
||||
#endif
|
||||
|
||||
fsdev_exit();
|
||||
|
||||
/* TODO: fix elf2rpl so it doesn't error with "Could not find matching symbol
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
|
||||
#include "../input_defines.h"
|
||||
#include "../input_driver.h"
|
||||
#include "../connect/joypad_connection.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#define POLL_THREAD_SLEEP 10000
|
||||
<<<<<<< HEAD
|
||||
|
@ -37,9 +39,18 @@ typedef struct wiiu_hid_user wiiu_hid_user_t;
|
|||
struct wiiu_hid_user
|
||||
{
|
||||
wiiu_hid_user_t *next;
|
||||
uint8_t *buffer;
|
||||
uint32_t transfersize;
|
||||
uint8_t *send_control_buffer;
|
||||
uint8_t *send_control_type;
|
||||
|
||||
uint32_t handle;
|
||||
uint32_t physical_device_inst;
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
uint8_t interface_index;
|
||||
uint8_t sub_class;
|
||||
uint8_t protocol;
|
||||
uint16_t max_packet_size_rx;
|
||||
uint16_t max_packet_size_tx;
|
||||
};
|
||||
|
||||
typedef struct wiiu_hid
|
||||
|
@ -53,6 +64,7 @@ typedef struct wiiu_hid
|
|||
} wiiu_hid_t;
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
|
||||
<<<<<<< HEAD
|
||||
#define DEVICE_UNUSED 0
|
||||
#define DEVICE_USED 1
|
||||
|
||||
|
@ -96,6 +108,9 @@ static OSFastMutex *new_fastmutex(const char *name);
|
|||
static void delete_fastmutex(OSFastMutex *mutex);
|
||||
|
||||
static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach);
|
||||
=======
|
||||
//static int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach);
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
static void start_polling_thread(wiiu_hid_t *hid);
|
||||
static void stop_polling_thread(wiiu_hid_t *hid);
|
||||
static int wiiu_hid_polling_thread(int argc, const char **argv);
|
||||
|
@ -106,7 +121,10 @@ static void enqueue_device(void);
|
|||
=======
|
||||
>>>>>>> Start implementing HID polling thread
|
||||
|
||||
static void enqueue_device(void);
|
||||
//HIDClient *new_hidclient(void);
|
||||
//void delete_hidclient(HIDClient *client);
|
||||
wiiu_hid_t *new_hid(void);
|
||||
void delete_hid(wiiu_hid_t *hid);
|
||||
|
||||
/**
|
||||
* HID driver entrypoints registered with hid_driver_t
|
||||
|
@ -119,7 +137,7 @@ static bool wiiu_hid_joypad_query(void *data, unsigned pad)
|
|||
|
||||
static const char *wiiu_hid_joypad_name(void *data, unsigned pad)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint64_t wiiu_hid_joypad_get_buttons(void *data, unsigned port)
|
||||
|
@ -161,32 +179,30 @@ static int16_t wiiu_hid_joypad_axis(void *data, unsigned port, uint32_t joyaxis)
|
|||
|
||||
static void *wiiu_hid_init(void)
|
||||
{
|
||||
wiiu_hid_t *hid = new_wiiu_hid_t();
|
||||
HIDClient *client = new_hidclient();
|
||||
wiiu_hid_t *hid = new_hid();
|
||||
// HIDClient *client = new_hidclient();
|
||||
|
||||
if(!hid || !client)
|
||||
// if(!hid || !client)
|
||||
if(!hid)
|
||||
goto error;
|
||||
|
||||
start_polling_thread(hid);
|
||||
if(hid->polling_thread == NULL)
|
||||
goto error;
|
||||
|
||||
HIDAddClient(client, wiiu_attach_callback);
|
||||
hid->client = client;
|
||||
// HIDAddClient(client, wiiu_attach_callback);
|
||||
// hid->client = client;
|
||||
|
||||
return hid;
|
||||
|
||||
error:
|
||||
if(hid) {
|
||||
stop_polling_thread(hid);
|
||||
delete_wiiu_hid_t(hid);
|
||||
}
|
||||
if(client)
|
||||
delete_hidclient(client);
|
||||
if(pad_list_mutex) {
|
||||
delete_fastmutex(pad_list_mutex);
|
||||
pad_list_mutex = NULL;
|
||||
delete_hid(hid);
|
||||
}
|
||||
// if(client) {
|
||||
// delete_hidclient(client);
|
||||
// }
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -197,6 +213,7 @@ static void wiiu_hid_free(void *data)
|
|||
|
||||
if (hid) {
|
||||
stop_polling_thread(hid);
|
||||
<<<<<<< HEAD
|
||||
delete_wiiu_hid_t(hid);
|
||||
}
|
||||
}
|
||||
|
@ -212,6 +229,9 @@ static void free_pad_list(void) {
|
|||
top = pad_list;
|
||||
pad_list = top->next;
|
||||
delete_wiiu_hid_user_t(top);
|
||||
=======
|
||||
delete_hid(hid);
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,14 +254,14 @@ static void wiiu_hid_poll(void *data)
|
|||
|
||||
static void start_polling_thread(wiiu_hid_t *hid) {
|
||||
OSThreadAttributes attributes = OS_THREAD_ATTRIB_AFFINITY_CPU2 |
|
||||
OS_THREAD_ATTRIB_DETACHED |
|
||||
OS_THREAD_ATTRIB_STACK_USAGE;
|
||||
int32_t stack_size = 0x8000;
|
||||
// wild-ass guess. the patcher thread used 28 for the network threads (10 for BOTW).
|
||||
int32_t priority = 19;
|
||||
int32_t priority = 10;
|
||||
OSThread *thread = memalign(8, sizeof(OSThread));
|
||||
void *stack = memalign(32, stack_size);
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
@ -257,6 +277,9 @@ static void start_polling_thread(wiiu_hid_t *hid) {
|
|||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
if(!thread || !stack)
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
goto error;
|
||||
|
||||
if(!OSCreateThread(thread, wiiu_hid_polling_thread, 1, (char *)hid, stack, stack_size, priority, attributes))
|
||||
|
@ -268,6 +291,7 @@ static void start_polling_thread(wiiu_hid_t *hid) {
|
|||
|
||||
error:
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
if(pad_list_mutex)
|
||||
delete_fastmutex(pad_list_mutex);
|
||||
|
@ -277,6 +301,8 @@ static void start_polling_thread(wiiu_hid_t *hid) {
|
|||
if(pad_list_mutex)
|
||||
delete_fastmutex(pad_list_mutex);
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
if(stack)
|
||||
free(stack);
|
||||
if(thread)
|
||||
|
@ -298,6 +324,7 @@ static void stop_polling_thread(wiiu_hid_t *hid) {
|
|||
free(hid->polling_thread_stack);
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
|
||||
|
@ -310,6 +337,8 @@ static void stop_polling_thread(wiiu_hid_t *hid) {
|
|||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -331,6 +360,7 @@ static void wiiu_hid_do_poll(wiiu_hid_t *hid) {
|
|||
usleep(POLL_THREAD_SLEEP);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
@ -357,19 +387,21 @@ int32_t wiiu_detach_device(HIDClient *client, HIDDevice *device) {
|
|||
>>>>>>> Start implementing HID polling thread
|
||||
=======
|
||||
>>>>>>> More progress on the HID driver
|
||||
=======
|
||||
>>>>>>> Only call HIDSetup/HidTeardown once
|
||||
/**
|
||||
* Callbacks
|
||||
*/
|
||||
|
||||
/*
|
||||
int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t attach) {
|
||||
int32_t result = DEVICE_UNUSED;
|
||||
|
||||
switch(attach) {
|
||||
case HID_DEVICE_ATTACH:
|
||||
result = wiiu_attach_device(client, device);
|
||||
RARCH_LOG("Device attached\n");
|
||||
break;
|
||||
case HID_DEVICE_DETACH:
|
||||
result = wiiu_detach_device(client, device);
|
||||
RARCH_LOG("Device detached\n");
|
||||
break;
|
||||
default:
|
||||
// Undefined behavior, bail out
|
||||
|
@ -378,91 +410,41 @@ int32_t wiiu_attach_callback(HIDClient *client, HIDDevice *device, uint32_t atta
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void wiiu_read_callback(uint32_t handle, int32_t errno, unsigned char *buffer, uint32_t transferred, void *usr) {
|
||||
}
|
||||
|
||||
static void wiiu_write_callback(uint32_t handle, int32_t errno, unsigned char *buffer, uint32_t transferred, void *usr) {
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Allocation/deallocation
|
||||
* Allocation
|
||||
*/
|
||||
|
||||
static wiiu_hid_t *new_wiiu_hid_t(void) {
|
||||
wiiu_hid_t *hid = (wiiu_hid_t*)calloc(1, sizeof(wiiu_hid_t));
|
||||
|
||||
if(!hid)
|
||||
goto error;
|
||||
|
||||
memset(hid, 0, sizeof(wiiu_hid_t));
|
||||
wiiu_hid_t *new_hid(void) {
|
||||
wiiu_hid_t *hid = calloc(1, sizeof(wiiu_hid_t));
|
||||
if(hid)
|
||||
memset(hid, 0, sizeof(wiiu_hid_t));
|
||||
|
||||
return hid;
|
||||
|
||||
error:
|
||||
if(hid)
|
||||
delete_wiiu_hid_t(hid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void delete_wiiu_hid_t(wiiu_hid_t *hid) {
|
||||
if(!hid)
|
||||
return;
|
||||
void delete_hid(wiiu_hid_t *hid) {
|
||||
if(hid) {
|
||||
if(hid->polling_thread_stack)
|
||||
free(hid->polling_thread_stack);
|
||||
|
||||
if(hid->client) {
|
||||
HIDDelClient(hid->client);
|
||||
delete_hidclient(hid->client);
|
||||
hid->client = NULL;
|
||||
free(hid);
|
||||
}
|
||||
|
||||
free(hid);
|
||||
}
|
||||
|
||||
static HIDClient *new_hidclient(void) {
|
||||
HIDClient *client = calloc(1, sizeof(HIDClient));
|
||||
if(client != NULL) {
|
||||
/*
|
||||
HIDClient *new_hidclient(void) {
|
||||
HIDClient *client = memalign(32, sizeof(HIDClient));
|
||||
if(client)
|
||||
memset(client, 0, sizeof(HIDClient));
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
static OSFastMutex *new_fastmutex(const char *name) {
|
||||
OSFastMutex *mutex = calloc(1, sizeof(OSFastMutex));
|
||||
if(mutex != NULL) {
|
||||
memset(mutex, 0, sizeof(OSFastMutex));
|
||||
}
|
||||
|
||||
OSFastMutex_Init(mutex, name);
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
static void delete_hidclient(HIDClient *client) {
|
||||
void delete_hidclient(HIDClient *client) {
|
||||
if(client)
|
||||
free(client);
|
||||
}
|
||||
|
||||
static wiiu_hid_user_t *new_wiiu_hid_user_t(void) {
|
||||
wiiu_hid_user_t *user = calloc(1, sizeof(wiiu_hid_user_t));
|
||||
if(user != NULL) {
|
||||
memset(user, 0, sizeof(wiiu_hid_user_t));
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
static void delete_wiiu_hid_user_t(wiiu_hid_user_t *user) {
|
||||
if(user) {
|
||||
free(user);
|
||||
}
|
||||
}
|
||||
|
||||
static void delete_fastmutex(OSFastMutex *mutex) {
|
||||
if(mutex)
|
||||
free(mutex);
|
||||
}
|
||||
|
||||
*/
|
||||
hid_driver_t wiiu_hid = {
|
||||
wiiu_hid_init,
|
||||
wiiu_hid_joypad_query,
|
||||
|
@ -473,5 +455,5 @@ hid_driver_t wiiu_hid = {
|
|||
wiiu_hid_poll,
|
||||
wiiu_hid_joypad_rumble,
|
||||
wiiu_hid_joypad_name,
|
||||
"wiiu",
|
||||
"wiiu_usb",
|
||||
};
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
#define GAMEPAD_OFFSET 0
|
||||
|
||||
static const hid_driver_t *hid_driver = NULL;
|
||||
|
||||
static uint64_t pad_state[MAX_PADS];
|
||||
static uint8_t pad_type[MAX_PADS-1] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE};
|
||||
|
||||
|
@ -299,6 +301,7 @@ static void wiiu_joypad_poll(void)
|
|||
|
||||
static bool wiiu_joypad_init(void* data)
|
||||
{
|
||||
hid_driver = input_hid_init_first();
|
||||
wiiu_joypad_autodetect_add(0);
|
||||
|
||||
wiiu_joypad_poll();
|
||||
|
@ -315,6 +318,11 @@ static bool wiiu_joypad_query_pad(unsigned pad)
|
|||
|
||||
static void wiiu_joypad_destroy(void)
|
||||
{
|
||||
if(hid_driver) {
|
||||
hid_driver->free(hid_driver_get_data());
|
||||
hid_driver_reset_data();
|
||||
hid_driver = NULL;
|
||||
}
|
||||
wiiu_pad_inited = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,10 @@ static input_device_driver_t *joypad_drivers[] = {
|
|||
#ifdef DJGPP
|
||||
&dos_joypad,
|
||||
#endif
|
||||
#ifdef HAVE_HID
|
||||
// Selecting the HID gamepad driver disables the Wii U gamepad. So while
|
||||
// we want the HID code to be compiled & linked, we don't want the driver
|
||||
// to be selectable in the UI.
|
||||
#if defined(HAVE_HID) && !defined(WIIU)
|
||||
&hid_joypad,
|
||||
#endif
|
||||
&null_joypad,
|
||||
|
@ -1829,6 +1832,14 @@ const void *hid_driver_get_data(void)
|
|||
return hid_data;
|
||||
}
|
||||
|
||||
// This is only to be called after we've invoked free() on the
|
||||
// HID driver; the memory will have already been freed, so we need to
|
||||
// reset the pointer.
|
||||
void hid_driver_reset_data(void)
|
||||
{
|
||||
hid_data = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* hid_driver_find_ident:
|
||||
* @idx : index of driver to get handle to.
|
||||
|
|
|
@ -647,6 +647,7 @@ const char* config_get_hid_driver_options(void);
|
|||
const hid_driver_t *input_hid_init_first(void);
|
||||
|
||||
const void *hid_driver_get_data(void);
|
||||
void hid_driver_reset_data(void);
|
||||
#endif
|
||||
|
||||
/** Line complete callback.
|
||||
|
|
Loading…
Reference in New Issue