Commit graph

140 commits

Author SHA1 Message Date
Marcin Bukat
d3893ead3a rk27xx: keep interrupt and bulk endpoints in separate groups
USB mass storage writes ran at 0.03 MB/s in the firmware - to the NAND
and to the SD card alike - while the bootloader, with the same driver,
wrote the same NAND at 2 MB/s. The firmware adds a HID interface, and
without it writes ran at full speed.

The UDC's endpoints come in groups of three - bulk OUT, bulk IN,
interrupt IN: 1-3, 4-6 and so on - and allocation handed out the first
free endpoint of each type, so HID's interrupt endpoint 3 landed in the
group of mass storage's bulk endpoints 1 and 2. The host polls it every
16 ms, the idle endpoint NAKs, and each poll costs the group's bulk
traffic: writes advanced about one packet per poll. Polled every 125 us
instead, they all but stopped; moved to endpoint 6, in a group of its
own, they ran at 2.36 MB/s, as without HID.

Never give an interrupt endpoint a group with bulk endpoints in use, or
the other way round, whichever class asks first. Since which endpoints
are available then depends on what is already allocated, the driver
tracks the allocation itself - option 2 of usb_drv.h, as usb-designware
does - with its context in usb-rk27xx.h, which usb_core.c includes before
usb_drv.h. HID keeps working.

Tested on a generic rk2705 with ums_stress.py over USB mass storage to
the SD card: 0.03 MB/s with HID on endpoint 3, 2.36 MB/s with it on
endpoint 6 - the allocation this change produces for mass storage plus
HID. (Measured with the driver's earlier allocator, before the USB core
took allocation over; this carries the same rule into the new scheme.)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: Ib80ed206a3705f2c76fc8457b5c0a54d60a46402
2026-09-28 16:55:21 +02:00
Solomon Peachy
2745e0b973 FS#14011: Handle usb hosts whose first request is SET_ADDRESS (Anthony Fletcher)
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
2026-09-27 19:36:21 -04:00
Paul Sauro
9aa2d7fe94 usb: accept replacement SETUP after an abandoned control transfer
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
2026-09-27 09:19:39 -04:00
Paul Sauro
841007dfa1 usb: let controller drivers handle SET_ADDRESS requests
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
2026-09-26 13:23:01 -04:00
Paul Sauro
2b664d6025 usb: preserve exclusive storage ownership across repeated configuration and reset
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
2026-09-25 07:48:31 -04:00
Paul Sauro
404e2c7626 usb: validate configuration descriptor indices and failed drivers
Reject the first out-of-range configuration index and omit class descriptors for drivers whose initialization failed.

Change-Id: I1f74dcceb69f19b52650aa6ae3f38331e320b151
2026-09-20 18:14:54 -04:00
mojyack
37943178f0 usb: Directly reference the "driver" in the endpoint data structure
Results in cleaner code versus effectively cut-n-pasting the driver's
completion callbacks into the endpoint structure.

Change-Id: I043c46c91796f787dec098a7db043481834950a0
2026-07-12 09:02:29 -04:00
Solomon Peachy
d54b9e6f8d chore: Get rid of *all* vestigal CVS '$Id:$' tags
Change-Id: I35c13a9768c582e4851aa252dd3ea5c89f760c8c
2026-06-01 16:01:18 -04:00
mojyack
2291aa24f2 usb: refactor control request handling
this commit is a combination of the following changes, which
significantly refactors usb core and class drivers.

1. unify usb buffers of each class driver to reduce iram usage
currently, many class drivers allocate their own buffer to receive
control out data, which is a waste of iram.
share one common buffer for that usage to address the issue.

2. simplify control request handling by implicitly receiving write
   request data packets
change 1 above fixed the data destination. therefore, having the core
receive the data allows us to reduce the class driver's work and
simplifies the api.

3. enhance usb core's control request handling and unify the legacy
   driver api
in order to implement change 2, both the legacy and new driver apis
should be supported. so that, using the designware driver as a
reference, the new driver api functionality is move into usb core.
this simplifies the usb device drivers by requiring them to implement
only the functionalities equivalent to the legacy api.

tested with ipodvideo(arc) and erosqnative(designware)

