Commit graph

967 commits

Author SHA1 Message Date
Johann Fischer
ec851ba7c7 usb: device_next: avoid false error logging in CDC ACM
The interface descriptor and its associated string descriptor are shared
between different speed configurations. Do not try to add a string
descriptor if it has already been added and the index is not zero.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-04-02 10:32:25 +02:00
Tomasz Moń
75109707e3 usb: device_next: Do not add serial number without HWINFO
For many devices iSerialNumber is not required. The only device class
currently supported in Zephyr that requires iSerialNumber is MSC. If the
serial number is not available then iSerialNumber must be 0. Failure to
read the string descriptor for non-zero iSerialNumber fails USB Command
Verifier Chapter 9 tests.

When USBD_DESC_SERIAL_NUMBER_DEFINE() was used without CONFIG_HWINFO
then it did lead to runtime failure when requesting the string (thus
failing certification).

Fail USBD_DESC_SERIAL_NUMBER_DEFINE() at build-time if CONFIG_HWINFO is
not set to prevent the surprise at runtime. Only define serial number
descriptors if CONFIG_HWINFO is enabled.

Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
2025-03-26 16:18:56 +01:00
Johann Fischer
21f4a7db60 usb: device_next: always reset endpoints to defaults on SetInterface
Disable/enable endpoints even if the new alternate is the same as the
current one, forcing the endpoint to reset to defaults.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-03-26 07:08:06 +01:00
Johann Fischer
87caef4389 usb: device_next: keep loopback function transfers going
Do not report canceled transfers as an error and continue the transfers
regardless of the previous transfer status.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-03-26 07:08:06 +01:00
Johann Fischer
f6d338c1b1 usb: host: fix set/clear feature shell commands
Implement Set/Clear Feature endpoint halt request and
fix the corresponding commands in the shell.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-03-24 07:53:21 +01:00
Johann Fischer
9be4c0fed3 usb: host: fix shell device commands
The device command is broken due to the overhaul of how USB devices are
handled in the host stack. Add a device address argument to all device
commands and obtain a pointer to the USB device during command
execution.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-03-24 07:53:21 +01:00
Johann Fischer
9cb0fbf80d usb: device_next: fix Get Status request response
We need to track the self-powered status of the device independently of
the D6 bit in the bmAttributes value of the configuration descriptor
because the Get Status request about the self-powered status is valid in
address state and we support multiple configurations.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-28 14:51:53 +01:00
Martin Gysel
9cc8301dfa usb: device_next: prevent CDC ACM notifications from being blocked forever
Reset semaphore if USB transfer failed or was canceled and prevent
cdc_acm_send_notification() from blocking forever.

Signed-off-by: Martin Gysel <me@bearsh.org>
2025-02-25 15:33:25 +00:00
Johann Fischer
7ffa6203e1 usb: device_next: allow CDC ACM UART to be initialized and enabled at boot
There are some boards and samples in the tree that use the CDC ACM UART
as the default serial backend, just like a real UART controller would.
The new device stack requires more detailed configuration than the old
one. In order to use the CDC ACM UART as the serial backend with the new
device stack in the same way as with the legacy stack, we need to
provide a solution to initialise and enable the CDC ACM UART at boot
time. We cannot use snippets as they do not support Kconfig files or
source code. Shields would be an option, but they cannot be used for
virtual devices such as the CDC ACM UART. The remaining solution is to
put the code and Kconfig file for it in the subsys directory.

