Line data Source code
1 1 : /*
2 : * Copyright (c) 2022 Nordic Semiconductor ASA
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief New USB device stack APIs and structures
10 : *
11 : * This file contains the USB device stack APIs and structures.
12 : */
13 :
14 : #ifndef ZEPHYR_INCLUDE_USBD_H_
15 : #define ZEPHYR_INCLUDE_USBD_H_
16 :
17 : #include <zephyr/device.h>
18 : #include <zephyr/usb/bos.h>
19 : #include <zephyr/usb/usb_ch9.h>
20 : #include <zephyr/usb/usbd_msg.h>
21 : #include <zephyr/drivers/usb/udc_buf.h>
22 : #include <zephyr/sys/byteorder.h>
23 : #include <zephyr/sys/slist.h>
24 : #include <zephyr/logging/log.h>
25 : #include <zephyr/sys/iterable_sections.h>
26 :
27 : #ifdef __cplusplus
28 : extern "C" {
29 : #endif
30 :
31 : /**
32 : * @brief New USB device stack core API
33 : * @defgroup usbd_api USB device core API
34 : * @ingroup usb
35 : * @since 3.3
36 : * @version 0.2.0
37 : * @{
38 : */
39 :
40 : /* 1 if USB device stack is compiled with High-Speed support */
41 0 : #define USBD_SUPPORTS_HIGH_SPEED IS_EQ(CONFIG_USBD_MAX_SPEED, 1)
42 :
43 : /* Maximum bulk max packet size the stack supports */
44 0 : #define USBD_MAX_BULK_MPS COND_CODE_1(USBD_SUPPORTS_HIGH_SPEED, (512), (64))
45 :
46 : /*
47 : * The length of the string descriptor (bLength) is calculated from the
48 : * size of the two octets bLength and bDescriptorType plus the
49 : * length of the UTF16LE string:
50 : *
51 : * bLength = 2 + bString_length
52 : * bLength = 2 + sizeof(initializer_string) * 2 - 2
53 : * bLength = sizeof(initializer_string) * 2
54 : * Use this macro to determine the bLength of the string descriptor.
55 : */
56 0 : #define USB_STRING_DESCRIPTOR_LENGTH(s) (sizeof(s) * 2)
57 :
58 : struct usbd_context;
59 :
60 : /** Used internally to keep descriptors in order
61 : * @cond INTERNAL_HIDDEN
62 : */
63 : enum usbd_str_desc_utype {
64 : USBD_DUT_STRING_LANG,
65 : USBD_DUT_STRING_MANUFACTURER,
66 : USBD_DUT_STRING_PRODUCT,
67 : USBD_DUT_STRING_SERIAL_NUMBER,
68 : USBD_DUT_STRING_CONFIG,
69 : USBD_DUT_STRING_INTERFACE,
70 : };
71 :
72 : enum usbd_bos_desc_utype {
73 : USBD_DUT_BOS_NONE,
74 : USBD_DUT_BOS_VREQ,
75 : };
76 : /** @endcond */
77 :
78 : /**
79 : * USBD string descriptor data
80 : */
81 1 : struct usbd_str_desc_data {
82 : /** Descriptor index, required for string descriptors */
83 1 : uint8_t idx;
84 : /** Descriptor usage type (not bDescriptorType) */
85 1 : enum usbd_str_desc_utype utype : 8;
86 : /** The string descriptor is in ASCII7 format */
87 1 : unsigned int ascii7 : 1;
88 : /** Device stack obtains SerialNumber using the HWINFO API */
89 1 : unsigned int use_hwinfo : 1;
90 : };
91 :
92 : /**
93 : * USBD vendor request node
94 : *
95 : * Vendor request node is identified by the vendor code and is used to register
96 : * callbacks to handle the vendor request with the receiving device.
97 : * When the device stack receives a request with type Vendor and recipient
98 : * Device, and bRequest value equal to the vendor request code, it will call
99 : * the vendor callbacks depending on the direction of the request.
100 : *
101 : * Example callback code fragment:
102 : *
103 : * @code{.c}
104 : * static int foo_to_host_cb(const struct usbd_context *const ctx,
105 : * const struct usb_setup_packet *const setup,
106 : * struct net_buf *const buf)
107 : * {
108 : * if (setup->wIndex == WEBUSB_REQ_GET_URL) {
109 : * uint8_t index = USB_GET_DESCRIPTOR_INDEX(setup->wValue);
110 : *
111 : * if (index != SAMPLE_WEBUSB_LANDING_PAGE) {
112 : * return -ENOTSUP;
113 : * }
114 : *
115 : * net_buf_add_mem(buf, &webusb_origin_url,
116 : * MIN(net_buf_tailroom(buf), sizeof(webusb_origin_url)));
117 : *
118 : * return 0;
119 : * }
120 : *
121 : * return -ENOTSUP;
122 : * }
123 : * @endcode
124 : */
125 1 : struct usbd_vreq_node {
126 : /** Node information for the dlist */
127 1 : sys_dnode_t node;
128 : /** Vendor code (bRequest value) */
129 1 : const uint8_t code;
130 : /** Vendor request callback for device-to-host direction */
131 1 : int (*to_host)(const struct usbd_context *const ctx,
132 : const struct usb_setup_packet *const setup,
133 : struct net_buf *const buf);
134 : /** Vendor request callback for host-to-device direction */
135 1 : int (*to_dev)(const struct usbd_context *const ctx,
136 : const struct usb_setup_packet *const setup,
137 : const struct net_buf *const buf);
138 : };
139 :
140 : /**
141 : * USBD BOS Device Capability descriptor data
142 : */
143 1 : struct usbd_bos_desc_data {
144 : /** Descriptor usage type (not bDescriptorType) */
145 1 : enum usbd_bos_desc_utype utype : 8;
146 : union {
147 0 : struct usbd_vreq_node *const vreq_nd;
148 0 : };
149 : };
150 :
151 : /**
152 : * Descriptor node
153 : *
154 : * Descriptor node is used to manage descriptors that are not
155 : * directly part of a structure, such as string or BOS capability descriptors.
156 : */
157 1 : struct usbd_desc_node {
158 : /** slist node struct */
159 1 : sys_dnode_t node;
160 : union {
161 0 : struct usbd_str_desc_data str;
162 0 : struct usbd_bos_desc_data bos;
163 0 : };
164 : /** Opaque pointer to a descriptor payload */
165 1 : const void *const ptr;
166 : /** Descriptor size in bytes */
167 1 : uint8_t bLength;
168 : /** Descriptor type */
169 1 : uint8_t bDescriptorType;
170 : };
171 :
172 : /**
173 : * Device configuration node
174 : *
175 : * Configuration node is used to manage device configurations,
176 : * at least one configuration is required. It does not have an index,
177 : * instead bConfigurationValue of the descriptor is used for
178 : * identification.
179 : */
180 1 : struct usbd_config_node {
181 : /** slist node struct */
182 1 : sys_snode_t node;
183 : /** Pointer to configuration descriptor */
184 1 : void *desc;
185 : /** Optional pointer to string descriptor node */
186 1 : struct usbd_desc_node *str_desc_nd;
187 : /** List of registered classes (functions) */
188 1 : sys_slist_t class_list;
189 : };
190 :
191 : /* TODO: Kconfig option USBD_NUMOF_INTERFACES_MAX? */
192 0 : #define USBD_NUMOF_INTERFACES_MAX 16U
193 :
194 : /**
195 : * USB device support middle layer runtime state
196 : *
197 : * Part of USB device states without suspended and powered
198 : * states, as it is better to track them separately.
199 : */
200 0 : enum usbd_ch9_state {
201 : USBD_STATE_DEFAULT = 0,
202 : USBD_STATE_ADDRESS,
203 : USBD_STATE_CONFIGURED,
204 : };
205 :
206 :
207 : /**
208 : * USB device support middle layer runtime data
209 : */
210 1 : struct usbd_ch9_data {
211 : /** Setup packet, up-to-date for the respective control request */
212 1 : struct usb_setup_packet setup;
213 : /** Control type, internally used for stage verification */
214 1 : int ctrl_type;
215 : /** Protocol state of the USB device stack */
216 1 : enum usbd_ch9_state state;
217 : /** Halted endpoints bitmap */
218 1 : uint32_t ep_halt;
219 : /** USB device stack selected configuration */
220 1 : uint8_t configuration;
221 : /** Post status stage work required, e.g. set new device address */
222 1 : bool post_status;
223 : /** Array to track interfaces alternate settings */
224 1 : uint8_t alternate[USBD_NUMOF_INTERFACES_MAX];
225 : };
226 :
227 : /**
228 : * @brief USB device speed
229 : */
230 1 : enum usbd_speed {
231 : /** Device supports or is connected to a full speed bus */
232 : USBD_SPEED_FS,
233 : /** Device supports or is connected to a high speed bus */
234 : USBD_SPEED_HS,
235 : /** Device supports or is connected to a super speed bus */
236 : USBD_SPEED_SS,
237 : };
238 :
239 : /**
240 : * USB device support status
241 : */
242 1 : struct usbd_status {
243 : /** USB device support is initialized */
244 1 : unsigned int initialized : 1;
245 : /** USB device support is enabled */
246 1 : unsigned int enabled : 1;
247 : /** USB device is suspended */
248 1 : unsigned int suspended : 1;
249 : /** USB remote wake-up feature is enabled */
250 1 : unsigned int rwup : 1;
251 : /** USB device is self-powered */
252 1 : unsigned int self_powered : 1;
253 : /** USB device speed */
254 1 : enum usbd_speed speed : 2;
255 : };
256 :
257 : /**
258 : * @brief Callback type definition for USB device message delivery
259 : *
260 : * If the Kconfig option USBD_MSG_DEFERRED_MODE is enabled, then the callback
261 : * is executed in the context of the system workqueue. Notification messages are
262 : * stored in a queue and delivered to the callback in sequence.
263 : *
264 : * If the Kconfig option USBD_MSG_DEFERRED_MODE is disabled, the callback is
265 : * executed in the context of the USB device stack thread. The user should make
266 : * sure that the callback execution does not block or disrupt device stack
267 : * handling.
268 : *
269 : * @param[in] ctx Pointer to USB device support context
270 : * @param[in] msg Pointer to USB device message
271 : */
272 1 : typedef void (*usbd_msg_cb_t)(struct usbd_context *const ctx,
273 : const struct usbd_msg *const msg);
274 :
275 : /**
276 : * USB device support runtime context
277 : *
278 : * Main structure that organizes all descriptors, configuration,
279 : * and interfaces. An UDC device must be assigned to this structure.
280 : */
281 1 : struct usbd_context {
282 : /** Name of the USB device */
283 1 : const char *name;
284 : /** Access mutex */
285 1 : struct k_mutex mutex;
286 : /** Pointer to UDC device */
287 1 : const struct device *dev;
288 : /** Notification message recipient callback */
289 1 : usbd_msg_cb_t msg_cb;
290 : /** Middle layer runtime data */
291 1 : struct usbd_ch9_data ch9_data;
292 : /** slist to manage descriptors like string, BOS */
293 1 : sys_dlist_t descriptors;
294 : /** slist to manage Full-Speed device configurations */
295 1 : sys_slist_t fs_configs;
296 : /** slist to manage High-Speed device configurations */
297 1 : sys_slist_t hs_configs;
298 : /** dlist to manage vendor requests with recipient device */
299 1 : sys_dlist_t vreqs;
300 : /** Status of the USB device support */
301 1 : struct usbd_status status;
302 : /** Pointer to Full-Speed device descriptor */
303 1 : void *fs_desc;
304 : /** Pointer to High-Speed device descriptor */
305 1 : void *hs_desc;
306 : };
307 :
308 : /**
309 : * @brief Vendor Requests Table
310 : */
311 1 : struct usbd_cctx_vendor_req {
312 : /** Array of vendor requests supported by the class */
313 1 : const uint8_t *reqs;
314 : /** Length of the array */
315 1 : uint8_t len;
316 : };
317 :
318 : /** USB Class instance registered flag */
319 1 : #define USBD_CCTX_REGISTERED 0
320 :
321 : struct usbd_class_data;
322 :
323 : /**
324 : * @brief USB device support class instance API
325 : */
326 1 : struct usbd_class_api {
327 : /** Feature halt state update handler */
328 1 : void (*feature_halt)(struct usbd_class_data *const c_data,
329 : uint8_t ep, bool halted);
330 :
331 : /** Configuration update handler */
332 1 : void (*update)(struct usbd_class_data *const c_data,
333 : uint8_t iface, uint8_t alternate);
334 :
335 : /** USB control request handler to device */
336 1 : int (*control_to_dev)(struct usbd_class_data *const c_data,
337 : const struct usb_setup_packet *const setup,
338 : const struct net_buf *const buf);
339 :
340 : /** USB control request handler to host */
341 1 : int (*control_to_host)(struct usbd_class_data *const c_data,
342 : const struct usb_setup_packet *const setup,
343 : struct net_buf *const buf);
344 :
345 : /** Endpoint request completion event handler */
346 1 : int (*request)(struct usbd_class_data *const c_data,
347 : struct net_buf *buf, int err);
348 :
349 : /** USB power management handler suspended */
350 1 : void (*suspended)(struct usbd_class_data *const c_data);
351 :
352 : /** USB power management handler resumed */
353 1 : void (*resumed)(struct usbd_class_data *const c_data);
354 :
355 : /** Start of Frame */
356 1 : void (*sof)(struct usbd_class_data *const c_data);
357 :
358 : /** Class associated configuration is selected */
359 1 : void (*enable)(struct usbd_class_data *const c_data);
360 :
361 : /** Class associated configuration is disabled */
362 1 : void (*disable)(struct usbd_class_data *const c_data);
363 :
364 : /** Initialization of the class implementation */
365 1 : int (*init)(struct usbd_class_data *const c_data);
366 :
367 : /** Shutdown of the class implementation */
368 1 : void (*shutdown)(struct usbd_class_data *const c_data);
369 :
370 : /** Get function descriptor based on speed parameter */
371 1 : void *(*get_desc)(struct usbd_class_data *const c_data,
372 : const enum usbd_speed speed);
373 : };
374 :
375 : /**
376 : * @brief USB device support class data
377 : */
378 1 : struct usbd_class_data {
379 : /** Name of the USB device class instance */
380 1 : const char *name;
381 : /** Pointer to USB device stack context structure */
382 1 : struct usbd_context *uds_ctx;
383 : /** Pointer to device support class API */
384 1 : const struct usbd_class_api *api;
385 : /** Supported vendor request table, can be NULL */
386 1 : const struct usbd_cctx_vendor_req *v_reqs;
387 : /** Pointer to private data */
388 1 : void *priv;
389 : };
390 :
391 : /**
392 : * @cond INTERNAL_HIDDEN
393 : *
394 : * Variables necessary for per speed class management. For each speed (Full,
395 : * High) there is separate `struct usbd_class_node` pointing to the same
396 : * `struct usbd_class_data` (because the class can only operate at one speed
397 : * at a time).
398 : */
399 : struct usbd_class_node {
400 : /** Node information for the slist. */
401 : sys_snode_t node;
402 : /** Pointer to public class node instance. */
403 : struct usbd_class_data *const c_data;
404 : /** Bitmap of all endpoints assigned to the instance.
405 : * The IN endpoints are mapped in the upper halfword.
406 : */
407 : uint32_t ep_assigned;
408 : /** Bitmap of the enabled endpoints of the instance.
409 : * The IN endpoints are mapped in the upper halfword.
410 : */
411 : uint32_t ep_active;
412 : /** Bitmap of the bInterfaceNumbers of the class instance */
413 : uint32_t iface_bm;
414 : /** Variable to store the state of the class instance */
415 : atomic_t state;
416 : };
417 :
418 : /** @endcond */
419 :
420 : /**
421 : * @brief Get the USB device runtime context under which the class is registered
422 : *
423 : * The class implementation must use this function and not access the members
424 : * of the struct directly.
425 : *
426 : * @param[in] c_data Pointer to USB device class data
427 : *
428 : * @return Pointer to USB device runtime context
429 : */
430 1 : static inline struct usbd_context *usbd_class_get_ctx(const struct usbd_class_data *const c_data)
431 : {
432 : return c_data->uds_ctx;
433 : }
434 :
435 : /**
436 : * @brief Get class implementation private data
437 : *
438 : * The class implementation must use this function and not access the members
439 : * of the struct directly.
440 : *
441 : * @param[in] c_data Pointer to USB device class data
442 : *
443 : * @return Pointer to class implementation private data
444 : */
445 1 : static inline void *usbd_class_get_private(const struct usbd_class_data *const c_data)
446 : {
447 : return c_data->priv;
448 : }
449 :
450 : /**
451 : * @brief Define USB device context structure
452 : *
453 : * Macro defines a USB device structure needed by the stack to manage its
454 : * properties and runtime data. The @p vid and @p pid parameters can also be
455 : * changed using usbd_device_set_vid() and usbd_device_set_pid().
456 : *
457 : * Example of use:
458 : *
459 : * @code{.c}
460 : * USBD_DEVICE_DEFINE(sample_usbd,
461 : * DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
462 : * YOUR_VID, YOUR_PID);
463 : * @endcode
464 : *
465 : * @param device_name USB device context name
466 : * @param udc_dev Pointer to UDC device structure
467 : * @param vid Vendor ID
468 : * @param pid Product ID
469 : */
470 1 : #define USBD_DEVICE_DEFINE(device_name, udc_dev, vid, pid) \
471 : static struct usb_device_descriptor \
472 : fs_desc_##device_name = { \
473 : .bLength = sizeof(struct usb_device_descriptor), \
474 : .bDescriptorType = USB_DESC_DEVICE, \
475 : .bcdUSB = sys_cpu_to_le16(USB_SRN_2_0), \
476 : .bDeviceClass = USB_BCC_MISCELLANEOUS, \
477 : .bDeviceSubClass = 2, \
478 : .bDeviceProtocol = 1, \
479 : .bMaxPacketSize0 = USB_CONTROL_EP_MPS, \
480 : .idVendor = vid, \
481 : .idProduct = pid, \
482 : .bcdDevice = sys_cpu_to_le16(USB_BCD_DRN), \
483 : .iManufacturer = 0, \
484 : .iProduct = 0, \
485 : .iSerialNumber = 0, \
486 : .bNumConfigurations = 0, \
487 : }; \
488 : IF_ENABLED(USBD_SUPPORTS_HIGH_SPEED, ( \
489 : static struct usb_device_descriptor \
490 : hs_desc_##device_name = { \
491 : .bLength = sizeof(struct usb_device_descriptor), \
492 : .bDescriptorType = USB_DESC_DEVICE, \
493 : .bcdUSB = sys_cpu_to_le16(USB_SRN_2_0), \
494 : .bDeviceClass = USB_BCC_MISCELLANEOUS, \
495 : .bDeviceSubClass = 2, \
496 : .bDeviceProtocol = 1, \
497 : .bMaxPacketSize0 = 64, \
498 : .idVendor = vid, \
499 : .idProduct = pid, \
500 : .bcdDevice = sys_cpu_to_le16(USB_BCD_DRN), \
501 : .iManufacturer = 0, \
502 : .iProduct = 0, \
503 : .iSerialNumber = 0, \
504 : .bNumConfigurations = 0, \
505 : }; \
506 : )) \
507 : static STRUCT_SECTION_ITERABLE(usbd_context, device_name) = { \
508 : .name = STRINGIFY(device_name), \
509 : .dev = udc_dev, \
510 : .fs_desc = &fs_desc_##device_name, \
511 : IF_ENABLED(USBD_SUPPORTS_HIGH_SPEED, ( \
512 : .hs_desc = &hs_desc_##device_name, \
513 : )) \
514 : }
515 :
516 : /**
517 : * @brief Define USB device configuration
518 : *
519 : * USB device requires at least one configuration instance per supported speed.
520 : * @p attrib is a combination of `USB_SCD_SELF_POWERED` or `USB_SCD_REMOTE_WAKEUP`,
521 : * depending on which characteristic the USB device should have in this
522 : * configuration.
523 : *
524 : * @param name Configuration name
525 : * @param attrib Configuration characteristics. Attributes can also be updated
526 : * with usbd_config_attrib_rwup() and usbd_config_attrib_self()
527 : * @param power bMaxPower value in 2 mA units. This value can also be set with
528 : * usbd_config_maxpower()
529 : * @param desc_nd Address of the string descriptor node used to describe the
530 : * configuration, see USBD_DESC_CONFIG_DEFINE().
531 : * String descriptors are optional and the parameter can be NULL.
532 : */
533 1 : #define USBD_CONFIGURATION_DEFINE(name, attrib, power, desc_nd) \
534 : static struct usb_cfg_descriptor \
535 : cfg_desc_##name = { \
536 : .bLength = sizeof(struct usb_cfg_descriptor), \
537 : .bDescriptorType = USB_DESC_CONFIGURATION, \
538 : .wTotalLength = 0, \
539 : .bNumInterfaces = 0, \
540 : .bConfigurationValue = 1, \
541 : .iConfiguration = 0, \
542 : .bmAttributes = USB_SCD_RESERVED | (attrib), \
543 : .bMaxPower = (power), \
544 : }; \
545 : BUILD_ASSERT((power) < 256, "Too much power"); \
546 : static struct usbd_config_node name = { \
547 : .desc = &cfg_desc_##name, \
548 : .str_desc_nd = desc_nd, \
549 : }
550 :
551 : /**
552 : * @brief Create a string descriptor node and language string descriptor
553 : *
554 : * This macro defines a descriptor node and a string descriptor that,
555 : * when added to the device context, is automatically used as the language
556 : * string descriptor zero. Both descriptor node and descriptor are defined with
557 : * static-storage-class specifier. Default and currently only supported
558 : * language ID is 0x0409 English (United States).
559 : * If string descriptors are used, it is necessary to add this descriptor
560 : * as the first one to the USB device context.
561 : *
562 : * @param name Language string descriptor node identifier.
563 : */
564 1 : #define USBD_DESC_LANG_DEFINE(name) \
565 : static const uint16_t langid_##name = sys_cpu_to_le16(0x0409); \
566 : static struct usbd_desc_node name = { \
567 : .str = { \
568 : .idx = 0, \
569 : .utype = USBD_DUT_STRING_LANG, \
570 : }, \
571 : .ptr = &langid_##name, \
572 : .bLength = sizeof(struct usb_string_descriptor), \
573 : .bDescriptorType = USB_DESC_STRING, \
574 : }
575 :
576 : /**
577 : * @brief Create a string descriptor
578 : *
579 : * This macro defines a descriptor node and a string descriptor.
580 : * The string literal passed to the macro should be in the ASCII7 format. It
581 : * is converted to UTF16LE format on the host request.
582 : *
583 : * @param d_name Internal string descriptor node identifier name
584 : * @param d_string ASCII7 encoded string literal
585 : * @param d_utype String descriptor usage type
586 : */
587 1 : #define USBD_DESC_STRING_DEFINE(d_name, d_string, d_utype) \
588 : static const uint8_t ascii_##d_name[sizeof(d_string)] = d_string; \
589 : static struct usbd_desc_node d_name = { \
590 : .str = { \
591 : .utype = d_utype, \
592 : .ascii7 = true, \
593 : }, \
594 : .ptr = &ascii_##d_name, \
595 : .bLength = USB_STRING_DESCRIPTOR_LENGTH(d_string), \
596 : .bDescriptorType = USB_DESC_STRING, \
597 : }
598 :
599 : /**
600 : * @brief Create a string descriptor node and manufacturer string descriptor
601 : *
602 : * This macro defines a descriptor node and a string descriptor that,
603 : * when added to the device context, is automatically used as the manufacturer
604 : * string descriptor. Both descriptor node and descriptor are defined with
605 : * static-storage-class specifier.
606 : *
607 : * @param d_name String descriptor node identifier.
608 : * @param d_string ASCII7 encoded manufacturer string literal
609 : */
610 1 : #define USBD_DESC_MANUFACTURER_DEFINE(d_name, d_string) \
611 : USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_MANUFACTURER)
612 :
613 : /**
614 : * @brief Create a string descriptor node and product string descriptor
615 : *
616 : * This macro defines a descriptor node and a string descriptor that,
617 : * when added to the device context, is automatically used as the product
618 : * string descriptor. Both descriptor node and descriptor are defined with
619 : * static-storage-class specifier.
620 : *
621 : * @param d_name String descriptor node identifier.
622 : * @param d_string ASCII7 encoded product string literal
623 : */
624 1 : #define USBD_DESC_PRODUCT_DEFINE(d_name, d_string) \
625 : USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_PRODUCT)
626 :
627 : /**
628 : * @brief Create a string descriptor node and serial number string descriptor
629 : *
630 : * This macro defines a descriptor node that, when added to the device context,
631 : * is automatically used as the serial number string descriptor. A valid serial
632 : * number is obtained from @ref hwinfo_interface whenever this string
633 : * descriptor is requested.
634 : *
635 : * @note The HWINFO driver must be available and the Kconfig option HWINFO
636 : * enabled.
637 : *
638 : * @param d_name String descriptor node identifier.
639 : */
640 1 : #define USBD_DESC_SERIAL_NUMBER_DEFINE(d_name) \
641 : BUILD_ASSERT(IS_ENABLED(CONFIG_HWINFO), "HWINFO not enabled"); \
642 : static struct usbd_desc_node d_name = { \
643 : .str = { \
644 : .utype = USBD_DUT_STRING_SERIAL_NUMBER, \
645 : .ascii7 = true, \
646 : .use_hwinfo = true, \
647 : }, \
648 : .bDescriptorType = USB_DESC_STRING, \
649 : }
650 :
651 : /**
652 : * @brief Create a string descriptor node for configuration descriptor
653 : *
654 : * This macro defines a descriptor node whose address can be used as an
655 : * argument for the USBD_CONFIGURATION_DEFINE() macro.
656 : *
657 : * @param d_name String descriptor node identifier.
658 : * @param d_string ASCII7 encoded configuration description string literal
659 : */
660 1 : #define USBD_DESC_CONFIG_DEFINE(d_name, d_string) \
661 : USBD_DESC_STRING_DEFINE(d_name, d_string, USBD_DUT_STRING_CONFIG)
662 :
663 : /**
664 : * @brief Define BOS Device Capability descriptor node
665 : *
666 : * The application defines a BOS capability descriptor node for descriptors
667 : * such as USB 2.0 Extension Descriptor.
668 : *
669 : * @note It requires Kconfig options USBD_BOS_SUPPORT to be enabled.
670 : *
671 : * @param name Descriptor node identifier
672 : * @param len Device Capability descriptor length
673 : * @param subset Pointer to a Device Capability descriptor
674 : */
675 1 : #define USBD_DESC_BOS_DEFINE(name, len, subset) \
676 : BUILD_ASSERT(IS_ENABLED(CONFIG_USBD_BOS_SUPPORT), \
677 : "USB device BOS support is disabled"); \
678 : static struct usbd_desc_node name = { \
679 : .bos = { \
680 : .utype = USBD_DUT_BOS_NONE, \
681 : }, \
682 : .ptr = subset, \
683 : .bLength = len, \
684 : .bDescriptorType = USB_DESC_BOS, \
685 : }
686 :
687 : /**
688 : * @brief Define a vendor request with recipient device
689 : *
690 : * @note It requires Kconfig options USBD_VREQ_SUPPORT to be enabled.
691 : *
692 : * @param name Vendor request identifier
693 : * @param vcode Vendor request code
694 : * @param vto_host Vendor callback for to-host direction request
695 : * @param vto_dev Vendor callback for to-device direction request
696 : */
697 1 : #define USBD_VREQUEST_DEFINE(name, vcode, vto_host, vto_dev) \
698 : BUILD_ASSERT(IS_ENABLED(CONFIG_USBD_VREQ_SUPPORT), \
699 : "USB device vendor request support is disabled"); \
700 : static struct usbd_vreq_node name = { \
701 : .code = vcode, \
702 : .to_host = vto_host, \
703 : .to_dev = vto_dev, \
704 : }
705 :
706 : /**
707 : * @brief Define BOS Device Capability descriptor node with vendor request
708 : *
709 : * This macro defines a BOS descriptor, usually a platform capability, with a
710 : * vendor request node.
711 : *
712 : * USBD_DESC_BOS_VREQ_DEFINE(bos_vreq_webusb, sizeof(bos_cap_webusb), &bos_cap_webusb,
713 : * SAMPLE_WEBUSB_VENDOR_CODE, webusb_to_host_cb, NULL);
714 : *
715 : * @note It requires Kconfig options USBD_VREQ_SUPPORT and USBD_BOS_SUPPORT to
716 : * be enabled.
717 : *
718 : * @param name Descriptor node identifier
719 : * @param len Device Capability descriptor length
720 : * @param subset Pointer to a Device Capability descriptor
721 : * @param vcode Vendor request code
722 : * @param vto_host Vendor callback for to-host direction request
723 : * @param vto_dev Vendor callback for to-device direction request
724 : */
725 1 : #define USBD_DESC_BOS_VREQ_DEFINE(name, len, subset, vcode, vto_host, vto_dev) \
726 : BUILD_ASSERT(IS_ENABLED(CONFIG_USBD_BOS_SUPPORT), \
727 : "USB device BOS support is disabled"); \
728 : USBD_VREQUEST_DEFINE(vreq_nd_##name, vcode, vto_host, vto_dev); \
729 : static struct usbd_desc_node name = { \
730 : .bos = { \
731 : .utype = USBD_DUT_BOS_VREQ, \
732 : .vreq_nd = &vreq_nd_##name, \
733 : }, \
734 : .ptr = subset, \
735 : .bLength = len, \
736 : .bDescriptorType = USB_DESC_BOS, \
737 : }
738 :
739 : /**
740 : * @brief Define USB device support class data
741 : *
742 : * Macro defines class (function) data, as well as corresponding node
743 : * structures used internally by the stack.
744 : *
745 : * @param class_name Class name
746 : * @param class_api Pointer to struct usbd_class_api
747 : * @param class_priv Class private data
748 : * @param class_v_reqs Pointer to struct usbd_cctx_vendor_req
749 : */
750 1 : #define USBD_DEFINE_CLASS(class_name, class_api, class_priv, class_v_reqs) \
751 : static struct usbd_class_data class_name = { \
752 : .name = STRINGIFY(class_name), \
753 : .api = class_api, \
754 : .v_reqs = class_v_reqs, \
755 : .priv = class_priv, \
756 : }; \
757 : static STRUCT_SECTION_ITERABLE_ALTERNATE( \
758 : usbd_class_fs, usbd_class_node, class_name##_fs) = { \
759 : .c_data = &class_name, \
760 : }; \
761 : IF_ENABLED(USBD_SUPPORTS_HIGH_SPEED, ( \
762 : static STRUCT_SECTION_ITERABLE_ALTERNATE( \
763 : usbd_class_hs, usbd_class_node, class_name##_hs) = { \
764 : .c_data = &class_name, \
765 : } \
766 : ))
767 :
768 : /** @brief Helper to declare request table of usbd_cctx_vendor_req
769 : *
770 : * @param _reqs Pointer to the vendor request field
771 : * @param _len Number of supported vendor requests
772 : */
773 1 : #define VENDOR_REQ_DEFINE(_reqs, _len) \
774 : { \
775 : .reqs = (const uint8_t *)(_reqs), \
776 : .len = (_len), \
777 : }
778 :
779 : /** @brief Helper to declare supported vendor requests
780 : *
781 : * @param _reqs Variable number of vendor requests
782 : */
783 1 : #define USBD_VENDOR_REQ(_reqs...) \
784 : VENDOR_REQ_DEFINE(((uint8_t []) { _reqs }), \
785 : sizeof((uint8_t []) { _reqs }))
786 :
787 :
788 : /**
789 : * @brief Add common USB descriptor
790 : *
791 : * Add common descriptor like string or BOS Device Capability.
792 : *
793 : * @param[in] uds_ctx Pointer to USB device support context
794 : * @param[in] dn Pointer to USB descriptor node
795 : *
796 : * @return 0 on success, other values on fail.
797 : */
798 1 : int usbd_add_descriptor(struct usbd_context *uds_ctx,
799 : struct usbd_desc_node *dn);
800 :
801 : /**
802 : * @brief Get USB string descriptor index from descriptor node
803 : *
804 : * @param[in] desc_nd Pointer to USB descriptor node
805 : *
806 : * @return Descriptor index, 0 if descriptor is not part of any device
807 : */
808 1 : uint8_t usbd_str_desc_get_idx(const struct usbd_desc_node *const desc_nd);
809 :
810 : /**
811 : * @brief Remove USB string descriptor
812 : *
813 : * Remove linked USB string descriptor from any list.
814 : *
815 : * @param[in] desc_nd Pointer to USB descriptor node
816 : */
817 1 : void usbd_remove_descriptor(struct usbd_desc_node *const desc_nd);
818 :
819 : /**
820 : * @brief Add a USB device configuration
821 : *
822 : * @param[in] uds_ctx Pointer to USB device support context
823 : * @param[in] speed Speed at which this configuration operates
824 : * @param[in] cd Pointer to USB configuration node
825 : *
826 : * @return 0 on success, other values on fail.
827 : */
828 1 : int usbd_add_configuration(struct usbd_context *uds_ctx,
829 : const enum usbd_speed speed,
830 : struct usbd_config_node *cd);
831 :
832 : /**
833 : * @brief Register an USB class instance
834 : *
835 : * An USB class implementation can have one or more instances.
836 : * To identify the instances we use device drivers API.
837 : * Device names have a prefix derived from the name of the class,
838 : * for example CDC_ACM for CDC ACM class instance,
839 : * and can also be easily identified in the shell.
840 : * Class instance can only be registered when the USB device stack
841 : * is disabled.
842 : * Registered instances are initialized at initialization
843 : * of the USB device stack, and the interface descriptors
844 : * of each instance are adapted to the whole context.
845 : *
846 : * @param[in] uds_ctx Pointer to USB device support context
847 : * @param[in] name Class instance name
848 : * @param[in] speed Configuration speed
849 : * @param[in] cfg Configuration value (bConfigurationValue)
850 : *
851 : * @return 0 on success, other values on fail.
852 : */
853 1 : int usbd_register_class(struct usbd_context *uds_ctx,
854 : const char *name,
855 : const enum usbd_speed speed, uint8_t cfg);
856 :
857 : /**
858 : * @brief Register all available USB class instances
859 : *
860 : * Register all available instances. Like usbd_register_class, but does not
861 : * take the instance name and instead registers all available instances.
862 : *
863 : * @note This cannot be combined. If your application calls
864 : * usbd_register_class for any device, configuration number, or instance,
865 : * either usbd_register_class or this function will fail.
866 : *
867 : * There may be situations where a particular function should not be
868 : * registered, for example, when using the USB DFU implementation, the DFU mode
869 : * function must be excluded during normal device operation. To do this, the
870 : * device can pass a blocklist in the form shown below as an optional argument.
871 : * If the blocklist is not needed, the argument should be NULL.
872 : *
873 : * @code{.c}
874 : * static const char *const blocklist[] = {
875 : * "dfu_dfu",
876 : * NULL,
877 : * };
878 : * @endcode
879 : *
880 : * @param[in] uds_ctx Pointer to USB device support context
881 : * @param[in] speed Configuration speed
882 : * @param[in] cfg Configuration value (bConfigurationValue)
883 : * @param[in] blocklist Null pointer terminated array of pointers to string
884 : * literals to be used as a block list
885 : *
886 : * @return 0 on success, other values on fail.
887 : */
888 1 : int usbd_register_all_classes(struct usbd_context *uds_ctx,
889 : const enum usbd_speed speed, uint8_t cfg,
890 : const char *const blocklist[]);
891 :
892 : /**
893 : * @brief Unregister an USB class instance
894 : *
895 : * USB class instance will be removed and will not appear
896 : * on the next start of the stack. Instance can only be unregistered
897 : * when the USB device stack is disabled.
898 : *
899 : * @param[in] uds_ctx Pointer to USB device support context
900 : * @param[in] name Class instance name
901 : * @param[in] speed Configuration speed
902 : * @param[in] cfg Configuration value (bConfigurationValue)
903 : *
904 : * @return 0 on success, other values on fail.
905 : */
906 1 : int usbd_unregister_class(struct usbd_context *uds_ctx,
907 : const char *name,
908 : const enum usbd_speed speed, uint8_t cfg);
909 :
910 : /**
911 : * @brief Unregister all available USB class instances
912 : *
913 : * Unregister all available instances. Like usbd_unregister_class, but does not
914 : * take the instance name and instead unregisters all available instances.
915 : *
916 : * @param[in] uds_ctx Pointer to USB device support context
917 : * @param[in] speed Configuration speed
918 : * @param[in] cfg Configuration value (bConfigurationValue)
919 : *
920 : * @return 0 on success, other values on fail.
921 : */
922 1 : int usbd_unregister_all_classes(struct usbd_context *uds_ctx,
923 : const enum usbd_speed speed, uint8_t cfg);
924 :
925 : /**
926 : * @brief Register USB notification message callback
927 : *
928 : * @param[in] uds_ctx Pointer to USB device support context
929 : * @param[in] cb Pointer to message callback function
930 : *
931 : * @return 0 on success, other values on fail.
932 : */
933 1 : int usbd_msg_register_cb(struct usbd_context *const uds_ctx,
934 : const usbd_msg_cb_t cb);
935 :
936 : /**
937 : * @brief Initialize USB device
938 : *
939 : * Initialize USB device descriptors and configuration,
940 : * initialize USB device controller.
941 : * Class instances should be registered before they are involved.
942 : * However, the stack should also initialize without registered instances,
943 : * even if the host would complain about missing interfaces.
944 : *
945 : * @param[in] uds_ctx Pointer to USB device support context
946 : *
947 : * @return 0 on success, other values on fail.
948 : */
949 1 : int usbd_init(struct usbd_context *uds_ctx);
950 :
951 : /**
952 : * @brief Enable the USB device support and registered class instances
953 : *
954 : * This function enables the USB device support.
955 : *
956 : * @param[in] uds_ctx Pointer to USB device support context
957 : *
958 : * @return 0 on success, other values on fail.
959 : */
960 1 : int usbd_enable(struct usbd_context *uds_ctx);
961 :
962 : /**
963 : * @brief Disable the USB device support
964 : *
965 : * This function disables the USB device support.
966 : *
967 : * @param[in] uds_ctx Pointer to USB device support context
968 : *
969 : * @return 0 on success, other values on fail.
970 : */
971 1 : int usbd_disable(struct usbd_context *uds_ctx);
972 :
973 : /**
974 : * @brief Shutdown the USB device support
975 : *
976 : * This function completely disables the USB device support.
977 : *
978 : * @param[in] uds_ctx Pointer to USB device support context
979 : *
980 : * @return 0 on success, other values on fail.
981 : */
982 1 : int usbd_shutdown(struct usbd_context *const uds_ctx);
983 :
984 : /**
985 : * @brief Halt endpoint
986 : *
987 : * @param[in] uds_ctx Pointer to USB device support context
988 : * @param[in] ep Endpoint address
989 : *
990 : * @return 0 on success, or error from udc_ep_set_halt()
991 : */
992 1 : int usbd_ep_set_halt(struct usbd_context *uds_ctx, uint8_t ep);
993 :
994 : /**
995 : * @brief Clear endpoint halt
996 : *
997 : * @param[in] uds_ctx Pointer to USB device support context
998 : * @param[in] ep Endpoint address
999 : *
1000 : * @return 0 on success, or error from udc_ep_clear_halt()
1001 : */
1002 1 : int usbd_ep_clear_halt(struct usbd_context *uds_ctx, uint8_t ep);
1003 :
1004 : /**
1005 : * @brief Checks whether the endpoint is halted.
1006 : *
1007 : * @param[in] uds_ctx Pointer to USB device support context
1008 : * @param[in] ep Endpoint address
1009 : *
1010 : * @return true if endpoint is halted, false otherwise
1011 : */
1012 1 : bool usbd_ep_is_halted(struct usbd_context *uds_ctx, uint8_t ep);
1013 :
1014 : /**
1015 : * @brief Allocate buffer for USB device request
1016 : *
1017 : * Allocate a new buffer from controller's driver buffer pool.
1018 : *
1019 : * @param[in] c_data Pointer to USB device class data
1020 : * @param[in] ep Endpoint address
1021 : * @param[in] size Size of the request buffer
1022 : *
1023 : * @return pointer to allocated request or NULL on error.
1024 : */
1025 1 : struct net_buf *usbd_ep_buf_alloc(const struct usbd_class_data *const c_data,
1026 : const uint8_t ep, const size_t size);
1027 :
1028 : /**
1029 : * @brief Queue USB device control request
1030 : *
1031 : * Add control request to the queue.
1032 : *
1033 : * @param[in] uds_ctx Pointer to USB device support context
1034 : * @param[in] buf Pointer to UDC request buffer
1035 : *
1036 : * @return 0 on success, all other values should be treated as error.
1037 : */
1038 1 : int usbd_ep_ctrl_enqueue(struct usbd_context *const uds_ctx,
1039 : struct net_buf *const buf);
1040 :
1041 : /**
1042 : * @brief Queue USB device request
1043 : *
1044 : * Add request to the queue.
1045 : *
1046 : * @param[in] c_data Pointer to USB device class data
1047 : * @param[in] buf Pointer to UDC request buffer
1048 : *
1049 : * @return 0 on success, or error from udc_ep_enqueue()
1050 : */
1051 1 : int usbd_ep_enqueue(const struct usbd_class_data *const c_data,
1052 : struct net_buf *const buf);
1053 :
1054 : /**
1055 : * @brief Remove all USB device controller requests from endpoint queue
1056 : *
1057 : * @param[in] uds_ctx Pointer to USB device support context
1058 : * @param[in] ep Endpoint address
1059 : *
1060 : * @return 0 on success, or error from udc_ep_dequeue()
1061 : */
1062 1 : int usbd_ep_dequeue(struct usbd_context *uds_ctx, const uint8_t ep);
1063 :
1064 : /**
1065 : * @brief Free USB device request buffer
1066 : *
1067 : * Put the buffer back into the request buffer pool.
1068 : *
1069 : * @param[in] uds_ctx Pointer to USB device support context
1070 : * @param[in] buf Pointer to UDC request buffer
1071 : *
1072 : * @return 0 on success, all other values should be treated as error.
1073 : */
1074 1 : int usbd_ep_buf_free(struct usbd_context *uds_ctx, struct net_buf *buf);
1075 :
1076 : /**
1077 : * @brief Checks whether the USB device controller is suspended.
1078 : *
1079 : * @param[in] uds_ctx Pointer to USB device support context
1080 : *
1081 : * @return true if endpoint is halted, false otherwise
1082 : */
1083 1 : bool usbd_is_suspended(struct usbd_context *uds_ctx);
1084 :
1085 : /**
1086 : * @brief Initiate the USB remote wakeup (TBD)
1087 : *
1088 : * @return 0 on success, other values on fail.
1089 : */
1090 1 : int usbd_wakeup_request(struct usbd_context *uds_ctx);
1091 :
1092 : /**
1093 : * @brief Set the self-powered status of the USB device
1094 : *
1095 : * The status is used in the Self Powered field of the Get Status request
1096 : * response to indicate whether the device is currently self-powered.
1097 : *
1098 : * @param[in] uds_ctx Pointer to a device context
1099 : * @param[in] status Sets self-powered status if true, clears it otherwise
1100 : */
1101 1 : void usbd_self_powered(struct usbd_context *uds_ctx, const bool status);
1102 :
1103 : /**
1104 : * @brief Get actual device speed
1105 : *
1106 : * @param[in] uds_ctx Pointer to a device context
1107 : *
1108 : * @return Actual device speed
1109 : */
1110 1 : enum usbd_speed usbd_bus_speed(const struct usbd_context *const uds_ctx);
1111 :
1112 : /**
1113 : * @brief Get highest speed supported by the controller
1114 : *
1115 : * @param[in] uds_ctx Pointer to a device context
1116 : *
1117 : * @return Highest supported speed
1118 : */
1119 1 : enum usbd_speed usbd_caps_speed(const struct usbd_context *const uds_ctx);
1120 :
1121 : /**
1122 : * @brief Set USB device descriptor value bcdUSB
1123 : *
1124 : * @param[in] uds_ctx Pointer to USB device support context
1125 : * @param[in] speed Speed for which the bcdUSB should be set
1126 : * @param[in] bcd bcdUSB value
1127 : *
1128 : * @return 0 on success, other values on fail.
1129 : */
1130 1 : int usbd_device_set_bcd_usb(struct usbd_context *const uds_ctx,
1131 : const enum usbd_speed speed, const uint16_t bcd);
1132 :
1133 : /**
1134 : * @brief Set USB device descriptor value idVendor
1135 : *
1136 : * @param[in] uds_ctx Pointer to USB device support context
1137 : * @param[in] vid idVendor value
1138 : *
1139 : * @return 0 on success, other values on fail.
1140 : */
1141 1 : int usbd_device_set_vid(struct usbd_context *const uds_ctx,
1142 : const uint16_t vid);
1143 :
1144 : /**
1145 : * @brief Set USB device descriptor value idProduct
1146 : *
1147 : * @param[in] uds_ctx Pointer to USB device support context
1148 : * @param[in] pid idProduct value
1149 : *
1150 : * @return 0 on success, other values on fail.
1151 : */
1152 1 : int usbd_device_set_pid(struct usbd_context *const uds_ctx,
1153 : const uint16_t pid);
1154 :
1155 : /**
1156 : * @brief Set USB device descriptor value bcdDevice
1157 : *
1158 : * @param[in] uds_ctx Pointer to USB device support context
1159 : * @param[in] bcd bcdDevice value
1160 : *
1161 : * @return 0 on success, other values on fail.
1162 : */
1163 1 : int usbd_device_set_bcd_device(struct usbd_context *const uds_ctx,
1164 : const uint16_t bcd);
1165 :
1166 : /**
1167 : * @brief Set USB device descriptor code triple Base Class, SubClass, and Protocol
1168 : *
1169 : * @param[in] uds_ctx Pointer to USB device support context
1170 : * @param[in] speed Speed for which the code triple should be set
1171 : * @param[in] base_class bDeviceClass value
1172 : * @param[in] subclass bDeviceSubClass value
1173 : * @param[in] protocol bDeviceProtocol value
1174 : *
1175 : * @return 0 on success, other values on fail.
1176 : */
1177 1 : int usbd_device_set_code_triple(struct usbd_context *const uds_ctx,
1178 : const enum usbd_speed speed,
1179 : const uint8_t base_class,
1180 : const uint8_t subclass, const uint8_t protocol);
1181 :
1182 : /**
1183 : * @brief Setup USB device configuration attribute Remote Wakeup
1184 : *
1185 : * @param[in] uds_ctx Pointer to USB device support context
1186 : * @param[in] speed Configuration speed
1187 : * @param[in] cfg Configuration number
1188 : * @param[in] enable Sets attribute if true, clears it otherwise
1189 : *
1190 : * @return 0 on success, other values on fail.
1191 : */
1192 1 : int usbd_config_attrib_rwup(struct usbd_context *const uds_ctx,
1193 : const enum usbd_speed speed,
1194 : const uint8_t cfg, const bool enable);
1195 :
1196 : /**
1197 : * @brief Setup USB device configuration attribute Self-powered
1198 : *
1199 : * @param[in] uds_ctx Pointer to USB device support context
1200 : * @param[in] speed Configuration speed
1201 : * @param[in] cfg Configuration number
1202 : * @param[in] enable Sets attribute if true, clears it otherwise
1203 : *
1204 : * @return 0 on success, other values on fail.
1205 : */
1206 1 : int usbd_config_attrib_self(struct usbd_context *const uds_ctx,
1207 : const enum usbd_speed speed,
1208 : const uint8_t cfg, const bool enable);
1209 :
1210 : /**
1211 : * @brief Setup USB device configuration power consumption
1212 : *
1213 : * @param[in] uds_ctx Pointer to USB device support context
1214 : * @param[in] speed Configuration speed
1215 : * @param[in] cfg Configuration number
1216 : * @param[in] power Maximum power consumption value (bMaxPower)
1217 : *
1218 : * @return 0 on success, other values on fail.
1219 : */
1220 1 : int usbd_config_maxpower(struct usbd_context *const uds_ctx,
1221 : const enum usbd_speed speed,
1222 : const uint8_t cfg, const uint8_t power);
1223 :
1224 : /**
1225 : * @brief Check that the controller can detect the VBUS state change.
1226 : *
1227 : * This can be used in a generic application to explicitly handle the VBUS
1228 : * detected event after usbd_init(). For example, to call usbd_enable() after a
1229 : * short delay to give the PMIC time to detect the bus, or to handle cases
1230 : * where usbd_enable() can only be called after a VBUS detected event.
1231 : *
1232 : * @param[in] uds_ctx Pointer to USB device support context
1233 : *
1234 : * @return true if controller can detect VBUS state change, false otherwise
1235 : */
1236 1 : bool usbd_can_detect_vbus(struct usbd_context *const uds_ctx);
1237 :
1238 : /**
1239 : * @brief Register an USB vendor request with recipient device
1240 : *
1241 : * The vendor request with the recipient device applies to all configurations
1242 : * within the device.
1243 : *
1244 : * @param[in] uds_ctx Pointer to USB device support context
1245 : * @param[in] vreq_nd Pointer to vendor request node
1246 : *
1247 : * @return 0 on success, other values on fail.
1248 : */
1249 1 : int usbd_device_register_vreq(struct usbd_context *const uds_ctx,
1250 : struct usbd_vreq_node *const vreq_nd);
1251 :
1252 : /**
1253 : * @}
1254 : */
1255 :
1256 : #ifdef __cplusplus
1257 : }
1258 : #endif
1259 :
1260 : #endif /* ZEPHYR_INCLUDE_USBD_H_ */
|