Change-Id: I3627daa90278751f599e2108ec150ec3f8f6c524
2026-05-25 12:42:36 +01:00
mojyack
142e1864ef usb: fix get_max_packet_size is called before endpoints are allocated
retrive the requirements like others rather than callback

Change-Id: I20efce76a418ebd7aa6943f02e53b3f7a8fd2797
2026-05-04 16:46:57 -04:00
mojyack
41caf678fe usb: allow more flexible endpoint allocation
the capabilities of endpoint of several devices such as dwc2 change during
runtime, so they cannot be determined during driver initialization.
therefore, allocation using ep_specs is inappropriate.

to support these devices, add functions to the driver that determine whether
endpoints are available and make allocation more flexible.

tested with ipodvideo(arc) and erosqnative(designware)

Change-Id: I8005c17f3d763cd17306bf49918e1cd8084bdeff
2026-05-04 13:31:21 -04:00
mojyack
bbdada7690 usb: enable cpu boost for specific class drivers
add needs_cpu_boost field to usb_class_driver and manage boost state in
usb_core, similar to needs_exclusive_storage.

Change-Id: Ieb0cd7bedda5b24bb0d209d5ce907db30f4815db
2026-05-04 18:15:52 +09:00
mojyack
732f7bcfd9 usb: allow class drivers to return error from init_connection()
Change-Id: Idcd48dd00d9d2f06c49a347e02a41a5de7252431
2026-05-04 18:15:49 +09:00
mojyack
3c10b21c10 usb: hold class_driver instance in each driver
Change-Id: Ia2f857bffcc6c3cca4dee59791c48c628082595b
2026-05-03 15:18:51 -04:00
mojyack
6d387e2e7f usb: allow class drivers to override max packet size
this is required to make hid endpoint of iap class driver work,
especially on ipodvideo(arc).
at least for arc, it is required to set mps as 64 instead of 512 on
highspeed, or some accessories ignore incoming hid reports.

Change-Id: I242060faced28a66204146a9c36ef10626d6d265
2026-05-03 14:59:15 -04:00
mojyack
fad99773e3 send iap status change notifications
install iap event notification callbacks in various locations

Change-Id: I637a3ad18cb07ca056ad9b678400ba11d2f8faad
2026-05-03 14:20:29 -04:00
mojyack
757e683506 usb: core: handle apple vendor usb request
Change-Id: Iab5135774353630e7bce4939f40ca35940e214f3
2026-05-03 13:03:42 -04:00
mojyack
3bb656625b usb: add usb iAP driver
add class driver source files.
also register iap audio sink.
usbstack/iap/libiap directory is imported from libiap.

Change-Id: I776c5caec33fe9efadc448e2e3b37d500bf19c9f
2026-05-03 12:40:54 -04:00
mojyack
f84003fa40 usb: add fallback implementation of emulated batch api
some targets can process requests fast enough without dedicated
batch api implementation.
provide generic implementationn for such targets.

Change-Id: I152681441e70e0e98396274d9305d371d2bbfbe3
2026-03-29 09:03:56 -04:00
Solomon Peachy
b349eea2c9 usb: fix yellow in eb69211791
Bootloaders with HAVE_USBSTACK but without HAVE_BOOTLOADER_USB_MODE end
up with USB_NUM_DRIVERS of 0 which leads to a warning due to a signed
number being checked to see if it's >= 0.

Work around this temporarily; the proper fix is to not build usb_core
and its class drivers when BOOTLOADER & !HAVE_BOOTLOADER_USB_MODE

Change-Id: I1b41140d31ba9df6b4c760478c4265d4e5584963
2026-01-27 15:23:47 -05:00
mojyack
eb69211791 usb: introduce USB_NOTIFY_CLASS_DRIVER
this invokes specified class driver's notify_event method.
initial purpose is to trigger a callback from isr, like a timer event.

Change-Id: Id600e9f0d8840a12da779d5a15783edf14bd76b5
2026-01-27 13:39:58 -05:00
mojyack
33d0a3efa3 usb: enter to exclusive disk mode only when required by usb config
currently, exclusive disk mode was enabled at the same time as the
usb insertion. when multiple usb configurations exist, this is not
appropriate.

