mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
The rk27xx UDC driver was fixed and stress-tested on a generic rk2705 against the USB core of early 2026 - including a port to the control request API of that time. Meanwhile the core took over the EP0 state machine (usb_core_setup_received()) and endpoint allocation, and the driver was converted to both without the fixes. This carries them over. Transfers and resets (a mass-storage stress test fell off the bus after 10,000 - 27,000 operations without these): - Transfers are set up with interrupts disabled: the interrupt handler advances buf/cnt of the same endpoint for the next packet. - ep_write()'s wait for TXFULL to clear is bounded by an iteration count. It also runs in the interrupt handler, where current_tick never advances, so a tick timeout spun forever. - A bus reset cancels transfers - usb_drv_cancel_all_transfers() was empty - instead of re-initialising the completion semaphores, which loses a thread blocked on one for good; blocked senders are woken with an error and the enabled endpoints NAKed and flushed. The reset handler also calls usb_core_bus_reset(), which it never did. - Blocking sends time out after a second and report the error. - An ACK with no transfer armed (one cancelled by a reset) is ignored. Configuration: - The configuration number is DEV_INFO [11:8]; it was read as bits 10:7, bit 7 being DEV_EN, so configuration 1 was reported as 2. - The UDC completes SET_ADDRESS and SET_CONFIGURATION itself, raising no interrupt, so udc_helper() - which reports them from DEV_INFO - also runs from a tick task while the device is unconfigured. After a bus reset of a configured device the host re-sends SET_CONFIGURATION and goes straight to a bulk command that NAKs without interrupting: without the tick, the device never came back. EP0, with the core now running the control state machine: - Right after connect the UDC reports one SETUP with both registers zero; no host sends that, and it is ignored. - A SETUP clears a stall, and ends - reported to the core as failed - any EP0 transfer still in flight, which belongs to a request the host abandoned; otherwise the core would wait for it forever. EP0 stall uses the EP0 registers, not endpoints[0], a stub without registers. - Control reads are clipped to wLength and end with a zero length packet when a short answer fills whole packets. - The core arms status stages with no buffer; they land in a dummy one. - A status OUT arriving while the data IN is still going - the host took less than was offered - ends the data stage too. - At a bus reset EP0 transfers are dropped silently: the core resets its own EP0 state. Tested on a generic rk2705. The transfer, reset and configuration fixes first against the USB core of early 2026: RAM-disk, NAND and SD stress tests over USB mass storage, and usbreset recovery. Then the driver as it is here, on the current core: enumeration, and a mass-storage stress test of three LUNs at once (RAM disk, NAND, SD) that also passes after an eject and a cold power cycle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Change-Id: I1b2d03ca8f688f2a0e7b28ead64b7ab050a0a9e8 |
||
|---|---|---|
| .. | ||
| asm | ||
| common | ||
| drivers | ||
| export | ||
| include | ||
| kernel | ||
| libc | ||
| reggen | ||
| target | ||
| usbstack | ||
| arabjoin.c | ||
| arabjoin.h | ||
| ata_idle_notify.c | ||
| backlight-sw-fading.c | ||
| backlight.c | ||
| bidi.c | ||
| buflib_malloc.c | ||
| buflib_mempool.c | ||
| chunk_alloc.c | ||
| COPYING | ||
| core_alloc.c | ||
| debug.c | ||
| eeprom_settings.c | ||
| elf_loader.c | ||
| enc_base.c | ||
| events.c | ||
| firmware.make | ||
| font.c | ||
| font_cache.c | ||
| general.c | ||
| hangul.c | ||
| lc-rock.c | ||
| linuxboot.c | ||
| logf.c | ||
| lru.c | ||
| panic.c | ||
| pcm.c | ||
| pcm_mixer.c | ||
| pcm_sampr.c | ||
| pcm_sw_volume.c | ||
| powermgmt.c | ||
| profile.c | ||
| README | ||
| rolo.c | ||
| rom.lds | ||
| screendump.c | ||
| scroll_engine.c | ||
| sdmmc.c | ||
| sound.c | ||
| SOURCES | ||
| storage.c | ||
| system.c | ||
| timer.c | ||
| tuner.c | ||
| usb.c | ||
See docs/README