1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(usb_bos, CONFIG_USB_DEVICE_LOG_LEVEL);
9 
10 #include <bos_desc.h>
11 
12 #include <zephyr/kernel.h>
13 #include <zephyr/usb/usb_device.h>
14 #include <zephyr/usb/bos.h>
15 
16 extern const uint8_t __usb_bos_desc_start[];
17 extern const uint8_t __usb_bos_desc_end[];
18 
19 #define USB_DEVICE_BOS_DESC_DEFINE_HDR \
20 	static __in_section(usb, bos_desc_area, 0) __aligned(1) __used
21 
22 USB_DEVICE_BOS_DESC_DEFINE_HDR struct usb_bos_descriptor bos_hdr = {
23 	.bLength = sizeof(struct usb_bos_descriptor),
24 	.bDescriptorType = USB_DESC_BOS,
25 	.wTotalLength = 0, /* should be corrected with register */
26 	.bNumDeviceCaps = 0, /* should be set with register */
27 };
28 
usb_bos_get_length(void)29 size_t usb_bos_get_length(void)
30 {
31 	return __usb_bos_desc_end - __usb_bos_desc_start;
32 }
33 
usb_bos_get_header(void)34 const void *usb_bos_get_header(void)
35 {
36 	return __usb_bos_desc_start;
37 }
38 
usb_bos_fix_total_length(void)39 void usb_bos_fix_total_length(void)
40 {
41 	bos_hdr.wTotalLength = usb_bos_get_length();
42 }
43 
usb_bos_register_cap(void * desc)44 void usb_bos_register_cap(void *desc)
45 {
46 	ARG_UNUSED(desc);
47 
48 	/* Has effect only on first register */
49 	bos_hdr.wTotalLength = usb_bos_get_length();
50 
51 	bos_hdr.bNumDeviceCaps += 1U;
52 }
53 
usb_handle_bos(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data)54 int usb_handle_bos(struct usb_setup_packet *setup,
55 		   int32_t *len, uint8_t **data)
56 {
57 	if (USB_GET_DESCRIPTOR_TYPE(setup->wValue) == USB_DESC_BOS) {
58 		LOG_DBG("Read BOS descriptor");
59 		*data = (uint8_t *)usb_bos_get_header();
60 		*len = usb_bos_get_length();
61 
62 		return 0;
63 	}
64 
65 	return -ENOTSUP;
66 }
67