Allow CDC ACM UART instance and USB device stack to be initialized and
enabled at boot time and to use it as serial backend for logging or
shell.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-12 02:22:18 +01:00
Johann Fischer
7b344567be usb: device_next: fix cdc_acm_send_notification()
Fix "warning: 'cdc_acm_send_notification' defined but not used"
when Kconfig option UART_USE_RUNTIME_CONFIGURE is not used and
properly handle enqueue error.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-12 02:22:18 +01:00
Johann Fischer
d22c0d2ec3 usb: usbip: add initial support for USBIP server
The server uses host support to export a USB device to a remote
USBIP client. It supports control and bulk transfers, interrupt
transfers may also work, but this depends on the host controller used.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
c8f3a2eb2d usb: host: allow dynamic allocation of USB devices
Allow dynamic allocation of USB devices on connected event.
Add very basic USB device validation and configuration.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
96f4f3ff14 usb: host: move bus event handling to a separate thread
Handle them in separate contexts so that the request completion callback
cannot be blocked, such as when a device connection is detected and
requires configuration.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
fa7752494d usb: host: rework usbh_xfer_alloc() parameters
The transfers require enpoint MPS for proper transaction handling,
assign it in the common place during transfer allsocation so that it can
be reused.
Some users, such as USBIP, may need to keep a reference to private data,
add a parameter for completion callback data.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
63bd9ac1d0 drivers: uhc: add opaque pointer to store upper layer private data
Add an opaque pointer to store upper layer private data and initialize
it with the USB host context during controller initialization. Use the
pointer in event processing to get the correct context.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
2ff20a8c66 usb: host: allow partially read device descriptor
To determine bMaxPacketSize0, which is unknown after the reset.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
a7c8a8d46d drivers: uhc: remove UHC transfer parameter addr and attrib
Address parameter/argument is no longer needed because we have a pointer
to the USB device. The Attrib parameter has never been used and will be
replaced by the interval and start-frame parameters in the future.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
60884cc326 usb: host: move representation of a USB device to UHC header
This will allow the controller driver to access information about the
device in the future.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
a91740e1cf drivers: uhc: implement the dequeue function
Implement the dequeue function and remove the timeout parameter as it is
no longer necessary and can be handled in the upper layer. The dequeue
function is required for the USBIP implementation.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
3fd7ea980e usb: host: fix callback parameter type
The parameter should not be a pointer to type usbh_udev_cb_t.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Johann Fischer
6e6c816446 usb: device_next: lock scheduler in usbd_enable()
Lock the scheduler until the device is fully enabled, similar to
usbd_init();

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-10 09:02:45 +01:00
Emil Gydesen
72b94f0d05 usb: device_next: Document if callbacks are mandatory
Adds additional documentation to the callbacks of uac2_ops
to describe if/when they are mandatory to register.

Additionally add asserts before calling them to help debugging
if the user did not register the required ones.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
2025-02-05 14:56:47 +01:00
Johann Fischer
712bc1678a usb: device_next: add USB DFU flash backend
Add a simpler flash backend, similar to what we have in the legacy USB
DFU implementation. Support slot-0 and slot-1 flash partitions, but
allow them to be enabled/disabled via Kconfig options.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-04 11:55:25 +01:00
Johann Fischer
8b0bdb563f usb: device_next: implement USB DFU class for the new device support
This new implementation is written from scratch and is not tied to the
image manager and MCUboot. It allows the user to define their own
backend and use a simple macro to instantiate an image. On the USB side
this is represented by an interface. The number of possible images is
configurable using the Kconfig option, and is a fairly inexpensive
approach since it only changes the size of the pointer array. The number
of images is only limited by the number of possible interfaces in a
configuration. The class implementation does not support multiple
instances, as there is no real use for it. However, it does provide two
class instances, one for runtime mode and one for DFU mode. The switch
from runtime to DFU mode can only be performed by the user application,
i.e. the application receives a notification when the host wants to
switch to DFU mode, and then the application can disable the runtime
configuration and enable the DFU configuration. This implementation does
not support switching to the DFU mode by bus reset issued by the
host.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-04 11:55:25 +01:00
Johann Fischer
3bfe163811 usb: device_next: implement blocklist for classes
In the usbd_register_all_classes(), we may need to skip some instances
as they may have very specific function like USB DFU "DFU mode" which
should not be available by default.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-02-04 11:55:25 +01:00
Titouan Christophe
c525e7a0a5 usb: device_next: add new MIDI 2.0 device class
This adds a new USB device class (based on usb/device_next) that implements
revision 2.0 of the MIDIStreaming interface, a sub-class of the USB audio
device class. In practice, the MIDI interface is much more simple and has
little in common with Audio, so it makes sense to have it as a separate
class driver.

MIDI inputs and outputs are configured through the device tree, under a
node `compatible = "zephyr,usb-midi"`. As per the USB-MIDI2.0 spec,
a single usb-midi interface can convey up to 16 Universal MIDI groups,
comprising 16 channels each. Data is carried from/to the host via
so-called Group Terminals, that are organized in Group Terminal Blocks.
They are represented as children of the usb-midi interface in the device
tree.

From the Zephyr application programmer perspective, MIDI data is exchanged
with the host through the device associated with the `zephyr,usb-midi`
interface, using the following API:

* Send a Universal MIDI Packet to the host: `usb_midi_send(device, pkt)`
* Universal MIDI Packets from the host are delivered to the function passed
  in `usb_midi_set_ops(device, &{.rx_packet_cb = handler})`

