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