1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/usb/usbd.h>
10 #include <zephyr/drivers/usb/udc.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/slist.h>
13
14 #include "usbd_device.h"
15 #include "usbd_desc.h"
16 #include "usbd_ch9.h"
17 #include "usbd_config.h"
18 #include "usbd_class.h"
19 #include "usbd_class_api.h"
20 #include "usbd_interface.h"
21
22 #include <zephyr/logging/log.h>
23 LOG_MODULE_REGISTER(usbd_ch9, CONFIG_USBD_LOG_LEVEL);
24
25 #define CTRL_AWAIT_SETUP_DATA 0
26 #define CTRL_AWAIT_STATUS_STAGE 1
27
reqtype_is_to_host(const struct usb_setup_packet * const setup)28 static bool reqtype_is_to_host(const struct usb_setup_packet *const setup)
29 {
30 return setup->wLength && USB_REQTYPE_GET_DIR(setup->bmRequestType);
31 }
32
reqtype_is_to_device(const struct usb_setup_packet * const setup)33 static bool reqtype_is_to_device(const struct usb_setup_packet *const setup)
34 {
35 return !reqtype_is_to_host(setup);
36 }
37
ch9_set_ctrl_type(struct usbd_contex * const uds_ctx,const int type)38 static void ch9_set_ctrl_type(struct usbd_contex *const uds_ctx,
39 const int type)
40 {
41 uds_ctx->ch9_data.ctrl_type = type;
42 }
43
ch9_get_ctrl_type(struct usbd_contex * const uds_ctx)44 static int ch9_get_ctrl_type(struct usbd_contex *const uds_ctx)
45 {
46 return uds_ctx->ch9_data.ctrl_type;
47 }
48
set_address_after_status_stage(struct usbd_contex * const uds_ctx)49 static int set_address_after_status_stage(struct usbd_contex *const uds_ctx)
50 {
51 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
52 int ret;
53
54 ret = udc_set_address(uds_ctx->dev, setup->wValue);
55 if (ret) {
56 LOG_ERR("Failed to set device address 0x%x", setup->wValue);
57 return ret;
58 }
59
60 uds_ctx->ch9_data.new_address = false;
61
62 return ret;
63 }
64
sreq_set_address(struct usbd_contex * const uds_ctx)65 static int sreq_set_address(struct usbd_contex *const uds_ctx)
66 {
67 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
68
69 /* Not specified if wLength is non-zero, treat as error */
70 if (setup->wValue > 127 || setup->wLength) {
71 errno = -ENOTSUP;
72 return 0;
73 }
74
75 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
76 errno = -ENOTSUP;
77 return 0;
78 }
79
80 if (usbd_state_is_configured(uds_ctx)) {
81 errno = -EPERM;
82 return 0;
83 }
84
85 uds_ctx->ch9_data.new_address = true;
86 if (usbd_state_is_address(uds_ctx) && setup->wValue == 0) {
87 uds_ctx->ch9_data.state = USBD_STATE_DEFAULT;
88 } else {
89 uds_ctx->ch9_data.state = USBD_STATE_ADDRESS;
90 }
91
92
93 return 0;
94 }
95
sreq_set_configuration(struct usbd_contex * const uds_ctx)96 static int sreq_set_configuration(struct usbd_contex *const uds_ctx)
97 {
98 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
99 int ret;
100
101 LOG_INF("Set Configuration Request value %u", setup->wValue);
102
103 /* Not specified if wLength is non-zero, treat as error */
104 if (setup->wValue > UINT8_MAX || setup->wLength) {
105 errno = -ENOTSUP;
106 return 0;
107 }
108
109 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
110 errno = -ENOTSUP;
111 return 0;
112 }
113
114 if (usbd_state_is_default(uds_ctx)) {
115 errno = -EPERM;
116 return 0;
117 }
118
119 if (setup->wValue && !usbd_config_exist(uds_ctx, setup->wValue)) {
120 errno = -EPERM;
121 return 0;
122 }
123
124 if (setup->wValue == usbd_get_config_value(uds_ctx)) {
125 LOG_DBG("Already in the configuration %u", setup->wValue);
126 return 0;
127 }
128
129 ret = usbd_config_set(uds_ctx, setup->wValue);
130 if (ret) {
131 LOG_ERR("Failed to set configuration %u, %d",
132 setup->wValue, ret);
133 return ret;
134 }
135
136 if (setup->wValue == 0) {
137 /* Enter address state */
138 uds_ctx->ch9_data.state = USBD_STATE_ADDRESS;
139 } else {
140 uds_ctx->ch9_data.state = USBD_STATE_CONFIGURED;
141 }
142
143 return ret;
144 }
145
sreq_set_interface(struct usbd_contex * const uds_ctx)146 static int sreq_set_interface(struct usbd_contex *const uds_ctx)
147 {
148 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
149 int ret;
150
151 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_INTERFACE) {
152 errno = -ENOTSUP;
153 return 0;
154 }
155
156 /* Not specified if wLength is non-zero, treat as error */
157 if (setup->wLength) {
158 errno = -ENOTSUP;
159 return 0;
160 }
161
162 if (setup->wValue > UINT8_MAX || setup->wIndex > UINT8_MAX) {
163 errno = -ENOTSUP;
164 return 0;
165 }
166
167 if (!usbd_state_is_configured(uds_ctx)) {
168 errno = -EPERM;
169 return 0;
170 }
171
172 ret = usbd_interface_set(uds_ctx, setup->wIndex, setup->wValue);
173 if (ret == -ENOENT) {
174 LOG_INF("Interface or alternate does not exist");
175 errno = ret;
176 ret = 0;
177 }
178
179 return ret;
180 }
181
sreq_feature_halt_notify(struct usbd_contex * const uds_ctx,const uint8_t ep,const bool halted)182 static void sreq_feature_halt_notify(struct usbd_contex *const uds_ctx,
183 const uint8_t ep, const bool halted)
184 {
185 struct usbd_class_node *c_nd = usbd_class_get_by_ep(uds_ctx, ep);
186
187 if (c_nd != NULL) {
188 usbd_class_feature_halt(c_nd, ep, halted);
189 }
190 }
191
sreq_clear_feature(struct usbd_contex * const uds_ctx)192 static int sreq_clear_feature(struct usbd_contex *const uds_ctx)
193 {
194 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
195 uint8_t ep = setup->wIndex;
196 int ret = 0;
197
198 /* Not specified if wLength is non-zero, treat as error */
199 if (setup->wLength) {
200 errno = -ENOTSUP;
201 return 0;
202 }
203
204 /* Not specified in default state, treat as error */
205 if (usbd_state_is_default(uds_ctx)) {
206 errno = -EPERM;
207 return 0;
208 }
209
210 if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
211 errno = -EPERM;
212 return 0;
213 }
214
215 switch (setup->RequestType.recipient) {
216 case USB_REQTYPE_RECIPIENT_DEVICE:
217 if (setup->wIndex != 0) {
218 errno = -EPERM;
219 return 0;
220 }
221
222 if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
223 LOG_DBG("Clear feature remote wakeup");
224 uds_ctx->status.rwup = false;
225 }
226 break;
227 case USB_REQTYPE_RECIPIENT_ENDPOINT:
228 if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
229 /* UDC checks if endpoint is enabled */
230 errno = usbd_ep_clear_halt(uds_ctx, ep);
231 ret = (errno == -EPERM) ? errno : 0;
232 if (ret == 0) {
233 /* Notify class instance */
234 sreq_feature_halt_notify(uds_ctx, ep, false);
235 }
236 break;
237 }
238 break;
239 case USB_REQTYPE_RECIPIENT_INTERFACE:
240 default:
241 break;
242 }
243
244 return ret;
245 }
246
sreq_set_feature(struct usbd_contex * const uds_ctx)247 static int sreq_set_feature(struct usbd_contex *const uds_ctx)
248 {
249 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
250 uint8_t ep = setup->wIndex;
251 int ret = 0;
252
253 /* Not specified if wLength is non-zero, treat as error */
254 if (setup->wLength) {
255 errno = -ENOTSUP;
256 return 0;
257 }
258
259 /*
260 * TEST_MODE is not supported yet, other are not specified
261 * in default state, treat as error.
262 */
263 if (usbd_state_is_default(uds_ctx)) {
264 errno = -EPERM;
265 return 0;
266 }
267
268 if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
269 errno = -EPERM;
270 return 0;
271 }
272
273 switch (setup->RequestType.recipient) {
274 case USB_REQTYPE_RECIPIENT_DEVICE:
275 if (setup->wIndex != 0) {
276 errno = -EPERM;
277 return 0;
278 }
279
280 if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
281 LOG_DBG("Set feature remote wakeup");
282 uds_ctx->status.rwup = true;
283 }
284 break;
285 case USB_REQTYPE_RECIPIENT_ENDPOINT:
286 if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
287 /* UDC checks if endpoint is enabled */
288 errno = usbd_ep_set_halt(uds_ctx, ep);
289 ret = (errno == -EPERM) ? errno : 0;
290 if (ret == 0) {
291 /* Notify class instance */
292 sreq_feature_halt_notify(uds_ctx, ep, true);
293 }
294 break;
295 }
296 break;
297 case USB_REQTYPE_RECIPIENT_INTERFACE:
298 default:
299 break;
300 }
301
302 return ret;
303 }
304
std_request_to_device(struct usbd_contex * const uds_ctx,struct net_buf * const buf)305 static int std_request_to_device(struct usbd_contex *const uds_ctx,
306 struct net_buf *const buf)
307 {
308 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
309 int ret;
310
311 switch (setup->bRequest) {
312 case USB_SREQ_SET_ADDRESS:
313 ret = sreq_set_address(uds_ctx);
314 break;
315 case USB_SREQ_SET_CONFIGURATION:
316 ret = sreq_set_configuration(uds_ctx);
317 break;
318 case USB_SREQ_SET_INTERFACE:
319 ret = sreq_set_interface(uds_ctx);
320 break;
321 case USB_SREQ_CLEAR_FEATURE:
322 ret = sreq_clear_feature(uds_ctx);
323 break;
324 case USB_SREQ_SET_FEATURE:
325 ret = sreq_set_feature(uds_ctx);
326 break;
327 default:
328 errno = -ENOTSUP;
329 ret = 0;
330 break;
331 }
332
333 return ret;
334 }
335
sreq_get_status(struct usbd_contex * const uds_ctx,struct net_buf * const buf)336 static int sreq_get_status(struct usbd_contex *const uds_ctx,
337 struct net_buf *const buf)
338 {
339 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
340 uint8_t ep = setup->wIndex;
341 uint16_t response = 0;
342
343 if (setup->wLength != sizeof(response)) {
344 errno = -ENOTSUP;
345 return 0;
346 }
347
348 /* Not specified in default state, treat as error */
349 if (usbd_state_is_default(uds_ctx)) {
350 errno = -EPERM;
351 return 0;
352 }
353
354 if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
355 errno = -EPERM;
356 return 0;
357 }
358
359 switch (setup->RequestType.recipient) {
360 case USB_REQTYPE_RECIPIENT_DEVICE:
361 if (setup->wIndex != 0) {
362 errno = -EPERM;
363 return 0;
364 }
365
366 response = uds_ctx->status.rwup ?
367 USB_GET_STATUS_REMOTE_WAKEUP : 0;
368 break;
369 case USB_REQTYPE_RECIPIENT_ENDPOINT:
370 response = usbd_ep_is_halted(uds_ctx, ep) ? BIT(0) : 0;
371 break;
372 case USB_REQTYPE_RECIPIENT_INTERFACE:
373 /* Response is always reset to zero.
374 * TODO: add check if interface exist?
375 */
376 break;
377 default:
378 break;
379 }
380
381 if (net_buf_tailroom(buf) < setup->wLength) {
382 errno = -ENOMEM;
383 return 0;
384 }
385
386 LOG_DBG("Get Status response 0x%04x", response);
387 net_buf_add_le16(buf, response);
388
389 return 0;
390 }
391
sreq_get_desc_cfg(struct usbd_contex * const uds_ctx,struct net_buf * const buf,const uint8_t idx)392 static int sreq_get_desc_cfg(struct usbd_contex *const uds_ctx,
393 struct net_buf *const buf,
394 const uint8_t idx)
395 {
396 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
397 struct usb_cfg_descriptor *cfg_desc;
398 struct usbd_config_node *cfg_nd;
399 struct usbd_class_node *c_nd;
400 uint16_t len;
401
402 cfg_nd = usbd_config_get(uds_ctx, idx + 1);
403 if (cfg_nd == NULL) {
404 LOG_ERR("Configuration descriptor %u not found", idx + 1);
405 errno = -ENOTSUP;
406 return 0;
407 }
408
409 cfg_desc = cfg_nd->desc;
410 len = MIN(setup->wLength, net_buf_tailroom(buf));
411 net_buf_add_mem(buf, cfg_desc, MIN(len, cfg_desc->bLength));
412
413 SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
414 struct usb_desc_header *head = c_nd->data->desc;
415 size_t desc_len = usbd_class_desc_len(c_nd);
416
417 len = MIN(setup->wLength, net_buf_tailroom(buf));
418 net_buf_add_mem(buf, head, MIN(len, desc_len));
419 }
420
421 LOG_DBG("Get Configuration descriptor %u, len %u", idx, buf->len);
422
423 return 0;
424 }
425
sreq_get_desc(struct usbd_contex * const uds_ctx,struct net_buf * const buf,const uint8_t type,const uint8_t idx)426 static int sreq_get_desc(struct usbd_contex *const uds_ctx,
427 struct net_buf *const buf,
428 const uint8_t type, const uint8_t idx)
429 {
430 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
431 struct usb_desc_header *head;
432 size_t len;
433
434 if (type == USB_DESC_DEVICE) {
435 head = uds_ctx->desc;
436 } else {
437 head = usbd_get_descriptor(uds_ctx, type, idx);
438 }
439
440 if (head == NULL) {
441 errno = -ENOTSUP;
442 return 0;
443 }
444
445 len = MIN(setup->wLength, net_buf_tailroom(buf));
446 net_buf_add_mem(buf, head, MIN(len, head->bLength));
447
448 return 0;
449 }
450
sreq_get_descriptor(struct usbd_contex * const uds_ctx,struct net_buf * const buf)451 static int sreq_get_descriptor(struct usbd_contex *const uds_ctx,
452 struct net_buf *const buf)
453 {
454 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
455 uint8_t desc_type = USB_GET_DESCRIPTOR_TYPE(setup->wValue);
456 uint8_t desc_idx = USB_GET_DESCRIPTOR_INDEX(setup->wValue);
457
458 LOG_DBG("Get Descriptor request type %u index %u",
459 desc_type, desc_idx);
460
461 switch (desc_type) {
462 case USB_DESC_DEVICE:
463 return sreq_get_desc(uds_ctx, buf, USB_DESC_DEVICE, 0);
464 case USB_DESC_CONFIGURATION:
465 return sreq_get_desc_cfg(uds_ctx, buf, desc_idx);
466 case USB_DESC_STRING:
467 return sreq_get_desc(uds_ctx, buf, USB_DESC_STRING, desc_idx);
468 case USB_DESC_INTERFACE:
469 case USB_DESC_ENDPOINT:
470 case USB_DESC_OTHER_SPEED:
471 default:
472 break;
473 }
474
475 errno = -ENOTSUP;
476 return 0;
477 }
478
sreq_get_configuration(struct usbd_contex * const uds_ctx,struct net_buf * const buf)479 static int sreq_get_configuration(struct usbd_contex *const uds_ctx,
480 struct net_buf *const buf)
481
482 {
483 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
484 uint8_t cfg = usbd_get_config_value(uds_ctx);
485
486 /* Not specified in default state, treat as error */
487 if (usbd_state_is_default(uds_ctx)) {
488 errno = -EPERM;
489 return 0;
490 }
491
492 if (setup->wLength != sizeof(cfg)) {
493 errno = -ENOTSUP;
494 return 0;
495 }
496
497 if (net_buf_tailroom(buf) < setup->wLength) {
498 errno = -ENOMEM;
499 return 0;
500 }
501
502 net_buf_add_u8(buf, cfg);
503
504 return 0;
505 }
506
sreq_get_interface(struct usbd_contex * const uds_ctx,struct net_buf * const buf)507 static int sreq_get_interface(struct usbd_contex *const uds_ctx,
508 struct net_buf *const buf)
509 {
510 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
511 struct usb_cfg_descriptor *cfg_desc;
512 struct usbd_config_node *cfg_nd;
513 uint8_t cur_alt;
514
515 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_INTERFACE) {
516 errno = -EPERM;
517 return 0;
518 }
519
520 cfg_nd = usbd_config_get_current(uds_ctx);
521 cfg_desc = cfg_nd->desc;
522
523 if (setup->wIndex > UINT8_MAX ||
524 setup->wIndex > cfg_desc->bNumInterfaces) {
525 errno = -ENOTSUP;
526 return 0;
527 }
528
529 if (usbd_get_alt_value(uds_ctx, setup->wIndex, &cur_alt)) {
530 errno = -ENOTSUP;
531 return 0;
532 }
533
534 LOG_DBG("Get Interfaces %u, alternate %u",
535 setup->wIndex, cur_alt);
536
537 if (setup->wLength != sizeof(cur_alt)) {
538 errno = -ENOTSUP;
539 return 0;
540 }
541
542 if (net_buf_tailroom(buf) < setup->wLength) {
543 errno = -ENOMEM;
544 return 0;
545 }
546
547 net_buf_add_u8(buf, cur_alt);
548
549 return 0;
550 }
551
std_request_to_host(struct usbd_contex * const uds_ctx,struct net_buf * const buf)552 static int std_request_to_host(struct usbd_contex *const uds_ctx,
553 struct net_buf *const buf)
554 {
555 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
556 int ret;
557
558 switch (setup->bRequest) {
559 case USB_SREQ_GET_STATUS:
560 ret = sreq_get_status(uds_ctx, buf);
561 break;
562 case USB_SREQ_GET_DESCRIPTOR:
563 ret = sreq_get_descriptor(uds_ctx, buf);
564 break;
565 case USB_SREQ_GET_CONFIGURATION:
566 ret = sreq_get_configuration(uds_ctx, buf);
567 break;
568 case USB_SREQ_GET_INTERFACE:
569 ret = sreq_get_interface(uds_ctx, buf);
570 break;
571 default:
572 errno = -ENOTSUP;
573 ret = 0;
574 break;
575 }
576
577 return ret;
578 }
579
nonstd_request(struct usbd_contex * const uds_ctx,struct net_buf * const dbuf)580 static int nonstd_request(struct usbd_contex *const uds_ctx,
581 struct net_buf *const dbuf)
582 {
583 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
584 struct usbd_class_node *c_nd = NULL;
585 int ret = 0;
586
587 switch (setup->RequestType.recipient) {
588 case USB_REQTYPE_RECIPIENT_ENDPOINT:
589 c_nd = usbd_class_get_by_ep(uds_ctx, setup->wIndex);
590 break;
591 case USB_REQTYPE_RECIPIENT_INTERFACE:
592 c_nd = usbd_class_get_by_iface(uds_ctx, setup->wIndex);
593 break;
594 case USB_REQTYPE_RECIPIENT_DEVICE:
595 c_nd = usbd_class_get_by_req(uds_ctx, setup->bRequest);
596 break;
597 default:
598 break;
599 }
600
601 if (c_nd != NULL) {
602 if (reqtype_is_to_device(setup)) {
603 ret = usbd_class_control_to_dev(c_nd, setup, dbuf);
604 } else {
605 ret = usbd_class_control_to_host(c_nd, setup, dbuf);
606 }
607 } else {
608 errno = -ENOTSUP;
609 }
610
611 return ret;
612 }
613
handle_setup_request(struct usbd_contex * const uds_ctx,struct net_buf * const buf)614 static int handle_setup_request(struct usbd_contex *const uds_ctx,
615 struct net_buf *const buf)
616 {
617 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
618 int ret;
619
620 errno = 0;
621
622 switch (setup->RequestType.type) {
623 case USB_REQTYPE_TYPE_STANDARD:
624 if (reqtype_is_to_device(setup)) {
625 ret = std_request_to_device(uds_ctx, buf);
626 } else {
627 ret = std_request_to_host(uds_ctx, buf);
628 }
629 break;
630 case USB_REQTYPE_TYPE_CLASS:
631 case USB_REQTYPE_TYPE_VENDOR:
632 ret = nonstd_request(uds_ctx, buf);
633 break;
634 default:
635 errno = -ENOTSUP;
636 ret = 0;
637 }
638
639 if (errno) {
640 LOG_INF("protocol error:");
641 LOG_HEXDUMP_INF(setup, sizeof(*setup), "setup:");
642 if (errno == -ENOTSUP) {
643 LOG_INF("not supported");
644 }
645 if (errno == -EPERM) {
646 LOG_INF("not permitted in device state %u",
647 uds_ctx->ch9_data.state);
648 }
649 }
650
651 return ret;
652 }
653
ctrl_xfer_get_setup(struct usbd_contex * const uds_ctx,struct net_buf * const buf)654 static int ctrl_xfer_get_setup(struct usbd_contex *const uds_ctx,
655 struct net_buf *const buf)
656 {
657 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
658 struct net_buf *buf_b;
659 struct udc_buf_info *bi, *bi_b;
660
661 if (buf->len < sizeof(struct usb_setup_packet)) {
662 return -EINVAL;
663 }
664
665 memcpy(setup, buf->data, sizeof(struct usb_setup_packet));
666
667 setup->wValue = sys_le16_to_cpu(setup->wValue);
668 setup->wIndex = sys_le16_to_cpu(setup->wIndex);
669 setup->wLength = sys_le16_to_cpu(setup->wLength);
670
671 bi = udc_get_buf_info(buf);
672
673 buf_b = buf->frags;
674 if (buf_b == NULL) {
675 LOG_ERR("Buffer for data|status is missing");
676 return -ENODATA;
677 }
678
679 bi_b = udc_get_buf_info(buf_b);
680
681 if (reqtype_is_to_device(setup)) {
682 if (setup->wLength) {
683 if (!bi_b->data) {
684 LOG_ERR("%p is not data", buf_b);
685 return -EINVAL;
686 }
687 } else {
688 if (!bi_b->status) {
689 LOG_ERR("%p is not status", buf_b);
690 return -EINVAL;
691 }
692 }
693 } else {
694 if (!setup->wLength) {
695 LOG_ERR("device-to-host with wLength zero");
696 return -ENOTSUP;
697 }
698
699 if (!bi_b->data) {
700 LOG_ERR("%p is not data", buf_b);
701 return -EINVAL;
702 }
703
704 }
705
706 return 0;
707 }
708
spool_data_out(struct net_buf * const buf)709 static struct net_buf *spool_data_out(struct net_buf *const buf)
710 {
711 struct net_buf *next_buf = buf;
712 struct udc_buf_info *bi;
713
714 while (next_buf) {
715 LOG_INF("spool %p", next_buf);
716 next_buf = net_buf_frag_del(NULL, next_buf);
717 if (next_buf) {
718 bi = udc_get_buf_info(next_buf);
719 if (bi->status) {
720 return next_buf;
721 }
722 }
723 }
724
725 return NULL;
726 }
727
usbd_handle_ctrl_xfer(struct usbd_contex * const uds_ctx,struct net_buf * const buf,const int err)728 int usbd_handle_ctrl_xfer(struct usbd_contex *const uds_ctx,
729 struct net_buf *const buf, const int err)
730 {
731 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
732 struct udc_buf_info *bi;
733 int ret = 0;
734
735 bi = udc_get_buf_info(buf);
736 if (USB_EP_GET_IDX(bi->ep)) {
737 LOG_ERR("Can only handle control requests");
738 return -EIO;
739 }
740
741 if (err && err != -ENOMEM && !bi->setup) {
742 if (err == -ECONNABORTED) {
743 LOG_INF("Transfer 0x%02x aborted (bus reset?)", bi->ep);
744 net_buf_unref(buf);
745 return 0;
746 }
747
748 LOG_ERR("Control transfer for 0x%02x has error %d, halt",
749 bi->ep, err);
750 net_buf_unref(buf);
751 return err;
752 }
753
754 LOG_INF("Handle control %p ep 0x%02x, len %u, s:%u d:%u s:%u",
755 buf, bi->ep, buf->len, bi->setup, bi->data, bi->status);
756
757 if (bi->setup && bi->ep == USB_CONTROL_EP_OUT) {
758 struct net_buf *next_buf;
759
760 if (ctrl_xfer_get_setup(uds_ctx, buf)) {
761 LOG_ERR("Malformed setup packet");
762 net_buf_unref(buf);
763 goto ctrl_xfer_stall;
764 }
765
766 /* Remove setup packet buffer from the chain */
767 next_buf = net_buf_frag_del(NULL, buf);
768 if (next_buf == NULL) {
769 LOG_ERR("Buffer for data|status is missing");
770 goto ctrl_xfer_stall;
771 }
772
773 /*
774 * Handle request and data stage, next_buf is either
775 * data+status or status buffers.
776 */
777 ret = handle_setup_request(uds_ctx, next_buf);
778 if (ret) {
779 net_buf_unref(next_buf);
780 return ret;
781 }
782
783 if (errno) {
784 /*
785 * Halt, only protocol errors are recoverable.
786 * Free data stage and linked status stage buffer.
787 */
788 net_buf_unref(next_buf);
789 goto ctrl_xfer_stall;
790 }
791
792 ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_STATUS_STAGE);
793 if (reqtype_is_to_device(setup) && setup->wLength) {
794 /* Enqueue STATUS (IN) buffer */
795 next_buf = spool_data_out(next_buf);
796 if (next_buf == NULL) {
797 LOG_ERR("Buffer for status is missing");
798 goto ctrl_xfer_stall;
799 }
800
801 ret = usbd_ep_ctrl_enqueue(uds_ctx, next_buf);
802 } else {
803 /* Enqueue DATA (IN) or STATUS (OUT) buffer */
804 ret = usbd_ep_ctrl_enqueue(uds_ctx, next_buf);
805 }
806
807 return ret;
808 }
809
810 if (bi->status && bi->ep == USB_CONTROL_EP_OUT) {
811 if (ch9_get_ctrl_type(uds_ctx) == CTRL_AWAIT_STATUS_STAGE) {
812 LOG_INF("s-in-status finished");
813 } else {
814 LOG_WRN("Awaited s-in-status not finished");
815 }
816
817 net_buf_unref(buf);
818
819 return 0;
820 }
821
822 if (bi->status && bi->ep == USB_CONTROL_EP_IN) {
823 net_buf_unref(buf);
824
825 if (ch9_get_ctrl_type(uds_ctx) == CTRL_AWAIT_STATUS_STAGE) {
826 LOG_INF("s-(out)-status finished");
827 if (unlikely(uds_ctx->ch9_data.new_address)) {
828 return set_address_after_status_stage(uds_ctx);
829 }
830 } else {
831 LOG_WRN("Awaited s-(out)-status not finished");
832 }
833
834 return ret;
835 }
836
837 ctrl_xfer_stall:
838 /*
839 * Halt only the endpoint over which the host expects
840 * data or status stage. This facilitates the work of the drivers.
841 *
842 * In the case there is -ENOMEM for data OUT stage halt
843 * control OUT endpoint.
844 */
845 if (reqtype_is_to_host(setup)) {
846 ret = udc_ep_set_halt(uds_ctx->dev, USB_CONTROL_EP_IN);
847 } else if (setup->wLength) {
848 uint8_t ep = (err == -ENOMEM) ? USB_CONTROL_EP_OUT : USB_CONTROL_EP_IN;
849
850 ret = udc_ep_set_halt(uds_ctx->dev, ep);
851 } else {
852 ret = udc_ep_set_halt(uds_ctx->dev, USB_CONTROL_EP_IN);
853 }
854
855 ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_SETUP_DATA);
856
857 return ret;
858 }
859
usbd_init_control_pipe(struct usbd_contex * const uds_ctx)860 int usbd_init_control_pipe(struct usbd_contex *const uds_ctx)
861 {
862 uds_ctx->ch9_data.state = USBD_STATE_DEFAULT;
863 ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_SETUP_DATA);
864
865 return 0;
866 }
867