manage it in the core and enable it only when necessary.

Change-Id: Iadbec05fad1d1319471233227ae0e72c12079295
2026-01-26 19:52:22 -05:00
mojyack
75edff7880 usb: fix random "null ctrl req" panic when switching usb config
Change-Id: I7839edb99461abfbff03460d63343691085ef34f
2026-01-14 16:23:07 -05:00
Aidan MacDonald
350e2b9b02 firmware: add missing 'void' in usb_charging_maxcurrent() definition
Change-Id: I5d1dbb9176160ae98a8ab20ac3436610cf8b805d
2026-01-13 16:59:49 -05:00
mojyack
e3bb80384d usb: do not call usb_core_do_set_config(0) inside bus reset isr
Change-Id: Ic06719ef92cd1fae42c7155ab72029466826a59b
2026-01-03 19:58:38 -05:00
mojyack
6db1e937e9 usb: set config to 0 on bus reset and exit
Change-Id: I4ee0e33f031388d17b30bbe591fe9b7d6386e940
2026-01-03 19:58:07 -05:00
mojyack
03fbd2784d usb: preparation to support multiple usb configs
- existing class drivers are placed to config 1
- drivers_connected==true is replaced with usb_config!=0
- supports config transition between nonzero configs
- STALL if request set_config was invalid

Change-Id: Ia775ae2dcb7d0cc08d2f3ee5ca41683837b04259
2026-01-03 19:57:33 -05:00
mojyack
350a2250b1 usb: implement endpoint allocation
this commit has following changes:
- introduce `usb_drv_ep_spec` table to udc drivers, which represents
  endpoint characteristics.
- introduce 'ep_allocs' table to class drivers, which represents what
  endpoint type does the class driver want.
- implement endpoint matching logic to usb core.

this is a required step to implement usb config switching, because we
need to create config descriptors without actually initializing endpoints.

Change-Id: I11c324cd35189ab636744488f6259d0cdb2179f0
2026-01-03 13:23:53 -05:00
Dana Conrad
9ce66e088e Add USB Audio 1.0 support
Original commit credit to Amaury Pouly, Moshe Piekarski
Pushed across the finish line by Dana Conrad

To enable, see setting under General Settings --> System --> USB-DAC.
On devices with few endpoints, this may not work while HID and/or
mass storage is enabled.

Adds new dedicated mixer channel.

setting usb-dac can have values:
- never (0)
- always (1)
- while_charge_only (2)
- while_mass_storage (3)

Relevant devices are DWC2 and ARC usb controller devices. That being:
x1000 Native targets (m3k, erosqnative, q1, others...?),
sansac200, creativezenxfi2, vibe500, ipodmini2g,
ipod4g, creativezenxfi, creativezenxfi3, sansaview, ipodcolor,
creativezenxfistyle, samsungypz5, sansafuzeplus, iriverh10_5gb,
tatungtpj1022, gigabeats, faketarget, samsungyh820, gogearhdd1630, samsungyh925, ipodmini1g, ipodvideo, creativezenmozaic, sonynwze370, creativezen, gogearsa9200, gogearhdd6330, sonynwze360, sansae200, mrobe100, iriverh10, creativezenv, ipodnano1g, samsungyh920

USB Driver-wise, it should be noted that this patch requires some
slight changes:
- proper blocking on control OUT transfers, to make sure the data is
  received *before* using it, the usb_core should probably use that too
- drivers can now support interface alternate settings
- drivers can be notified of completion by a new fast handler, which
  is called directly from the driver; this is is necessary for
  isochronous transfers because going through the usb queue is way too
  slow

Designware changes:

- enable for USBOTG_DESIGNWARE
- set maxpacketsize to 1023 for ISO endpoints

Change-Id: I570871884a4e4820b4312b203b07701f06ecacc6
2025-11-15 07:30:15 -05:00
Solomon Peachy
5a4030cb35 usb: Partial revert of previous commit
...A rebase gone wrong led to a bunch of extra crap in the commit.

