A host that is done with a mass-storage device - "safely remove", eject,
udisksctl power-off - sends START STOP UNIT with the start bit clear, and
may cut power right after. usb_storage only marked the LUN ejected.
Storage drivers can still hold data in RAM at that point: a flash
translation layer keeps part-written pages until a later write completes
them, and HAVE_STORAGE_FLUSH exists so they can be committed - but only
shutdown and ROLO called it. On a device unplugged after a proper eject
and then losing power, that data was lost although the host had done
everything right.
Call storage_flush() on stop and on eject, on targets that define
HAVE_STORAGE_FLUSH. The SCSI handler runs in the USB thread, as do the
reads and writes, so the flush cannot race them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I5b5811858c75dfb3ee89535ab59f4a19663945df
Thanks for the SET_ADDRESS rework. I think it leaves one case uncovered:
a host whose first request is SET_ADDRESS ends up with a device whose
interfaces are all numbered 0.
Two things still depend on the core seeing a request before the address arrives:
1. usb_core assigns interfaces and endpoints only on the first control
request it handles in DEFAULT. When SET_ADDRESS comes first, the driver
completes it and usb_core_set_address() moves the state to ADDRESS. So
allocate_interfaces_and_endpoints() never runs.
2. Under USB_DETECT_BY_REQUEST, usb.c enables the class drivers only
on a USB_TRANSFER_COMPLETION event. The SET_ADDRESS status stage now
completes inside the driver, so the drivers are still disabled when the
address arrives.
Change-Id: Ifacb8b07cbdefb0dee3d414c2257a50a08759f3d
run_file() joins /mnt/sd_0 and the filename without a /, so /bin/sh cannot open any script and always returns 2.
The path bug has been fixed and the buffer size adjusted and freed after execution.
GPT 6 Sol did the work. I'm just the meat proxy.
Change-Id: I644a773b2bd707e0ee2d8c70c91b7a6075cf2622
A host can replace an unfinished control transfer with a new SETUP. ARC
and DesignWare flush EP0 without reporting completion callbacks, leaving
the core waiting for a data/status packet that will never arrive.
Explicitly notify the core after both directions and stale completion
bits have been cancelled. Return an abandoned data/status stage to READY.
If a queued or running handler still owns the request and data buffer,
keep that ownership and suppress its response; dispatch only the latest
replacement when it returns. A driver-owned SET_ADDRESS can also cancel
a deferred request without passing its SETUP to the core.
Do not overwrite an arbitrary busy state in usb_core_setup_received().
ARC cancellation is a prerequisite in the preceding patch; DesignWare
cancels both EP0 directions before notifying and rearming reception.
Change-Id: Ia8e0a68fe47ccab952168da24a2f76e311ca2b15
Four `ARM_ARCH == 5` checks -- in SOURCES and celt/arm/{bands_arm,
comb_filter_arm,vq_arm}.h -- excluded ARMv6 from every ARMv5E kernel:
denorm_band, haar1, comb_filter_const, celt_sat, deemphasis_stereo_simple,
exp_rotation1 and normres_scale all silently fell back to plain C on
ARM1136/ARM1176, since ARMv6 is a strict superset of the EDSP instructions
those kernels use. Widened to ARM_ARCH >= 5, matching config.h's own
OPUS_ARM_INLINE_EDSP gate, which was already ARM_ARCH > 4.
These four can't be fixed at the commits that introduced them: those
commits are already merged into master under different SHAs. A fifth
instance of the same bug, in celt/arm/mdct_armv5e.h, was fixed at its
origin commit instead, since that one is still open for review.
Verified on both native ARMv6 targets (iPod Nano 4G, ARM1176JZ-S; Gigabeat
S, ARM1136JF-S) and the hosted Samsung YP-R0 (ARM1176JZ-S, cross toolchain
built for the occasion): all three now link and call all 16 ARMv5E
kernels, where they linked and called zero before this fix. Decoded PCM
bit-identical to the ARMv5E build under qemu.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Change-Id: I7e6f6b421b9c0203812fb45d2258c7eb81738d98
53% of the dimensions a decode walks hold no pulses, and that arm leaves
_k alone, so the two CELT_PVQ_U_ROW pointers stay valid. U is
non-decreasing in _k, so p <= _i < q is the single unsigned test
(_i-p) < (q-p). Bit-exact over 8.2M samples.
Modelled: -0.40% ARMv4, -0.78% ARMv5E; the function -4.8% and -7.1%.
Measured: e200v1 39.19 -> 38.96 MHz, Clip+ 28.13 -> 28.08 MHz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Id50be222e101aeabd9a1f4cf5380d3244da610ff
At stride 1 the rotation chain writes X[i+stride] and reads it straight
back, so one load an iteration is redundant and one store is dead. The
kernel carries that value, narrowed, since mul reads all 32 bits where
smulbb does not. Bit-exact over 8.2M samples.
Modelled: -0.87% ARMv4, the function -10.0%.
Measured: e200v1 39.59 -> 39.19 MHz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Idbd1a088bc805fecfb9ee54fc372ad16a7d91606
34 functions and the ARMv4 kernels, chosen by a greedy fill of the free
codec IRAM window ranked by cycles per byte. The mixed-radix
butterflies give their IRAM back, being unreachable under the prime
factor transform.
The cycle model does not see this at all: it models no instruction cache.
Measured: e200v1 48.96 -> 42.60 MHz; reclaiming the mixed-radix IRAM was
a further -0.52%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I9e22025cba99521750a3b664cd0d59357fcd0810
Every 48 kHz CELT length is 15 times a power of two and the factors are
co-prime, so the inter-stage twiddles -- 73% of the FFT multiplies at
N=480 -- vanish. New pfa_fft15 and mdct_postrot_pfa kernels on both
cores; accuracy also improves 0.3 to 0.4 dB against opusdec.
Modelled: -6.17% ARMv4, -1.82% ARMv5E.
Measured: e200v1 42.33 -> 40.10 MHz, Clip+ 29.30 -> 28.24 MHz.
Rescheduling these kernels, folded in here, measured a further -0.75% on
e200v1 and -0.39% on Clip+.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Ifa4a30d1045e905522828958949954615faa440d
One ldr fetches two celt_norm coefficients and smlabb/smlatt take the
halves apart; scalar fallback when the three pointers disagree on
alignment.
Modelled: -0.88% ARMv5E.
Measured: Clip+ 28.13 -> 28.08 MHz, the same build with and without it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I79719132ccecfb7664616bca019e3856ee3479da
Handle SET_ADDRESS directly when each controller receives SETUP, before
passing other requests to the core. Cancel transfers, send the status
response in the driver and queue usb_core_notify_set_address(); the core
only updates its address/configuration state. Remove usb_drv_set_address
and avoid a request callback from the core back into the controller.
Keep status completions for this driver-owned request out of the core EP0
state machine. ARC writes DEVICEADDR and notifies after successful status
IN completion; other controllers retain their existing register/status
ordering or automatic address handling. Use IRQ-local operations on
DesignWare rather than helpers which unconditionally re-enable its IRQ.
Take the low seven bits of wValue; do not impose new validation on the
unspecified wIndex/wLength fields. Convert all eleven firmware backends;
the separate hwstub API is unchanged.
Change-Id: I7b96275df90c14ef4a9954f04ac6fdc004ec8d6c
We already shut down the playback path and the voice path, but that
doesn't necessarily mean the PCM hardware is idle.
Add a call to pcm_play_stop() to ensure the PCM sink is completely idle.
This will prevent a badly-timed callback from firing during a ROLO
operation.
Change-Id: I1eb8c105895fb47bc3d0af91b4d87345f5399aa4
Advertise only the implemented 32, 44.1 and 48 kHz stereo formats. Add
128-byte packets at 32 kHz and wrap the 44.1 kHz cadence at ten packets;
a uint8_t wrap at 256 otherwise emits extra samples every cycle.
Use the serialized UAC header length (including baInterfaceNr), maintain
the active alternate setting, accept alt 0 on non-streaming interfaces,
and retain the last valid sample rate when a SET_CUR request is rejected.
Change-Id: I41dab55fc0c7d2e6474492f97062e9838bc3aebf
A host may send a command after SET_CONFIGURATION while filesystem clients are still acknowledging the storage handover. Previously TEST UNIT READY could report no medium, while other commands could reach storage before exclusive access was granted.
Retain the first CBW until exclusive access is available. Notify the mass-storage class when handover completes, then execute the retained command and keep the OUT endpoint unarmed until its CSW. On BOT reset, discard the retained CBW and accept a new command.
This changes command handling while waiting for ownership. The policy for requesting, preserving and releasing exclusive storage is handled by a separate preparatory patch.
Change-Id: If82fc87160e9d7da930a3217445fea92e58dd1ec
Do not release and reacquire the disk when a host repeats configuration
or resets the bus before selecting mass storage again. This avoids
remounting local filesystems while the host still owns the disk.
After reset the filesystems remain unmounted until the host selects a
configuration which releases storage, or the cable is unplugged. A host
normally reconfigures promptly; one that never does leaves the disk
unavailable locally until unplug, rather than risking simultaneous access.
Change-Id: I6e296247dd2227e549105d85760613c1a81554a1
Rockbox lists no encoder, so CELT_DECODE_ONLY folds away the thirteen
encoder branches in celt/bands.c and stops gcc keeping their values live
across quant_partition's recursive calls. 2,976 bytes smaller.
Modelled: -0.47% ARMv4, -0.69% ARMv5E.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Ie96a0a63e035ab0cdcdbe9eeeb6691f24fecfa41
Its reachable input set is 2,985 (qn,i) pairs for any stream ever, so it
tabulates exactly in 6,484 bytes. Verified exhaustively against the
compiled functions. Only built for PP5022/PP5024, where the tables fit
the 80 KB IRAM window; elsewhere it measured no gain.
Measured, e200v1: 39.18 -> 38.96 MHz with the tables in IRAM, 39.07 with
them in DRAM. Clip+: 28.05 -> 28.08 MHz, so not built there.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I38417793dc337ec6cb61139cc919d23ac09b04dd
This re-enables upstream ASM optimizations for Cortex-M. Only the
our downstream improvements are disabled, as they do not assemble in
thumb2 mode.
Change-Id: Icca1b3dbf04786c7714fb4eef92ad66aa55132f3
* Only use new ARMv5e optimizations on classic (non-M) profile
* fix inconsistent ARM_ARCH >= 5 vs == 5
Fixes red in 0c4345475a and ae223933bf
Change-Id: Ieb688679d2d698a19870b1a63b4151a8593e04e0
radix-3, 4 and 5. The gain is bookkeeping: twiddles addressed by
displacement from one base register, post-indexed stores, and C_MUL's
Q15 doubling folded into the add that consumes it.
Modelled: -4.72% ARMv5E, opus_fft_impl -25.3%.
Measured: Clip+ 30.89 -> 29.33 MHz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I173667ebb13308f83bd6fcb4e876f5a56c698cd3
Pre-rotation, post-rotation and mirror, with a packed-twiddle complex
multiply throughout.
Modelled: -8.0% ARMv5E against the C loops.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I3fcaf2343e04e3f3f4462fc442f8fac623729631
deemphasis_stereo_simple on both cores, with the filter state kept
unshifted and shifted inside the add that consumes it.
Modelled: -0.53% ARMv4, -0.96% ARMv5E.
Measured with the three preceding commits: e200v1 49.42 -> 48.96 MHz,
Clip+ 32.83 -> 30.89 MHz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Id09297974f3b66a5a193b524d68fd8844f71cc02
Currently, the link points to the unofficial bootloader builds and installation instructions by freemyipod.org, but it can be changed at any time by the rockbox.org website maintainer.
Co-authored-by: ChatGPT-5.6 Luna
Change-Id: I05a78a6540ebcc0e03a1f12f5d765e69e68af00c
ARMv4 has no CLZ, so all 8,680 ilog2 calls went through libgcc's
__clzsi2. Fifteen branchless instructions replace it.
Modelled: -0.91% ARMv4; ARMv5E unaffected, it already emits CLZ.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Ib84b97acb687da4101e02bad1b0e8bbd256d32df
The USB core can accept a replacement SETUP while the previous control transfer is unfinished. Before dispatching that SETUP, flush both EP0 directions and discard their old completion bits so old descriptors cannot be reported as the new transfer. Leave non-control endpoints alone.
The register-stub test verifies both flushes, EP0 completion clearing and release of old EP0 waiters. This complements the separate generic control-request state-machine fix.
Change-Id: If595c7c0cfade7d855f113587621847926143606
audio_hard_stop() should be called *prior* to rolo_load(), and indeed
already is at every call site.
The reason to remove it from inside rolo_load() as opposed to the call
sites is because those already show a feedback splash while the audio
path is being shut down.
Change-Id: Ib6b995f7172c6a92599ace75245909730b2e941a
Move the iriver-specific functions for detecting flashed
Rockbox/OF images into system-iriver.c and remove the
HAVE_FLASHED_ROCKBOX define which is now redundant (all
targets using system-iriver.c enable it).
Copyright attribution on the new system-iriver.h header
is a best guess from Git history.
Change-Id: If1933f881a63fd517162ab9ca8f4a3007b997739
Only Coldfire targets have ever implemented this. Gate it
behind CPU_COLDFIRE so the stub functions won't be needed
in other targets.
Change-Id: I507952c40a04d813a40296142a6eba1df24b0a68
Some files were not using the standard header with the
Rockbox logo. Add this and move any technical notes into
a separate comment.
Change-Id: Idaac932cd56154c7b785ba0e6c0231a21878f786
CLEAR_FEATURE(ENDPOINT_HALT) must reset the selected non-control endpoint data toggle as well as removing STALL. Set the corresponding ARC toggle-reset bit when clearing the halt, including when the endpoint is already unstalled. EP0 keeps its SETUP-controlled toggle handling.
The register-stub test checks IN/OUT independently and verifies that EP0 does not receive a non-control toggle reset.
Change-Id: I18bce488ec250336512bfda4db6ff369d21d9180
If RESET and IOC/SOF are reported together, the old interrupt order can refill audio or report completions from descriptors invalidated by the reset. Handle RESET first and return without dispatching those stale events. Disable SOF refill and stop the batch ring when resetting the controller.
The register-stub regression exercises simultaneous RESET, IOC and SOF and checks that no old completion or refill is dispatched.
Change-Id: Iac98df59aea30dfee155302f7ad31c6ba9902975
comb_filter_const on both cores, and celt_synthesis's SIG_SAT clamp
four samples at a time through one ldm and one stm.
Modelled for the saturation loop: -1.05% ARMv4, -1.42% ARMv5E.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I381afab451eb29a91513ce6ab29c1b2d565b7ee9
denormalise_bands on both cores; exp_rotation1, haar1 and the
normalise_residual scaling loop on ARMv5E. Bit-exact.
Modelled: -0.50% ARMv4, -2.91% ARMv5E.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: If40f5dbe7cb9e7c12aa0a5b4ac9e73433a850b6e
98.6% of __udivsi3 calls are ec_decode and ec_decode_bin computing
val/ext, where the quotient only matters below 2^16. Exact over 80
million cases including corrupt-stream values.
Modelled: -1.34% ARMv4, -2.37% ARMv5E.
Measured with the previous commit: e200v1 50.80 -> 49.42 MHz,
Clip+ 33.40 -> 32.83 MHz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Ia09cb6cd8e42d4885e4d5be0f84862b9b951136c
Modern rockbox builds are just larger than 1MB on the Sansa Fuze/Fuzev2,
which exceeds the reserved space to load the firmware.
The other AMS targets are a little under 1MB, so their time is likely
to come soon. Bump the buffer to 2MB so we never have to worry about
this again.
Change-Id: Ie6bf998596f5e55f5cc8e576a2a22639344306a4
If the variable is provided, the resulting .dmg will be uploaded to Apple's servers for notarization. If successful, Apple's notarization ticket is attached to the image.
Notarization of ~30MiB .dmg takes 40-50 seconds including upload time, ~30 seconds sans the upload time.
Tested building and notarizing of Rockbox Utility, Rockbox Theme Editor, and both as a single target, i.e. deploy.
Co-authored-by: ChatGPT-5.6 Luna
Change-Id: Ib31b1f825893111d23248fb8511fe5b6c73d5525
Cuts realtime decode on the Sansa e200v1 from 52.1 MHz to 50.8 MHz.
clt_mdct_backward was the largest remaining item at 13.5% of decode.
Only the three inner loops move to assembly. The setup stays in C, so
mdct.c remains readable and the assembly needs no knowledge of
mdct_lookup.
What the compiled loops lose is registers. Each needs more live values
than gcc can hold, so it spills the loop-invariant pointers, strides and
limits and reloads them every pass: five stack accesses per iteration in
the post-rotation alone. Holding the twiddle as a 16-bit value and
accumulating the product pair with smull/smlal is what makes the
bookkeeping fit, needing seven live registers where the shifted
MULT16_32_Q15 form needs nine.
ldm/stm helps only where the addressing allows. The post-rotation walks
the buffer from both ends and so reads and writes contiguous pairs. The
pre-rotation reads the spectrum through a runtime stride and writes
through the bitrev table, so only its 8-byte output pair merges, and the
TDAC mirror merges nothing.
Over 160 ms of stereo music, traced under qemu:
clt_mdct_backward 1,037,962 -> 900,982 -13.2%
whole decode 7,695,876 -> 7,558,896 -1.8%
loads 650,157 -> 611,667 -5.9%
stores 350,605 -> 323,605 -7.7%
multiplies 337,493 -> 337,493 unchanged
Accuracy improves substantially, because all three loops keep 32 bits of
each Q15 product where MULT16_32_Q15_armv4 drops the low bit, and the
backward MDCT applies three such rounds per sample. The rounding SNR of
the backward transform rises about 9.5 dB, and its worst case error falls
from 708 to 186. Decoded output differs from the previous build in 90 of
15,360 samples, each by one LSB.
Build with OPUS_ARM_NO_MDCT_ASM to select the C loops instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I3c4404b4dbe581d8bcf1f357266a658a068fdb50
Cuts realtime Opus decode on the Sansa e200v1 (PP502x, ARM7TDMI) from
55.55 MHz to 52.1 MHz.
Two exact changes to celt/kiss_fft.c first:
- kf_bfly5 folds the four cosine products into a shift and a single
multiply. cos(2*pi/5) + cos(4*pi/5) is exactly -1/2, and the Q15
constants satisfy that identity exactly (10126 - 26510 == -16384), so
the substitution gives up no accuracy.
- kf_bfly3, kf_bfly4 and kf_bfly5 peel the pass that twiddles by
twiddles[0], which is 1, by rotating the loop rather than duplicating
the body. In fixed point twiddles[0] is 32767 rather than 32768, so
skipping it also drops a small systematic gain error.
Then celt/arm/kiss_fft_armv4_asm.S replaces the radix-3, radix-4 and
radix-5 bodies, reached through OVERRIDE_kf_bfly3/4/5. The compiled
kernels spill their loop-invariant pointers and reload them every pass,
and gcc will not form ldm/stm from contiguous C accesses: it reorders the
loads while scheduling and does not hand out ascending register pairs.
The assembly keeps the bookkeeping resident and sends the transient
butterfly values to the frame instead, in bursts.
Over 160 ms of stereo music, traced under qemu and costed with an
ARM7TDMI model:
FFT cycles 1,876,926 -> 1,430,748 -23.8%
whole decode 8,142,054 -> 7,695,876 -5.5%
loads 769,935 -> 650,157 -15.6%
stores 409,999 -> 350,605 -14.5%
multiplies 350,909 -> 337,493 -3.8%
text 3,368 -> 2,656 bytes
The radix-5 fold accounts for the whole multiply reduction. The assembly
leaves the count untouched and wins purely on memory traffic.
Accuracy improves by up to 2.9 dB rather than degrading, because the
assembly keeps all 32 bits of each Q15 product where MULT16_32_Q15_armv4
drops the low bit. Decoded output differs from the C build in 27 of
15,360 samples, each by one LSB.
Build with OPUS_ARM_NO_FFT_ASM to select the C butterflies instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I2e8a0904da8a85b654ff648a01234348977a0edc
A contributor's check archive matches the row exactly and passes
test_crash clean. test_ftl disagrees with the oracle on two logical
pages in one block - a second, distinct false positive from the
A5D5D589 x2 case: a closed data block addressed purely by position,
with one stale leftover page. Confirmed against the decode notes
(_FTLRestore's "closed blocks -> map" step) and documented in
test_ftl.c alongside the existing false positive.
Testing evidence: utils/ipodnano3g/RESULTS.md.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Change-Id: Ib24d2df18e2b0e60e000ee6ea43bef9c214f7f72