I tried the firmware you referred to and it does stop the reset errors. However I'm still suffering from a timeout fairly soon after starting. It looks like its my issue with memory corruption happening - if I force the keyboard module to be loaded much higher in memory I don't see any errors.
Thanks for the tip
Now I just have to track down a seemingly random memory write. I'm pretty certain its coming from inside CSUD. I've tried allocating 1MB before loading it, and set that 1MB to all 0xAAs. I check that memory before and after calling KeyboardPoll, and at some point that memory gets changed before the call returns. For example in my last attempt, I found that after calling KeyboardPoll repeatedly for two minutes the following gets written:
0x000f0000: 00000000 000000e4 aaaaaaaa aaaaaaaa
That could quite possibly be the USB host writing the result of a request, and somehow getting the memory location corrupted - or else for some reason CSUD is setting that address into the host register.
[Edit]another memory overwrite:
0x00050070: 00000000 000000e4 aaaaaaaa aaaaaaaa
[edit2] Its always one of these two addresses that get corrupted, apparently by the USB host writing to them, as there's nothing in the CSUD code writing to these addresses. I've checked that the DMA address set for USB operations (i.e. value written to 0x20980514) is always set to either 0x7bd8 (stack) or 0x139f28 (CSUD heap). However in the middle of waiting for a response from the USB keyboard, memory at either 0x000f0000 or 0x00050070 gets written with the response from the keyboard - in fact I've caught it happening with a key pressed and that value appears in this memory location.
[edit3] I've gone back to statically linking CSUD into my kernel and I still see these memory addresses getting written to.
So any clue as to why the USB host would write to one of these two specific fixed addresses?