Compliant USB-MIDI 2.0 devices are required to expose a USB-MIDI1.0
interface as alt setting 0, and the 2.0 interface on alt setting 1.
To avoid the extra complexity of generating backward compatible USB
descriptors and translating Universal MIDI Packets from/to the old
USB-MIDI1.0 format, this driver generates an empty MIDI1.0 interface
(without any input/output); and therefore will only be able to exchange
MIDI data when the host has explicitely enabled MIDI2.0 (alt setting 1).

This implementation is based on the following documents, which are referred
to in the inline comments:

* `midi20`:
    Universal Serial Bus Device Class Definition for MIDI Devices
    Release 2.0
    https://www.usb.org/sites/default/files/USB%20MIDI%20v2_0.pdf
* `ump112`:
    Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol
      With MIDI 1.0 Protocol in UMP Format
    Document Version 1.1.2
    https://midi.org/universal-midi-packet-ump-and-midi-2-0-protocol-specification

Signed-off-by: Titouan Christophe <moiandme@gmail.com>
2025-01-31 19:50:26 +01:00
Emil Gydesen
8ed24ae3a0 usb: device_next: Make buf ownership consistent for usbd_uac2_send
The usbd_uac2_send function sometimes took ownership of the
provided buffer in error cases, and sometimes not.

The commit modifies the function so that ownership is never
taken in case a non-0 return value.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
2025-01-30 14:08:53 +01:00
Fabio Baltieri
5a40e49cff usb: device_next: cdc_acm: move few constant data to flash
Add a config structure and move few pointers that don't need to change
into it, save few bytes of SRAM.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
2025-01-29 12:53:04 +01:00
Johann Fischer
81dc390115 usb: device_next: add bulk transfers to loopback function
This allows us to use the testusb Linux kernel tool again. All tests
involving control and bulk transfers should pass. Additionally, add a
shell command that allows the user to manually enqueue bulk transfers.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2025-01-29 04:16:42 +01:00
Fabio Baltieri
b0791400f6 usb: device_next: cdc_acm: allow setting the interface description
Add a interface-name string for the CDC-ACM node, this allow setting a
string that is then set as iInterface, which can then be used downstream
in an udev rule such as:

SUBSYSTEM=="tty", ACTION=="add",
ATTRS{interface}=="my interface descriptor",
SYMLINK+="tty-my-device"

To create known aliases for these ports.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
2025-01-24 01:14:28 +01:00
Chew Zeh Yang
d770a4c584 usbd: device_next: cdc: add option to enable short packet terminate
For usbser.sys driver, which is the default USB host driver for CDC
devices in windows, it is expected that USB device always indicate
completion of transmission by short packet. In case where the last
packet length is multiple of max packet size of the BULK IN endpoint,
the USB device shall indicate completion of transmission by sending a
zero length packet. This commit adds the sending of the short packet
termination mentioned above, ensuring condition of short packet
terminate is fulfilled.

Signed-off-by: Chew Zeh Yang <zeon.chew@ambiq.com>
2025-01-23 00:12:24 +01:00
Tomasz Moń
c705551a8c usb: device_next: hid: Pass request buffer in input report done
Pass the report buffer originally provided in hid_device_submit_report()
as a parameter to input_report_done() callback. Example use case is to
enable HID report multi buffering which is easiest achieved by
allocating report buffer before submitting it and then releasing the
buffer after it has been sent.

Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
2025-01-14 10:56:06 +01:00
Fabio Baltieri
5a8671e7ed usb: device_next: cdc_acm: set the thread name after initializing it
The cdc-acm workqueue thread name is set before initializing it right
now, which results in an empty thread name as apparently it gets cleared
by k_work_queue_init. Fix it by moving the thread name setting after the
workqueu is initialized and started.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
2024-12-27 14:10:05 +01:00
Henrik Brix Andersen
52abef2f54 usb: device: next: reduce log level for vendor requests
Reduce the log level from error to debug for received vendor requests.

Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
2024-12-25 03:37:26 +01:00
Johann Fischer
dd5492b3ce usb: device_next: rework wSequence check in CDC NCM implementation
The consequences of a wSequence mismatch are unspecified and are
primarily for debugging purposes. Our checks are a bit too strict, and
if the header check fails, the sequence is not updated, and the header
check subsequently fails. Rework the code to just log a warning on
mismatch and also reset OUT sequence counter the same way as the IN
sequence counter.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
82891d3d32 usb: device_next: do not stop when OUT transfer has zero length
Align the OUT handling with the CDC NCM and change the logic to track
when the alternate data interface is set/reset instead of the class
implementation being part of the active configuration.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
502e8116b5 usb: device_next: allow CDC ECM to survive alternate toggling
When interface alternate is set back to zero, the implementation still
attempts to submit OUT transfers, but the addressed endpoint is actually
disabled. Change the logic a bit to track when the alternate data
interface is set/reset instead of the class implementation being part of
the active configuration.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
8940f43f5d usb: device_next: rework CDC ECM connected/disconnected notifications
Do not fail in iface_start/iface_stop if sending notification fails,
just log the error and try to send connected notification when alternate
interface is set and network interface is started.

