1 /*
2 * LPCUSB, an USB device driver for LPC microcontrollers
3 * Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
4 * Copyright (c) 2016 Intel Corporation
5 * Copyright (c) 2020 PHYTEC Messtechnik GmbH
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /**
31 * @file
32 * @brief USB device core layer
33 *
34 * This module handles control transfer handler, standard request handler and
35 * USB Interface for customer application.
36 *
37 * Control transfers handler is normally installed on the
38 * endpoint 0 callback.
39 *
40 * Control transfers can be of the following type:
41 * 0 Standard;
42 * 1 Class;
43 * 2 Vendor;
44 * 3 Reserved.
45 *
46 * A callback can be installed for each of these control transfers using
47 * usb_register_request_handler.
48 * When an OUT request arrives, data is collected in the data store provided
49 * with the usb_register_request_handler call. When the transfer is done, the
50 * callback is called.
51 * When an IN request arrives, the callback is called immediately to either
52 * put the control transfer data in the data store, or to get a pointer to
53 * control transfer data. The data is then packetized and sent to the host.
54 *
55 * Standard request handler handles the 'chapter 9' processing, specifically
56 * the standard device requests in table 9-3 from the universal serial bus
57 * specification revision 2.0
58 */
59
60 #include <errno.h>
61 #include <stddef.h>
62 #include <bos_desc.h>
63 #include <zephyr/sys/util.h>
64 #include <zephyr/sys/__assert.h>
65 #include <zephyr/init.h>
66 #include <zephyr/drivers/gpio.h>
67 #include <zephyr/sys/byteorder.h>
68 #include <zephyr/usb/usb_device.h>
69 #include <usb_descriptor.h>
70 #include <zephyr/usb/class/usb_audio.h>
71 #include <zephyr/sys/iterable_sections.h>
72 #include <zephyr/logging/log.h>
73 LOG_MODULE_REGISTER(usb_device, CONFIG_USB_DEVICE_LOG_LEVEL);
74
75 #include <zephyr/usb/bos.h>
76 #include <os_desc.h>
77 #include "usb_transfer.h"
78
79 #define MAX_DESC_HANDLERS 4 /** Device, interface, endpoint, other */
80
81 /* general descriptor field offsets */
82 #define DESC_bLength 0 /** Length offset */
83 #define DESC_bDescriptorType 1 /** Descriptor type offset */
84
85 /* config descriptor field offsets */
86 #define CONF_DESC_wTotalLength 2 /** Total length offset */
87 #define CONF_DESC_bConfigurationValue 5 /** Configuration value offset */
88 #define CONF_DESC_bmAttributes 7 /** configuration characteristics */
89
90 /* interface descriptor field offsets */
91 #define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
92 #define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
93
94 /* endpoint descriptor field offsets */
95 #define ENDP_DESC_bEndpointAddress 2U /** Endpoint address offset */
96 #define ENDP_DESC_bmAttributes 3U /** Bulk or interrupt? */
97 #define ENDP_DESC_wMaxPacketSize 4U /** Maximum packet size offset */
98
99 #define MAX_NUM_REQ_HANDLERS 4U
100 #define MAX_STD_REQ_MSG_SIZE 8U
101
102 K_MUTEX_DEFINE(usb_enable_lock);
103
104 static struct usb_dev_priv {
105 /** Setup packet */
106 struct usb_setup_packet setup;
107 /** Pointer to data buffer */
108 uint8_t *data_buf;
109 /** Remaining bytes in buffer */
110 int32_t data_buf_residue;
111 /** Total length of control transfer */
112 int32_t data_buf_len;
113 /** Zero length packet flag of control transfer */
114 bool zlp_flag;
115 /** Installed custom request handler */
116 usb_request_handler custom_req_handler;
117 /** USB stack status callback */
118 usb_dc_status_callback status_callback;
119 /** USB user status callback */
120 usb_dc_status_callback user_status_callback;
121 /** Pointer to registered descriptors */
122 const uint8_t *descriptors;
123 /** Array of installed request handler callbacks */
124 usb_request_handler req_handlers[MAX_NUM_REQ_HANDLERS];
125 /* Buffer used for storing standard, class and vendor request data */
126 uint8_t req_data[CONFIG_USB_REQUEST_BUFFER_SIZE];
127
128 /** Variable to check whether the usb has been enabled */
129 bool enabled;
130 /** Variable to check whether the usb has been configured */
131 bool configured;
132 /** Currently selected configuration */
133 uint8_t configuration;
134 /** Currently selected alternate setting */
135 uint8_t alt_setting[CONFIG_USB_MAX_ALT_SETTING];
136 /** Remote wakeup feature status */
137 bool remote_wakeup;
138 /** Tracks whether set_endpoint() had been called on an EP */
139 uint32_t ep_bm;
140 /** Maximum Packet Size (MPS) of control endpoint */
141 uint8_t mps0;
142 } usb_dev;
143
144 /* Setup packet definition used to read raw data from USB line */
145 struct usb_setup_packet_packed {
146 uint8_t bmRequestType;
147 uint8_t bRequest;
148 uint16_t wValue;
149 uint16_t wIndex;
150 uint16_t wLength;
151 } __packed;
152
153 static bool reset_endpoint(const struct usb_ep_descriptor *ep_desc);
154
155 /*
156 * @brief print the contents of a setup packet
157 *
158 * @param [in] setup The setup packet
159 *
160 */
usb_print_setup(struct usb_setup_packet * setup)161 static void usb_print_setup(struct usb_setup_packet *setup)
162 {
163 /* avoid compiler warning if LOG_DBG is not defined */
164 ARG_UNUSED(setup);
165
166 LOG_DBG("Setup: "
167 "bmRT 0x%02x, bR 0x%02x, wV 0x%04x, wI 0x%04x, wL 0x%04x",
168 setup->bmRequestType,
169 setup->bRequest,
170 setup->wValue,
171 setup->wIndex,
172 setup->wLength);
173 }
174
usb_reset_alt_setting(void)175 static void usb_reset_alt_setting(void)
176 {
177 memset(usb_dev.alt_setting, 0, ARRAY_SIZE(usb_dev.alt_setting));
178 }
179
usb_set_alt_setting(uint8_t iface,uint8_t alt_setting)180 static bool usb_set_alt_setting(uint8_t iface, uint8_t alt_setting)
181 {
182 if (iface < ARRAY_SIZE(usb_dev.alt_setting)) {
183 usb_dev.alt_setting[iface] = alt_setting;
184 return true;
185 }
186
187 return false;
188 }
189
usb_get_alt_setting(uint8_t iface)190 static uint8_t usb_get_alt_setting(uint8_t iface)
191 {
192 if (iface < ARRAY_SIZE(usb_dev.alt_setting)) {
193 return usb_dev.alt_setting[iface];
194 }
195
196 return 0;
197 }
198
199 /*
200 * @brief handle a request by calling one of the installed request handlers
201 *
202 * Local function to handle a request by calling one of the installed request
203 * handlers. In case of data going from host to device, the data is at *ppbData.
204 * In case of data going from device to host, the handler can either choose to
205 * write its data at *ppbData or update the data pointer.
206 *
207 * @param [in] setup The setup packet
208 * @param [in,out] len Pointer to data length
209 * @param [in,out] data Data buffer
210 *
211 * @return true if the request was handles successfully
212 */
usb_handle_request(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data)213 static bool usb_handle_request(struct usb_setup_packet *setup,
214 int32_t *len, uint8_t **data)
215 {
216 uint32_t type = setup->RequestType.type;
217 usb_request_handler handler;
218
219 if (type >= MAX_NUM_REQ_HANDLERS) {
220 LOG_DBG("Error Incorrect iType %d", type);
221 return false;
222 }
223
224 handler = usb_dev.req_handlers[type];
225 if (handler == NULL) {
226 LOG_DBG("No handler for reqtype %d", type);
227 return false;
228 }
229
230 if ((*handler)(setup, len, data) < 0) {
231 LOG_DBG("Handler Error %d", type);
232 usb_print_setup(setup);
233 return false;
234 }
235
236 return true;
237 }
238
239 /*
240 * @brief send next chunk of data (possibly 0 bytes) to host
241 */
usb_data_to_host(void)242 static void usb_data_to_host(void)
243 {
244 if (usb_dev.zlp_flag == false) {
245 uint32_t chunk = usb_dev.data_buf_residue;
246
247 /*Always EP0 for control*/
248 usb_write(USB_CONTROL_EP_IN, usb_dev.data_buf,
249 usb_dev.data_buf_residue, &chunk);
250 usb_dev.data_buf += chunk;
251 usb_dev.data_buf_residue -= chunk;
252
253 /*
254 * Set ZLP flag when host asks for a bigger length and the
255 * last chunk is wMaxPacketSize long, to indicate the last
256 * packet.
257 */
258 if (!usb_dev.data_buf_residue && chunk &&
259 usb_dev.setup.wLength > usb_dev.data_buf_len) {
260 /* Send less data as requested during the Setup stage */
261 if (!(usb_dev.data_buf_len % usb_dev.mps0)) {
262 /* Transfers a zero-length packet */
263 LOG_DBG("ZLP, requested %u , length %u ",
264 usb_dev.setup.wLength,
265 usb_dev.data_buf_len);
266 usb_dev.zlp_flag = true;
267 }
268 }
269
270 } else {
271 usb_dev.zlp_flag = false;
272 usb_dc_ep_write(USB_CONTROL_EP_IN, NULL, 0, NULL);
273 }
274 }
275
276 /*
277 * @brief handle IN/OUT transfers on EP0
278 *
279 * @param [in] ep Endpoint address
280 * @param [in] ep_status Endpoint status
281 */
usb_handle_control_transfer(uint8_t ep,enum usb_dc_ep_cb_status_code ep_status)282 static void usb_handle_control_transfer(uint8_t ep,
283 enum usb_dc_ep_cb_status_code ep_status)
284 {
285 uint32_t chunk = 0U;
286 struct usb_setup_packet *setup = &usb_dev.setup;
287 struct usb_setup_packet_packed setup_raw;
288
289 LOG_DBG("ep 0x%02x, status 0x%02x", ep, ep_status);
290
291 if (ep == USB_CONTROL_EP_OUT && ep_status == USB_DC_EP_SETUP) {
292 /*
293 * OUT transfer, Setup packet,
294 * reset request message state machine
295 */
296 if (usb_dc_ep_read(ep, (uint8_t *)&setup_raw,
297 sizeof(setup_raw), NULL) < 0) {
298 LOG_DBG("Read Setup Packet failed");
299 usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
300 return;
301 }
302
303 /* Take care of endianness */
304 setup->bmRequestType = setup_raw.bmRequestType;
305 setup->bRequest = setup_raw.bRequest;
306 setup->wValue = sys_le16_to_cpu(setup_raw.wValue);
307 setup->wIndex = sys_le16_to_cpu(setup_raw.wIndex);
308 setup->wLength = sys_le16_to_cpu(setup_raw.wLength);
309
310 usb_dev.data_buf = usb_dev.req_data;
311 usb_dev.zlp_flag = false;
312 /*
313 * Set length to 0 as a precaution so that no trouble
314 * happens if control request handler does not check the
315 * request values sufficiently.
316 */
317 usb_dev.data_buf_len = 0;
318 usb_dev.data_buf_residue = 0;
319
320 if (usb_reqtype_is_to_device(setup)) {
321 if (setup->wLength > CONFIG_USB_REQUEST_BUFFER_SIZE) {
322 LOG_ERR("Request buffer too small");
323 usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
324 usb_dc_ep_set_stall(USB_CONTROL_EP_OUT);
325 return;
326 }
327
328 if (setup->wLength) {
329 /* Continue with data OUT stage */
330 usb_dev.data_buf_len = setup->wLength;
331 usb_dev.data_buf_residue = setup->wLength;
332 return;
333 }
334 }
335
336 /* Ask installed handler to process request */
337 if (!usb_handle_request(setup,
338 &usb_dev.data_buf_len,
339 &usb_dev.data_buf)) {
340 LOG_DBG("usb_handle_request failed");
341 usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
342 return;
343 }
344
345 /* Send smallest of requested and offered length */
346 usb_dev.data_buf_residue = MIN(usb_dev.data_buf_len,
347 setup->wLength);
348 /* Send first part (possibly a zero-length status message) */
349 usb_data_to_host();
350 } else if (ep == USB_CONTROL_EP_OUT) {
351 /* OUT transfer, data or status packets */
352 if (usb_dev.data_buf_residue <= 0) {
353 /* absorb zero-length status message */
354 if (usb_dc_ep_read(USB_CONTROL_EP_OUT,
355 usb_dev.data_buf, 0, &chunk) < 0) {
356 LOG_DBG("Read DATA Packet failed");
357 usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
358 }
359 return;
360 }
361
362 if (usb_dc_ep_read(USB_CONTROL_EP_OUT,
363 usb_dev.data_buf,
364 usb_dev.data_buf_residue, &chunk) < 0) {
365 LOG_DBG("Read DATA Packet failed");
366 usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
367 usb_dc_ep_set_stall(USB_CONTROL_EP_OUT);
368 return;
369 }
370
371 usb_dev.data_buf += chunk;
372 usb_dev.data_buf_residue -= chunk;
373 if (usb_dev.data_buf_residue == 0) {
374 /* Received all, send data to handler */
375 usb_dev.data_buf = usb_dev.req_data;
376 if (!usb_handle_request(setup,
377 &usb_dev.data_buf_len,
378 &usb_dev.data_buf)) {
379 LOG_DBG("usb_handle_request1 failed");
380 usb_dc_ep_set_stall(USB_CONTROL_EP_IN);
381 return;
382 }
383
384 /*Send status to host*/
385 LOG_DBG(">> usb_data_to_host(2)");
386 usb_data_to_host();
387 }
388 } else if (ep == USB_CONTROL_EP_IN) {
389 /* Send more data if available */
390 if (usb_dev.data_buf_residue != 0 || usb_dev.zlp_flag == true) {
391 usb_data_to_host();
392 }
393 } else {
394 __ASSERT_NO_MSG(false);
395 }
396 }
397
398 /*
399 * @brief register a callback for handling requests
400 *
401 * @param [in] type Type of request, e.g. USB_REQTYPE_TYPE_STANDARD
402 * @param [in] handler Callback function pointer
403 */
usb_register_request_handler(int32_t type,usb_request_handler handler)404 static void usb_register_request_handler(int32_t type,
405 usb_request_handler handler)
406 {
407 usb_dev.req_handlers[type] = handler;
408 }
409
410 /*
411 * @brief register a pointer to a descriptor block
412 *
413 * This function registers a pointer to a descriptor block containing all
414 * descriptors for the device.
415 *
416 * @param [in] usb_descriptors The descriptor byte array
417 */
usb_register_descriptors(const uint8_t * usb_descriptors)418 static void usb_register_descriptors(const uint8_t *usb_descriptors)
419 {
420 usb_dev.descriptors = usb_descriptors;
421 }
422
usb_get_status(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data_buf)423 static bool usb_get_status(struct usb_setup_packet *setup,
424 int32_t *len, uint8_t **data_buf)
425 {
426 uint8_t *data = *data_buf;
427
428 LOG_DBG("Get Status request");
429 data[0] = 0U;
430 data[1] = 0U;
431
432 if (IS_ENABLED(CONFIG_USB_SELF_POWERED)) {
433 data[0] |= USB_GET_STATUS_SELF_POWERED;
434 }
435
436 if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
437 data[0] |= (usb_dev.remote_wakeup ?
438 USB_GET_STATUS_REMOTE_WAKEUP : 0);
439 }
440
441 *len = 2;
442
443 return true;
444 }
445
446 /*
447 * @brief get specified USB descriptor
448 *
449 * This function parses the list of installed USB descriptors and attempts
450 * to find the specified USB descriptor.
451 *
452 * @param [in] setup The setup packet
453 * @param [out] len Descriptor length
454 * @param [out] data Descriptor data
455 *
456 * @return true if the descriptor was found, false otherwise
457 */
usb_get_descriptor(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data)458 static bool usb_get_descriptor(struct usb_setup_packet *setup,
459 int32_t *len, uint8_t **data)
460 {
461 uint8_t type = 0U;
462 uint8_t index = 0U;
463 uint8_t *p = NULL;
464 uint32_t cur_index = 0U;
465 bool found = false;
466
467 LOG_DBG("Get Descriptor request");
468 type = USB_GET_DESCRIPTOR_TYPE(setup->wValue);
469 index = USB_GET_DESCRIPTOR_INDEX(setup->wValue);
470
471 /*
472 * Invalid types of descriptors,
473 * see USB Spec. Revision 2.0, 9.4.3 Get Descriptor
474 */
475 if ((type == USB_DESC_INTERFACE) || (type == USB_DESC_ENDPOINT) ||
476 (type > USB_DESC_OTHER_SPEED)) {
477 return false;
478 }
479
480 p = (uint8_t *)usb_dev.descriptors;
481 cur_index = 0U;
482
483 while (p[DESC_bLength] != 0U) {
484 if (p[DESC_bDescriptorType] == type) {
485 if (cur_index == index) {
486 found = true;
487 break;
488 }
489 cur_index++;
490 }
491 /* skip to next descriptor */
492 p += p[DESC_bLength];
493 }
494
495 if (found) {
496 /* set data pointer */
497 *data = p;
498 /* get length from structure */
499 if (type == USB_DESC_CONFIGURATION) {
500 /* configuration descriptor is an
501 * exception, length is at offset
502 * 2 and 3
503 */
504 *len = (p[CONF_DESC_wTotalLength]) |
505 (p[CONF_DESC_wTotalLength + 1] << 8);
506 } else {
507 /* normally length is at offset 0 */
508 *len = p[DESC_bLength];
509 }
510 } else {
511 /* nothing found */
512 LOG_DBG("Desc %x not found!", setup->wValue);
513 }
514 return found;
515 }
516
517 /*
518 * @brief Get 32-bit endpoint bitmask from index
519 *
520 * In the returned 32-bit word, the bit positions in the lower 16 bits
521 * indicate OUT endpoints, while the upper 16 bits indicate IN
522 * endpoints
523 *
524 * @param [in] ep Endpoint of interest
525 *
526 * @return 32-bit bitmask
527 */
get_ep_bm_from_addr(uint8_t ep)528 static uint32_t get_ep_bm_from_addr(uint8_t ep)
529 {
530 uint32_t ep_bm = 0;
531 uint8_t ep_idx;
532
533 ep_idx = ep & (~USB_EP_DIR_IN);
534 if (ep_idx > 15) {
535 LOG_ERR("Endpoint 0x%02x is invalid", ep);
536 goto done;
537 }
538
539 if (ep & USB_EP_DIR_IN) {
540 ep_bm = BIT(ep_idx + 16);
541 } else {
542 ep_bm = BIT(ep_idx);
543 }
544 done:
545 return ep_bm;
546 }
547
548 /*
549 * @brief configure and enable endpoint
550 *
551 * This function sets endpoint configuration according to one specified in USB
552 * endpoint descriptor and then enables it for data transfers.
553 *
554 * @param [in] ep_desc Endpoint descriptor byte array
555 *
556 * @return true if successfully configured and enabled
557 */
set_endpoint(const struct usb_ep_descriptor * ep_desc)558 static bool set_endpoint(const struct usb_ep_descriptor *ep_desc)
559 {
560 struct usb_dc_ep_cfg_data ep_cfg;
561 uint32_t ep_bm;
562 int ret;
563
564 ep_cfg.ep_addr = ep_desc->bEndpointAddress;
565 ep_cfg.ep_mps = sys_le16_to_cpu(ep_desc->wMaxPacketSize);
566 ep_cfg.ep_type = ep_desc->bmAttributes & USB_EP_TRANSFER_TYPE_MASK;
567
568 LOG_DBG("Set endpoint 0x%x type %u MPS %u",
569 ep_cfg.ep_addr, ep_cfg.ep_type, ep_cfg.ep_mps);
570
571 /* if endpoint is has been set() previously, reset() it first */
572 ep_bm = get_ep_bm_from_addr(ep_desc->bEndpointAddress);
573 if (ep_bm & usb_dev.ep_bm) {
574 reset_endpoint(ep_desc);
575 /* allow any canceled transfers to terminate */
576 if (!k_is_in_isr()) {
577 k_usleep(150);
578 }
579 }
580
581 ret = usb_dc_ep_configure(&ep_cfg);
582 if (ret == -EALREADY) {
583 LOG_WRN("Endpoint 0x%02x already configured", ep_cfg.ep_addr);
584 } else if (ret) {
585 LOG_ERR("Failed to configure endpoint 0x%02x", ep_cfg.ep_addr);
586 return false;
587 } else {
588 ;
589 }
590
591 ret = usb_dc_ep_enable(ep_cfg.ep_addr);
592 if (ret == -EALREADY) {
593 LOG_WRN("Endpoint 0x%02x already enabled", ep_cfg.ep_addr);
594 } else if (ret) {
595 LOG_ERR("Failed to enable endpoint 0x%02x", ep_cfg.ep_addr);
596 return false;
597 } else {
598 ;
599 }
600
601 usb_dev.configured = true;
602 usb_dev.ep_bm |= ep_bm;
603
604 return true;
605 }
606
disable_endpoint(uint8_t ep_addr)607 static int disable_endpoint(uint8_t ep_addr)
608 {
609 uint32_t ep_bm;
610 int ret;
611
612 ret = usb_dc_ep_disable(ep_addr);
613 if (ret == -EALREADY) {
614 LOG_WRN("Endpoint 0x%02x already disabled", ep_addr);
615 } else if (ret) {
616 LOG_ERR("Failed to disable endpoint 0x%02x", ep_addr);
617 return ret;
618 }
619
620 /* clear endpoint mask */
621 ep_bm = get_ep_bm_from_addr(ep_addr);
622 usb_dev.ep_bm &= ~ep_bm;
623
624 return 0;
625 }
626
627 /*
628 * @brief Disable endpoint for transferring data
629 *
630 * This function cancels transfers that are associated with endpoint and
631 * disabled endpoint itself.
632 *
633 * @param [in] ep_desc Endpoint descriptor byte array
634 *
635 * @return true if successfully deconfigured and disabled
636 */
reset_endpoint(const struct usb_ep_descriptor * ep_desc)637 static bool reset_endpoint(const struct usb_ep_descriptor *ep_desc)
638 {
639 struct usb_dc_ep_cfg_data ep_cfg;
640
641 ep_cfg.ep_addr = ep_desc->bEndpointAddress;
642 ep_cfg.ep_type = ep_desc->bmAttributes & USB_EP_TRANSFER_TYPE_MASK;
643
644 LOG_DBG("Reset endpoint 0x%02x type %u",
645 ep_cfg.ep_addr, ep_cfg.ep_type);
646
647 usb_cancel_transfer(ep_cfg.ep_addr);
648
649 return disable_endpoint(ep_cfg.ep_addr) ? false : true;
650 }
651
usb_eps_reconfigure(struct usb_ep_descriptor * ep_desc,uint8_t cur_alt_setting,uint8_t alt_setting)652 static bool usb_eps_reconfigure(struct usb_ep_descriptor *ep_desc,
653 uint8_t cur_alt_setting,
654 uint8_t alt_setting)
655 {
656 bool ret;
657
658 if (cur_alt_setting != alt_setting) {
659 LOG_DBG("Disable endpoint 0x%02x", ep_desc->bEndpointAddress);
660 ret = reset_endpoint(ep_desc);
661 } else {
662 LOG_DBG("Enable endpoint 0x%02x", ep_desc->bEndpointAddress);
663 ret = set_endpoint(ep_desc);
664 }
665
666 return ret;
667 }
668
669 /*
670 * @brief set USB configuration
671 *
672 * This function configures the device according to the specified configuration
673 * index and alternate setting by parsing the installed USB descriptor list.
674 * A configuration index of 0 unconfigures the device.
675 *
676 * @param [in] setup The setup packet
677 *
678 * @return true if successfully configured false if error or unconfigured
679 */
usb_set_configuration(struct usb_setup_packet * setup)680 static bool usb_set_configuration(struct usb_setup_packet *setup)
681 {
682 uint8_t *p = (uint8_t *)usb_dev.descriptors;
683 uint8_t cur_alt_setting = 0xFF;
684 uint8_t cur_config = 0xFF;
685 bool found = false;
686
687 LOG_DBG("Set Configuration %u request", setup->wValue);
688
689 if (setup->wValue == 0U) {
690 usb_reset_alt_setting();
691 usb_dev.configuration = setup->wValue;
692 if (usb_dev.status_callback) {
693 usb_dev.status_callback(USB_DC_CONFIGURED,
694 &usb_dev.configuration);
695 }
696
697 return true;
698 }
699
700 /* configure endpoints for this configuration/altsetting */
701 while (p[DESC_bLength] != 0U) {
702 switch (p[DESC_bDescriptorType]) {
703 case USB_DESC_CONFIGURATION:
704 /* remember current configuration index */
705 cur_config = p[CONF_DESC_bConfigurationValue];
706 if (cur_config == setup->wValue) {
707 found = true;
708 }
709
710 break;
711
712 case USB_DESC_INTERFACE:
713 /* remember current alternate setting */
714 cur_alt_setting =
715 p[INTF_DESC_bAlternateSetting];
716 break;
717
718 case USB_DESC_ENDPOINT:
719 if ((cur_config != setup->wValue) ||
720 (cur_alt_setting != 0)) {
721 break;
722 }
723
724 found = set_endpoint((struct usb_ep_descriptor *)p);
725 break;
726
727 default:
728 break;
729 }
730
731 /* skip to next descriptor */
732 p += p[DESC_bLength];
733 }
734
735 if (found) {
736 usb_reset_alt_setting();
737 usb_dev.configuration = setup->wValue;
738 if (usb_dev.status_callback) {
739 usb_dev.status_callback(USB_DC_CONFIGURED,
740 &usb_dev.configuration);
741 }
742 } else {
743 LOG_DBG("Set Configuration %u failed", setup->wValue);
744 }
745
746 return found;
747 }
748
749 /*
750 * @brief set USB interface
751 *
752 * @param [in] setup The setup packet
753 *
754 * @return true if successfully configured false if error or unconfigured
755 */
usb_set_interface(struct usb_setup_packet * setup)756 static bool usb_set_interface(struct usb_setup_packet *setup)
757 {
758 const uint8_t *p = usb_dev.descriptors;
759 const uint8_t *if_desc = NULL;
760 struct usb_ep_descriptor *ep;
761 uint8_t cur_alt_setting = 0xFF;
762 uint8_t cur_iface = 0xFF;
763 bool ret = false;
764
765 LOG_DBG("Set Interface %u alternate %u", setup->wIndex, setup->wValue);
766
767 while (p[DESC_bLength] != 0U) {
768 switch (p[DESC_bDescriptorType]) {
769 case USB_DESC_INTERFACE:
770 /* remember current alternate setting */
771 cur_alt_setting = p[INTF_DESC_bAlternateSetting];
772 cur_iface = p[INTF_DESC_bInterfaceNumber];
773
774 if (cur_iface == setup->wIndex &&
775 cur_alt_setting == setup->wValue) {
776 ret = usb_set_alt_setting(setup->wIndex,
777 setup->wValue);
778 if_desc = (void *)p;
779 }
780
781 LOG_DBG("Current iface %u alt setting %u",
782 cur_iface, cur_alt_setting);
783 break;
784 case USB_DESC_ENDPOINT:
785 if (cur_iface == setup->wIndex) {
786 ep = (struct usb_ep_descriptor *)p;
787 ret = usb_eps_reconfigure(ep, cur_alt_setting,
788 setup->wValue);
789 }
790 break;
791 default:
792 break;
793 }
794
795 /* skip to next descriptor */
796 p += p[DESC_bLength];
797 }
798
799 if (usb_dev.status_callback) {
800 usb_dev.status_callback(USB_DC_INTERFACE, if_desc);
801 }
802
803 return ret;
804 }
805
usb_get_interface(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data_buf)806 static bool usb_get_interface(struct usb_setup_packet *setup,
807 int32_t *len, uint8_t **data_buf)
808 {
809 const uint8_t *p = usb_dev.descriptors;
810 uint8_t *data = *data_buf;
811 uint8_t cur_iface;
812
813 while (p[DESC_bLength] != 0U) {
814 if (p[DESC_bDescriptorType] == USB_DESC_INTERFACE) {
815 cur_iface = p[INTF_DESC_bInterfaceNumber];
816 if (cur_iface == setup->wIndex) {
817 data[0] = usb_get_alt_setting(cur_iface);
818 LOG_DBG("Current iface %u alt setting %u",
819 setup->wIndex, data[0]);
820 *len = 1;
821 return true;
822 }
823 }
824
825 /* skip to next descriptor */
826 p += p[DESC_bLength];
827 }
828
829 return false;
830 }
831
832 /**
833 * @brief Check if the device is in Configured state
834 *
835 * @return true if Configured, false otherwise.
836 */
is_device_configured(void)837 static bool is_device_configured(void)
838 {
839 return (usb_dev.configuration != 0);
840 }
841
842 /*
843 * @brief handle a standard device request
844 *
845 * @param [in] setup The setup packet
846 * @param [in,out] len Pointer to data length
847 * @param [in,out] data_buf Data buffer
848 *
849 * @return true if the request was handled successfully
850 */
usb_handle_std_device_req(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data_buf)851 static bool usb_handle_std_device_req(struct usb_setup_packet *setup,
852 int32_t *len, uint8_t **data_buf)
853 {
854 uint8_t *data = *data_buf;
855
856 if (usb_reqtype_is_to_host(setup)) {
857 switch (setup->bRequest) {
858 case USB_SREQ_GET_STATUS:
859 return usb_get_status(setup, len, data_buf);
860
861 case USB_SREQ_GET_DESCRIPTOR:
862 return usb_get_descriptor(setup, len, data_buf);
863
864 case USB_SREQ_GET_CONFIGURATION:
865 LOG_DBG("Get Configuration request");
866 /* indicate if we are configured */
867 data[0] = usb_dev.configuration;
868 *len = 1;
869 return true;
870 default:
871 break;
872 }
873 } else {
874 switch (setup->bRequest) {
875 case USB_SREQ_SET_ADDRESS:
876 LOG_DBG("Set Address %u request", setup->wValue);
877 return !usb_dc_set_address(setup->wValue);
878
879 case USB_SREQ_SET_CONFIGURATION:
880 return usb_set_configuration(setup);
881
882 case USB_SREQ_CLEAR_FEATURE:
883 LOG_DBG("Clear Feature request");
884
885 if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
886 if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
887 usb_dev.remote_wakeup = false;
888 return true;
889 }
890 }
891 break;
892
893 case USB_SREQ_SET_FEATURE:
894 LOG_DBG("Set Feature request");
895
896 if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
897 if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
898 usb_dev.remote_wakeup = true;
899 return true;
900 }
901 }
902 break;
903
904 default:
905 break;
906 }
907 }
908
909 LOG_DBG("Unsupported bmRequestType 0x%02x bRequest 0x%02x",
910 setup->bmRequestType, setup->bRequest);
911 return false;
912 }
913
914 /**
915 * @brief Check if the interface of given number is valid
916 *
917 * @param [in] interface Number of the addressed interface
918 *
919 * This function searches through descriptor and checks
920 * is the Host has addressed valid interface.
921 *
922 * @return true if interface exists - valid
923 */
is_interface_valid(uint8_t interface)924 static bool is_interface_valid(uint8_t interface)
925 {
926 const uint8_t *p = (uint8_t *)usb_dev.descriptors;
927 const struct usb_cfg_descriptor *cfg_descr;
928
929 /* Search through descriptor for matching interface */
930 while (p[DESC_bLength] != 0U) {
931 if (p[DESC_bDescriptorType] == USB_DESC_CONFIGURATION) {
932 cfg_descr = (const struct usb_cfg_descriptor *)p;
933 if (interface < cfg_descr->bNumInterfaces) {
934 return true;
935 }
936 }
937 p += p[DESC_bLength];
938 }
939
940 return false;
941 }
942
943 /*
944 * @brief handle a standard interface request
945 *
946 * @param [in] setup The setup packet
947 * @param [in,out] len Pointer to data length
948 * @param [in] data_buf Data buffer
949 *
950 * @return true if the request was handled successfully
951 */
usb_handle_std_interface_req(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data_buf)952 static bool usb_handle_std_interface_req(struct usb_setup_packet *setup,
953 int32_t *len, uint8_t **data_buf)
954 {
955 uint8_t *data = *data_buf;
956
957 /** The device must be configured to accept standard interface
958 * requests and the addressed Interface must be valid.
959 */
960 if (!is_device_configured() ||
961 (!is_interface_valid((uint8_t)setup->wIndex))) {
962 return false;
963 }
964
965 if (usb_reqtype_is_to_host(setup)) {
966 switch (setup->bRequest) {
967 case USB_SREQ_GET_STATUS:
968 /* no bits specified */
969 data[0] = 0U;
970 data[1] = 0U;
971 *len = 2;
972 return true;
973
974 case USB_SREQ_GET_INTERFACE:
975 return usb_get_interface(setup, len, data_buf);
976
977 default:
978 break;
979 }
980 } else {
981 if (setup->bRequest == USB_SREQ_SET_INTERFACE) {
982 return usb_set_interface(setup);
983 }
984
985 }
986
987 LOG_DBG("Unsupported bmRequestType 0x%02x bRequest 0x%02x",
988 setup->bmRequestType, setup->bRequest);
989 return false;
990 }
991
992 /**
993 * @brief Check if the endpoint of given address is valid
994 *
995 * @param [in] ep Address of the Endpoint
996 *
997 * This function checks if the Endpoint of given address
998 * is valid for the configured device. Valid Endpoint is
999 * either Control Endpoint or one used by the device.
1000 *
1001 * @return true if endpoint exists - valid
1002 */
is_ep_valid(uint8_t ep)1003 static bool is_ep_valid(uint8_t ep)
1004 {
1005 const struct usb_ep_cfg_data *ep_data;
1006
1007 /* Check if its Endpoint 0 */
1008 if (USB_EP_GET_IDX(ep) == 0) {
1009 return true;
1010 }
1011
1012 STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
1013 ep_data = cfg_data->endpoint;
1014
1015 for (uint8_t n = 0; n < cfg_data->num_endpoints; n++) {
1016 if (ep_data[n].ep_addr == ep) {
1017 return true;
1018 }
1019 }
1020 }
1021
1022 return false;
1023 }
1024
usb_get_status_endpoint(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data_buf)1025 static bool usb_get_status_endpoint(struct usb_setup_packet *setup,
1026 int32_t *len, uint8_t **data_buf)
1027 {
1028 uint8_t ep = setup->wIndex;
1029 uint8_t *data = *data_buf;
1030
1031 /* Check if request addresses valid Endpoint */
1032 if (!is_ep_valid(ep)) {
1033 return false;
1034 }
1035
1036 /* This request is valid for Control Endpoints when
1037 * the device is not yet configured. For other
1038 * Endpoints the device must be configured.
1039 * Firstly check if addressed ep is Control Endpoint.
1040 * If no then the device must be in Configured state
1041 * to accept the request.
1042 */
1043 if ((USB_EP_GET_IDX(ep) == 0) || is_device_configured()) {
1044 /* bit 0 - Endpoint halted or not */
1045 usb_dc_ep_is_stalled(ep, &data[0]);
1046 data[1] = 0U;
1047 *len = 2;
1048 return true;
1049 }
1050
1051 return false;
1052 }
1053
1054
usb_halt_endpoint_req(struct usb_setup_packet * setup,bool halt)1055 static bool usb_halt_endpoint_req(struct usb_setup_packet *setup, bool halt)
1056 {
1057 uint8_t ep = setup->wIndex;
1058
1059 /* Check if request addresses valid Endpoint */
1060 if (!is_ep_valid(ep)) {
1061 return false;
1062 }
1063
1064 /* This request is valid for Control Endpoints when
1065 * the device is not yet configured. For other
1066 * Endpoints the device must be configured.
1067 * Firstly check if addressed ep is Control Endpoint.
1068 * If no then the device must be in Configured state
1069 * to accept the request.
1070 */
1071 if ((USB_EP_GET_IDX(ep) == 0) || is_device_configured()) {
1072 if (halt) {
1073 LOG_INF("Set halt ep 0x%02x", ep);
1074 usb_dc_ep_set_stall(ep);
1075 if (usb_dev.status_callback) {
1076 usb_dev.status_callback(USB_DC_SET_HALT, &ep);
1077 }
1078 } else {
1079 LOG_INF("Clear halt ep 0x%02x", ep);
1080 usb_dc_ep_clear_stall(ep);
1081 if (usb_dev.status_callback) {
1082 usb_dev.status_callback(USB_DC_CLEAR_HALT, &ep);
1083 }
1084 }
1085
1086 return true;
1087 }
1088
1089 return false;
1090 }
1091
1092 /*
1093 * @brief handle a standard endpoint request
1094 *
1095 * @param [in] setup The setup packet
1096 * @param [in,out] len Pointer to data length
1097 * @param [in] data_buf Data buffer
1098 *
1099 * @return true if the request was handled successfully
1100 */
usb_handle_std_endpoint_req(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data_buf)1101 static bool usb_handle_std_endpoint_req(struct usb_setup_packet *setup,
1102 int32_t *len, uint8_t **data_buf)
1103 {
1104
1105 if (usb_reqtype_is_to_host(setup)) {
1106 if (setup->bRequest == USB_SREQ_GET_STATUS) {
1107 return usb_get_status_endpoint(setup, len, data_buf);
1108 }
1109 } else {
1110 switch (setup->bRequest) {
1111 case USB_SREQ_CLEAR_FEATURE:
1112 if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
1113 return usb_halt_endpoint_req(setup, false);
1114 }
1115 break;
1116 case USB_SREQ_SET_FEATURE:
1117 if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
1118 return usb_halt_endpoint_req(setup, true);
1119 }
1120 break;
1121 default:
1122 break;
1123 }
1124 }
1125
1126 LOG_DBG("Unsupported bmRequestType 0x%02x bRequest 0x%02x",
1127 setup->bmRequestType, setup->bRequest);
1128 return false;
1129 }
1130
1131 /*
1132 * @brief default handler for standard ('chapter 9') requests
1133 *
1134 * If a custom request handler was installed, this handler is called first.
1135 *
1136 * @param [in] setup The setup packet
1137 * @param [in,out] len Pointer to data length
1138 * @param [in] data_buf Data buffer
1139 *
1140 * @return true if the request was handled successfully
1141 */
usb_handle_standard_request(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data_buf)1142 static int usb_handle_standard_request(struct usb_setup_packet *setup,
1143 int32_t *len, uint8_t **data_buf)
1144 {
1145 int rc = 0;
1146
1147 if (!usb_handle_bos(setup, len, data_buf)) {
1148 return 0;
1149 }
1150
1151 if (!usb_handle_os_desc(setup, len, data_buf)) {
1152 return 0;
1153 }
1154
1155 /* try the custom request handler first */
1156 if (usb_dev.custom_req_handler &&
1157 !usb_dev.custom_req_handler(setup, len, data_buf)) {
1158 return 0;
1159 }
1160
1161 switch (setup->RequestType.recipient) {
1162 case USB_REQTYPE_RECIPIENT_DEVICE:
1163 if (usb_handle_std_device_req(setup, len, data_buf) == false) {
1164 rc = -EINVAL;
1165 }
1166 break;
1167 case USB_REQTYPE_RECIPIENT_INTERFACE:
1168 if (usb_handle_std_interface_req(setup, len, data_buf) == false) {
1169 rc = -EINVAL;
1170 }
1171 break;
1172 case USB_REQTYPE_RECIPIENT_ENDPOINT:
1173 if (usb_handle_std_endpoint_req(setup, len, data_buf) == false) {
1174 rc = -EINVAL;
1175 }
1176 break;
1177 default:
1178 rc = -EINVAL;
1179 }
1180 return rc;
1181 }
1182
1183 /*
1184 * @brief Registers a callback for custom device requests
1185 *
1186 * In usb_register_custom_req_handler, the custom request handler gets a first
1187 * chance at handling the request before it is handed over to the 'chapter 9'
1188 * request handler.
1189 *
1190 * This can be used for example in HID devices, where a REQ_GET_DESCRIPTOR
1191 * request is sent to an interface, which is not covered by the 'chapter 9'
1192 * specification.
1193 *
1194 * @param [in] handler Callback function pointer
1195 */
usb_register_custom_req_handler(usb_request_handler handler)1196 static void usb_register_custom_req_handler(usb_request_handler handler)
1197 {
1198 usb_dev.custom_req_handler = handler;
1199 }
1200
1201 /*
1202 * @brief register a callback for device status
1203 *
1204 * This function registers a callback for device status. The registered callback
1205 * is used to report changes in the status of the device controller.
1206 *
1207 * @param [in] cb Callback function pointer
1208 */
usb_register_status_callback(usb_dc_status_callback cb)1209 static void usb_register_status_callback(usb_dc_status_callback cb)
1210 {
1211 usb_dev.status_callback = cb;
1212 }
1213
foreach_ep(int (* endpoint_callback)(const struct usb_ep_cfg_data *))1214 static int foreach_ep(int (* endpoint_callback)(const struct usb_ep_cfg_data *))
1215 {
1216 struct usb_ep_cfg_data *ep_data;
1217
1218 STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
1219 ep_data = cfg_data->endpoint;
1220
1221 for (uint8_t n = 0; n < cfg_data->num_endpoints; n++) {
1222 int ret;
1223
1224 ret = endpoint_callback(&ep_data[n]);
1225 if (ret < 0) {
1226 return ret;
1227 }
1228 }
1229 }
1230
1231 return 0;
1232 }
1233
disable_interface_ep(const struct usb_ep_cfg_data * ep_data)1234 static int disable_interface_ep(const struct usb_ep_cfg_data *ep_data)
1235 {
1236 uint32_t ep_bm;
1237 int ret;
1238
1239 ret = usb_dc_ep_disable(ep_data->ep_addr);
1240
1241 /* clear endpoint mask */
1242 ep_bm = get_ep_bm_from_addr(ep_data->ep_addr);
1243 usb_dev.ep_bm &= ~ep_bm;
1244
1245 return ret;
1246 }
1247
forward_status_cb(enum usb_dc_status_code status,const uint8_t * param)1248 static void forward_status_cb(enum usb_dc_status_code status, const uint8_t *param)
1249 {
1250 if (status == USB_DC_DISCONNECTED) {
1251 usb_reset_alt_setting();
1252 }
1253
1254 if (status == USB_DC_DISCONNECTED || status == USB_DC_RESET) {
1255 if (usb_dev.configured) {
1256 usb_cancel_transfers();
1257 foreach_ep(disable_interface_ep);
1258 usb_dev.configured = false;
1259 }
1260 }
1261
1262 STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
1263 if (cfg_data->cb_usb_status) {
1264 cfg_data->cb_usb_status(cfg_data, status, param);
1265 }
1266 }
1267
1268 if (usb_dev.user_status_callback) {
1269 usb_dev.user_status_callback(status, param);
1270 }
1271 }
1272
1273 /**
1274 * @brief turn on/off USB VBUS voltage
1275 *
1276 * To utilize this in the devicetree the chosen node should have a
1277 * zephyr,usb-device property that points to the usb device controller node.
1278 * Additionally the usb device controller node should have a vbus-gpios
1279 * property that has the GPIO details.
1280 *
1281 * Something like:
1282 *
1283 * chosen {
1284 * zephyr,usb-device = &usbd;
1285 * };
1286 *
1287 * usbd: usbd {
1288 * vbus-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
1289 * };
1290 *
1291 * @param on Set to false to turn off and to true to turn on VBUS
1292 *
1293 * @return 0 on success, negative errno code on fail
1294 */
usb_vbus_set(bool on)1295 static int usb_vbus_set(bool on)
1296 {
1297 #define USB_DEV_NODE DT_CHOSEN(zephyr_usb_device)
1298 #if DT_NODE_HAS_STATUS(USB_DEV_NODE, okay) && \
1299 DT_NODE_HAS_PROP(USB_DEV_NODE, vbus_gpios)
1300 int ret = 0;
1301 struct gpio_dt_spec gpio_dev = GPIO_DT_SPEC_GET(USB_DEV_NODE, vbus_gpios);
1302
1303 if (!gpio_is_ready_dt(&gpio_dev)) {
1304 LOG_DBG("USB requires GPIO. Device %s is not ready!", gpio_dev.port->name);
1305 return -ENODEV;
1306 }
1307
1308 /* Enable USB IO */
1309 ret = gpio_pin_configure_dt(&gpio_dev, GPIO_OUTPUT);
1310 if (ret) {
1311 return ret;
1312 }
1313
1314 ret = gpio_pin_set_dt(&gpio_dev, on == true ? 1 : 0);
1315 if (ret) {
1316 return ret;
1317 }
1318 #endif
1319
1320 return 0;
1321 }
1322
usb_deconfig(void)1323 int usb_deconfig(void)
1324 {
1325 /* unregister descriptors */
1326 usb_register_descriptors(NULL);
1327
1328 /* unregister standard request handler */
1329 usb_register_request_handler(USB_REQTYPE_TYPE_STANDARD, NULL);
1330
1331 /* unregister class request handlers for each interface*/
1332 usb_register_request_handler(USB_REQTYPE_TYPE_CLASS, NULL);
1333
1334 /* unregister class request handlers for each interface*/
1335 usb_register_custom_req_handler(NULL);
1336
1337 /* unregister status callback */
1338 usb_register_status_callback(NULL);
1339
1340 /* unregister user status callback */
1341 usb_dev.user_status_callback = NULL;
1342
1343 /* Reset USB controller */
1344 usb_dc_reset();
1345
1346 return 0;
1347 }
1348
usb_disable(void)1349 int usb_disable(void)
1350 {
1351 int ret;
1352
1353 if (usb_dev.enabled != true) {
1354 /*Already disabled*/
1355 return 0;
1356 }
1357
1358 ret = usb_dc_detach();
1359 if (ret < 0) {
1360 return ret;
1361 }
1362
1363 usb_cancel_transfers();
1364 for (uint8_t i = 0; i <= 15; i++) {
1365 if (usb_dev.ep_bm & BIT(i)) {
1366 ret = disable_endpoint(i);
1367 if (ret < 0) {
1368 return ret;
1369 }
1370 }
1371 if (usb_dev.ep_bm & BIT(i + 16)) {
1372 ret = disable_endpoint(USB_EP_DIR_IN | i);
1373 if (ret < 0) {
1374 return ret;
1375 }
1376 }
1377 }
1378
1379 /* Disable VBUS if needed */
1380 usb_vbus_set(false);
1381
1382 usb_dev.enabled = false;
1383
1384 return 0;
1385 }
1386
usb_write(uint8_t ep,const uint8_t * data,uint32_t data_len,uint32_t * bytes_ret)1387 int usb_write(uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *bytes_ret)
1388 {
1389 int tries = CONFIG_USB_NUMOF_EP_WRITE_RETRIES;
1390 int ret;
1391
1392 do {
1393 ret = usb_dc_ep_write(ep, data, data_len, bytes_ret);
1394 if (ret == -EAGAIN) {
1395 LOG_WRN("Failed to write endpoint buffer 0x%02x", ep);
1396 k_yield();
1397 }
1398
1399 } while (ret == -EAGAIN && tries--);
1400
1401 return ret;
1402 }
1403
usb_read(uint8_t ep,uint8_t * data,uint32_t max_data_len,uint32_t * ret_bytes)1404 int usb_read(uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *ret_bytes)
1405 {
1406 return usb_dc_ep_read(ep, data, max_data_len, ret_bytes);
1407 }
1408
usb_ep_set_stall(uint8_t ep)1409 int usb_ep_set_stall(uint8_t ep)
1410 {
1411 return usb_dc_ep_set_stall(ep);
1412 }
1413
usb_ep_clear_stall(uint8_t ep)1414 int usb_ep_clear_stall(uint8_t ep)
1415 {
1416 return usb_dc_ep_clear_stall(ep);
1417 }
1418
usb_ep_read_wait(uint8_t ep,uint8_t * data,uint32_t max_data_len,uint32_t * ret_bytes)1419 int usb_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *ret_bytes)
1420 {
1421 return usb_dc_ep_read_wait(ep, data, max_data_len, ret_bytes);
1422 }
1423
usb_ep_read_continue(uint8_t ep)1424 int usb_ep_read_continue(uint8_t ep)
1425 {
1426 return usb_dc_ep_read_continue(ep);
1427 }
1428
usb_get_remote_wakeup_status(void)1429 bool usb_get_remote_wakeup_status(void)
1430 {
1431 return usb_dev.remote_wakeup;
1432 }
1433
usb_wakeup_request(void)1434 int usb_wakeup_request(void)
1435 {
1436 if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
1437 if (usb_get_remote_wakeup_status()) {
1438 return usb_dc_wakeup_request();
1439 }
1440 return -EACCES;
1441 } else {
1442 return -ENOTSUP;
1443 }
1444 }
1445
1446 /*
1447 * The functions class_handler(), custom_handler() and vendor_handler()
1448 * go through the interfaces one after the other and compare the
1449 * bInterfaceNumber with the wIndex and then call the appropriate
1450 * callback of the USB function.
1451 * Note, a USB function can have more than one interface and the
1452 * request does not have to be directed to the first interface (unlikely).
1453 * These functions can be simplified and moved to usb_handle_request()
1454 * when legacy initialization through the usb_set_config() and
1455 * usb_enable() is no longer needed.
1456 */
1457
class_handler(struct usb_setup_packet * pSetup,int32_t * len,uint8_t ** data)1458 static int class_handler(struct usb_setup_packet *pSetup,
1459 int32_t *len, uint8_t **data)
1460 {
1461 const struct usb_if_descriptor *if_descr;
1462 struct usb_interface_cfg_data *iface;
1463
1464 LOG_DBG("bRequest 0x%02x, wIndex 0x%04x",
1465 pSetup->bRequest, pSetup->wIndex);
1466
1467 STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
1468 iface = &cfg_data->interface;
1469 if_descr = cfg_data->interface_descriptor;
1470 /*
1471 * Wind forward until it is within the range
1472 * of the current descriptor.
1473 */
1474 if ((uint8_t *)if_descr < usb_dev.descriptors) {
1475 continue;
1476 }
1477
1478 if (iface->class_handler &&
1479 if_descr->bInterfaceNumber == (pSetup->wIndex & 0xFF)) {
1480 return iface->class_handler(pSetup, len, data);
1481 }
1482 }
1483
1484 return -ENOTSUP;
1485 }
1486
custom_handler(struct usb_setup_packet * pSetup,int32_t * len,uint8_t ** data)1487 static int custom_handler(struct usb_setup_packet *pSetup,
1488 int32_t *len, uint8_t **data)
1489 {
1490 const struct usb_if_descriptor *if_descr;
1491 struct usb_interface_cfg_data *iface;
1492
1493 LOG_DBG("bRequest 0x%02x, wIndex 0x%04x",
1494 pSetup->bRequest, pSetup->wIndex);
1495
1496 STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
1497 iface = &cfg_data->interface;
1498 if_descr = cfg_data->interface_descriptor;
1499 /*
1500 * Wind forward until it is within the range
1501 * of the current descriptor.
1502 */
1503 if ((uint8_t *)if_descr < usb_dev.descriptors) {
1504 continue;
1505 }
1506
1507 if (iface->custom_handler == NULL) {
1508 continue;
1509 }
1510
1511 if (if_descr->bInterfaceNumber == (pSetup->wIndex & 0xFF)) {
1512 return iface->custom_handler(pSetup, len, data);
1513 } else {
1514 /*
1515 * Audio has several interfaces. if_descr points to
1516 * the first interface, but the request may be for
1517 * subsequent ones, so forward each request to audio.
1518 * The class does not actively engage in request
1519 * handling and therefore we can ignore return value.
1520 */
1521 if (if_descr->bInterfaceClass == USB_BCC_AUDIO) {
1522 (void)iface->custom_handler(pSetup, len, data);
1523 }
1524 }
1525 }
1526
1527 return -ENOTSUP;
1528 }
1529
vendor_handler(struct usb_setup_packet * pSetup,int32_t * len,uint8_t ** data)1530 static int vendor_handler(struct usb_setup_packet *pSetup,
1531 int32_t *len, uint8_t **data)
1532 {
1533 struct usb_interface_cfg_data *iface;
1534
1535 LOG_DBG("bRequest 0x%02x, wIndex 0x%04x",
1536 pSetup->bRequest, pSetup->wIndex);
1537
1538 if (usb_os_desc_enabled()) {
1539 if (!usb_handle_os_desc_feature(pSetup, len, data)) {
1540 return 0;
1541 }
1542 }
1543
1544 STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
1545 iface = &cfg_data->interface;
1546 if (iface->vendor_handler) {
1547 if (!iface->vendor_handler(pSetup, len, data)) {
1548 return 0;
1549 }
1550 }
1551 }
1552
1553 return -ENOTSUP;
1554 }
1555
composite_setup_ep_cb(void)1556 static int composite_setup_ep_cb(void)
1557 {
1558 struct usb_ep_cfg_data *ep_data;
1559
1560 STRUCT_SECTION_FOREACH(usb_cfg_data, cfg_data) {
1561 ep_data = cfg_data->endpoint;
1562 for (uint8_t n = 0; n < cfg_data->num_endpoints; n++) {
1563 LOG_DBG("set cb, ep: 0x%x", ep_data[n].ep_addr);
1564 if (usb_dc_ep_set_callback(ep_data[n].ep_addr,
1565 ep_data[n].ep_cb)) {
1566 return -1;
1567 }
1568 }
1569 }
1570
1571 return 0;
1572 }
1573
usb_set_config(const uint8_t * device_descriptor)1574 int usb_set_config(const uint8_t *device_descriptor)
1575 {
1576 /* register descriptors */
1577 usb_register_descriptors(device_descriptor);
1578
1579 /* register standard request handler */
1580 usb_register_request_handler(USB_REQTYPE_TYPE_STANDARD,
1581 usb_handle_standard_request);
1582
1583 /* register class request handlers for each interface*/
1584 usb_register_request_handler(USB_REQTYPE_TYPE_CLASS, class_handler);
1585
1586 /* register vendor request handler */
1587 usb_register_request_handler(USB_REQTYPE_TYPE_VENDOR, vendor_handler);
1588
1589 /* register class request handlers for each interface*/
1590 usb_register_custom_req_handler(custom_handler);
1591
1592 return 0;
1593 }
1594
usb_enable(usb_dc_status_callback status_cb)1595 int usb_enable(usb_dc_status_callback status_cb)
1596 {
1597 int ret;
1598 struct usb_dc_ep_cfg_data ep0_cfg;
1599 struct usb_device_descriptor *dev_desc;
1600
1601 /* Prevent from calling usb_enable form different context.
1602 * This should only be called once.
1603 */
1604 LOG_DBG("lock usb_enable_lock mutex");
1605 k_mutex_lock(&usb_enable_lock, K_FOREVER);
1606
1607 if (usb_dev.enabled == true) {
1608 LOG_WRN("USB device support already enabled");
1609 ret = -EALREADY;
1610 goto out;
1611 }
1612
1613 /*
1614 * If usb_dev.descriptors is equal to NULL (usb_dev has static
1615 * specifier), then usb_get_device_descriptor() and usb_set_config()
1616 * are likely not called yet. If so, set the configuration here.
1617 */
1618 if (usb_dev.descriptors == NULL) {
1619 usb_set_config(usb_get_device_descriptor());
1620 if (usb_dev.descriptors == NULL) {
1621 LOG_ERR("Failed to configure USB device stack");
1622 ret = -1;
1623 goto out;
1624 }
1625 }
1626
1627 /* Enable VBUS if needed */
1628 ret = usb_vbus_set(true);
1629 if (ret < 0) {
1630 goto out;
1631 }
1632
1633 dev_desc = (void *)usb_dev.descriptors;
1634 usb_dev.user_status_callback = status_cb;
1635 usb_register_status_callback(forward_status_cb);
1636 usb_dc_set_status_callback(forward_status_cb);
1637
1638 ret = usb_dc_attach();
1639 if (ret < 0) {
1640 goto out;
1641 }
1642
1643 ret = usb_transfer_init();
1644 if (ret < 0) {
1645 goto out;
1646 }
1647
1648 if (dev_desc->bDescriptorType != USB_DESC_DEVICE ||
1649 dev_desc->bMaxPacketSize0 == 0) {
1650 LOG_ERR("Erroneous device descriptor or bMaxPacketSize0");
1651 ret = -EINVAL;
1652 goto out;
1653 }
1654
1655 /* Configure control EP */
1656 usb_dev.mps0 = dev_desc->bMaxPacketSize0;
1657 ep0_cfg.ep_mps = usb_dev.mps0;
1658 ep0_cfg.ep_type = USB_DC_EP_CONTROL;
1659
1660 ep0_cfg.ep_addr = USB_CONTROL_EP_OUT;
1661 ret = usb_dc_ep_configure(&ep0_cfg);
1662 if (ret < 0) {
1663 goto out;
1664 }
1665
1666 ep0_cfg.ep_addr = USB_CONTROL_EP_IN;
1667 ret = usb_dc_ep_configure(&ep0_cfg);
1668 if (ret < 0) {
1669 goto out;
1670 }
1671
1672 /* Register endpoint 0 handlers*/
1673 ret = usb_dc_ep_set_callback(USB_CONTROL_EP_OUT,
1674 usb_handle_control_transfer);
1675 if (ret < 0) {
1676 goto out;
1677 }
1678
1679 ret = usb_dc_ep_set_callback(USB_CONTROL_EP_IN,
1680 usb_handle_control_transfer);
1681 if (ret < 0) {
1682 goto out;
1683 }
1684
1685 /* Register endpoint handlers*/
1686 ret = composite_setup_ep_cb();
1687 if (ret < 0) {
1688 goto out;
1689 }
1690
1691 /* Enable control EP */
1692 ret = usb_dc_ep_enable(USB_CONTROL_EP_OUT);
1693 if (ret < 0) {
1694 goto out;
1695 }
1696 usb_dev.ep_bm |= get_ep_bm_from_addr(USB_CONTROL_EP_OUT);
1697
1698 ret = usb_dc_ep_enable(USB_CONTROL_EP_IN);
1699 if (ret < 0) {
1700 goto out;
1701 }
1702 usb_dev.ep_bm |= get_ep_bm_from_addr(USB_CONTROL_EP_IN);
1703
1704 usb_dev.enabled = true;
1705 ret = 0;
1706 out:
1707 LOG_DBG("unlock usb_enable_lock mutex");
1708 k_mutex_unlock(&usb_enable_lock);
1709 return ret;
1710 }
1711
1712 #if defined(CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT)
usb_device_init(void)1713 static int usb_device_init(void)
1714 {
1715 return usb_enable(NULL);
1716 }
1717
1718 SYS_INIT(usb_device_init, POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY);
1719 #endif
1720