* Move logic around tracking transfers to asyncio.c.
* Add a "short buffer" holding 0-3 bytes between writes, so that the
driver performs only 4-byte writes in the FIFO and a short write in
the commit, if needed.
- This is partially due to me thinking at some point that degrading
writing size was impossible, but it might actually be possible by
writing to FIFO/FIFO+2 or FIFO/FIFO+1/FIFO+2/FIFO+3.
- In any case I think this new approach wins on performance.
* Get rid of unit_size since we now always use 4 bytes.
* Add a waiting function which is used in usb_close() (and once tested
should be used in world switches too).
* Eliminate some of the special cases for the DCP, though not all (in
particular I can't get the commit to rely on the BEMP interrupt yet,
nor can I properly clear PID to NAK when unbinding).
* Finish updating the register list
* Use RTC-based timeouts to not involve more interrupts
* Be a lot more conservative about PID=BUF
* Start setting up parameters and checking invariants for future
bidirectional communications
* Add options to RESET, go to menu, or abort()
* Define weak symbols for driver functions so that low-level debugging
add-ins can be linked with minimal drivers (CPU/INTC/MMU)
We're not using them yet (specifically in fxlink) because timeouts
leave the pipes in undesirable states that currently end up crashing.
Some reset mechanism is needed, plus support from the protocol for
canceling messages, etc.
When the driver goes through a world switch a reconnection with the host
is needed before operations can resume. This requires usb_open_status to
be reset.
Also: bind a FIFO before a commit that involves data transfer, mirroring
what happens in writes. This ensures that PID is set to BUF, mainly.
Performing an asynchronous commit on an inactive pipe would yield
USB_COMMIT_INACTVE and *not* invoke the callback (as intended),
which usb_commit_sync() ignored, causing a freeze.
This issue appeared after a world switch, which (for reasons not yet
known) appear to fail the first writes until a commit, and that commit
would then hit an inactive pipe.
Having repeat settings only for getkey() meant that repeats that occur
while getkey() is not running (i.e., all of them) would be lost. This is
due to e57efb5e3 which replaced on-demand repeats with normal event
generation.
Now the settings are applied globally, which allows repeats to be
enabled even when getkey() is not active. This also reduces the feature
gap between getkey() and raw events, which reduces the risk of running
into edges cases by using both.
The previous API is retained for source compatibility until gint 3.0 but
the changes are now applied globally so the semantics are slightly
different.