mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
Fix up HID device driver initialization
== DETAILS Turns out the cause of the crash was a bad cast, resulting in a function call to nowhere. Also, I think the DSI exception handler only works on the primary core; when this was happening in the background thread, I got a black screen error instead. Next up: finishing up the GCA driver.
This commit is contained in:
parent
dc6f4c23ed
commit
180d6a28bf
@ -21,7 +21,7 @@ struct ds3_instance {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
static void *ds3_init(hid_driver_instance_t *hid_driver)
|
||||
static void *ds3_init(void *handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ struct ds4_instance {
|
||||
void *handle;
|
||||
};
|
||||
|
||||
static void *ds4_init(hid_driver_instance_t *hid_driver)
|
||||
static void *ds4_init(void *handle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ static uint8_t activation_packet[] = { 0x13 };
|
||||
#define GCA_PORT_CONNECTED 0x14
|
||||
|
||||
typedef struct wiiu_gca_instance {
|
||||
hid_driver_instance_t *driver;
|
||||
void *handle;
|
||||
bool online;
|
||||
uint8_t device_state[37];
|
||||
joypad_connection_t *pads[4];
|
||||
@ -39,17 +39,29 @@ static void unregister_pad(wiiu_gca_instance_t *instance, int slot);
|
||||
|
||||
extern pad_connection_interface_t wiiu_gca_pad_connection;
|
||||
|
||||
static void *wiiu_gca_init(hid_driver_instance_t *driver)
|
||||
static void *wiiu_gca_init(void *handle)
|
||||
{
|
||||
RARCH_LOG("[gca]: allocating driver instance...\n");
|
||||
wiiu_gca_instance_t *instance = calloc(1, sizeof(wiiu_gca_instance_t));
|
||||
if(instance == NULL) goto error;
|
||||
RARCH_LOG("[gca]: zeroing memory...\n");
|
||||
memset(instance, 0, sizeof(wiiu_gca_instance_t));
|
||||
instance->driver = driver;
|
||||
instance->handle = handle;
|
||||
|
||||
driver->os_driver->send_control(driver->os_driver_data, activation_packet, sizeof(activation_packet));
|
||||
driver->os_driver->read(driver->os_driver_data, instance->device_state, sizeof(instance->device_state));
|
||||
RARCH_LOG("[gca]: sending activation packet to device...\n");
|
||||
hid_instance.os_driver->send_control(handle, activation_packet, sizeof(activation_packet));
|
||||
RARCH_LOG("[gca]: reading initial state packet...\n");
|
||||
hid_instance.os_driver->read(handle, instance->device_state, sizeof(instance->device_state));
|
||||
instance->online = true;
|
||||
|
||||
RARCH_LOG("[gca]: init done\n");
|
||||
return instance;
|
||||
|
||||
error:
|
||||
RARCH_ERR("[gca]: init failed\n");
|
||||
if(instance)
|
||||
free(instance);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wiiu_gca_free(void *data) {
|
||||
@ -110,15 +122,15 @@ static joypad_connection_t *register_pad(wiiu_gca_instance_t *instance) {
|
||||
if(!instance || !instance->online)
|
||||
return NULL;
|
||||
|
||||
slot = pad_connection_find_vacant_pad(instance->driver->pad_list);
|
||||
slot = pad_connection_find_vacant_pad(hid_instance.pad_list);
|
||||
if(slot < 0)
|
||||
return NULL;
|
||||
|
||||
result = &(instance->driver->pad_list[slot]);
|
||||
result = &(hid_instance.pad_list[slot]);
|
||||
result->iface = &wiiu_gca_pad_connection;
|
||||
result->data = result->iface->init(instance, slot, instance->driver->os_driver);
|
||||
result->data = result->iface->init(instance, slot, hid_instance.os_driver);
|
||||
result->connected = true;
|
||||
input_pad_connect(slot, instance->driver->pad_driver);
|
||||
input_pad_connect(slot, hid_instance.pad_driver);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -20,9 +20,10 @@
|
||||
#include "../../input_driver.h"
|
||||
#include "../../connect/joypad_connection.h"
|
||||
#include "../../include/hid_driver.h"
|
||||
#include "../../../verbosity.h"
|
||||
|
||||
typedef struct hid_device {
|
||||
void *(*init)(hid_driver_instance_t *driver);
|
||||
void *(*init)(void *handle);
|
||||
void (*free)(void *data);
|
||||
void (*handle_packet)(void *data, uint8_t *buffer, size_t size);
|
||||
bool (*detect)(uint16_t vid, uint16_t pid);
|
||||
|
@ -108,10 +108,8 @@ static int16_t hidpad_axis(unsigned pad, uint32_t axis)
|
||||
|
||||
static void hidpad_poll(void)
|
||||
{
|
||||
#if 0
|
||||
if (ready)
|
||||
hid_driver->poll(hid_data);
|
||||
#endif
|
||||
hid_instance.os_driver->poll(hid_instance.os_driver_data);
|
||||
}
|
||||
|
||||
static const char *hidpad_name(unsigned pad)
|
||||
|
@ -134,7 +134,11 @@ static void wiiu_hid_free(const void *data)
|
||||
|
||||
static void wiiu_hid_poll(void *data)
|
||||
{
|
||||
(void)data;
|
||||
wiiu_hid_t *hid = (wiiu_hid_t *)data;
|
||||
if(hid == NULL)
|
||||
return;
|
||||
|
||||
synchronized_process_adapters(hid);
|
||||
}
|
||||
|
||||
static void wiiu_hid_send_control(void *data, uint8_t *buf, size_t size)
|
||||
@ -310,6 +314,46 @@ static void log_device(HIDDevice *device)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t try_init_driver(wiiu_adapter_t *adapter)
|
||||
{
|
||||
adapter->driver_handle = adapter->driver->init(adapter);
|
||||
if(adapter->driver_handle == NULL) {
|
||||
RARCH_ERR("[hid]: Failed to initialize driver: %s\n",
|
||||
adapter->driver->name);
|
||||
return ADAPTER_STATE_DONE;
|
||||
}
|
||||
|
||||
return ADAPTER_STATE_READY;
|
||||
}
|
||||
|
||||
static void synchronized_process_adapters(wiiu_hid_t *hid)
|
||||
{
|
||||
wiiu_adapter_t *adapter = NULL;
|
||||
|
||||
OSFastMutex_Lock(&(adapters.lock));
|
||||
for(adapter = adapters.list; adapter != NULL; adapter = adapter->next)
|
||||
{
|
||||
switch(adapter->state)
|
||||
{
|
||||
case ADAPTER_STATE_DONE:
|
||||
break;
|
||||
case ADAPTER_STATE_NEW:
|
||||
adapter->state = try_init_driver(adapter);
|
||||
break;
|
||||
case ADAPTER_STATE_READY:
|
||||
case ADAPTER_STATE_READING:
|
||||
#if 0
|
||||
adapter->driver->poll();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
RARCH_ERR("[hid]: Invalid adapter state: %d\n", adapter->state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
OSFastMutex_Unlock(&(adapters.lock));
|
||||
}
|
||||
|
||||
static void synchronized_add_event(wiiu_attach_event *event)
|
||||
{
|
||||
OSFastMutex_Lock(&(events.lock));
|
||||
@ -413,12 +457,7 @@ static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event)
|
||||
|
||||
adapter->hid = hid;
|
||||
adapter->driver = event->driver;
|
||||
|
||||
adapter->driver_handle = adapter->driver->init(hid->driver);
|
||||
if(adapter->driver_handle == NULL) {
|
||||
RARCH_ERR("[hid]: Failed to initialize driver: %s\n",
|
||||
adapter->driver->name);
|
||||
}
|
||||
adapter->state = ADAPTER_STATE_NEW;
|
||||
|
||||
RARCH_LOG("[hid]: adding to adapter list\n");
|
||||
synchronized_add_to_adapters_list(adapter);
|
||||
@ -434,13 +473,11 @@ error:
|
||||
|
||||
void wiiu_start_read_loop(wiiu_adapter_t *adapter)
|
||||
{
|
||||
adapter->state = ADAPTER_STATE_READING;
|
||||
#if 0
|
||||
RARCH_LOG("HIDRead(0x%08x, 0x%08x, %d, 0x%08x, 0x%08x)\n",
|
||||
adapter->handle, adapter->rx_buffer, adapter->rx_size,
|
||||
wiiu_hid_read_loop_callback, adapter);
|
||||
#endif
|
||||
HIDRead(adapter->handle, adapter->rx_buffer, adapter->rx_size, wiiu_hid_read_loop_callback, adapter);
|
||||
HIDRead(adapter->handle,
|
||||
adapter->rx_buffer,
|
||||
adapter->rx_size,
|
||||
wiiu_hid_read_loop_callback,
|
||||
adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -493,32 +530,42 @@ static void log_buffer(uint8_t *data, uint32_t len)
|
||||
static void wiiu_hid_read_loop_callback(uint32_t handle, int32_t error,
|
||||
uint8_t *buffer, uint32_t buffer_size, void *userdata)
|
||||
{
|
||||
wiiu_adapter_t *adapter = (wiiu_adapter_t *)userdata;
|
||||
if(!adapter)
|
||||
{
|
||||
RARCH_ERR("read_loop_callback: bad userdata\n");
|
||||
return;
|
||||
}
|
||||
wiiu_adapter_t *adapter = (wiiu_adapter_t *)userdata;
|
||||
if(!adapter)
|
||||
{
|
||||
RARCH_ERR("read_loop_callback: bad userdata\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(adapter->hid->polling_thread_quit)
|
||||
{
|
||||
RARCH_LOG("Shutting down read loop for device: %s\n",
|
||||
if(adapter->hid->polling_thread_quit)
|
||||
{
|
||||
RARCH_LOG("Shutting down read loop for device: %s\n",
|
||||
adapter->driver->name);
|
||||
adapter->state = ADAPTER_STATE_DONE;
|
||||
return;
|
||||
}
|
||||
adapter->state = ADAPTER_STATE_DONE;
|
||||
}
|
||||
|
||||
if(error)
|
||||
{
|
||||
RARCH_ERR("Read failed with error 0x%08x\n", error);
|
||||
adapter->state = ADAPTER_STATE_DONE;
|
||||
return;
|
||||
}
|
||||
if(adapter->state == ADAPTER_STATE_READY ||
|
||||
adapter->state == ADAPTER_STATE_READING) {
|
||||
|
||||
adapter->driver->handle_packet(adapter->driver_handle, buffer, buffer_size);
|
||||
adapter->state = ADAPTER_STATE_READING;
|
||||
|
||||
adapter->state = ADAPTER_STATE_READING;
|
||||
HIDRead(adapter->handle, adapter->rx_buffer, adapter->rx_size,
|
||||
if(error)
|
||||
{
|
||||
int16_t r1 = (error & 0x0000FFFF);
|
||||
int16_t r2 = ((error & 0xFFFF0000) >> 16);
|
||||
RARCH_ERR("[hid]: read failed: %08x (%d:%d)\n", error, r2, r1);
|
||||
} else {
|
||||
#if 0
|
||||
adapter->driver->handle_packet(adapter->driver_handle, buffer, buffer_size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* this can also get set if something goes wrong in initialization */
|
||||
if(adapter->state == ADAPTER_STATE_DONE)
|
||||
return;
|
||||
|
||||
HIDRead(adapter->handle, adapter->rx_buffer, adapter->rx_size,
|
||||
wiiu_hid_read_loop_callback, adapter);
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,10 @@
|
||||
#define DEVICE_USED 1
|
||||
|
||||
#define ADAPTER_STATE_NEW 0
|
||||
#define ADAPTER_STATE_READING 1
|
||||
#define ADAPTER_STATE_DONE 2
|
||||
#define ADAPTER_STATE_READY 1
|
||||
#define ADAPTER_STATE_READING 2
|
||||
#define ADAPTER_STATE_DONE 3
|
||||
|
||||
|
||||
static void *alloc_zeroed(size_t alignment, size_t size);
|
||||
static OSThread *new_thread(void);
|
||||
@ -47,6 +49,7 @@ static wiiu_attach_event *synchronized_get_events_list(void);
|
||||
static void wiiu_handle_attach_events(wiiu_hid_t *hid, wiiu_attach_event *list);
|
||||
static void wiiu_hid_attach(wiiu_hid_t *hid, wiiu_attach_event *event);
|
||||
static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event);
|
||||
static void synchronized_process_adapters(wiiu_hid_t *hid);
|
||||
static void synchronized_add_to_adapters_list(wiiu_adapter_t *adapter);
|
||||
static wiiu_adapter_t *synchronized_remove_from_adapters_list(uint32_t handle);
|
||||
static void synchronized_add_event(wiiu_attach_event *event);
|
||||
|
Loading…
x
Reference in New Issue
Block a user