Change-Id: Id8f0e33b9fba0949594701fbc574da58e74fa776
2025-10-05 15:56:00 -04:00
Solomon Peachy
43ec77f84c usb: Strip ALL spaces from passthrough ATA serial number
Leading spaces in particular were resulting in Linux warnings/panics, but
to be safe strip out all spaces, including those in the middle.

This was noticed on an ipod6g with the stock hard drive; it reported
a serial number of '            xxxxxxxx', which is technically legal
per ATA specs, but needs to be properly trimmed.

Change-Id: I34309fe64b341caefd5b18f6d0cf539cb97d4a38
2025-10-05 15:48:12 -04:00
Solomon Peachy
94d6265df0 gcc9: Move structure packing to the struct definition
Silences GCC9 warnings about possible casting misalignments.

Change-Id: I2120638d4d143e9e539b7f240c31653ad55ae4e0
2024-10-12 09:23:37 -04:00
Vencislav Atanasov
9c458bbb0d Use literal ATA serial number for USB SN descriptor if the string is printable
Change-Id: Ic2c853a0b124d7b590ea36229347c56f96a32f33
2024-06-23 08:00:06 +03:00
Vencislav Atanasov
9fda39d1ad Prevent using PP-based iPods' set_serial_descriptor on S5L87xx-based ones
On PortalPlayer iPods, it looks like the serial number is available in a
specific memory location. When adding support for Samsung S5L87xx-based
iPods, this algorithm has not been limited to PP-only, so it sets the
serial number USB descriptor to random memory data.
With this change, it will use the ATA HDD serial number on iPod 6G. On
Nano 2G it won't provide a serial number at all.

Change-Id: I53d48915d629dbd87b2dbbcba5f228ca5949fa9b
2024-06-23 05:24:04 +03:00
Aidan MacDonald
1025283042 usb: Fix iPod video connection issues
Apparently a response is coming out of nowhere and tripping this
check. I can't be bothered to look into it; it would be better to
just update the ARC USB driver to the new control request API...

Change-Id: Ic5062443e060534f170d3afe17c00d3c25d1d3bd
2023-01-23 16:04:16 +00:00
Aidan MacDonald
bd7b54a3c4 usb: Attempt to handle overlapped control requests in legacy drivers
It seems connecting an iPod Video to a Mac triggers the null
request check, resulting in a panic. Ignoring the error with
a bare return "fixes" it and allows the iPod to connect. This
isn't ideal though, because it could silently introduce bugs
on other targets.

The likely cause of this is the host sending control requests
too fast, or a driver problem (the Video uses the ARC driver,
which is still on the legacy interface), with multiple requests
getting queued at once. Since the USB core expects to deal with
only one request at a time, the second response trips the check.

Try to handle this situation a bit more gracefully by detecting
overlapped requests and returning a STALL to the host when it
occurs. At this point the USB stack is able to safely handle a
new request.

Link: https://forums.rockbox.org/index.php/topic,54414.0.html
Change-Id: I9a2b7e35620ff540ebdb39f81671377062a4917d
2023-01-18 14:22:26 -05:00
Aidan MacDonald
6e61e6f0c8 usb_core: don't buffer control request unnecessarily
Due to how the old control request API worked, the request
pointer (and the pointed-to contents) passed by the driver
must remain valid for the lifetime of the request.

The buffered copy wasn't used consistently anyway, so it
should be safe to just get rid of it.

(This only affects the old API compatibility layer.)

Change-Id: I00294c718a7515a91b84f7c7cae5220c73aa5960
2021-11-14 17:58:39 +00:00
Aidan MacDonald
f8810be6de usb_core: More legacy control API fixes
In the old API, usb_core_transfer_complete() would ignore
any completions on EP0. The legacy control API will also
ignore most completions on EP0, but it only did so after
filling in the completion event.

If the driver submits a spurious completion on EP0, then
this could clobber a previously queued completion event.

Fix this by deciding whether to ignore the completion
*before* modifying the event data.

Change-Id: I68526898a96efa594ada4e94bb6851aaaf12e92a
2021-11-13 18:37:33 +00:00
Aidan MacDonald
7af98ce6bb usb: Fix possible SET ADDRESS data corruption
The address from the packet needs to be saved before sending
the response -- after the response the request being pointed
to could get overwritten. This used to be done correctly but
I unintentionally broke it when updating the handler to the
new control request API.

