== DETAILS
The Wii U GC adapter doesn't seem to like doing async reads if it is connected
via a USB hub. It seems to be device-specific, though, because my DS3 works
just fine through the same hub.
I tried creating a fallback to synchronous reads, but it resulted in a hard
lock of the system. So, for the time being, it's going to be a known
limitation. Might be solved by using a powered USB hub.
Learned that the cache alignment is 64, not 32, so the alignment math has
been updated. Thanks, @aliaspider for that info.
== DETAILS
TIL that it's bad to call synchronization code from callbacks.
To avoid that, I made the following changes:
- Implemented an atomic swap (see previous commit) to avoid explicit
locking when working with the event list
- ensure locks are only acquired in either the main thread or the
I/O polling thread
- use an explicit polling loop; we still use async reads, but the
read doesn't immediately re-invoke itself.
- remove the sleep in the polling thread.
- remove unnecessary locking in the thread cleanup call--verified that
the list can't be modified while it is being executed.
== TESTING
I tested locally, and was able to disconnect/reconnect USB devices several times without the worker thread getting deadlocked.
== DETAILS
- fix the bitshift math
- read the right bytes out of the ds3 data packet
- remove verbose logging in critical path
- stop caring about errors in the hid read loop -- seems to just
be benign "device not ready" -- or at least, that's what I'm assuming
given that the read eventually succeeds.
== TESTING
Played Mario 3 with the DS3 with no issues.
== DETAILS
- update to not try starting the read loop until after the device
is successfully initialized
- add new HID wrapper macros needed by ds3 driver
- add some debug logging to help with troubleshooting
- add button map for DS3
== TESTING
Tested with local build. DS3 init is not working.
== DETAILS
Now that I have a working implementation, it's time to tidy up a bit:
- there was no need for the HID subsystem's object data to have a reference
to the global hid state (since it's global), so removed it.
- refactored the users of that member to use the global state, defining
reusable macros.
- reorganized the information in *.h files
- removing the hid state also made the constructor changes to the hid driver
unneeded, so I reverted those changes.
== TESTING
Confirmed clean build. Haven't tested the build yet to make sure everything
still works, though.
== DETAILS
- Added a new method to the joypad_connection_t interface for
getting a single button
- wired everything into the hidpad driver
- for testing purposes, hacking the top-level joypad driver
so that kpad isn't used
- add a new RARCH_LOG_BUFFER method to verbosity for logging the
contents of a binary buffer (useful for writing/debugging pad drivers)
- fix a few bugs in the wiiu GC pad driver
The button mapping isn't quite right, and I'm not sure what's
going wrong.
== DETAILS
Trying to do weird pad math just wasn't working so I bit the bullet and just
let it allocate all 16 pads in the slot list, then just mark 0-4 as
connected so that the slot allocator would start at 5.
I can see it detect the pad, but no idea if it works. Out of time for
today.
== DETAILS
Turns out freeing memory that's already been freed is.. bad.
Fix two double-free instances; one due to over-freeing and the other
due to wrong order-of-operations causing a double free.
Also updated logging a little.
== TESTING
The GC adapter still clobbers slot 0, but the "emergency exit" sequence
works to quit RA cleanly.
== DETAILS
(I think)
- Uncomment the call in the read loop to start feeding packets to the
driver
- implement the GCA packet driver
- implement the pad interface
- fix indentations in GCA driver
== TESTING
Compiles. Haven't tested yet.
== 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.
== DETAILS
We're at a point where we need to do more than just
clean up a local data structure, so I've started
implementing the "detach" part of the code so that
everything gets cleaned up properly.
Also, added error handling inside the polling
thread.
== TESTING
Have not tested yet.
== DETAILS
I've created the concept of a hid_driver_instance_t which is basically
a central place to store the hid pad driver, hid subsystem driver,
the pad list, and the instance data for the above in a central location.
The HID pad device drivers can use it to perform HID operations in a
generic manner.
This is more-or-less a pause point so I can catch up with upstream.
== TESTING
Haven't tested this yet. Compiles without warnings though!
== DETAILS
- detect() methods in device_* files now check for VID/PID
instead of just returning false
- add "name" field on hid device, mainly for logging purposes
== TESTING
Verified my WiiU GC adapter detected properly
== DETAILS
- Add *.swp to gitignore so editor swap files don't get committed
- Remove unneeded commented-out defines from WiiU build
- Start on fix for DSI when switching cores on WiiU
== TESTING
Sigh. I'm back at "System Memory error", which makes me think the problem
might be the SD card. (On the plus side, I manually verified the hash so
at least the copy process is working).
So, that's to say that I can't actually test to see if the DSI error is
fixed.
== DETAILS
TIL that the "max_packet_size_*" fields in the HIDDevice struct
are actually requirements, not maximums.
The reason HIDRead() was blocking was because the HIDWrite() that
sent the activation command was silently failing.
The reason HIDWrite() was silently failing was because I was using too
small of a buffer for the device.
In this case: the Wii U GC adapter, which has a "max" tx packet size of 5.
"max" is misleading. You actually have to write all 5 bytes.
Which means: copying the 1-byte buffer to the 5-byte buffer, and writing
the 5-byte buffer via HIDWrite().
So, in summary:
- Use correct semantics for HIDWrite() so that HIDRead() can work.
- Update the OSThread struct to reflect the current knowledge over at
WUT. It's unlikely this was actually causing a problem, but never
hurts to be more correct.
== TESTING
I temporarily enabled the call to log_buffer() and confirmed that the
GC adapter's state is successfully being read.
== DETAILS
This should fix#6025.
After confirming that dummying out the init block of the HID subsystem
driver eliminated the crash, I narrowed it down to the event loop.
And that's when I noticed that, when the thread consumes the event,
it doesn't free it.
Oops.
Updated the event loop to free the event after it has been processed.
== TESTING
Local build, was able to load multiple ROMs in succession where prior
I was getting the system memory errors.
I've #if 0'd out a call to HIDRead that is still getting deadlocked,
because it slows down the startup/shutdown process.
== DETAILS
If a call to HIDRead() ends up blocking indefinitely, it will
cause the shutdown process to wait forever.
To avoid a deadlock, I've put in a retry counter so that it will
give up after 5s and print a warning to the log.
== DETAILS
RetroArch's general HID drivers are intended as a full-on substitute for
other input drivers such as XInput, DInput, SDL, etc. The Wii U port is,
to my knowledge, the first case of heterogenous input drivers working
concurrently.
As such, I've moved things around:
- The HID driver source is moved into the wiiu/input/ directory alongside
the joypad subdrivers.
- We no longer use the input_hid_init_first() method to instantiate; instead
we just init the wiiu HID driver directly.
- The HID pad driver and HID subsystem driver enjoy a tighter coupling,
mainly having to do with the initialization of the joypad connections
list, because there's no way to inform the HID driver's init() method
how many slots to allocate.
== TESTING
Will test in a moment, but at least it compiles cleanly. ;)