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