Do not block in notification send function and allow to submit more than
one notification which means that the last valid one will also be
delivered.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
376e965d04 usb: device_next: do not accidentally disable CDC NCM network interface
The Zephyr network interface should not be disabled by the USB device
functions. This sounds confusing, but in the current implementation they
are different ends of the connection.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
78c0072dd9 usb: device_next: rework notification handling
We need to handle notifications periodically, for example, when the
interface alternate changes and we also need to track whether the
notification was actually transfered to the host. There is no need to
trigger notification work on iface_start/iface_stop when the USB
interface is not in active configuration. This commit intentianly
changes log level in the notification handling code.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
c437230b58 usb: device_next: fix CDC NCM GET_NTB_INPUT_SIZE
The device should set the maximum size and maximum number of datagrams
within the IN NTB.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
7f39e1a9ec usb: device_next: fix block length check in CDC NCM
In the current implementation, the block length in the OUT direciton
should be equal to the transfer length.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
539961035b usb: device_next: make error logging more verbose in CDC NCM
Log errors with LOG_ERR.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
c7baf39126 usb: device_next: fix CDC NCM datagram pointers processing
The implementation should not assume that NDP is placed immediately
after NTH. According to the specification (revision 1.0), NDP can be
anywhere in the transfer buffer. There is also always a "terminating
zero datagram pointer entry", which we should also use to terminate the
datagram processing loop.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-18 12:46:08 +01:00
Johann Fischer
704b36f78f usb: device_next: remove redundant memset() after net_buf_alloc.*()
With changes introduced in commit 6a3602a306
("net: buf: Clear `user_data` on allocation")
our memset() calls are redundant.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-17 11:38:22 +00:00
Johann Fischer
36e8144b90 usb: device: remove USB H4 Bluetooth function and sample
The Bluetooth HCI USB transport layer implementation is provided by
"subsys/usb/device/class/bluetooth.c". The USB H4 Bluetooth function
implements a non-standard transport layer. There is no known host-side
equivalent that uses this protocol.

Note that the H4 protocol functionality is also provided by the
"subsys/usb/device/class/bluetooth.c".

Since that there are no real USB H4 Bluetooth users, remove the
implementation and sample without deprecation.

Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
2024-12-17 11:35:57 +00:00
Tomasz Moń
9006780db4 usb: device_next: Update IAD first interface on init
IAD must be before the interfaces it associates and therefore there is
no need for the class to be in charge of updating the bFirstInterface.
Update IAD in common initialization code and remove the updates from
classes.

This fixes UAC2 instances where the IAD bFirstInterface is not 0, e.g.
when HID was used together with UAC2.

Signed-off-by: Tomasz Moń <tomasz.mon@nordicsemi.no>
2024-12-12 16:22:49 +01:00
Johan Carlsson
f756d0d2bd usb-c: pe: set correct sink/src ready state.
policy engine errors were unconditionally setting the state back
to sink ready. this fix sets the correct state based on the current
power role.

Signed-off-by: Johan Carlsson <johan.carlsson@teenage.engineering>
2024-12-09 15:11:39 +01:00
Johan Carlsson
9b021bc8e1 usb-c: add PE_SRC_Disabled support.
with this fix the pd stack works with type-c devices that does not
respond to pd.

Signed-off-by: Johan Carlsson <johan.carlsson@teenage.engineering>
2024-12-09 15:11:39 +01:00
Johan Carlsson
cae67312d1 usb-c: ignore VDM messaged when using PD 2.0
according to PD 2.0 sepecification VDM should be ignored
if not supported.

Signed-off-by: Johan Carlsson <johan.carlsson@teenage.engineering>
2024-12-09 15:11:39 +01:00