Change-Id: I9b11548baf20dce44a82301731405dc8e8f1cef3
2021-11-09 14:45:07 +00:00
Aidan MacDonald
8c954c68e5 usb: Attempt to fix race condition in compatibility layer
Because usb_core_legacy_control_request() is called by an
interrupt handler the global variables used to track the
current control request at the very least need to be volatile.

It might also be necessary to disable IRQs but I'm not sure
of that.

Change-Id: I0f0bb86d0ad63734e8d3c73cb1c52fedf5a98120
2021-11-08 21:46:36 +00:00
Aidan MacDonald
77731c3579 usb: port usb_core control request handling to new API
Change-Id: I3850c9cfcb87831e56884c83e31f728590b76f83
2021-10-16 21:14:42 +01:00
Aidan MacDonald
82efb1150e usb: implement new API with legacy emulation layer
All existing USB drivers now define USB_LEGACY_CONTROL_API to
enable the emulation layer.

Control request handlers will be ported in follow-up commits.

Change-Id: I4be1ce7c372f2f6fee5978a4858c841b72e77405
2021-10-16 21:14:42 +01:00
Aidan MacDonald
dff8320a5d usb: add request data argument to all control request handlers
Change-Id: I237143fa0d95c914b8e25ed22f8acde96ec00551
2021-10-16 21:14:42 +01:00
Aidan MacDonald
b69d43c247 usb: give USB transfer completion events two data pointers
Change-Id: I036cc7f02c2f86a364d2dba59493a6aa893f2c16
2021-10-16 21:14:42 +01:00
Aidan MacDonald
ec164c389c usb: introduce new control request API
Change-Id: I6545d8985ab683c026f28f6a7c0e23b40d0a6506
2021-10-16 15:58:43 -04:00
James Buren
c0a59b9a6a usbstack: Revise usb string descriptor table to use enum values for indices
This makes it possible for macros of conditionally included string
descriptors to get a correct index no matter what other usb drivers
are enabled or disabled due to the nature behavior of enums.

Change-Id: I8ccebbd316605bed0f5d90b6b73fab4a333c02fa
2021-10-06 17:59:17 -04:00
Aidan MacDonald
3a89fdee96 x1000: fix hang that may occur in USB mode
Upon getting a USB reset, the USB core will update charging
current by calling usb_charging_maxcurrent_change(). On all
current X1000 targets this may cause a hang, since changing
the charge current involves a blocking I2C transaction.

Eg. if the host issues a reset when we're already configured
as part of error recovery, the change from 500 mA -> 100 mA
will cause a hang.

Change-Id: I5b45272c01fa16b179ae3d16bbc50c7fab9a416b
2021-10-02 15:09:46 +01:00
Aidan MacDonald
672bbe434b usb: rename usb_drv_recv() to usb_recv_recv_nonblocking()
IMHO the current name is somewhat misleading:

- usb_drv_send() is blocking and we have usb_drv_send_nonblocking()
  for the non-blocking case. This inconsistent naming can only
  promote confusion. (And what would we call a blocking receive?)

- Other hardware abstraction APIs in Rockbox are usually blocking:
  storage, LCD, backlight, audio... in other words, blocking is the
  default expected behavior, with non-blocking calls being a rarity.

Change-Id: I05b41088d09eab582697674f4f06fdca0c8950af
2021-09-20 22:41:29 +01:00
Tomasz Moń
b4ecd612f7
Sansa Connect: Use deviceid in USB Serial Number
Atmel AT88SC6416C CryptoMemory is almost I2C compatible. The device
is connected to bitbanged I2C bus shared with compliant I2C devices.

Change-Id: Iec54702db1bdfb93c01291eef18ec60391c63b16
2021-07-10 08:56:32 +02:00
James Buren
018372bf39 usb: implement macro for initializing USB strings
This uses the new unicode string literal feature that is available
now to greatly simplify the initialization of these special string
types. This makes them much more readable at a quick glance.

Change-Id: Iad8b49aa763486608e3bb7e83fb8abfb48ce0a7b
2021-03-25 13:26:03 -05:00