1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <ztest.h>
8 #include <tc_util.h>
9 
10 #include <sys/byteorder.h>
11 #include <usb/usb_device.h>
12 
13 /* Max packet size for endpoints */
14 #define BULK_EP_MPS		64
15 
16 #define ENDP_BULK_IN		0x81
17 
18 #define VALID_EP		ENDP_BULK_IN
19 #define INVALID_EP		0x20
20 
21 struct usb_device_desc {
22 	struct usb_if_descriptor if0;
23 	struct usb_ep_descriptor if0_in_ep;
24 } __packed;
25 
26 #define INITIALIZER_IF							\
27 	{								\
28 		.bLength = sizeof(struct usb_if_descriptor),		\
29 		.bDescriptorType = USB_DESC_INTERFACE,			\
30 		.bInterfaceNumber = 0,					\
31 		.bAlternateSetting = 0,					\
32 		.bNumEndpoints = 1,					\
33 		.bInterfaceClass = USB_BCC_VENDOR,			\
34 		.bInterfaceSubClass = 0,				\
35 		.bInterfaceProtocol = 0,				\
36 		.iInterface = 0,					\
37 	}
38 
39 #define INITIALIZER_IF_EP(addr, attr, mps, interval)			\
40 	{								\
41 		.bLength = sizeof(struct usb_ep_descriptor),		\
42 		.bDescriptorType = USB_DESC_ENDPOINT,			\
43 		.bEndpointAddress = addr,				\
44 		.bmAttributes = attr,					\
45 		.wMaxPacketSize = sys_cpu_to_le16(mps),			\
46 		.bInterval = interval,					\
47 	}
48 
49 USBD_CLASS_DESCR_DEFINE(primary, 0) struct usb_device_desc dev_desc = {
50 	.if0 = INITIALIZER_IF,
51 	.if0_in_ep = INITIALIZER_IF_EP(ENDP_BULK_IN, USB_DC_EP_BULK,
52 				       BULK_EP_MPS, 0),
53 };
54 
status_cb(struct usb_cfg_data * cfg,enum usb_dc_status_code status,const uint8_t * param)55 static void status_cb(struct usb_cfg_data *cfg,
56 		      enum usb_dc_status_code status,
57 		      const uint8_t *param)
58 {
59 	ARG_UNUSED(cfg);
60 	ARG_UNUSED(status);
61 	ARG_UNUSED(param);
62 }
63 
64 /* EP Bulk IN handler, used to send data to the Host */
bulk_in(uint8_t ep,enum usb_dc_ep_cb_status_code ep_status)65 static void bulk_in(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status)
66 {
67 }
68 
69 /* Describe EndPoints configuration */
70 static struct usb_ep_cfg_data device_ep[] = {
71 	{
72 		.ep_cb = bulk_in,
73 		.ep_addr = ENDP_BULK_IN
74 	},
75 };
76 
77 USBD_CFG_DATA_DEFINE(primary, device) struct usb_cfg_data device_config = {
78 	.usb_device_description = NULL,
79 	.interface_descriptor = &dev_desc.if0,
80 	.cb_usb_status = status_cb,
81 	.interface = {
82 		.vendor_handler = NULL,
83 		.class_handler = NULL,
84 		.custom_handler = NULL,
85 	},
86 	.num_endpoints = ARRAY_SIZE(device_ep),
87 	.endpoint = device_ep,
88 };
89 
test_usb_disable(void)90 static void test_usb_disable(void)
91 {
92 	zassert_equal(usb_disable(), TC_PASS, "usb_disable() failed");
93 }
94 
test_usb_deconfig(void)95 static void test_usb_deconfig(void)
96 {
97 	zassert_equal(usb_deconfig(), TC_PASS, "usb_deconfig() failed");
98 }
99 
100 /* Test USB Device Cotnroller API */
test_usb_dc_api(void)101 static void test_usb_dc_api(void)
102 {
103 	/* Control endpoins are configured */
104 	zassert_equal(usb_dc_ep_mps(0x0), 64,
105 		      "usb_dc_ep_mps(0x00) failed");
106 	zassert_equal(usb_dc_ep_mps(0x80), 64,
107 		      "usb_dc_ep_mps(0x80) failed");
108 
109 	/* Bulk EP is not configured yet */
110 	zassert_equal(usb_dc_ep_mps(ENDP_BULK_IN), 0,
111 		      "usb_dc_ep_mps(ENDP_BULK_IN) not configured");
112 }
113 
114 /* Test USB Device Cotnroller API for invalid parameters */
test_usb_dc_api_invalid(void)115 static void test_usb_dc_api_invalid(void)
116 {
117 	uint32_t size;
118 	uint8_t byte;
119 
120 	/* Set stall to invalid EP */
121 	zassert_not_equal(usb_dc_ep_set_stall(INVALID_EP), TC_PASS,
122 			  "usb_dc_ep_set_stall(INVALID_EP)");
123 
124 	/* Clear stall to invalid EP */
125 	zassert_not_equal(usb_dc_ep_clear_stall(INVALID_EP), TC_PASS,
126 			  "usb_dc_ep_clear_stall(INVALID_EP)");
127 
128 	/* Check if the selected endpoint is stalled */
129 	zassert_not_equal(usb_dc_ep_is_stalled(INVALID_EP, &byte), TC_PASS,
130 			  "usb_dc_ep_is_stalled(INVALID_EP, stalled)");
131 	zassert_not_equal(usb_dc_ep_is_stalled(VALID_EP, NULL), TC_PASS,
132 			  "usb_dc_ep_is_stalled(VALID_EP, NULL)");
133 
134 	/* Halt invalid EP */
135 	zassert_not_equal(usb_dc_ep_halt(INVALID_EP), TC_PASS,
136 			  "usb_dc_ep_halt(INVALID_EP)");
137 
138 	/* Enable invalid EP */
139 	zassert_not_equal(usb_dc_ep_enable(INVALID_EP), TC_PASS,
140 			  "usb_dc_ep_enable(INVALID_EP)");
141 
142 	/* Disable invalid EP */
143 	zassert_not_equal(usb_dc_ep_disable(INVALID_EP), TC_PASS,
144 			  "usb_dc_ep_disable(INVALID_EP)");
145 
146 	/* Flush invalid EP */
147 	zassert_not_equal(usb_dc_ep_flush(INVALID_EP), TC_PASS,
148 			  "usb_dc_ep_flush(INVALID_EP)");
149 
150 	/* Set callback to invalid EP */
151 	zassert_not_equal(usb_dc_ep_set_callback(INVALID_EP, NULL), TC_PASS,
152 			  "usb_dc_ep_set_callback(INVALID_EP, NULL)");
153 
154 	/* Write to invalid EP */
155 	zassert_not_equal(usb_dc_ep_write(INVALID_EP, &byte, sizeof(byte),
156 					  &size),
157 			  TC_PASS, "usb_dc_ep_write(INVALID_EP)");
158 
159 	/* Read invalid EP */
160 	zassert_not_equal(usb_dc_ep_read(INVALID_EP, &byte, sizeof(byte),
161 					 &size),
162 			  TC_PASS, "usb_dc_ep_read(INVALID_EP)");
163 	zassert_not_equal(usb_dc_ep_read_wait(INVALID_EP, &byte, sizeof(byte),
164 					      &size),
165 			  TC_PASS, "usb_dc_ep_read_wait(INVALID_EP)");
166 	zassert_not_equal(usb_dc_ep_read_continue(INVALID_EP), TC_PASS,
167 			  "usb_dc_ep_read_continue(INVALID_EP)");
168 
169 	/* Get endpoint max packet size for invalid EP */
170 	zassert_not_equal(usb_dc_ep_mps(INVALID_EP), TC_PASS,
171 			  "usb_dc_ep_mps(INVALID_EP)");
172 }
173 
test_usb_dc_api_read_write(void)174 static void test_usb_dc_api_read_write(void)
175 {
176 	uint32_t size;
177 	uint8_t byte;
178 
179 	/* Read invalid EP */
180 	zassert_not_equal(usb_read(INVALID_EP, &byte, sizeof(byte), &size),
181 			  TC_PASS, "usb_read(INVALID_EP)");
182 
183 	/* Write to invalid EP */
184 	zassert_not_equal(usb_write(INVALID_EP, &byte, sizeof(byte), &size),
185 			  TC_PASS, "usb_write(INVALID_EP)");
186 }
187 
188 /* test case main entry */
test_main(void)189 void test_main(void)
190 {
191 	int ret;
192 
193 	ret = usb_enable(NULL);
194 	if (ret != 0) {
195 		printk("Failed to enable USB\n");
196 		return;
197 	}
198 
199 	ztest_test_suite(test_device,
200 			 /* Test API for not USB attached state */
201 			 ztest_unit_test(test_usb_dc_api_invalid),
202 			 ztest_unit_test(test_usb_dc_api),
203 			 ztest_unit_test(test_usb_dc_api_read_write),
204 			 ztest_unit_test(test_usb_dc_api_invalid),
205 			 ztest_unit_test(test_usb_deconfig),
206 			 ztest_unit_test(test_usb_disable));
207 
208 	ztest_run_test_suite(test_device);
209 }
210